[C] 纯文本查看 复制代码 #include<NTDDK.H>
/*********************************************************************
******
“多核环境下,如何保证对一个高并发的内核函数进行HOOK而不会出错?”
******
**********************************************************************/
LONG AddressOfSwapContext = 0x805428e8;// 805428e0 这是SwapContext的地址
/*****************************************************
*******
**** 自己的函数需要做的事情
*******
****************************************************/
_declspec(naked)VOID HookSwapContext()
{
_asm{
or cl, cl;
mov byte ptr es : [esi + 2Dh], 2;
pushfd;
jmp AddressOfSwapContext;
}
}
LONG OldCode[2] = { 0 };
VOID ULodeDriver(PDRIVER_OBJECT pDriver)
{
OldCode[0] = 0xC626C90A;
OldCode[1] = 0x9C022D46;
_asm{
pushad;
pushfd;
mov esi, 0x805428E0;
mov edx, [esi];
mov eax, [esi + 4];
mov ebx, OldCode[0];
mov ecx, OldCode[4];
lock CMPXCHG8B[esi];
popfd;
popad;
}
DbgPrint("驱动已经卸载完毕!\n");
}
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver,PUNICODE_STRING pReg)
{
//汇编的情况下可以写地址,但是这个是硬编码
LONG JmpCode = (LONG)HookSwapContext - 0x805428e0 - 5;
DbgPrint("HookSwapContext:%X\n", HookSwapContext);
DbgPrint("JmpCode:%X\n", JmpCode);
LONG Code[2] = {0};
Code[0] = (JmpCode << 8) + 0xE9;
Code[1] = (JmpCode >> 24);
DbgPrint("Code[0]:%X\n", Code[0]);
DbgPrint("Code[1]:%X\n", Code[1]);
__asm{
pushad;
pushfd;
mov esi, 0x805428E0;
mov eax, [esi];
mov edx, [esi + 4];
mov ebx, Code[0];
mov ecx, Code[4];
lock CMPXCHG8B[esi];
/*
CMPXCHG8B的用法
该指令判断指定内存中的8字节内容和EDX:EAX (edx高32位,eax, 低32位)中的64字节内容是否相同,
如果相同,就把ECX : EBX(ecx高32位,ebx, 低32位)中的内容替换到指定内存。
如果不相同,就把指定内存中的值替换到ECX : EBX中。
*/
popfd;
popad;
}
DbgPrint("OldCode【0】是:%X\n",OldCode[0]);
DbgPrint("OldCode【1】是:%X\n",OldCode[1]);
DbgPrint("高并发HOOK成功!\n");
pDriver->DriverUnload = ULodeDriver;
return STATUS_SUCCESS;
}
/*
为什么会使用CMPXCHG8B这个指令
以往我们在HOOK的时候会使用memcpy这个函数,但是这个只能一个一个替换
如果你还没有替换完成的时候,别的函数在调用,就会出错。
*/
|