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

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

本文是对上一篇的补充。关于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位系统上的实现


你可能感兴趣的:(windows,Win32,api,winapi)