BOOL DebugPortHook(PVOID pKernelBase, PVOID pRelocKernel, DWORD dwRelocKernelSize, HANDLE hHookProcessPID)
{
DWORD i;
test();
if (IsDebugPortHook)
{
ghPID_ProcesstoHook = hHookProcessPID;
KdPrint(("ghPID_ProcesstoHook = %d\n", ghPID_ProcesstoHook));
return TRUE;
}
if (pRelocKernel != NULL && pKernelBase != NULL)
{
gpRelocKernel = pRelocKernel;
gdwOffset_RelocKernel = (DWORD)pRelocKernel - (DWORD)pKernelBase;
gdwRelocKernelSize = dwRelocKernelSize;
KdPrint(("gdwOffset_RelocKernel = %x\n", gdwOffset_RelocKernel));
}
else
{
KdPrint(("pKernelBase或pRelocKernel为NULL,调用DebugPortHook失败\n"));
return FALSE;
}
for(i=0; i<INLINEHOOKPROCNUM; i++)
{
if(VK_InlineHook(&InlineHookProceTable[i]) == FALSE)
{
KdPrint(("InlineHook%s失败\n", InlineHookProceTable[i].Name));
return FALSE;
}
}
ghPID_ProcesstoHook = hHookProcessPID;
KdPrint(("ghPID_ProcesstoHook = %d\n", ghPID_ProcesstoHook));
IsDebugPortHook = TRUE;
return TRUE;
}
代码如上,前面的代码主要是一些初始化,然后调用VK_InlineHook(&InlineHookProceTable[i])进行InlineHook,InlineHookProceTable是一个结构数组,保存要HOOK的函数的地址,跳转地址,名称等一些信息,代码如下
BOOL VK_InlineHook(PSTRUCT_INLINEHOOKPROC pSTRUCT_INLINEHOOKPROC)
{
ULONG CallCode;
DWORD HookAddr;
PVOID FindRelocKernelAddr;
DWORD i;
if ( pSTRUCT_INLINEHOOKPROC->NewAddr == 0 && pSTRUCT_INLINEHOOKPROC->Signature[0] == 0)
{
KdPrint(("pSTRUCT_INLINEHOOKPROC->NewAddr or 特征码为NULL\n"));
return FALSE;
}
FindRelocKernelAddr = VK_FindData(gpRelocKernel, gdwRelocKernelSize, pSTRUCT_INLINEHOOKPROC->Signature, 12);
if (FindRelocKernelAddr != NULL)
{
pSTRUCT_INLINEHOOKPROC->OldAddr = (DWORD)FindRelocKernelAddr - gdwOffset_RelocKernel - pSTRUCT_INLINEHOOKPROC->SignatureAddr + pSTRUCT_INLINEHOOKPROC->OldAddr;
KdPrint(("%s函数地址 =%x\n", pSTRUCT_INLINEHOOKPROC->Name, pSTRUCT_INLINEHOOKPROC->OldAddr));
}
else
{
pSTRUCT_INLINEHOOKPROC->OldAddr = 0;
KdPrint(("查找%s函数地址失败\n", pSTRUCT_INLINEHOOKPROC->Name));
return FALSE;
}
RtlCopyMemory(pSTRUCT_INLINEHOOKPROC->CodeToHook, (PVOID)(pSTRUCT_INLINEHOOKPROC->OldAddr + pSTRUCT_INLINEHOOKPROC->HookOffset), pSTRUCT_INLINEHOOKPROC->HookLength);
CallCode = pSTRUCT_INLINEHOOKPROC->NewAddr - pSTRUCT_INLINEHOOKPROC->OldAddr -5; //得到要写入的跳转地址码
HookAddr = pSTRUCT_INLINEHOOKPROC->OldAddr;
_asm
{
cli
mov eax, cr0
and eax, 0FFFEFFFFh
mov cr0, eax
mov eax, CallCode
mov ebx, HookAddr
mov byte ptr ds:[ebx], 0E8h
mov [ebx + 1], eax
mov eax, cr0
or eax, 10000h
mov cr0, eax
sti
}
return TRUE;
}
主要代码为
mov eax, CallCode //Call的地址指令码
mov ebx, HookAddr //Inline Hook的地址
mov byte ptr ds:[ebx], 0E8h //写入Call的指令
mov [ebx + 1], eax //写入Call的地址指令码
当Inline Hook DbgkpSetProcessDebugObject,DbgkpMarkProcessPeb时都没问题,但当Hook DbgkpQueueMessage时蓝屏,用windbg跟踪,发现是mov byte ptr ds:[ebx], 0E8h这句蓝屏,跟踪时发现地址是对的,代码也没问题,蓝屏时说DRIVER_IRQL_NOT_LESS_OR_EQUAL,我加自旋锁、提升IRQL等都没用,但我把DebugPortHook中的test();去掉时就不蓝屏了,加上就立即蓝屏test()代码如下:
VOID test()
{
KdPrint(("test函数执行成功\n"));
}
试过把test()改为一个什么都不做的空函数也还是蓝屏,还试过把test()放到其他地方也蓝屏,但不调用 test()就不蓝,很是奇怪,测试了一天了,求指点
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)