首页
社区
课程
招聘
[讨论]64位下的inline Hook
发表于: 2017-11-17 00:22 10204

[讨论]64位下的inline Hook

2017-11-17 00:22
10204
最近在研究64位下的inline Hook,在网上搜了搜,找到了两种方法。

1. 48H B8H XX XX XX XX XX XX XX XX 50H C3H 12字节

2. FFH,25H,0,0,0,0,XX XX XX XX XX XX XX XX 14 字节

第一种好像会影响寄存器的值,我就用了第二种,写了如下代码

CPP:

InlineHook_x64::InlineHook_x64(void)
{
	pOldAPI = NULL;            //此指针pOldAP
	strcpy(szOldAPI, "\xFF\x25\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00");//先清空原数据
	strcpy(szNewAPI,"\xFF\x25\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00");//初始跳转数据
	MessageBox(0, L"", L"", 0);
}


InlineHook_x64::~InlineHook_x64(void)
{
}
//*********************HOOK API的函数*************************//
bool InlineHook_x64::HookAPI(char const * ModuleName,char const * ApiName,PVOID NewAPI)
{
    //找到API函数在内存中的地址
	pOldAPI = 0;
    HMODULE hModule = LoadLibraryA(ModuleName); 
    pOldAPI = (PVOID)GetProcAddress(hModule, ApiName);

	WCHAR msg[64];
	

	memcpy(szNewAPI + 6, &pOldAPI, 8);
	wsprintf(msg, L"GetProcAddress:%p\nszNewAPI:%p\n", pOldAPI, szNewAPI);
	MessageBox(0, msg, L"", 0);


	DWORD64 dwJmpAddr = 0; 
	dwJmpAddr = (DWORD64)NewAPI; 
	memcpy(szNewAPI + 6, &dwJmpAddr, 8); 
	FreeLibrary(hModule); 
	ReadProcessMemory ((void*)-1, pOldAPI, szOldAPI, 14, NULL);    //读出原来的前12个字节 
	WriteProcessMemory((void*)-1, pOldAPI, szNewAPI, 14, NULL);    //写入我们处理后的12个字节 
	wsprintf(msg, L"WriteProcessMemory:%p\ndwJmpAddr:%p\n", pOldAPI, dwJmpAddr);
	MessageBox(0, msg, L"", 0);
    return true;
}

H:

class InlineHook_x64
{
public:
	InlineHook_x64(void);
	~InlineHook_x64(void);
	PVOID pOldAPI ;            //此指针pOldAPI保存原来API函数的地址(通过GetProcAddress获取)
	char  szOldAPI[14];                //存放原来API函数在内存中的前12个字节
	char  szNewAPI[14];    //存放64位的跳转地址
	//*********************停止HOOK的函数************************//
	void UnHook();
	//*********************重新HOOK API 的函数********************//
	void ReHook();
	//*********************HOOK API的函数*************************//
	bool HookAPI(char const * ModuleName,char const * ApiName,PVOID NewAPI);
};
DLLMAIN:

void GameD3D_HOOK()
{
	//MessageBox(0, L"GameD3D_HOOK", L"", 0);
	InlineHook_x64 hook;
	hook.HookAPI("d3d9.dll", "Direct3DCreate9", (PVOID)New_Direct3DCreate9);
	//MessageBox(0, L"GameD3D_HOOK", L"", 0);
}
直接注入微软D3DSDK demo:
Microsoft DirectX SDK (June 2010)\Samples\C++\Direct3D\Bin\x64\StateManager.exe
奇怪的是它居然没跳入我的HOOK函数New_Direct3DCreate9,写的代码有问题么?这问题折磨我一天了,来大神带我走出痛苦的深渊吧。



[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (6)
雪    币: 269
活跃值: (906)
能力值: ( LV12,RANK:345 )
在线值:
发帖
回帖
粉丝
2
这种问题自己调试下看看原地址有没有被改成跳转指令,跳转地址对不对不就知道了?64位主要是注意需要8字节保存地址
2017-11-17 10:56
0
雪    币: 5734
活跃值: (1737)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
3
目测没有写入成功  代码段需要修改内存页属性
2017-11-17 15:49
0
雪    币: 202
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
小艾 目测没有写入成功 代码段需要修改内存页属性
有道理,我以为DLL都是自己人了就不要改内存属性,VirtualProtect(pOldAPI,  14,  PAGE_EXECUTE_READWRITE,  &oldpro);写在WriteProcessMemory就可以了吧,我回去试试。感谢
2017-11-17 18:41
0
雪    币: 202
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
AJISky 这种问题自己调试下看看原地址有没有被改成跳转指令,跳转地址对不对不就知道了?64位主要是注意需要8字节保存地址
我用的是vs2017,内存察看器不知道怎么调出来,只能用ce看,再一个DLL调试的话好像得有被调试程序的源代码才能调试,现在用对话框调试,网上搜索没结果,可以的话你教我啊。
2017-11-17 18:49
0
雪    币: 202
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
找到问题了,赋初值的时候strcpy_s换成memcpy就清零了,但是依旧没有跳转到我的函数里
2017-11-18 02:18
0
雪    币: 341
活跃值: (1005)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
7
ff 25这种方法好像8字节的地址被截断了;
/*
The absolute jump is (x64) :
48 b8 ef cd ab 89 67 45 23 01   mov rax, 0x0123456789abcdef
ff e0                                            jmp rax
And for x86 :
b8 67 45 23 01   mov eax, 0x01234567
ff e0                    jmp eax
*/(摘自某位网友的回复。这个好像可以)
2018-7-11 12:59
0
游客
登录 | 注册 方可回帖
返回
//