本文是对上一篇的补充。关于apihook的原理,效果动画,代码分析,实现细节和32位hook的源码请见上一篇:[Win32] API Hook(1)在32位系统上的实现
原理一样,就是换了个指令,jmp只能跳转32位大小,如果超过了就没法跳转了,所以更换指令,对于只会16位汇编和一点点Win32汇编的我,自然不懂amd64,百度到了一个,可惜原作者已不可考,谨对做出无私贡献的前辈奉上真诚的感谢!
mov rax,地址 push rax ret
这回指令设计的非常巧妙,利用了一个ret,因为已经把返回地址压入栈了,因此直接返回到了我们自己的函数里了,因为用的ret,不是ret(at)num,因此入栈的实参并没有清除,而原来的返回地址已经在call的时候就入栈了,因此也会保留,完美地实现了跳转。
修改后dll源码如下,在win8.1 64位下完美实现了上一篇32位中的效果:
#include <stdio.h> #include <windows.h> unsigned char code[12]; unsigned char oldcode[12]; FARPROC addr; DWORD pid; int getpid() { char buffer[255]; DWORD get = 255; //判断环境是否为WOW64 BOOL isWOW64; REGSAM p = KEY_READ; IsWow64Process(GetCurrentProcess(), &isWOW64); if (isWOW64)p |= KEY_WOW64_64KEY; HKEY hKey; if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, TEXT("Software\\测试"), 0, NULL, 0, p, NULL, &hKey, NULL) != ERROR_SUCCESS){ return 0; } if (RegQueryValueExA(hKey, "Main_PID", 0, NULL, (BYTE*)buffer, &get) != ERROR_SUCCESS){ return 0; } return atoi(buffer); } HANDLE WINAPI MyOpenProcess(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId){ HANDLE handle; if (getpid() == dwProcessId){ SetLastError(5); return NULL; } DWORD old; if (VirtualProtectEx(GetCurrentProcess(), addr, 12, PAGE_EXECUTE_READWRITE, &old)){ WriteProcessMemory(GetCurrentProcess(), addr, oldcode, 12, NULL); VirtualProtectEx(GetCurrentProcess(), addr, 12, old, &old); } handle = OpenProcess(dwDesiredAccess, bInheritHandle, dwProcessId); if (VirtualProtectEx(GetCurrentProcess(), addr, 12, PAGE_EXECUTE_READWRITE, &old)){ WriteProcessMemory(GetCurrentProcess(), addr, code, 12, NULL); VirtualProtectEx(GetCurrentProcess(), addr, 12, old, &old); } return handle; } BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: addr = 0; HMODULE hdll; hdll = LoadLibrary(TEXT("Kernel32.dll")); addr = GetProcAddress(hdll, "OpenProcess"); if (addr){ code[0] = 0x48; code[1] = 0xB8; code[10] = 0x50; code[11] = 0xC3; long long a = (long long)MyOpenProcess; RtlMoveMemory(code + 2, &a, 8); DWORD old; if (VirtualProtectEx(GetCurrentProcess(), addr, 12, PAGE_EXECUTE_READWRITE, &old)){ RtlMoveMemory(oldcode, addr, 12); WriteProcessMemory(GetCurrentProcess(), addr, code, 12, NULL); VirtualProtectEx(GetCurrentProcess(), addr, 12, old, &old); } } case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE; }
本文是对上一篇的补充。关于apihook的原理,效果动画,代码分析,实现细节和32位hook的源码请见上一篇:[Win32] API Hook(1)在32位系统上的实现