• 1281阅读
  • 2回复

Detour注意点及原理 [复制链接]

上一主题 下一主题
离线啊冲
 

只看楼主 倒序阅读 使用道具 楼主  发表于: 2016-02-15


[cpp] view plain copy

  1. DetourTransactionBegin();  
  2.         DetourUpdateThread(GetCurrentThread());  
  3.         DetourAttach((PVOID *)&g_pPresent, New_Present);  
  4.         DWORD nErr = DetourTransactionCommit();  




[cpp] view plain copy

  1. DetourTransactionBegin();  
  2.         DetourUpdateThread(GetCurrentThread());  
  3.         DetourDetach((PVOID *)&g_pPresent, New_Present);  
  4.         DWORD nErr = DetourTransactionCommit();  
  5.         if (!nErr)  
  6.         {  
  7.             ::FreeLibrary(g_hDll);  
  8.             g_bSubclassed = false;    
  9.         }  
  10.         else  
  11.         {  


注意的是卸载时,必须加上这个DetourTransactionCommit,这函数退出时才是Hook真正被还原,我刚开始没加这个,接着后面直接FreeLibrary,结果杯具了!直接崩掉在Hook函数部分






好东西,

用DETOURS库获取NT管理员权限
陈志敏
---- Detours是微软开发的一个函数库(源代码可在http://research.microsoft.com/sn/detours 免费获得), 用于修改运行中的程序在内存中的影像,从而即使没有源代码也能改变程序的行为。具体用途是:

拦截WIN32 API调用,将其引导到自己的子程序,从而实现WIN32 API的定制。
为一个已在运行的进程创建一新线程,装入自己的代码并运行。
---- 本文将简介Detours的原理,Detours库函数的用法, 并利用Detours库函数在Windows NT上编写了一个程序,该程序能使有“调试程序”的用户权限的用户成为系统管理员,附录利用Detours库函数修改该程序使普通用户即可成为系统管理员(在NT4 SP3上)。

Detours的原理

---- 1. WIN32进程的内存管理

---- 总所周知,WINDOWS NT实现了虚拟存储器,每一WIN32进程拥有4GB的虚存空间, 关于WIN32进程的虚存结构及其操作的具体细节请参阅WIN32 API手册, 以下仅指出与Detours相关的几点:

---- (1) 进程要执行的指令也放在虚存空间中
---- (2) 可以使用QueryProtectEx函数把存放指令的页面的权限更改为可读可写可执行,再改写其内容,从而修改正在运行的程序
---- (3) 可以使用VirtualAllocEx从一个进程为另一正运行的进程分配虚存,再使用 QueryProtectEx函数把页面的权限更改为可读可写可执行,并把要执行的指令以二进制机器码的形式写入,从而为一个正在运行的进程注入任意的代码

---- 2. 拦截WIN32 API的原理

---- Detours定义了三个概念:

---- (1) Target函数:要拦截的函数,通常为Windows的API。
---- (2) Trampoline函数:Target函数的复制品。因为Detours将会改写Target函数,所以先把Target函数复制保存好,一方面仍然保存Target函数的过程调用语义,另一方面便于以后的恢复。
---- (3) Detour 函数:用来替代Target函数的函数。

---- Detours在Target函数的开头加入JMP Address_of_ Detour_ Function指令(共5个字节)把对Target函数的调用引导到自己的Detour函数, 把Target函数的开头的5个字节加上JMP Address_of_ Target _ Function+5作为Trampoline函数。例子如下:

拦截前:Target _ Function:
  ;Target函数入口,以下为假想的常见的子程序入口代码
  push  ebp
  mov  ebp,  esp
  push  eax
  push  ebx
  Trampoline:
  ;以下是Target函数的继续部分
  ……

拦截后: Target _ Function:
  jmp  Detour_Function
  Trampoline:
  ;以下是Target函数的继续部分
  ……

  Trampoline_Function:
  ; Trampoline函数入口, 开头的5个字节与Target函数相同
  push  ebp
  mov  ebp,  esp
  push  eax
  push  ebx
  ;跳回去继续执行Target函数
  jmp  Target_Function+5

这样可能更清楚点:

[cpp] view plain copy
  1. DetourAttach((PVOID *)&pPresent, New_Present);  
  2. DWORD nErr = DetourTransactionCommit();  
  3. pPresent传入前的值为5d0a10c3,传入后的值为5ce50060(DetourTransactionCommit后)  
  4. 0:000> u 5d0a10c3    //Hook前函数汇编  
  5. d3d9!CBaseDevice::Present:  
  6. 5d0a10c3 8bff            mov     edi,edi  
  7. 5d0a10c5 55              push    ebp  
  8. 5d0a10c6 8bec            mov     ebp,esp  
  9. 5d0a10c8 56              push    esi  
  10. 5d0a10c9 57              push    edi  
  11. 5d0a10ca 8b7d08          mov     edi,dword ptr [ebp+8]  
  12. 5d0a10cd 85ff            test    edi,edi  
  13. 5d0a10cf 7444            je      d3d9!CBaseDevice::Present+0x13 (5d0a1115)  
  14.   
  15. d3d9!CBaseDevice::Present://Hook后函数汇编  
  16. 5d0a10c3 e9dc002fa3      jmp     FpsTool1!ILT+415(?New_PresentYGJPAUIDirect3DDevice9PBUtagRECT (003911a4)  //5个字节  
  17. 5d0a10c8 56              push    esi  
  18. 5d0a10c9 57              push    edi  
  19. 5d0a10ca 8b7d08          mov     edi,dword ptr [ebp+8]  
  20. 5d0a10cd 85ff            test    edi,edi  
  21. 5d0a10cf 7444            je      d3d9!CBaseDevice::Present+0x13 (5d0a1115)  
  22. 5d0a10d1 8d7704          lea     esi,[edi+4]  
  23. 5d0a10d4 837e1800        cmp     dword ptr [esi+18h],0  
  24.   
  25.   
  26. 0:000> u 5ce50060//Hook后pPresent的值,我们可以看到是保存了Hook前函数汇编的前五个字节,再跳转回前面函数  
  27. 5ce50060 8bff            mov     edi,edi  
  28. 5ce50062 55              push    ebp  
  29. 5ce50063 8bec            mov     ebp,esp  
  30. 5ce50065 e95e102500      jmp     d3d9!CBaseDevice::Present+0x5 (5d0a10c8)  
所以注意的是pPresent在HOOK前和HOOK后都是指向原函数的地址,只不过函数地址值不再相同了,HOOK后是把原函数被截掉的字节先保存到新地址,再JMP到原函数未改变的部分
善者 慈悲心常在 无怨无恨 以苦为乐
默认压缩密码www.hifyl.com
文件分享密码问题:http://www.hifyl.com/read-htm-tid-4444.html
离线im86165507

只看该作者 沙发  发表于: 2016-02-15
离线v2680267313

只看该作者 板凳  发表于: 2016-04-30
用户被禁言,该主题自动屏蔽!
快速回复
限100 字节
批量上传需要先选择文件,再选择上传
 
上一个 下一个