日期:2014-05-17  浏览次数:20970 次

简单的API 挂钩问题
/*
最近学习PE结构,就写了个简单的API替换,我想问下各位大神,我的这段代码哪儿出现了问题,为什么release版本和debug版本最后几行执行回不一样,谢谢
*/
// ImportAddress.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <Windows.h>
#include <WindowsX.h>


DWORD data = 0;
DWORD * message = NULL;


//自定义挂钩函数
int (APIENTRY MyMessageBox)(
   HWND hWnd, 
   LPCTSTR lpText, 
   LPCTSTR lpCaption, 
   UINT uType
   )
{
printf("hellor word!\n");
return 0;

}

int _tmain(int argc, _TCHAR* argv[])
{
printf("%p",MyMessageBox);
LPVOID baseAddress = GetModuleHandle(NULL);

PIMAGE_DOS_HEADER pDosHead = (PIMAGE_DOS_HEADER)baseAddress;

PIMAGE_NT_HEADERS  pNtHead = (PIMAGE_NT_HEADERS)((BYTE*)baseAddress+pDosHead->e_lfanew);

PIMAGE_IMPORT_DESCRIPTOR pImportDes = (PIMAGE_IMPORT_DESCRIPTOR)((BYTE*)baseAddress+pNtHead->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);


//MessageBoxA(NULL,NULL,NULL,MB_OK);
while(pImportDes->FirstThunk)
{

char *dllName = (char *)((BYTE*)baseAddress+pImportDes->Name);
printf("the module name\t%s\n",dllName);
int n = 0;
PIMAGE_THUNK_DATA pThunk = (PIMAGE_THUNK_DATA)((BYTE*)baseAddress+pImportDes->OriginalFirstThunk);
while (pThunk->u1.Function)
{
char *FunName = (char*)((BYTE*)baseAddress+(DWORD)pThunk->u1.AddressOfData+2);
    DWORD * address = (DWORD*)((BYTE*)baseAddress+pImportDes->FirstThunk)+n;
printf("          %-30s%x\n",FunName,*address);
n++;
pThunk++;
//判断是否为MessageBoxW函数
if(strcmp(FunName,"MessageBoxW")==0)
{
MEMORY_BASIC_INFORMATION mbi ;
VirtualQuery(address,&mbi,sizeof(mbi));
DWORD oldProtect;
data  = *address;
message = address;

VirtualProtect(mbi.BaseAddress,4096,PAGE_READWRITE,&oldProtect);
//将地址替换为自定义的函数地址
*address = (DWORD)MyMessageBox;
printf("%d   %d\n\n",address,data);
VirtualProtect(mbi.BaseAddress,4096,oldProtect,NULL);
}
}
pImportDes++;
printf("\n\n");


}
printf("%d     %d\n\n",message,data);
printf("%d\n",&message);
//调用函数 为自定义函数执行体
MessageBox(NULL,NULL,NULL,MB_OK);
MEMORY_BASIC_INFORMATION mi;
VirtualQuery((LPVOID)*message,&mi,sizeof(mi));
DWORD protect ;
VirtualProtect(mi.BaseAddress,4096,PAGE_READWRITE,&protect);
//还原地址
*message = data;
VirtualProtect(mi.BaseAddress,4096,protect,NULL);

    //再次调用,为什么release版本和debug版本结果不一样????????
    MessageBox(NULL,NULL,NULL,MB_OK);

return 0;
}


------最佳解决方案--------------------
熟悉PE结构:
http://blog.csdn.net/agoago_2009/article/details/7171070
注意使用ImageRvaToVa
------其他解决方案--------------------
恩 好的 我仔细看看,谢谢