首页
论坛
课程
招聘
[旧帖] [原创]Inline_Hook 无需找表。只要在!ntosknl模块,Inline任意位置 0.00雪花
2011-8-14 21:22 2263

[旧帖] [原创]Inline_Hook 无需找表。只要在!ntosknl模块,Inline任意位置 0.00雪花

2011-8-14 21:22
2263
#include <NTDDK.h>

//----------------置全局变量+初始化.初始化是个好习惯.虽然我反汇编的时候发现编译器会帮你做这件事---------
ULONG JmpTest=0;
UCHAR  TestByte[5]={0x00,0x00,0x00,0x00,0x00}; 
ULONG retAddrIoCF_Xp=0;
//----------------

//----------------下面是系统信息类.偷懒复制过来的.实际上只SystemModuleInformation再用---------
typedef enum _SYSTEM_INFORMATION_CLASS {
SystemBasicInformation, // 0 Y N
SystemProcessorInformation, // 1 Y N
SystemPerformanceInformation, // 2 Y N
SystemTimeOfDayInformation, // 3 Y N
SystemNotImplemented1, // 4 Y N
SystemProcessesAndThreadsInformation, // 5 Y N
SystemCallCounts, // 6 Y N
SystemConfigurationInformation, // 7 Y N
SystemProcessorTimes, // 8 Y N
SystemGlobalFlag, // 9 Y Y
SystemNotImplemented2, // 10 Y N
SystemModuleInformation, // 11 Y N
SystemLockInformation, // 12 Y N
SystemNotImplemented3, // 13 Y N
SystemNotImplemented4, // 14 Y N
SystemNotImplemented5, // 15 Y N
SystemHandleInformation, // 16 Y N
SystemObjectInformation, // 17 Y N
SystemPagefileInformation, // 18 Y N
SystemInstructionEmulationCounts, // 19 Y N
SystemInvalidInfoClass1, // 20
SystemCacheInformation, // 21 Y Y
SystemPoolTagInformation, // 22 Y N
SystemProcessorStatistics, // 23 Y N
SystemDpcInformation, // 24 Y Y
SystemNotImplemented6, // 25 Y N
SystemLoadImage, // 26 N Y
SystemUnloadImage, // 27 N Y
SystemTimeAdjustment, // 28 Y Y
SystemNotImplemented7, // 29 Y N
SystemNotImplemented8, // 30 Y N
SystemNotImplemented9, // 31 Y N
SystemCrashDumpInformation, // 32 Y N
SystemExceptionInformation, // 33 Y N
SystemCrashDumpStateInformation, // 34 Y Y/N
SystemKernelDebuggerInformation, // 35 Y N
SystemContextSwitchInformation, // 36 Y N
SystemRegistryQuotaInformation, // 37 Y Y
SystemLoadAndCallImage, // 38 N Y
SystemPrioritySeparation, // 39 N Y
SystemNotImplemented10, // 40 Y N
SystemNotImplemented11, // 41 Y N
SystemInvalidInfoClass2, // 42
SystemInvalidInfoClass3, // 43
SystemTimeZoneInformation, // 44 Y N
SystemLookasideInformation, // 45 Y N
SystemSetTimeSlipEvent, // 46 N Y
SystemCreateSession, // 47 N Y
SystemDeleteSession, // 48 N Y
SystemInvalidInfoClass4, // 49
SystemRangeStartInformation, // 50 Y N
SystemVerifierInformation, // 51 Y Y
SystemAddVerifier, // 52 N Y
SystemSessionProcessesInformation // 53 Y N
} SYSTEM_INFORMATION_CLASS;

typedef struct _SYSTEM_MODULE_INFORMATION { // Information Class 11
ULONG Reserved[2];
PVOID Base;
ULONG Size;
ULONG Flags;
USHORT Index;
USHORT Unknown;
USHORT LoadCount;
USHORT ModuleNameOffset;
CHAR ImageName[256];
} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;


//---------------------Api申明---------


PVOID GetUndocumentFunctionAdress();

NTSYSAPI
NTSTATUS
NTAPI
ZwQuerySystemInformation(    //这个函数使用起来十分繁琐.但是功能强大
IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
IN OUT PVOID SystemInformation,
IN ULONG SystemInformationLength,
OUT PULONG ReturnLength OPTIONAL
); 

//---------------------开关内存读写保护--------
VOID WPOFF(VOID)
{
__asm
{
cli
mov eax,cr0
and eax,not 10000h
mov cr0,eax
}
}


VOID WPON(VOID)
{
__asm
{
mov eax,cr0
or eax,10000h
mov cr0,eax
sti
}
}

//------------------获取未知函数地址

PVOID
GetUndocumentFunctionAdress()
{

	ULONG size,index;
	PULONG buf;
    	ULONG i;
	PSYSTEM_MODULE_INFORMATION module;
	PVOID driverAddress=0;
   	ULONG ntosknlBase;
	ULONG ntosknlEndAddr;
	ULONG curAddr;
	NTSTATUS status;

	ULONG	code1_IoF=0x5d89db33,code2_IoF=0x1c758be0,code3_IoF=0x8903e683,code4_IoF=0xa164d475;


	ZwQuerySystemInformation(SystemModuleInformation,&size, 0, &size); //内存

	if(NULL==(buf = (PULONG)ExAllocatePool(PagedPool, size)))
	{
		DbgPrint("failed alloc memory failed  \n");
		return 0;
	}
     
	status=ZwQuerySystemInformation(SystemModuleInformation,buf, size , 0); //请求
	if(!NT_SUCCESS( status ))
	{
           	DbgPrint("failed  query\n");
	        return 0;
	}

	module = (PSYSTEM_MODULE_INFORMATION)(( PULONG )buf + 1);
	
	ntosknlEndAddr=(ULONG)module->Base+(ULONG)module->Size;
	ntosknlBase=(ULONG)module->Base;
	curAddr=ntosknlBase;
	ExFreePool(buf);

	for (i=curAddr;i<=ntosknlEndAddr;i++)  //在ntoskn内存范围内搜索.由于函数类型Break就不+了
		{
			if ((*((ULONG *)i)==code1_IoF)&&(*((ULONG *)(i+4))==code2_IoF)&&(*((ULONG *)(i+8))==code3_IoF)&&(*((ULONG *)(i+12))==code4_IoF)) 
			 
			{			
				retAddrIoCF_Xp = i;
				JmpTest = i + 0x5;
			 	DbgPrint(".");	
			 	DbgPrint("[retAddrIoCF_Xp] %x\n",retAddrIoCF_Xp);
			 	DbgPrint("[JmpTest] %x\n",JmpTest);		
			}
	}
return 0;

}


//--------------------------自定义函数--------------------

NTSTATUS _declspec(naked) MyKnowCall()  //这里一定要naked.不然函数多3句经典代码.参数呢?我偷懒了
{
__asm 
{
xor ebx, ebx            //这2句是原函数被HOOK地方的代码
mov dword ptr [ebp-0x20], ebx
jmp JmpTest             //调回到后面继续执行
}
}



//-------------------开始HOOK-----------

VOID StartInLineHook()
{
ULONG JmpOffsetTest;
 
UCHAR JmpCode[5]={0xe9,0x00,0x00,0x00,0x00};  //jmp

UCHAR JmpCodeTest[5]={0xe9,0x00,0x00,0x00,0x00};

//-----------------
   	 RtlCopyMemory (TestByte, (PVOID)retAddrIoCF_Xp, 5);  //备份原先没HOOK的时候该地址的代码

   	 DbgPrint("[TestByte] 0x%x\n",TestByte);


//---------------------新函数与老函数的偏移差
JmpOffsetTest=(PCHAR)MyKnowCall-(PCHAR)retAddrIoCF_Xp-0x5;   
//因为自己的驱动是后加载的,属于高位地址。所以放在前面减去老地址, -5是跳转所占的5个字节。得到偏移差

DbgPrint("[JmpOffsetTest]:%08X",JmpOffsetTest);
DbgPrint("[MyKnowCall]:%08X",MyKnowCall);

//-----------------

RtlCopyMemory(JmpCodeTest+1,&JmpOffsetTest,4);     //这是构成一条跳转语句 


DbgPrint("[JmpCodeTest]:%08X",JmpCodeTest);
DbgPrint(".");
DbgPrint("[retAddrIoCF_Xp]:%08X",retAddrIoCF_Xp);
DbgPrint("[JmpCodeTest]:%08X",(PVOID)JmpCodeTest); //ULONG.UCHAR.PVOID之类的+不+都不影响。同上语句
//-----------------------------

//-----------开始HOOK--------

WPOFF();        //内存不可直接操作。先关保护,和提升IRQL级别一个道理、
RtlCopyMemory((PVOID)retAddrIoCF_Xp,(PVOID)JmpCodeTest,5); 
WPON();         //完了记得开启保护、内核不是R3;不开保护容易BSOD。
}

//-----------------------卸载入口--------------
VOID DriverUnload (PDRIVER_OBJECT pDriverObject)  //后面这个参数是用来卸载调用的
{
WPOFF(); 
RtlCopyMemory((PVOID)retAddrIoCF_Xp,TestByte,5);    //把原先备份的地址代码复制到我们HOOK的地址、就是还原、
WPON(); 
DbgPrint("InLine HOOK已恢复!!!\n驱动服务已卸载\n");
}

//-------------------------驱动入口-----------------
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject,PUNICODE_STRING pRegistryPath) //其实这个代码只需要运行一次
{
GetUndocumentFunctionAdress();  //获取未知函数地址.通过特征码搜索的、和aob一个道理

StartInLineHook();              //开始运行HOOK函数
pDriverObject->DriverUnload =DriverUnload;   //记得给卸载派发例程
return STATUS_SUCCESS;          //这里就直接返回成功了。
}



[招生]科锐逆向工程师培训46期预科班将于 2023年02月09日 正式开班

收藏
点赞0
打赏
分享
最新回复 (5)
雪    币: 123
活跃值: 活跃值 (216)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
xed 活跃值 2011-8-14 21:24
2
0
同时问问
任意位置的话要怎么做
雪    币: 3800
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
paulbaby 活跃值 2011-8-15 00:05
3
0
源码清晰,谢谢楼主
雪    币: 1872
活跃值: 活跃值 (706)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
z许 活跃值 2011-8-15 02:43
4
0
楼主好厉害。。学习了。
雪    币: 203
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
myliliyi 活跃值 2013-2-26 11:59
5
0
ULONG  code1_IoF=0x5d89db33,code2_IoF=0x1c758be0,code3_IoF=0x8903e683,code4_IoF=0xa164d475;

这里怎么理解?通用?
雪    币: 3004
活跃值: 活跃值 (2371)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
caolinkai 活跃值 2013-2-26 14:04
6
0
要搜索的特征码。。。。。。。。。
游客
登录 | 注册 方可回帖
返回