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 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
不错!
[***.144.177.141]2024年04月07日 15时41分16秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
使用LoadRunner监控Apache的步骤
2019-04-29
LoadRunner录制脚本时报加载GrooveUtil.dll出错的解决方法
2019-04-29
用Spotlight实时监控Windows Server 2008
2019-04-29
Tomcat 6.0.32中调整JVM大小及最大线程数
2019-04-29
Mysql数据库下载及安装
2019-04-29
MySql安装时解决要输入current root password的方法
2019-04-29
Linux下free命令详解
2019-04-29
Linux下启动rpc时提示Cannot register service: RPC: Unableto receive; errno = Connectionrefused的问题
2019-04-29
Google纪念遗传学之父孟德尔诞辰一百周年图标
2019-04-29
在Apache下配置多个虚拟主机站点
2019-04-29
Apache中目录权限访问控制配置
2019-04-29
Apache的认证和授权配置
2019-04-29
【学习笔记】Linux下CPU性能评估
2019-04-29
【学习笔记】Linux下内存性能评估
2019-04-29
【学习笔记】Linux下磁盘IO性能评估
2019-04-29
【学习笔记】Mysql中通过profiling定位query性能瓶颈
2019-04-29
2011年网上购书清单
2019-04-29
质量管理专家——戴明的14点说
2019-04-29
软件测试需要思考的问题?
2019-04-29
软件问题的分类与管理
2019-04-29