A盾学习笔记(2)反inlinehook
发布日期:2021-06-29 01:11:24 浏览次数:4 分类:技术文章

本文共 4363 字,大约阅读时间需要 14 分钟。

下面学习下反inlinehook

在工程的AntilineHook.c里

总体思路就是找到jmp指令,判断是不是被inlinehook的跳转,然后自己重载了内核之后,把原来被感染inlinehook跳过去执行的函数的地址位置,再hook成我们重载正常的的函数地址,实现反inlinehook,我还以为要把污染的hook拷贝成正常code。

VOID AntiInlineHook(WCHAR *FunctionName){	ULONG ulTemp = NULL;	PUCHAR p;	BOOL bIsHooked = FALSE;	INSTRUCTION	Inst;	INSTRUCTION	Instb;	BOOL bInit = FALSE;	ULONG ulHookFunctionAddress;	ULONG JmpReloadFunctionAddress;	__try	{		//RMmIsAddressValid = ReLoadNtosCALL(L"MmIsAddressValid",SystemKernelModuleBase,ImageModuleBase);		if (RMmIsAddressValid)		{			bInit = TRUE;		}		if (!bInit)			return;		JmpFunctionAddress = GetSystemRoutineAddress(1,FunctionName);  //得到函数地址		if (DebugOn)			KdPrint(("Get System Routine Address:%ws:%08x\r\n",FunctionName,JmpFunctionAddress));		if (JmpFunctionAddress)		{			JmpReloadFunctionAddress = JmpFunctionAddress - SystemKernelModuleBase + (ULONG)ImageModuleBase;  //获得原始地址			if (!RMmIsAddressValid(JmpFunctionAddress) ||				!RMmIsAddressValid(JmpReloadFunctionAddress))			{				if (DebugOn)					KdPrint(("get function failed\r\n"));				return;			}			if (GetFunctionCodeSize(JmpFunctionAddress) == GetFunctionCodeSize(JmpReloadFunctionAddress) &&				memcmp(JmpFunctionAddress,JmpReloadFunctionAddress,GetFunctionCodeSize(JmpFunctionAddress)) != NULL)//意味着被inlinehook了,长度一样,内容不一样			{				if (DebugOn)					KdPrint(("search---->%ws",FunctionName));				//KdPrint(("---->%s:%08x",functionName,ulOldAddress));				//开始扫描hook				for (p=JmpFunctionAddress ;p< JmpFunctionAddress+GetFunctionCodeSize(JmpFunctionAddress); p++)				{					//是否结束?					if (*p == 0xcc ||						*p == 0xc2)//ret					{						break;					}					ulHookFunctionAddress = (*(PULONG)(p + 1) + (ULONG)p + 5);  //得到hook的地址,就是jmp指令跳到的函数地址					if (!RMmIsAddressValid(ulHookFunctionAddress))					{						continue;					}					ulTemp = NULL;//跳转地址,对P位置反汇编,libdasm和xde					get_instruction(&Inst,p,MODE_32);//就是把p处二进制转化成汇编					switch (Inst.type)//下面几个都是各种跳转的opcode					{					case INSTRUCTION_TYPE_JMP:						if(Inst.opcode==0xFF&&Inst.modrm==0x25)						{							//DIRECT_JMP							ulTemp = Inst.op1.displacement;						}						else if (Inst.opcode==0xEB)						{							ulTemp = (ULONG)(p+Inst.op1.immediate);						}						else if(Inst.opcode==0xE9)						{							//RELATIVE_JMP;							ulTemp = (ULONG)(p+Inst.op1.immediate);						}						break;					case INSTRUCTION_TYPE_CALL:						if(Inst.opcode==0xFF&&Inst.modrm==0x15)						{							//DIRECT_CALL							ulTemp = Inst.op1.displacement;						}						else if (Inst.opcode==0x9A)						{							ulTemp = (ULONG)(p+Inst.op1.immediate);						}						else if(Inst.opcode==0xE8)						{							//RELATIVE_CALL;							ulTemp = (ULONG)(p+Inst.op1.immediate);						}						break;					case INSTRUCTION_TYPE_PUSH:						if(!RMmIsAddressValid((PVOID)(p)))						{							break;						}						get_instruction(&Instb,(BYTE*)(p),MODE_32);						if(Instb.type == INSTRUCTION_TYPE_RET)						{							//StartAddress+len-inst.length-instb.length;							ulTemp = Instb.op1.displacement;						}						break;					}					if (ulTemp &&						RMmIsAddressValid(ulTemp))					{						if (ulTemp > SystemKernelModuleBase &&							ulTemp < SystemKernelModuleBase+SystemKernelModuleSize)   //太近的跳也不是,函数内部的跳转,一般不是rootkit的跳转						{							continue;						}						//ulTemp也不能小于 SystemKernelModuleBase,就是应用层跳转了。						if (ulTemp < SystemKernelModuleBase)						{							continue;						}						if (*(ULONG *)ulTemp == 0x00000000 ||							*(ULONG *)ulTemp == 0x00000005)						{							continue;						}						if (ulTemp > ulMyDriverBase &&//a盾的hook							ulTemp < ulMyDriverBase + ulMyDriverSize)						{							if (DebugOn)								KdPrint(("safesystem hook, denied access!"));							return;						}						ulRunAddress = (ULONG)p - (ULONG)JmpFunctionAddress;   //执行到达hook点的时候,一共执行了多少长度的代码						JmpReloadFunctionAddress = JmpReloadFunctionAddress + ulRunAddress;     //跳过前面执行的代码,继续往下执行 						if (DebugOn)							KdPrint(("found hook---->%ws:%08x:%08x-%x-%08x",FunctionName,ulTemp + 0x5,p,ulRunAddress,JmpReloadFunctionAddress));						//得到正确的跳转地址,直接hook人家的hook函数的头部,然后让它跳到reload代码的ulReloadAddress地址处继续执行剩下的代码,这样就绕过hook鸟						ulTemp = ulTemp + 0x5;						HookFunctionByHeaderAddress(							(DWORD)JmpReloadFunctionAddress,							ulTemp,//这个是正在运行的内核中inlinehook之后的代码							(PVOID)HookFunctionProcessHookZone,							&HookFunctionProcessPatchCodeLen,							&HookFunctionProcessRet							);					}				}			}		}	}__except(EXCEPTION_EXECUTE_HANDLER){	}	return;}

 

转载地址:https://blog.csdn.net/youyou519/article/details/94802088 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:知识点复习
下一篇:A盾学习笔记(1)

发表评论

最新留言

不错!
[***.144.177.141]2024年04月07日 15时41分16秒