inline hook 驱动框架.doc
文本预览下载声明
这段代码是针对KiInsertQueueApc函数。那么inline hook的流程是什么呢?我们知道,inline hook的目的就是修改内核函数的代码。为什么要修改呢?因为原始函数的代码我不是很满意,或者说不符合我的想法。我们还知道,函数的代码的处理对象其实就是传进来的参数。如果说我修改KiInsertQueueApc函数的开头几个字节,使其原来的代码变成一个跳转指令,跳到我自己的函数地址上并且执行我自己构建的函数,执行完成之后再跳回到原函数代码的下条指令。那么inline hook技术就实现了。而我自己构建的函数就可以事先验证参数信息。举个例子或许就非常容易理解。现在很多杀毒软件具有自我保护能力(比如保护自身进程),他会inline hook NtTerminateProcess()。具体原理是一样的,杀毒软件会修改这个函数开头的几个字节使其变为一个跳转指令,跳到杀毒软件作者自己写的函数地址上,之后这个自定义函数开始分析传进来的参数,如果发现是自己进程,那么返回失败,如果是其他进程,那么不做任何反映直接跳回去执行原始函数以后的代码。这样杀毒软件的进程就不会被关闭。现在分析代码。一开始肯定是驱动程序的入口函数NTSTATUS DriverEntry( IN PDRIVER_OBJECT theDriverObject, IN PUNICODE_STRING theRegistryPath ){DbgPrint(My Driver Loaded!);theDriverObject-DriverUnload = OnUnload;g_KiInsertQueueApc = FindKiInsertQueueApcAddress();DetourFunctionKiInsertQueueApc();return STATUS_SUCCESS;}没啥特别的地方,和普通的驱动程序一样。由于不用处理IRP,那么分发函数就没有必要去定义。需要注意的是,驱动程序不一定必须要创建设备。你可以发现,这个驱动程序就没有创建设备对象,因为此驱动程序不跟应用程序打交道。读者要正确理解驱动程序的概念我们来看看FindKiInsertQueueApcAddress();ULONG FindKiInsertQueueApcAddress(){char * Addr_KeInsertQueueApc = 0; (1)int i = 0;char Findcode[] = { 0xE8, 0xcc, 0x29, 0x00, 0x00 }; (2)ULONG Addr_KiInsertQueueApc = 0; Addr_KeInsertQueueApc = (char *) GetFunctionAddr(LKeInsertQueueApc); (3)for(i = 0; i 100; i ++) (4){if( Addr_KeInsertQueueApc == Findcode[0] Addr_KeInsertQueueApc[i + 1] == Findcode[1] Addr_KeInsertQueueApc[i + 2] == Findcode[2] Addr_KeInsertQueueApc[i + 3] == Findcode[3] Addr_KeInsertQueueApc[i + 4] == Findcode[4] ){Addr_KiInsertQueueApc = (ULONG)Addr_KeInsertQueueApc + 0x29cc + 5; (5)break;}}return Addr_KiInsertQueueApc;}具体分析:这个函数的作用是找到KiInsertQueueApc()的首地址。具体看代码:(1)定义一个指针变量。此指针的跳跃数为1字节。(2)你必须用windbg分析KeInsertQueueApc()函数,由于这个函数必定调用KiInsertQueueApc(),那么“调用代码”必定会出现在函数中。那么我们选出这个“调用代码”作为特征值就可以定位到KiInsertQueueApc()的首地址。具体是这样的:{ 0xE8, 0xcc, 0x29, 0x00, 0x00 }这是在内存中的样子。而从程序的角度来讲是:000029ccE8,那么这样的机器码对应的汇编代码是 ADD BYTE PTR DS:[EAX],ALSUB ESP,ECXCALLCALL对应的机器码是0xE8.那么既然CALL出现了,后面跟的东西肯定为一个地址值。通过用windbg分析可知,这个地址就是KiInsertQueueApc()的首地址
显示全部