[Win32] API Hook(2)在64位系统上的实现

末蓝、 2022-08-04 11:51 209阅读 0赞

 本博文由CSDN博主zuishikonghuan所作,版权归zuishikonghuan所有,转载请注明出处:http://blog.csdn.net/zuishikonghuan/article/details/47979603

本文是对上一篇的补充。关于apihook的原理,效果动画,代码分析,实现细节和32位hook的源码请见上一篇:[Win32] API Hook(1)在32位系统上的实现

原理一样,就是换了个指令,jmp只能跳转32位大小,如果超过了就没法跳转了,所以更换指令,对于只会16位汇编和一点点Win32汇编的我,自然不懂amd64,百度到了一个,可惜原作者已不可考,谨对做出无私贡献的前辈奉上真诚的感谢!

  1. mov rax,地址
  2. push rax
  3. ret

这回指令设计的非常巧妙,利用了一个ret,因为已经把返回地址压入栈了,因此直接返回到了我们自己的函数里了,因为用的ret,不是ret(at)num,因此入栈的实参并没有清除,而原来的返回地址已经在call的时候就入栈了,因此也会保留,完美地实现了跳转。

修改后dll源码如下,在win8.1 64位下完美实现了上一篇32位中的效果:

  1. #include <stdio.h>
  2. #include <windows.h>
  3. unsigned char code[12];
  4. unsigned char oldcode[12];
  5. FARPROC addr;
  6. DWORD pid;
  7. int getpid()
  8. {
  9. char buffer[255];
  10. DWORD get = 255;
  11. //判断环境是否为WOW64
  12. BOOL isWOW64;
  13. REGSAM p = KEY_READ;
  14. IsWow64Process(GetCurrentProcess(), &isWOW64);
  15. if (isWOW64)p |= KEY_WOW64_64KEY;
  16. HKEY hKey;
  17. if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, TEXT("Software\\测试"), 0, NULL, 0, p, NULL, &hKey, NULL) != ERROR_SUCCESS){
  18. return 0;
  19. }
  20. if (RegQueryValueExA(hKey, "Main_PID", 0, NULL, (BYTE*)buffer, &get) != ERROR_SUCCESS){
  21. return 0;
  22. }
  23. return atoi(buffer);
  24. }
  25. HANDLE WINAPI MyOpenProcess(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId){
  26. HANDLE handle;
  27. if (getpid() == dwProcessId){
  28. SetLastError(5);
  29. return NULL;
  30. }
  31. DWORD old;
  32. if (VirtualProtectEx(GetCurrentProcess(), addr, 12, PAGE_EXECUTE_READWRITE, &old)){
  33. WriteProcessMemory(GetCurrentProcess(), addr, oldcode, 12, NULL);
  34. VirtualProtectEx(GetCurrentProcess(), addr, 12, old, &old);
  35. }
  36. handle = OpenProcess(dwDesiredAccess, bInheritHandle, dwProcessId);
  37. if (VirtualProtectEx(GetCurrentProcess(), addr, 12, PAGE_EXECUTE_READWRITE, &old)){
  38. WriteProcessMemory(GetCurrentProcess(), addr, code, 12, NULL);
  39. VirtualProtectEx(GetCurrentProcess(), addr, 12, old, &old);
  40. }
  41. return handle;
  42. }
  43. BOOL APIENTRY DllMain(HMODULE hModule,
  44. DWORD ul_reason_for_call,
  45. LPVOID lpReserved
  46. )
  47. {
  48. switch (ul_reason_for_call)
  49. {
  50. case DLL_PROCESS_ATTACH:
  51. addr = 0;
  52. HMODULE hdll; hdll = LoadLibrary(TEXT("Kernel32.dll"));
  53. addr = GetProcAddress(hdll, "OpenProcess");
  54. if (addr){
  55. code[0] = 0x48;
  56. code[1] = 0xB8;
  57. code[10] = 0x50;
  58. code[11] = 0xC3;
  59. long long a = (long long)MyOpenProcess;
  60. RtlMoveMemory(code + 2, &a, 8);
  61. DWORD old;
  62. if (VirtualProtectEx(GetCurrentProcess(), addr, 12, PAGE_EXECUTE_READWRITE, &old)){
  63. RtlMoveMemory(oldcode, addr, 12);
  64. WriteProcessMemory(GetCurrentProcess(), addr, code, 12, NULL);
  65. VirtualProtectEx(GetCurrentProcess(), addr, 12, old, &old);
  66. }
  67. }
  68. case DLL_THREAD_ATTACH:
  69. case DLL_THREAD_DETACH:
  70. case DLL_PROCESS_DETACH:
  71. break;
  72. }
  73. return TRUE;
  74. }

本文是对上一篇的补充。关于apihook的原理,效果动画,代码分析,实现细节和32位hook的源码请见上一篇:[Win32] API Hook(1)在32位系统上的实现

Center

发表评论

表情:
评论列表 (有 0 条评论,209人围观)

还没有评论,来说两句吧...

相关阅读

    相关 WIN32 消息Hook API

    前言 在`Win32`中存在一个消息机制,程序任何点击或者消息都会通过窗口过程下发,而微软提供`SetWindowsHookEx`API来来允许我们进行相关事件监听,并且