过GPK驱动

本文介绍了一种驱动级代码注入技术,通过修改内核服务描述符表(SSDT)中的函数指针,实现对NT开头的内核函数进行绕过和钩子操作。包括NtCreateThread、NtProtectVirtualMemory等关键函数的处理方法。
摘要由CSDN通过智能技术生成
  

NtCreateThread
NtProtectVirtualMemory
NtQueueApcThread
NtTerminateProcess
NtWriteVitualMemory


Ke386IoSetAccessProcess
KeAttachProcess
KeInitalizeApc
KeStackAttachProcess
ObCheckObjectAccess
ZwOpenSection

 

 

这些函数被挂钩,全部都是头部push   retn的形式挂钩

SSDT HOOk可以绕过上面Nt开头的函数。

下面的函数没法绕,已经挂了头部了,貌似改任何字节都给检测出来。估计得挂G。P_K驱动的函数才行

随便写个驱动,能分析10分钟左右,够用了。(其实就跟XT直接恢复的效果一样,自己动手写下也是种收获吧)

 

上代码:

 

#include <windef.h>
#include <stdio.h>
#include <string.h>




typedef struct _ServiceDescriptorTable {
	PVOID ServiceTableBase; //System Service Dispatch Table 的基地址  
	PVOID ServiceCounterTable;//包含着 SSDT 中每个服务被调用次数的计数器。这个计数器一般由sysenter 更新。 
	unsigned int NumberOfServices;//由 ServiceTableBase 描述的服务的数目。  
	PVOID ParamTableBase; //包含每个系统服务参数字节数表的基地址-系统服务参数表 
}*PServiceDescriptorTable;  

extern "C" extern PServiceDescriptorTable KeServiceDescriptorTable;
extern "C" __declspec(dllimport) _stdcall KeAddSystemServiceTable(PVOID, PVOID, PVOID, PVOID, PVOID);

BOOL MyHook_flag=FALSE;


LONG ssdt_start; 
LONG ssdt_No_53;
LONG ssdt_No_137;
LONG ssdt_No_180;
LONG ssdt_No_257;
LONG ssdt_No_277;

LONG NtCreateThreadAddr;
LONG ntCreateThreadPush1;
LONG ntCreateThreadPush2;
LONG ntCreateThread_7;

LONG NtProtectVirtualMemoryAddr;
LONG ntProtectVirtualMemoryParam1;
LONG ntProtectVirtualMemoayParam2;
LONG ntProtectVirtualMemory_7;

LONG NtQueueAqcThreadAddr;
LONG ntQueueAqcThread_6;

LONG NtTerminateProcessAddr;
LONG ntTerminateProcess_8;

LONG NtWriteVirtualMemoryAddr;
LONG ntWriteVirtualMemoryParam1;
LONG ntWriteVirtualMemoryParam2;
LONG ntWriteVirtualMemory_7;

LONG Ke386IoSetAccessProcessAddr;
LONG ke386IoSetAccessProcess_7;

LONG KeAttachProcessAddr;
LONG keAttachProcess_6;

LONG KeInitializeApcAddr;
LONG keInitializeApc_8;

LONG KeStackAttachProcessAddr;
LONG keStackAttachProcess_6;

LONG ObCheckObjectAccessAddr;
LONG obCheckObjectAccess_8;

LONG ZwOpenSectionAddr;
LONG zwOpenSection_9;

VOID getKernelFunctionAddr();
VOID MyHook();
VOID unpass();


__declspec(naked) VOID MyNtCreateThread(){

	__asm{
		push ntCreateThreadPush1
		push ntCreateThreadPush2
		jmp ntCreateThread_7
	}

}

__declspec(naked) VOID MyNtVirtualProtectMemory(){

	__asm{
		push ntProtectVirtualMemoryParam1
		push ntProtectVirtualMemoayParam2
		jmp ntProtectVirtualMemory_7
	}

}


__declspec(naked) VOID MyNtQueueAqcThread(){

	__asm{
		mov edi,edi
		push ebp
		mov ebp,esp
		push ecx
		jmp ntQueueAqcThread_6
	}

}

__declspec(naked) VOID MyNtTerminateProcess(){

	__asm{
		mov edi,edi
		push ebp
		mov ebp,esp
		sub esp,0x10
		jmp ntTerminateProcess_8
	}

}

__declspec(naked) VOID MyNtWriteVirtualMemory(){

	__asm{
		push ntWriteVirtualMemoryParam1
		push ntWriteVirtualMemoryParam2
		jmp ntWriteVirtualMemory_7
	}

}

__declspec(naked) VOID MyKe386IoSetAccessProcess(){

	__asm{
		mov edi,edi
		push ebp
		mov ebp,esp
		xor ecx,ecx
		jmp ke386IoSetAccessProcess_7
	}

}

__declspec(naked) VOID MyKeAttachProcess(){

	__asm{
		mov edi,edi
		push ebp
		mov ebp,esp
		push esi
		jmp keAttachProcess_6
	}

}

__declspec(naked) VOID MyKeInitialzeApc(){

	__asm{
		mov edi,edi
		push ebp
		mov ebp,esp
		mov eax,dword ptr[ebp+8]
		jmp keInitializeApc_8
	}

}

__declspec(naked) VOID MyStackAttachProcess(){

	__asm{
		mov edi,edi
		push ebp
		mov ebp,esp
		push esi
		jmp keStackAttachProcess_6
	}

}

__declspec(naked) VOID MyObCheckObjectAccess(){

	__asm{
		mov edi,edi
		push ebp
		mov ebp,esp
		sub esp,0x10
		jmp obCheckObjectAccess_8
	}

}


__declspec(naked) VOID MyZwOpenSection(){

	__asm{
		mov eax,0x7d
		lea edx,dword ptr[esp+4]
		jmp zwOpenSection_9
	}

}

VOID pass(){
	

	if ( TRUE == MyHook_flag )
	{
		KdPrint(("Hook Already\n"));
		return;
	}

	MyHook_flag = TRUE;

	getKernelFunctionAddr();
	MyHook();

}


VOID MyHook(){
	

	__asm //去掉页面保护
	{
		cli
		mov eax,cr0
		and eax,not 10000h //and eax,0FFFEFFFFh
		mov cr0,eax

		mov eax,ssdt_No_53
		mov ebx,MyNtCreateThread
		mov dword ptr [eax], ebx

		mov eax,ssdt_No_137
		mov ebx,MyNtVirtualProtectMemory
		mov dword ptr [eax],ebx

		mov eax,ssdt_No_180
		mov ebx,MyNtQueueAqcThread
		mov dword ptr[eax],ebx

		mov eax,ssdt_No_257
		mov ebx,MyNtTerminateProcess
		mov dword ptr[eax],ebx
	
		mov eax,ssdt_No_277
		mov ebx,MyNtWriteVirtualMemory
		mov dword ptr[eax],ebx

		mov eax,Ke386IoSetAccessProcessAddr
		mov byte ptr[eax],0x68
		mov ebx,MyKe386IoSetAccessProcess
// 		sub ebx,eax
// 		sub ebx,5
		mov dword ptr[eax+1],ebx
		mov byte ptr[eax+5],0xc3

		mov eax,KeAttachProcessAddr
		mov byte ptr[eax],0x68
		mov ebx,MyKeAttachProcess
// 		sub ebx,eax
// 		sub ebx,5
		mov dword ptr[eax+1],ebx
		mov byte ptr[eax+5],0xc3
		
		mov eax,KeInitializeApcAddr
		mov byte ptr[eax],0x68
		mov ebx,MyKeInitialzeApc
// 		sub ebx,eax
// 		sub ebx,5
		mov dword ptr[eax+1],ebx
		mov byte ptr[eax+5],0xc3

		mov eax,KeStackAttachProcessAddr
		mov byte ptr[eax],0x68
		mov ebx,MyStackAttachProcess
// 		sub ebx,eax
// 		sub ebx,5
		mov dword ptr[eax+1],ebx
		mov byte ptr[eax+5],0xc3

	
		mov eax,ObCheckObjectAccessAddr
		mov byte ptr[eax],0x68
		mov ebx,MyObCheckObjectAccess
// 		sub ebx,eax
// 		sub ebx,5
		mov dword ptr[eax+1],ebx
		mov byte ptr[eax+5],0xc3


		mov eax,ZwOpenSectionAddr
		mov byte ptr[eax],0x68
		mov ebx,MyZwOpenSection
// 		sub ebx,eax
// 		sub ebx,5
		mov dword ptr[eax+1],ebx
		mov byte ptr[eax+5],0xc3

		mov  eax,cr0 
		or eax,10000h 
		mov cr0,eax 
		sti 
	}   
}

VOID unpass(){

	if ( FALSE == MyHook_flag )
	{
		KdPrint(("Not Hook Yet\n"));
		return;
	}

	KdPrint(("Unhook Ok\n"));
	MyHook_flag = FALSE;


	__asm //去掉页面保护
	{
		cli
		mov eax,cr0
		and eax,not 10000h //and eax,0FFFEFFFFh
		mov cr0,eax

		mov ebx,ssdt_No_53//ntCreateThread
		mov eax,NtCreateThreadAddr
		mov [ebx],eax

		mov ebx,ssdt_No_137//ntProtectVirtualMemory
		mov eax,NtProtectVirtualMemoryAddr
		mov [ebx],eax

		mov ebx,ssdt_No_180//ntNtQueueAqcThread
		mov eax,NtQueueAqcThreadAddr
		mov [ebx],eax

		mov ebx,ssdt_No_257//ntTerminalProcess
		mov eax,NtTerminateProcessAddr
		mov [ebx],eax

		mov ebx,ssdt_No_277
		mov eax,NtWriteVirtualMemoryAddr
		mov [ebx],eax

		mov ebx,Ke386IoSetAccessProcessAddr
		mov dword ptr[ebx],0x8b55ff8b
		mov dword ptr[ebx+4],0x57c933ec

		mov ebx,KeAttachProcessAddr
		mov dword ptr[ebx],0x8b55ff8b
		mov word ptr[ebx+4],0x56ec

		mov ebx,KeInitializeApcAddr//mov edi,edi;push ebp;mov ebp,esp;mov eax,[ebp+8]
		mov dword ptr[ebx],0x8b55ff8b
		mov dword ptr[ebx+4],0x08458bec

		mov ebx,KeStackAttachProcessAddr
		mov dword ptr[ebx],0x8b55ff8b
		mov word ptr[ebx+4],0x56ec

		mov ebx,ObCheckObjectAccessAddr
		mov dword ptr[ebx],0x8b55ff8b
		mov dword ptr[ebx+4],0x10ec83ec


		mov ebx,ObCheckObjectAccessAddr
		mov dword ptr[ebx],0x8b55ff8b
		mov dword ptr[ebx+4],0x10ec83ec
        mov dword ptr[ebx+8],0x5608458b

		mov ebx,ZwOpenSectionAddr
		mov dword ptr[ebx],0x7db8
		mov dword ptr[ebx+4],0x24548d00
		mov byte ptr[ebx+8],0x04

		mov  eax,cr0 
		or eax,10000h 
		mov cr0,eax 
		sti 
	} 
}

VOID getKernelFunctionAddr(){
	UNICODE_STRING Ke386IoSetAccessProcessStr;
	UNICODE_STRING KeAttachProcessStr;
	UNICODE_STRING KeInitializeApcStr;
	UNICODE_STRING KeStackAttachProcessStr;
	UNICODE_STRING ObCheckObjectAccessStr;
	UNICODE_STRING ZwOpenSectionStr;

	RtlInitUnicodeString(&Ke386IoSetAccessProcessStr,L"Ke386IoSetAccessProcess");
	RtlInitUnicodeString(&KeAttachProcessStr,L"KeAttachProcess");
	RtlInitUnicodeString(&KeInitializeApcStr,L"KeInitializeApc");
	RtlInitUnicodeString(&KeStackAttachProcessStr,L"KeStackAttachProcess");
	RtlInitUnicodeString(&ObCheckObjectAccessStr,L"ObCheckObjectAccess");
	RtlInitUnicodeString(&ZwOpenSectionStr,L"ZwOpenSection");

	Ke386IoSetAccessProcessAddr = (LONG)MmGetSystemRoutineAddress(&Ke386IoSetAccessProcessStr);
 	KeAttachProcessAddr         = (LONG)MmGetSystemRoutineAddress(&KeAttachProcessStr);
 	KeInitializeApcAddr         = (LONG)MmGetSystemRoutineAddress(&KeInitializeApcStr);
 	KeStackAttachProcessAddr    = (LONG)MmGetSystemRoutineAddress(&KeStackAttachProcessStr);
 	ObCheckObjectAccessAddr     = (LONG)MmGetSystemRoutineAddress(&ObCheckObjectAccessStr);
 	ZwOpenSectionAddr           = (LONG)MmGetSystemRoutineAddress(&ZwOpenSectionStr);

	ke386IoSetAccessProcess_7 = Ke386IoSetAccessProcessAddr + 7;
	keAttachProcess_6         = KeAttachProcessAddr + 6;
	keInitializeApc_8         = KeInitializeApcAddr + 8;
	keStackAttachProcess_6    = KeStackAttachProcessAddr + 6;
	obCheckObjectAccess_8     = ObCheckObjectAccessAddr + 8;
	zwOpenSection_9           = ZwOpenSectionAddr + 9;


	KdPrint(("Ke386IoSetAccessProcess=%X\n",Ke386IoSetAccessProcessAddr));
	KdPrint(("KeAttachProcess=%X\n",KeAttachProcessAddr));
	KdPrint(("KeInitializeApc=%X\n",KeInitializeApcAddr));
	KdPrint(("KeStackAttachProcess=%X\n",KeStackAttachProcessAddr));
	KdPrint(("ObCheckObjectAccess=%X\n",ObCheckObjectAccessAddr));
	KdPrint(("ZwOpenSection=%X\n",ZwOpenSectionAddr));


	ssdt_start = (LONG)KeServiceDescriptorTable->ServiceTableBase;
	ssdt_No_53  = ssdt_start + 53*4;
	ssdt_No_137 = ssdt_start + 137*4;
	ssdt_No_180 = ssdt_start + 180*4;
	ssdt_No_257 = ssdt_start + 257*4;
	ssdt_No_277 = ssdt_start + 277*4;


	NtCreateThreadAddr   = *(LONG*)ssdt_No_53;
	ntCreateThreadPush1 = *(BYTE*)(*(LONG*)ssdt_No_53+1);
	ntCreateThreadPush2 = *(LONG*)(*(LONG*)ssdt_No_53+3);
	ntCreateThread_7     = NtCreateThreadAddr+7;

	NtProtectVirtualMemoryAddr   = *(LONG*)ssdt_No_137;
	ntProtectVirtualMemoryParam1 = *(BYTE*)(*(LONG*)ssdt_No_137+1);
	ntProtectVirtualMemoayParam2 = *(LONG*)(*(LONG*)ssdt_No_137+3);
	ntProtectVirtualMemory_7     = NtProtectVirtualMemoryAddr+7;
	
	NtQueueAqcThreadAddr=*(LONG*)ssdt_No_180;
	ntQueueAqcThread_6=NtQueueAqcThreadAddr+6;

	NtTerminateProcessAddr=*(LONG*)ssdt_No_257;
	ntTerminateProcess_8=NtTerminateProcessAddr+8;
	
	NtWriteVirtualMemoryAddr   = *(LONG*)ssdt_No_277;
	ntWriteVirtualMemoryParam1 = *(BYTE*)(*(LONG*)ssdt_No_277+1);
	ntWriteVirtualMemoryParam2 = *(LONG*)(*(LONG*)ssdt_No_277+3);
	ntWriteVirtualMemory_7     = NtWriteVirtualMemoryAddr+7;



}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值