#include "windows.h"
#include "stdio.h"
BOOL bMessage = 0;
typedef int (WINAPI *PFNMESSAGEBOX)(HWND,LPCSTR,LPCSTR,UINT);
PROC g_orgAddr = (PROC)MessageBoxA;
int MyMessageBox(HWND hWnd,LPCSTR lpContent,LPCSTR lpTitle,UINT uType);
int main()
{
HMODULE hMod = GetModuleHandle(NULL);
IMAGE_DOS_HEADER* pDosHeader = (IMAGE_DOS_HEADER*)(BYTE*)hMod;
IMAGE_OPTIONAL_HEADER* pOptHeader = (IMAGE_OPTIONAL_HEADER*)(pDosHeader->e_lfanew + 24 + (BYTE*)hMod);
IMAGE_IMPORT_DESCRIPTOR* pImportDesc = (IMAGE_IMPORT_DESCRIPTOR*)((BYTE*)hMod + pOptHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress); 
while(pImportDesc->FirstThunk)
{
char* pszDllName = (char*)(pImportDesc->Name + (BYTE*)hMod);
printf("Dll Name : %-10s \n",pszDllName);
IMAGE_THUNK_DATA* pThunk = (IMAGE_THUNK_DATA*)((BYTE*)hMod + pImportDesc->OriginalFirstThunk);
while(pThunk->u1.Function)
{
char* pszFuncName = (char*)((DWORD)pThunk->u1.AddressOfData + (BYTE*)hMod + 2);
DWORD* pszFuncAddr = (DWORD*)(pThunk->u1.Function + (BYTE*)hMod);
printf("\t函数名称:%-30s",pszFuncName);
printf("函数地址:%-8x\n",pszFuncAddr);
char* fnName = pszFuncName;
if(strcmp(fnName,"MessageBoxA")==0)
{
bMessage = 1;
DWORD* lpNewAddr = (DWORD*)MyMessageBox;
printf("\t%-39s写新地址:%x \n","",lpNewAddr);
VirtualProtect(pszFuncAddr,sizeof(DWORD),PAGE_READWRITE,NULL);
BOOL bRet = ::WriteProcessMemory(GetCurrentProcess(),pszFuncAddr,lpNewAddr,sizeof(DWORD),NULL);
DWORD* gpNewAddr = NULL;
::ReadProcessMemory(GetCurrentProcess(),pszFuncAddr,gpNewAddr,sizeof(DWORD),NULL); 
if(bRet)
puts("\tWriteProcessMemory successfully");
printf("\t函数名称:%-30s",fnName);
printf("函数地址:%x\n",gpNewAddr);
}
pThunk++;
}
pImportDesc++;
}
if(bMessage)
MessageBox(NULL,"当你看到这个,说明没有HOOK成功啊!","失败了!",0);
getchar();
return 0;
}
int WINAPI MyMessageBox(HWND hWnd,LPCSTR lpContent,LPCSTR lpTitle,UINT uType)
{
return ((PFNMESSAGEBOX)g_orgAddr)(hWnd,"原函数退休了,我接管了!",lpTitle,uType);
}这个代码编译通过了,运行结果有问题:我HOOK掉了MessageBoxA函数,这个结果说WriteProcessMemory是成功了的,但是最后弹出来的还是原来的没有被HOOk的函数!!我用ReadProcessMemory去验证到底写成功了没,结果是没有读出数据,不知道这是怎么回事!!!
请大家帮我看看,谢谢哦

解决方案 »

  1.   

    没有用到动态连接库和全局钩子?看看api hook是如何实现的
      

  2.   

    hook api... 
    1. 要hook 其他进程的api,则需要dll注入.
    2. hook 自己进程的api,则不需要dll. 直接在自己工程里hook之.
    你这个就是hook本进程api而已。
      

  3.   

    #include "windows.h"
    #include "stdio.h"
    BOOL bMessage = 0;
    typedef int (WINAPI *PFNMESSAGEBOX)(HWND,LPCSTR,LPCSTR,UINT);
    //PROC g_orgAddr = (PROC)MessageBoxA; //这样会造成死循环的
    PFNMESSAGEBOX g_orgAddr = NULL; //既然定义了PFNMESSAGEBOX就不用PROC
    //int MyMessageBox(HWND hWnd,LPCSTR lpContent,LPCSTR lpTitle,UINT uType);
    int WINAPI MyMessageBox(HWND hWnd,LPCSTR lpContent,LPCSTR lpTitle,UINT uType);//漏了WINAPI,不知怎样通过编译的
    int main()
    {
    HMODULE hMod = GetModuleHandle(NULL);
    IMAGE_DOS_HEADER* pDosHeader = (IMAGE_DOS_HEADER*)(BYTE*)hMod;
    IMAGE_OPTIONAL_HEADER* pOptHeader = (IMAGE_OPTIONAL_HEADER*)(pDosHeader->e_lfanew + 24 + (BYTE*)hMod);
    IMAGE_IMPORT_DESCRIPTOR* pImportDesc = (IMAGE_IMPORT_DESCRIPTOR*)((BYTE*)hMod + pOptHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress); 
    while(pImportDesc->FirstThunk)
    {
    char* pszDllName = (char*)(pImportDesc->Name + (BYTE*)hMod);
    printf("Dll Name : %-10s \n",pszDllName);
    IMAGE_THUNK_DATA* pThunk = (IMAGE_THUNK_DATA*)((BYTE*)hMod + pImportDesc->OriginalFirstThunk);
    IMAGE_THUNK_DATA* pThunk2 = (IMAGE_THUNK_DATA*)((BYTE*)hMod + pImportDesc->FirstThunk); //这个才是要修改的
    while(pThunk->u1.Function)
    {
    char* pszFuncName = (char*)((DWORD)pThunk->u1.AddressOfData + (BYTE*)hMod + 2);
    //DWORD* pszFuncAddr = (DWORD*)(pThunk->u1.Function + (BYTE*)hMod);
    DWORD* pszFuncAddr = (DWORD*)&(pThunk2->u1.Function); //这才是取地址
    printf("\t函数名称:%-30s",pszFuncName);
    printf("函数地址:%-8x\n",pszFuncAddr);
    char* fnName = pszFuncName;
    if(strcmp(fnName,"MessageBoxA")==0)
    {
    g_orgAddr=(PFNMESSAGEBOX)pThunk2->u1.Function; //保存原来MessageBoxA地址值
    bMessage = 1;
    DWORD* lpNewAddr = (DWORD*)MyMessageBox;
    printf("\t%-39s写新地址:%x \n","",lpNewAddr);
    //VirtualProtect(pszFuncAddr,sizeof(DWORD),PAGE_READWRITE,NULL);
    DWORD dwProtect;
    VirtualProtect(pszFuncAddr,sizeof(DWORD),PAGE_READWRITE, &dwProtect); //看看MSDN怎么说,貌似最后一个参数不能为NULL
    //BOOL bRet = ::WriteProcessMemory(GetCurrentProcess(),pszFuncAddr,lpNewAddr,sizeof(DWORD),NULL);
    BOOL bRet = ::WriteProcessMemory(GetCurrentProcess(),pszFuncAddr,&lpNewAddr,sizeof(DWORD),NULL);//注意第三个参数是填lpNewAddr地址,而不是值
    DWORD* gpNewAddr = NULL;
    //::ReadProcessMemory(GetCurrentProcess(),pszFuncAddr,gpNewAddr,sizeof(DWORD),NULL); 
    ::ReadProcessMemory(GetCurrentProcess(),pszFuncAddr,&gpNewAddr,sizeof(DWORD),NULL);//同上
    if(bRet)
    puts("\tWriteProcessMemory successfully");
    printf("\t函数名称:%-30s",fnName);
    printf("函数地址:%x\n",gpNewAddr);
    }
    pThunk++;
    }
    pImportDesc++;
    }
    if(bMessage)
    MessageBox(NULL,"当你看到这个,说明没有HOOK成功啊!","失败了!",0);
    getchar();
    return 0;
    }
    int WINAPI MyMessageBox(HWND hWnd,LPCSTR lpContent,LPCSTR lpTitle,UINT uType)
    {
    //    return ((PFNMESSAGEBOX)g_orgAddr)(hWnd,"原函数退休了,我接管了!",lpTitle,uType);
    return g_orgAddr(hWnd,"原函数退休了,我接管了!",lpTitle,uType);
    }
      

  4.   

    while(pThunk->u1.Function)
    {
    ...
    pThunk++;
    pThunk2++; //漏了这个
    }