1. 程式人生 > >監控應用層通訊_hook_kifastcallentry(系統服務呼叫)

監控應用層通訊_hook_kifastcallentry(系統服務呼叫)

#include"ntddk.h"
#pragma pack(1) //寫這個記憶體以一位元組對齊 如果不寫是以4位元組的對齊的    
typedef struct ServiceDescriptorEntry {//這個結構就是為了管理這個陣列而來的 核心api所在的陣列 才有這個結構的 這個是ssdt    
	unsigned int *ServiceTableBase;//就是ServiceTable ssdt陣列    
	unsigned int *ServiceCounterTableBase; //僅適用於checked build版本 無用    
	unsigned int NumberOfServices;//(ServiceTableBase)陣列中有多少個元素 有多少個項    
	unsigned char *ParamTableBase;//引數表基址 我們層傳過來的api的引數 佔用多少位元組 多大    
} ServiceDescriptorTableEntry_t, *PServiceDescriptorTableEntry_t;
#pragma pack(1)    
_declspec(dllimport) ServiceDescriptorTableEntry_t KeServiceDescriptorTable;//(名字不要寫錯)  //匯入ssdt表  
ULONG sosuohookdiandizhi();
void yebaohuguanbi();
void yebaohukaiqi();
unsigned int lao_ntopenfile;//老的ntopenfile函式的地址
ULONG dizhi1 = 0;//KiFasetCallEntry彙編程式碼中的 (call ntcreatefile)下一句的地址
ULONG dizhi2 = 0;//KiFasetCallEntry彙編程式碼中要hook的地址
typedef  NTSTATUS(*hanshuzhizhen1)(
	__out PHANDLE FileHandle,
	__in ACCESS_MASK DesiredAccess,
	__in POBJECT_ATTRIBUTES ObjectAttributes,
	__out PIO_STATUS_BLOCK IoStatusBlock,
	__in_opt PLARGE_INTEGER AllocationSize,
	__in ULONG FileAttributes,
	__in ULONG ShareAccess,
	__in ULONG CreateDisposition,
	__in ULONG CreateOptions,
	__in_bcount_opt(EaLength) PVOID EaBuffer,
	__in ULONG EaLength
	);
VOID xiezai1(PDRIVER_OBJECT qudongduixiang)
{
	yebaohuguanbi();//頁保護關閉    
	KeServiceDescriptorTable.ServiceTableBase[66] = (unsigned int)lao_ntopenfile;//還原ntcreatefile
	yebaohukaiqi();//頁保護開啟    
	UCHAR tezhengma[5] = { 0x2b, 0xe1, 0xc1, 0xe9, 0x02 };
	yebaohuguanbi();//頁保護關閉    
	RtlCopyMemory((PVOID)dizhi2, tezhengma, 5);//還原kifastcallentry 
	yebaohukaiqi();//頁保護開啟    
	KdPrint(("已經執行到驅動解除安裝歷程\n"));
}
void yebaohuguanbi()//頁保護關閉    
{
	__asm{//去掉記憶體保護    
		cli
			mov  eax, cr0
			and  eax, not 10000h
			mov  cr0, eax
	}
}
void yebaohukaiqi()//頁保護開啟    
{
	__asm{//恢復記憶體保護      
		mov  eax, cr0
			or   eax, 10000h
			mov  cr0, eax
			sti
	}
}

void lisaisaide_guolvhanshu(ULONG ServiceTableBase, ULONG NumberOfServices)//李賽賽的過濾函式 注意不要在這裡加 __declspec (naked)這個不是彙編程式碼 注意傳過來的引數是ulong型別
{
	//KdPrint(("進入到我的的過濾函式來了 歐耶 可以監控應用層傳過來的請求(呼叫nt函式的資訊)\n"));
	if (ServiceTableBase == (ULONG)KeServiceDescriptorTable.ServiceTableBase)
	{
		if (NumberOfServices==190)
		{
	KdPrint(("看那些進入KiFasetCallEntry呼叫ntopenkey程序名是%s\n", (char*)PsGetCurrentProcess() + 0x16c));
		}
	}
}
__declspec (naked)
VOID lisaisaide_KiFasetCallEntry()//李賽賽的KiFasetCallEntry
{
	__asm
	{
		pushad 
		pushfd
		push eax
		push edi 
		call lisaisaide_guolvhanshu //呼叫我們的過濾函式
		popfd
		popad
		pop eax
		sub esp,ecx         //call lisaisaide_KiFasetCallEntry 替換掉的5個位元組的程式碼
		shr ecx,2
		jmp eax
	}
}
VOID hook_KiFasetCallEntry()//inlinehookKiFasetCallEntry
{
	ULONG  pianyi1 = 0;
	UCHAR tezhengma[5];
	pianyi1 = (ULONG)lisaisaide_KiFasetCallEntry - 5 - dizhi2;
	tezhengma[0] = 0xe8;
	*(ULONG*)&tezhengma[1] = pianyi1;
	//KdPrint(("李賽賽的KiFasetCallEntry地址%x  計算出來的 偏移%x\n", (ULONG)lisaisaide_KiFasetCallEntry, pianyi1));
	yebaohuguanbi();//頁保護關閉   
	RtlCopyMemory((PVOID)dizhi2, tezhengma, 5);//inlinehook_KiFasetCallEntry
	yebaohukaiqi();//頁保護開啟  
}
NTSTATUS lisaisaide_NtCreateFile(    //李賽賽的_NtCreateFile函式
	__out PHANDLE FileHandle,
	__in ACCESS_MASK DesiredAccess,
	__in POBJECT_ATTRIBUTES ObjectAttributes,
	__out PIO_STATUS_BLOCK IoStatusBlock,
	__in_opt PLARGE_INTEGER AllocationSize,
	__in ULONG FileAttributes,
	__in ULONG ShareAccess,
	__in ULONG CreateDisposition,
	__in ULONG CreateOptions,
	__in_bcount_opt(EaLength) PVOID EaBuffer,
	__in ULONG EaLength
	)
{
	__asm
	{
		pushad
		mov eax, [ebp + 0x4]
		mov dizhi1, eax
		popad
	}
	//KdPrint(("通過核心棧得到地址call ebx下一句的地址%x\n", dizhi1));//得到地址正確
	sosuohookdiandizhi();//搜尋hook KiFastCallEntry 
	//yebaohuguanbi();//頁保護關閉    
	//KeServiceDescriptorTable.ServiceTableBase[66] = (unsigned int)lao_ntopenfile;//還原ntcreatefile
	//yebaohukaiqi();//頁保護開啟    
	hook_KiFasetCallEntry(); //開始hook
	return   ((hanshuzhizhen1)lao_ntopenfile)(FileHandle, DesiredAccess, ObjectAttributes, IoStatusBlock, AllocationSize, FileAttributes, ShareAccess, CreateDisposition, CreateOptions, EaBuffer, EaLength);
}
ULONG sosuohookdiandizhi()//搜尋hook KiFastCallEntry 
{
	UCHAR *p = (UCHAR *)dizhi1;
	for (ULONG i = 0; i < 300;i++)
	{
		if (*p==0x2b&&*(p+1)==0xe1&&*(p+2)==0xc1&&*(p+3)==0xe9&&*(p+4)==0x02)
		{
			//KdPrint(("找到地址kifastcallentry的hook點地址  %x\n",(ULONG)p));
			dizhi2 = (ULONG)p;
			return (ULONG)p;
		}
		p--;
	}
	//KdPrint(("沒有找到hook點的地址%x 是錯誤的", (ULONG)p));
	return 0;
}
NTSTATUS DriverEntry(PDRIVER_OBJECT qudongduixiang,PUNICODE_STRING zhucebiao)
{
	lao_ntopenfile = KeServiceDescriptorTable.ServiceTableBase[66];//儲存老的ntopenfile函式地址
	yebaohuguanbi();//頁保護關閉    
	KeServiceDescriptorTable.ServiceTableBase[66] = (unsigned int)lisaisaide_NtCreateFile;//ssdthook_ntopenfile 屬於ssdthook
	yebaohukaiqi();//頁保護開啟    
	qudongduixiang->DriverUnload = xiezai1;
	return STATUS_SUCCESS;
}