用 IAT 法准备 HOOK 一个控制台程序的 printf 函数、
但 HOOK 不成功、WriteProcessMemory 成功、但就是不执行 IAT 后的自定义函数、下面是标准代码:DWORD WINAPI hook_printf(LPVOID params)
{
HMODULE lpBase = GetModuleHandle(NULL);
IMAGE_DOS_HEADER *dosHeader;
IMAGE_NT_HEADERS *ntHeader;
IMAGE_IMPORT_BY_NAME *ImportName;
printf_address = GetProcAddress(GetModuleHandle(L"KERNEL32.DLL"), "AddAtomA"); dosHeader = (IMAGE_DOS_HEADER*)lpBase;
ntHeader = (IMAGE_NT_HEADERS*)((BYTE*)lpBase + dosHeader->e_lfanew);
IMAGE_IMPORT_DESCRIPTOR *pImportDesc = (IMAGE_IMPORT_DESCRIPTOR*)((BYTE*)lpBase + ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
while(pImportDesc->FirstThunk)
{
char* pszDllName = (char*)((BYTE*)lpBase + pImportDesc->Name);
if(strcmpi(pszDllName, "KERNEL32.DLL") == 0)
break;
pImportDesc ++;
} IMAGE_THUNK_DATA *pThunk = (IMAGE_THUNK_DATA*)((BYTE*)lpBase + pImportDesc->FirstThunk);
while(pThunk->u1.Function)
{
lpAddr = (DWORD*)&(pThunk->u1.Function);
if(*lpAddr == (DWORD)printf_address)
{
DWORD dwOldProtect;
VirtualProtect(lpAddr, sizeof(DWORD), PAGE_EXECUTE_READWRITE, &dwOldProtect);
WriteProcessMemory(GetCurrentProcess(), lpAddr, &vhook_printf, sizeof(DWORD), NULL);
VirtualProtect(lpAddr, sizeof(DWORD), dwOldProtect, &dwOldProtect);
}
pThunk ++;
} return 0;
}
 

解决方案 »

  1.   

    上面代码上错了、下面才是的、
    现在就是 123 的消息框可以弹出来、自己的 printf 弹不出来、
    int __cdecl vhook_printf(const char * _Format, ...)
    {
    MessageBoxA(0, "", "", 0);
    return 0;
    }DWORD WINAPI hook_printf(LPVOID params)
    {
    HMODULE lpBase = GetModuleHandle(NULL);
    IMAGE_DOS_HEADER *dosHeader;
    IMAGE_NT_HEADERS *ntHeader;
    IMAGE_IMPORT_BY_NAME *ImportName;
    printf_address = GetProcAddress(GetModuleHandle(L"MSVCRT.DLL"), "printf"); dosHeader = (IMAGE_DOS_HEADER*)lpBase;
    ntHeader = (IMAGE_NT_HEADERS*)((BYTE*)lpBase + dosHeader->e_lfanew);
    IMAGE_IMPORT_DESCRIPTOR *pImportDesc = (IMAGE_IMPORT_DESCRIPTOR*)((BYTE*)lpBase + ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
    while(pImportDesc->FirstThunk)
    {
    char* pszDllName = (char*)((BYTE*)lpBase + pImportDesc->Name);
    if(strcmpi(pszDllName, "MSVCRT.DLL") == 0)
    break;
    pImportDesc ++;
    } IMAGE_THUNK_DATA *pThunk = (IMAGE_THUNK_DATA*)((BYTE*)lpBase + pImportDesc->FirstThunk);
    while(pThunk->u1.Function)
    {
    lpAddr = (DWORD*)&(pThunk->u1.Function);
    if(*lpAddr == (DWORD)printf_address)
    {
    DWORD dwOldProtect;
    VirtualProtect(lpAddr, sizeof(DWORD), PAGE_EXECUTE_READWRITE, &dwOldProtect);
    WriteProcessMemory(GetCurrentProcess(), lpAddr, &vhook_printf, sizeof(DWORD), NULL);
    VirtualProtect(lpAddr, sizeof(DWORD), dwOldProtect, &dwOldProtect);
    MessageBoxA(0, "123", "", 0);
    }
    pThunk ++;
    } return 0;
    }
      

  2.   

    WriteProcessMemory(GetCurrentProcess(), lpAddr, &vhook_printf, sizeof(DWORD), NULL);
    这句问题很大啊!不应该是不执行,应该是执行到printf崩溃才对吧!
      

  3.   

    没崩溃、就是没反应、确定 WriteProcessMemory 返回成功、
      

  4.   

    WriteProcessMemory(GetCurrentProcess(), lpAddr, &vhook_printf, sizeof(DWORD), NULL);这句写入的不是你的vhook_printf的地址,而是地址入口的内容。就是第一句push ebp....
    所以肯定会崩溃的。应该是:
    DWORD vhpaddr = (DWORD)vhook_printf;
    WriteProcessMemory(GetCurrentProcess(), lpAddr, &vhpaddr, sizeof(DWORD), NULL);
    才对。或 *lpAddr = (DWORD)vhook_printf; 不用WriteProcessMemory也行。
      

  5.   

    参考我的‘HookPrintf.rar‘ 0分
    http://download.csdn.net/detail/schlafenhamster/3811842
      

  6.   

    You are right!不过就是搞不懂、
    DWORD vhpaddr = (DWORD)vhook_printf;
    &vhpaddr 和直接 &vhook_printf 有什么区别?、
    不都是取地址么?、
      

  7.   

    懂了、对于 C 语言函数名前加不加 & 一个意思....
    对于 C++ 则是引用、
    OK、完事结帖、
      

  8.   

    WriteProcessMemory写的是指针指向的内容,而非指针本身的值.这末说你明白了吗.
      

  9.   

    了解、先以为 &vhook_printf 是取函数地址的地址、结果不是、