我的程序总被人HOOK,修改.那个补丁只HOOK WriteProcessMemory 这个函数.我如何跳过他的HOOK,执行原始的函数代码?
我看过一个牛人写过介绍.就是自己读kernel32.dll入内存.然后读取PE头,里的导出表,自己修复.可是这位牛人只是简单介绍,不知道哪里有这样的代码或详细的资料....
请各位大侠出手相助.........

解决方案 »

  1.   

    王道:自已先把要改的HOOK了,而且要用Jmp Hook.
      

  2.   

    顶楼上的,至于解决方案你就去看微软自己出的Detours吧
      

  3.   

    who hooks me then me reverse it.
      

  4.   

    现在的Windows Hook 或者API Hook 都通常向你的进程插入一个DLL
    因此我想你可以监视进程加载的DLL模块关于如何进程加载的DLL模块请参考:HWND hwnd:显示控件窗口句柄,
    DWORD dwProcessID:要监视的进程ID号VOID ShowProcessInfo(HWND hwnd, DWORD dwProcessID) {   SetWindowText(hwnd, TEXT(""));   // Clear the output box   CToolhelp th(TH32CS_SNAPALL, dwProcessID);   // Show Process details
       PROCESSENTRY32 pe = { sizeof(pe) };
       BOOL fOk = th.ProcessFirst(&pe);
       for (; fOk; fOk = th.ProcessNext(&pe)) {
          if (pe.th32ProcessID == dwProcessID) {
             AddText(hwnd, TEXT("Filename: %s\r\n"), pe.szExeFile);
             AddText(hwnd, TEXT("   PID=%08X, ParentPID=%08X, ")
                TEXT("PriorityClass=%d, Threads=%d, Heaps=%d\r\n"),
                pe.th32ProcessID, pe.th32ParentProcessID, 
                pe.pcPriClassBase, pe.cntThreads,
                th.HowManyHeaps());
             break;   // No need to continue looping
          }
       }
       // Show Modules in the Process
       // Number of characters to display an address
       const int cchAddress = sizeof(PVOID) * 2;
       AddText(hwnd, TEXT("\r\nModules Information:\r\n")
          TEXT("  Usage  %-*s(%-*s)  %8s  Module\r\n"),
          cchAddress, TEXT("BaseAddr"),
          cchAddress, TEXT("ImagAddr"), TEXT("Size"));   MODULEENTRY32 me = { sizeof(me) };
       fOk = th.ModuleFirst(&me);
       for (; fOk; fOk = th.ModuleNext(&me)) {
          if (me.ProccntUsage == 65535) {
             // Module was implicitly loaded and cannot be unloaded
             AddText(hwnd, TEXT("  Fixed"));
          } else {
             AddText(hwnd, TEXT("  %5d"), me.ProccntUsage);
          }
          PVOID pvPreferredBaseAddr = 
             GetModulePreferredBaseAddr(pe.th32ProcessID, me.modBaseAddr);
          if (me.modBaseAddr == pvPreferredBaseAddr) {
             AddText(hwnd, TEXT("  %p %*s   %8u  %s\r\n"), 
                me.modBaseAddr, cchAddress, TEXT(""), 
                me.modBaseSize, me.szExePath);
          } else {
             AddText(hwnd, TEXT("  %p(%p)  %8u  %s\r\n"), 
                me.modBaseAddr, pvPreferredBaseAddr, me.modBaseSize, me.szExePath);
          }
       }   
       // Show threads in the process
       AddText(hwnd, TEXT("\r\nThread Information:\r\n")
          TEXT("      TID     Priority\r\n"));
       THREADENTRY32 te = { sizeof(te) };
       fOk = th.ThreadFirst(&te);
       for (; fOk; fOk = th.ThreadNext(&te)) {
          if (te.th32OwnerProcessID == dwProcessID) {
             int nPriority = te.tpBasePri + te.tpDeltaPri;
             if ((te.tpBasePri < 16) && (nPriority > 15)) nPriority = 15;
             if ((te.tpBasePri > 15) && (nPriority > 31)) nPriority = 31;
             if ((te.tpBasePri < 16) && (nPriority <  1)) nPriority =  1;
             if ((te.tpBasePri > 15) && (nPriority < 16)) nPriority = 16;
             AddText(hwnd, TEXT("   %08X       %2d\r\n"), 
                te.th32ThreadID, nPriority);
          }
       }
    }
      

  5.   

    最简单的办法:读PE头里的Import Section,将他们保存到一个函数表,调用时直接从表里调用,但是如果别人采取其他办法来Hook时,比如,先你读取ImportSection并更改,就无效了。
    最牢靠的办法就是自己读kernel32.dll。
    具体方法可以看看PE文件格式相关说明,比如Iczelion写的PE教程,网上搜一下,很多中文翻译版。
      

  6.   

    赫赫
    最简单做法是
    帮API执行几条指令
    再执行原来的API代码
    HOOK管不到,赫赫
      

  7.   

    防止api hook要先知道是怎么被hook的,一般2种方法:1:修改IAT,那只要使用GetProcAddress获取api函数,再进行调用即可;2:修改内存,这个需要具体情况具体分析,一种简单的hook方法是把被hook的地方修改为jmp xxxx,跳转到hook去执行。
    这种情况,只要简单的判断目标api入口的内容即可
    void* fn;
    /* ...get function address... */
    if( (char)(*fn) == 0xff ) 
    {
    /* function have been hooked */
    }但是,可以有很多其他办法进行hook,防不胜防,总之是道高一尺,魔高一丈。为了防止被hook,也可以先hook目标api,甚至先hook可能用于hook的api。去看雪学院看看吧,这个帖子
    http://bbs.pediy.com/showthread.php?s=&threadid=37586
      

  8.   

    即然知道被hook了 WriteProcessMemory 很简单就可以复原了1.可以还原勾子
    2.也可以不还原勾子本人喜欢用第二种,不还原勾子,因为有时对方的hook程序会定时检测挂勾的地方是否被修改,这样就产生了许多不必要的麻烦第二种的作法思路一般为先copy一份被hook了的API所在的dll文件,到你的程序目录下
    然后运态加载 
    loadlibrary(copydll)
    GetProcAddress()
    然后是直接调用还是还原到IAT中,就看你各人喜好了推荐用直接调用,还原的操作有点复杂,还容易被检测出来
      

  9.   

    有了数据执行保护有还可以在RING3里用WriteProcessMemory 吗
      

  10.   

    正如 WingForce(初六,履霜,坚冰至。) 提到的第2种hook的方法,
    自己读kernel32.dll入内存.然后读取PE头,.....就没意义了.还是先看看是被如何hook的.
      

  11.   

    我觉得:
    1. LoadLibrary再GetProcAddress不可取,因为对方有可能Hook GetProcAddress
    2. 读取PE文件获得IAT,再call对应的地址也不可取。因为对方有可能直接修改API的入口代码为JMP到自己的函数。
    貌似最本质的解决方法是自己写个函数分配一块内存,然后读取DLL,再把DLL代码/数据Copy到这块内存中,直接CALL/JMP过去调用,模拟WIndows的加载器的行为,就是过于复杂。简单点的方法还是阻止Hook本身吧。
      

  12.   

    用 native api
    像使用 普通dll一样 导出ZwWriteProcessMemoryNTSYSAPI
    NTSTATUS
    NTAPI
    ZwWriteVirtualMemory(
    IN HANDLE ProcessHandle,
    IN PVOID BaseAddress,
    IN PVOID Buffer,
    IN ULONG BufferLength,
    OUT PULONG ReturnLength OPTIONAL
    );
      

  13.   


    WriteVirtualMemory 
    在NT内核的操作系统平台下 最终是 调用ZwWriteVirtualMemory