阅读:978回复:1
Hook程序中不确定错误!!
__declspec(naked)
NTAPI HOOKQueryValueKey(IN HANDLE KeyHandle, IN PUNICODE_STRING ValueName, IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass, OUT PVOID KeyValueInformation, IN ULONG Lenth, OUT PULONG ResultLength ) { _asm { //first execulte overwrited 7BYTES //int 3; add esp, 12; pushfd; push ResultLength; push Lenth; push KeyValueInformation; push KeyValueInformationClass; push ValueName; push KeyHandle; jmp forwArd; bAck: //.........15bytes _emit 0xAA;//1 _emit 0xAA;//2 _emit 0xAA;//3 _emit 0xAA;//4 _emit 0xAA;//5 _emit 0xAA;//6 _emit 0xAA;//7 _emit 0xAA;//8 _emit 0xAA;//9 _emit 0xAA;//10 _emit 0xAA;//11 _emit 0xAA;//12 _emit 0xAA;//13 _emit 0xAA;//14 _emit 0xAA;//15 //......... _emit 0xEA; _emit 0xAA; _emit 0xAA; _emit 0xAA; _emit 0xAA; _emit 0x08; _emit 0x00; forwArd: call bAck; } //处理结果 KdPrint(("%08x, %08x, %08x, %wZ\n", KeyHandle, Lenth, ResultLength, ValueName)); _asm { popfd; mov esp, ebp; pop ebp; ret; } } 我使用上面代码进行inline hook QueryValueKey的第15Bytes,为什么会出现不确定的错误? Kd QueryValueKey显示 push ebp mov ebp,esp push .... push .... push .... mov eax, fs:[000000??] //RePlace with far Jump to HOOKQueryValueKey with 7Bytes push eax ..... 我的确HOOK到了数据,好多,但是突然就会挂掉:-(大牛们解释一下 |
|
沙发#
发布于:2007-09-11 22:55
#include <ntddk.h>
#include "AsmCodeLen.h" #include "main.h" BYTE oldByte[9] = {0}; BYTE newcode[9] = {0xEA, 0x44, 0x33, 0x22, 0x11, 0x08, 0x00, 0x90, 0x90}; BYTE oldByte2[7] = {0}; BYTE newcode2[7] = {0xEA, 0x44, 0x33, 0x22, 0x11, 0x08, 0x00}; PBYTE g_lpDeviceIoControlFile = NULL; PBYTE g_lpQueryValueKey = NULL; NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) { int i; PBYTE lpDeviceIoControlFile = (PBYTE)NtDeviceIoControlFile; PBYTE lpHookDeviceIoControlFile = (PBYTE)my_function_detour_ntdeviceiocontrolfile; PBYTE lpQueryValueKey = GetSSDTFunction((PBYTE)ZwQueryValueKey); PBYTE lpHookQueryValueKey = (PBYTE)HOOKQueryValueKey; g_lpDeviceIoControlFile = lpDeviceIoControlFile; g_lpQueryValueKey = lpQueryValueKey; //NtDeviceIoControlFile反汇编如下 //55 PUSH EBP //8BEC MOV EBP, ESP //6A01 PUSH 01 //FF752C PUSH DWORD PTR [EBP + 2C] //ff7528 push dword ptr [ebp+0x28] //ff7524 push dword ptr [ebp+0x24] //ff7520 push dword ptr [ebp+0x20] //... //Hook it At ff7528 - ff7520 //with write 7 bytes [far jmp 0xAAAAAAAA:0800] + 2bytes nop *(PULONG)(newcode+1) = (ULONG)lpHookDeviceIoControlFile; *(PULONG)(newcode2+1) = (ULONG)lpHookQueryValueKey; //*(PULONG)(newcode2+1) = (ULONG)HOOKQueryValueKey; //重定位Hook中的0xAAAAAAAA for(i=0; i<256;i++) { if ((0xAA == lpHookDeviceIoControlFile) && (0xAA == lpHookDeviceIoControlFile[i+1]) && (0xAA == lpHookDeviceIoControlFile[i+2]) && (0xAA == lpHookDeviceIoControlFile[i+3])) { *(PULONG)(lpHookDeviceIoControlFile + i) = (ULONG)lpDeviceIoControlFile + 8 + sizeof(newcode); break; } } for(i=0; i<256; i++) { if ((0xAA == lpHookQueryValueKey) && (0xAA == lpHookQueryValueKey[i+1]) && (0xAA == lpHookQueryValueKey[i+2]) && (0xAA == lpHookQueryValueKey[i+3])) { //write 15 bytes RtlCopyBytes(lpHookQueryValueKey + i, lpQueryValueKey, 15); //注意EA占1Byte *(PULONG)(&lpHookQueryValueKey[i + 15 + 1]) = (ULONG)lpQueryValueKey + 15 + sizeof(newcode2); break; } } //hook _asm { CLI; //dissable interrupt MOV EAX, CR0; //move CR0 register into EAX AND EAX, NOT 10000H; //disable WP bit MOV CR0, EAX; //write register back } RtlCopyBytes(oldByte, lpDeviceIoControlFile+8, sizeof(newcode)); RtlCopyBytes(lpDeviceIoControlFile+8, newcode, sizeof(newcode)); //HOOKQueryValueKey RtlCopyBytes(oldByte2, lpQueryValueKey+15, sizeof(newcode2)); RtlCopyBytes(lpQueryValueKey+15, newcode2, sizeof(newcode2)); _asm { MOV EAX, CR0; OR EAX, 10000H; MOV CR0, EAX; STI; } KdPrint(("Success, %08x, %08x", lpHookQueryValueKey, lpHookDeviceIoControlFile)); DriverObject->DriverUnload = DriverUnload; return STATUS_SUCCESS; } VOID DriverUnload (IN struct _DRIVER_OBJECT *DriverObject) { //back up _asm { CLI; //dissable interrupt MOV EAX, CR0; //move CR0 register into EAX AND EAX, NOT 10000H; //disable WP bit MOV CR0, EAX; //write register back } RtlCopyBytes(g_lpDeviceIoControlFile+8, oldByte, sizeof(newcode)); RtlCopyBytes(g_lpQueryValueKey+15, oldByte2, sizeof(newcode2)); _asm { MOV EAX, CR0; OR EAX, 10000H; MOV CR0, EAX; STI; } KdPrint(("Unload")); } /* * 得到NT内核函数的实际执行地址 */ PBYTE GetSSDTFunction(PBYTE lpNtFunction) { //返回指定函数的实际地址以便inline hook //MOV eax, FunID //LEA EDX, [esp+4] //INT 2E //RET // ULONG id = *(PULONG)(lpNtFunction + 1); return (PBYTE)(*((PULONG)KeServiceDescriptorTable->ServiceTableBase + id)); } NTSTATUS CheckFunctionBytesNtDeviceIoControlFile() { int i=0; char *p = (char *)NtDeviceIoControlFile; //The beginning of the NtDeviceIoControlFile function //should match: //55 PUSH EBP //8BEC MOV EBP, ESP //6A01 PUSH 01 //FF752C PUSH DWORD PTR [EBP + 2C] // BYTE c[] = {0x55, 0x8B, 0xEC, 0x6A, 0x01, 0xFF, 0x75, 0x2C}; while(i<8) { DbgPrint(" - 0x%02X ", (unsigned char)p); DbgPrint("\n"); if(p != c) { return STATUS_UNSUCCESSFUL; } i++; } return STATUS_SUCCESS; } //-------------------------------------------------------------------- // naked functions have no prolog/epilog code - they are functionally like the // target of a goto statement //-------------------------------------------------------------------- __declspec(naked) NTAPI my_function_detour_ntdeviceiocontrolfile(IN HANDLE FileHandle, IN HANDLE Event OPTIONAL, IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, IN PVOID ApcContext OPTIONAL, OUT PIO_STATUS_BLOCK IoStatusBlock, IN ULONG IoControlCode, IN PVOID InputBuffer OPTIONAL, IN ULONG InputBufferLength, OUT PVOID OutputBuffer OPTIONAL, IN ULONG OutputBufferLength ) { //首先反向恢复堆栈 //55 PUSH EBP //8BEC MOV EBP, ESP //6A01 PUSH 01 //FF752C PUSH DWORD PTR [EBP + 2C] _asm { add esp, 8; //pushad; //普通寄存器顺序入栈 //执行原始NtDeviceIoControlFile函数 push OutputBufferLength; push OutputBuffer; push InputBufferLength; push InputBuffer; push IoControlCode; push IoStatusBlock; push ApcContext; push ApcRoutine; push Event; push FileHandle; jmp forwArd; bAck: push ebp; mov ebp, esp push 0x01 push dword ptr [ebp+0x2C]; push dword ptr [ebp+0x28]; push dword ptr [ebp+0x24]; push dword ptr [ebp+0x20]; _emit 0xEA; _emit 0xAA; _emit 0xAA; _emit 0xAA; _emit 0xAA; _emit 0x08; _emit 0x00; forwArd: call bAck; } //ok! //过滤IP数据 if (IOCTL_TCP_QUERY_INFORMATION_EX == IoControlCode) { //显示数据到调试 DebugBuffer(InputBuffer, InputBufferLength, OutputBuffer, OutputBufferLength); } _asm { //popad; mov esp, ebp; pop ebp; ret; } } __declspec(naked) NTAPI HOOKQueryValueKey(IN HANDLE KeyHandle, IN PUNICODE_STRING ValueName, IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass, OUT PVOID KeyValueInformation, IN ULONG Lenth, OUT PULONG ResultLength ) { _asm { //first execulte overwrited 7BYTES //int 3; add esp, 12; pushfd; push ResultLength; push Lenth; push KeyValueInformation; push KeyValueInformationClass; push ValueName; push KeyHandle; jmp forwArd; bAck: //.........15bytes _emit 0xAA;//1 _emit 0xAA;//2 _emit 0xAA;//3 _emit 0xAA;//4 _emit 0xAA;//5 _emit 0xAA;//6 _emit 0xAA;//7 _emit 0xAA;//8 _emit 0xAA;//9 _emit 0xAA;//10 _emit 0xAA;//11 _emit 0xAA;//12 _emit 0xAA;//13 _emit 0xAA;//14 _emit 0xAA;//15 //......... _emit 0xEA; _emit 0xAA; _emit 0xAA; _emit 0xAA; _emit 0xAA; _emit 0x08; _emit 0x00; forwArd: call bAck; } //处理结果 KdPrint(("%08x, %08x, %08x, %wZ\n", KeyHandle, Lenth, ResultLength, ValueName)); _asm { popfd; mov esp, ebp; pop ebp; ret; } } VOID DebugBuffer(IN PVOID lpBuf, IN ULONG BufLen, IN PVOID lpOutBuf, IN ULONG OutBufLen) { ULONG i; TDIObjectID *TdiObj = (PTDIObjectID)lpBuf; //KdPrint(("%08x,%08x,%08x,%08x,%08x", TdiObj->toi_type, TdiObj->toi_class, TdiObj->toi_id, BufLen, OutBufLen)); if (0x102 == TdiObj->toi_id) { //ipconfig use it to get ip! //KdPrint(("OutBuf Len [%08x]", OutBufLen)); for(i=0; i<OutBufLen-1; i+=4) { if (0x0201a8c0 == *(PULONG)((PBYTE)lpOutBuf + i)) { *(PULONG)((PBYTE)lpOutBuf + i) = 0x0301a8c0; } //KdPrint(("[%d]%08x", i>>2, *(PULONG)((PBYTE)lpOutBuf + i))); } } } 大牛们帮我调试一下哦: |
|