|
void PrintHook() { DbgPrint(" Now Get In ZwCreateFile Hook: %d...Pid: %d...\n", g_HookNumber++, (DWORD)PsGetCurrentProcessId()); }
__declspec(naked) void NewZwCreateFile() { __asm { pushfd; // 仅仅适合于 XP 操作系统 call PrintHook; popfd; mov eax,0x25; jmp g_OldCreateFile; } }
void SetHB() // set hardware breakpoint 设置硬件断点 { __asm { mov eax, ZwCreateFile; // 想要挂接的函数或者地址 mov dr0, eax; mov eax, dr7; or eax, 0x2703; // 也要修改 dr7:GD 位,以免DrX被操作系统或其他程序修改 and eax, 0xfff0ffff; mov dr7, eax; } }
__declspec(naked) void NewDBEntry() { __asm { pushfd; push eax;
mov eax, dr6; test eax, 0x2000; jz NOT_EDIT_DRX;
// 以下是如果有对DRX的操作的简单处理,如有需要可以修改 // 我只是简单的跳过这些指令 and eax, 0xFFFFDFFF; mov dr6, eax; // 清除DR6的标志
cmp g_bExit, 0; jnz MY_DRV_EXIT; // 驱动 Unload
mov eax, [esp+8]; // 获取堆栈中的 EIP add eax, 3; // 由于所有对 DRX 的操作全都是3个字节的 mov [esp+8], eax; // 修改 EIP ,跳过当前指令,返回时执行下条指令
jmp MY_INT_END;
NOT_EDIT_DRX:
mov eax, dr6; test eax, 0x1; jz SYS_INT; // 如果不是Dr0 产生的中断,则跳回原系统中断
mov eax, [esp+8]; cmp eax, ZwCreateFile; // 判断一下是不是 ZwCreateFile 的线性地址 jnz SYS_INT;
mov eax, NewZwCreateFile; mov [esp+8],eax; // 修改堆栈中的 EIP ,实现返回时跳转
MY_INT_END:
mov eax, dr7; or eax, 0x2000; // 恢复 GD 位 mov dr7, eax;
MY_DRV_EXIT: // 整个驱动 UnLoad 时,不恢复 Dr7
pop eax; popfd; iretd;
SYS_INT: pop eax; popfd; jmp g_OldDBEntry; } }
DWORD GetDBEntry() { PIDTENTRY IdtEntry; DWORD Entry;
__asm sidt g_IDTR;
IdtEntry = (PIDTENTRY)(g_IDTR.IDTBase + 8);
Entry = IdtEntry->HiOffset << 16; Entry |= IdtEntry->LowOffset;
return Entry; }
void HookDBInt() { DWORD NewEntry; PIDTENTRY IdtEntry;
NewEntry = (DWORD)NewDBEntry;
g_OldCreateFile = (DWORD)ZwCreateFile + 5; // 新的要跳转过去的地址
g_OldDBEntry = GetDBEntry();
IdtEntry = (PIDTENTRY)(g_IDTR.IDTBase + 8);
CliAndDisableWPBit();
IdtEntry->LowOffset = (USHORT)NewEntry;
IdtEntry->HiOffset = (USHORT)( NewEntry >> 16 );
ReLoadCR0AndSti();
SetHB();
g_bExit = FALSE;
return; }
void UnHookDBInt() { PIDTENTRY IdtEntry; DWORD Entry; __asm sidt g_IDTR; IdtEntry = (PIDTENTRY)(g_IDTR.IDTBase + 8);
CliAndDisableWPBit();
g_bExit = TRUE;
__asm mov eax, dr7; // 产生一次例外并且清除Dr7:GD
if ( g_OldDBEntry != 0 ) { IdtEntry->LowOffset = (USHORT)g_OldDBEntry; IdtEntry->HiOffset = (USHORT)( g_OldDBEntry >> 16 ); }
ReLoadCR0AndSti(); DbgPrint(" UnLoad drx hook..\n");
return; }
NTSTATUS DriverUnload(IN PDRIVER_OBJECT DriverObject) { UnHookDBInt(); return STATUS_SUCCESS; }
NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath ) { HookDBInt(); DriverObject->DriverUnload = DriverUnload;
DbgPrint("Load drxhook Driver Ok...\n");
return STATUS_SUCCESS; } /***********************/
以上代码实现了简单的ZwCreateFile 函数的HOOK,可以拿DbgView查看效果.
由于本人水平有限,代码中难免有错误出现,希望指正. 同时也希望各位牛人来指点,yykingking@126.com
/**************下面是罗嗦几句********************/ 1.这个方法呢首先不怎么实用,因为你用了调试寄存器后某些壳也想用,因此就冲突了,可能会使某些东西失效,不如传统的HOOK好用(据说利用缺页中断HOOK也比较好用,没试过)。还有人认为呢这个HOOK虽然是HOOK成功了,但是还得HOOK中断向量,没有必要。其实呢,只是多了种思路罢了,多给大家提供一些想法而已。 2.其次呢,这个方法是我在调试某ARK时想到的,这个ARK的作者说他们会恢复函数的inline hook然后才去调用(大面积的恢复,甚至是整个文件的恢复),于是我就用调试器在该函数上下断点,结果自然是没有断下了,因为下的 (0xcc)断点被恢复了。于是就索性下了个硬件断点,这下就断住了,然后呢就想到了拿这个东西来HOOK。然后就去网上搜资料,发现不少人还是稍微提到过这个方法的,包括 vxk,xikug,都说过。上一页 [1] [2] |