HOOK GetMessageTime有感
来源:互联网 发布:田岛美工刀架 编辑:程序博客网 时间:2024/06/04 01:14
参考文章:http://www.codeproject.com/Articles/21414/Powerful-x-x-Mini-Hook-Engine
Mini-Hook-Engine下载:http://download.csdn.net/detail/friendan/9182677
-----------------------------------------------------------------------------------------------------
我使用 Detours和Mini-Hook-Engine来HOOK GetMessageTime都没有成功,
Detours直接返回失败,Mini-Hook-Engine虽然成功写了JMP,但在HOOK后,调用原GetMessageTime时出错了,原因是其Bridge写错了。。。
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
先Copy下Mini-Hook-Engine的原理,后面我们写自己的Bridge时用到:
Let's make a real world example. If the first instructions of the function/API we want to hook are:
mov edi, edipush ebpmov ebp, espxor ecx, ecx
They will be replaced by our:
00400000 jmp our_code00400005 xor ecx, ecx
Our bride will look like this:
mov edi, edipush ebpmov ebp, espjmp 00400005
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------我们来看看GetMessageTime的汇编代码:
// GetMessageTime入口原始汇编指令7608F600 6A 0A push 0Ah 7608F602 E8 C7 17 FE FF call 76070DCE 7608F607 C3 ret 7608F608 81 C2 58 07 00 00 add edx,758h 7608F60E E9 B0 27 FE FF jmp 76071DC3 7608F613 50 push eax 7608F614 6A 00 push 0...
// 使用Mini Hook-Engine后,GetMessageTime入口汇编指令被修改如下7608F600 FF 25 06 F6 08 76 jmp dword ptr ds:[7608F606h] 7608F606 18 AB 5B 0F 58 07 sbb byte ptr [ebx+7580F5Bh],ch 7608F60C 00 00 add byte ptr [eax],al 7608F60E E9 B0 27 FE FF jmp 76071DC3 7608F613 50 push eax 7608F614 6A 00 push 0 ...
// Mini Hook-Engine对GetMessageTime的Bridge如下001E0000 EB 05 jmp 001E0007 001E0002 90 nop 001E0003 90 nop 001E0004 90 nop 001E0005 90 nop 001E0006 90 nop 001E0007 FF 25 40 0C E6 74 jmp dword ptr ds:[74E60C40h] 001E000D FF 25 13 00 1E 00 jmp dword ptr ds:[1E0013h] 001E0013 19 11 sbb dword ptr [ecx],edx 001E0015 E6 74 out 74h,al 001E0017 6A 0A push 0Ah // GetMessageTime原入口第一条指令001E0019 E8 C7 17 FE FF call 001C17E5 // 这里错了。。。,原函数是:call 76070DCE 001E001E C3 ret 001E001F 81 C2 58 07 00 00 add edx,758h 001E0025 FF 25 2B 00 1E 00 jmp dword ptr ds:[1E002Bh] 001E002B 0E push cs 001E002C ?? db f6h 001E002D 08 76 00 or byte ptr [esi],dh 001E0030 00 00 add byte ptr [eax],al 001E0032 00 00 add byte ptr [eax],al 001E0034 00 00 add byte ptr [eax],al 001E0036 00 00 add byte ptr [eax],al
----------------------------------------------------------------------------------------------------------------------
知道了错误原因,我继续使用Mini Hook-Engine来HOOK GetMessageTime,不过Bridge我们得自己写:
我的Bridge代码如下:
VOID __declspec(naked) GetMessageTime_Bridge(VOID){ _asm {push 0xA//call g_iGetMessageTimeCallAddr // 这里动态写入,先用5个nop来占位nopnopnopnopnopret//jmp iJmpAddr // 这里动态写入,先用5个nop来占位nopnopnopnopnop }}
LONG WINAPI MyGetMessageTime(VOID){// 调用原函数LONG liRet = 0;LONG (WINAPI *pGetMessageTime)(VOID) = NULL;//pGetMessageTime = (LONG (__stdcall *)(void))NtHookEngine_GetOriginalFunction((ULONG_PTR)MyGetTickCount);pGetMessageTime = (LONG (__stdcall *)(void))GetMessageTime_Bridge;if (pGetMessageTime != NULL){liRet = pGetMessageTime();}return liRet;}
最重要的HOOK GetMessageTime函数:
VOID Hook_GetMessageTime(VOID){// E8 C7 17 FE FF call 76070DCE DWORD dwOldProtect = 0;VirtualProtect(TrueGetMessageTime, 5, PAGE_EXECUTE_READWRITE, &dwOldProtect);// 这里得到C7 17 FE FFint iCallAddr = 0;memcpy((VOID*)&iCallAddr, (VOID*)((INT)TrueGetMessageTime + 3), 4);// 将C7 17 FE FF还原成76070DCE// ((int)TrueGetMessageTime + 7) == CALL的下一行地址iCallAddr = iCallAddr + ((int)TrueGetMessageTime + 7); VirtualProtect(TrueGetMessageTime, 5, dwOldProtect, NULL);// 修正我们的GetMessageTime_Bridgeint iAddr = (int)GetMessageTime_Bridge;byte bData[5] = {0};byte bKey[5] = {0x90, 0x90, 0x90, 0x90, 0x90};while(true){// 查找那5个nop指令的首地址VirtualProtect((VOID*)iAddr, 5, PAGE_EXECUTE_READWRITE, &dwOldProtect);memcpy(bData, (VOID*)iAddr, 5);VirtualProtect((VOID*)iAddr, 5, dwOldProtect, NULL);if (memcmp(bData, bKey, 5) != 0){iAddr ++;continue;}VirtualProtect((VOID*)iAddr, 5, PAGE_EXECUTE_READWRITE, &dwOldProtect);// 写入 call 76070DCE // 目标地址 - 当前指令地址的下个指令地址 = 距离*((byte*)iAddr) = 0xE8;*((int*)(iAddr + 1)) = iCallAddr - (iAddr + 5);// 写入 jmp 7608F60C// 目标地址 - JMP指令所在地址 - 5 = JMP地址*((byte*)(iAddr + 6)) = 0xE9;*((int*)(iAddr + 7)) = ((int)TrueGetMessageTime + 0xC) - (iAddr + 6) - 5;VirtualProtect((VOID*)iAddr, 5, dwOldProtect, NULL);break;}// HOOK GetMessageTimeNtHookEngine_Hook((ULONG_PTR)TrueGetMessageTime, (ULONG_PTR)&MyGetMessageTime);}
---------------------------------------------------------------------------------------------------
此次收获:
1. 懂得了Bridge的写法和用法,原来函数只是一个地址,我们强制转换就可以了:
LONG (WINAPI *pGetMessageTime)(VOID) = NULL;
pGetMessageTime = (LONG (__stdcall *)(void))GetMessageTime_Bridge;
2. 懂得了CALL 后面的地址的计算方法:
// 目标地址(76070DCE) - 当前CALL指令的下个地址 = CALL后面的4个字节数据:E8 C7 17 FE FF
*((byte*)iAddr) = 0xE8;
*((int*)(iAddr + 1)) = iCallAddr - (iAddr + 5);
- HOOK GetMessageTime有感
- 有感
- 有感`~`
- 有感
- 有感。。。。
- 有感
- 有感
- 有感
- 有感
- 有感!!!
- 有感
- 有感
- 有感
- 有感
- 有感
- 有感
- 有感
- 有感
- 后缀数组
- C# Window编程随记——新建一个window项目
- 2 :复杂动画2
- CSS实现垂直居中的几种方法
- mysql 学习记录---->索引、视图
- HOOK GetMessageTime有感
- 通过Spring工具类获取classpath下的文件资源--笔记
- 欢迎使用CSDN-markdown编辑器
- JavaScript instanceof 运算符深入剖析
- Eclipse导入外部项目问题总结1
- Plist文件存储及沙盒路径详解
- windows service 2012:[7]搭建FTP服务器
- Android -- 使用inBitmap要注意的地方
- SSH之Hibernate save或update方法已经执行,但是数据库没保存数据