A盾学习笔记(2)反inlinehook

85 篇文章 6 订阅
83 篇文章 9 订阅

下面学习下反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;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值