哈哈,MJ牛放血那么久了,今天才仔细看了看她射的一个帖子. 原来inline hook是如此之方便耶. 当然是简单的.复杂滴还得自己写...
-----------------------------------------------------------------------------------------------------------
NTSTATUS
InlineHookFuncXP (
IN PVOID FuncAddress,
IN PVOID NewFuncAddress
)
/*++
Author : MJ0011
User : sudami [xiao_rui_119@163.com]
Time : 08/01/24
参数 :
FuncAddress - [IN] 原函数
NewFuncAddress - [IN] inline hook 函数
返回 :
STATUS_SUCCESS - inline hook 成功
STATUS_UNSUCCESSFUL - 失败
功能 :
在普通函数的开头处简单实现inline hook.XP以上版本适用
btw -- 在新函数执行完后需要跳转到原函数地址 + 2处
直线上的这5字节内容,是在大部分函数头前面.都是nop.这刚好可以
放5字节的跳转: JMP XXXX
|ˉˉˉ| --> 0xe9 (JMP)
|ˉˉˉ|
|ˉˉˉ|
|ˉˉˉ|
|ˉˉˉ| 这4字节存放新函数的地址
ˉˉ |ˉˉˉ|ˉˉ--> 符合inline hook 条件的函数的前5字节一般都是---
|ˉˉˉ| |
↓ˉˉˉˉˉˉ
<-- 8bff mov edi,edi
故只需要把8bff这2字节换成一个短转移 <-- 55 push ebp
"ebf9" 便会跳转到 FuncAddress -5 处 <-- 8bec mov ebp,esp
<简单inline hook示意图>
--*/
{
KSPIN_LOCK SDTSpinLock;
KIRQL oldIrql;
NTSTATUS state;
KeAcquireSpinLock (&SDTSpinLock, &oldIrql);
WPOFF();
__asm {
push eax
push ecx
lea eax,[FuncAddress]
mov eax,[ eax]
/* 这几句是判断原函数是否符合这种简单inline hook的条件 */
cmp byte ptr[ eax],0x8b
jnz failtohook
cmp byte ptr[ eax+1],0xff
jnz failtohook
mov ecx,0xffffffff
loopcheck:
/* 这个循环确保函数头的上面5字节为nop;不是则hook失败 */
cmp byte ptr[ eax+ ecx],0x90
jnz failtohook
dec ecx
cmp ecx,0xfffffffa
jnz loopcheck
/* write the new function header:jmp short funcaddr-5(0x00-0x07) */
mov byte ptr[ eax],0xeb
mov byte ptr[ eax+1],0xf9
/* write 1 byte : jmp xxxx */
mov byte ptr[ eax-5],0xe9
/* write 4 byte : x xxxx */
mov ecx,[NewFuncAddress]
sub ecx, eax
mov dword ptr[ eax-4], ecx
jmp hookok
failtohook:
mov stat,0xc0000001
jmp end
hookok:
mov stat,0
end:
pop ecx
pop eax
}
WPON();
KeReleaseSpinLock (&SDTSpinLock, OldIrql);
return state;
}