Inline Hook检测模块到驱动
2008-10-16 15:07
363 查看
by sudami
由于项目需要,驱动中要做所有的事情,所以我负责的一个小小的模块自然要全部在驱动中实现;
小小的模块中一个小小的Inline Hook检测部分当然也不例外. 不过是要把某个函数调用链下所有调用过的函数都扫一遍,看是否存在恶意程序的干扰,自然用个深度递归就搞定,可是移植到驱动中,扫描是没问题,就怕那些变态的HOOK恢复不过来,还好,经过一小段时间的算法改进,差不多实现了. 当然,"实现了"和"产品级"是不可同日而语的,嘿嘿,但是总算前进了一小步吧,同时也期待wy同学的进展...
还有,堆栈回溯也很好玩,其实没啥难度,关键是要仔细的理解,结合windbg+vm,然后自己写个驱动,下断点调试下,就知道那些寄存器中的东西,写code就简单了.这样做主要是回溯定位出恶意程序的模块,结合搜索隐藏模块那些东西,自然能找到他们...
哎,高端调试很强大,稍微跟下,就能知道很多东西,看来以后得多学习~~~~
//
// 像 "微点/KV 2008"的JMP类型的HOOK,可能会在JMP前后留下一堆nop.
// 所以必须精确计算出要恢复的长度,无奈项目需要,检测模块全部得在
// 驱动中完成,所以把以前在R3写的艰难的移植到了驱动中,测试了下,还算
// 稳定,哎,一般到驱动做全模块的HOOK检测,稳定性降低了不少啊...
// -- sudami 08/10/01
//
![](http://hiphotos.baidu.com/sudami/pic/item/37d86b738200e3068601b040.jpg)
![](http://hiphotos.baidu.com/sudami/pic/item/b6260c5490f78d4e574e0040.jpg)
对于其中的计算被Patch掉的长度,我是这样做的:
// 计算出要恢复的长度
pTmp1ForJMP = p - 10 ; // 从JMP的前10字节开始对比
tForJMP = (DWORD)pTmp1ForJMP - (DWORD)g_pKernelBase + (DWORD)hMod;
lengthForJMP = 0 ;
for( pAddrForJmp = (PBYTE)(void*)pTmp1ForJMP;
pAddrForJmp < (PBYTE)(void*)pTmp1ForJMP + 0x20;
pAddrForJmp += lengthForJMP)
{
lengthForJMP = Disasm(pAddrForJmp, &sForJMP);
if( 0 == lengthForJMP ) {
pAddrForJmp++;
continue;
}
if( 0 == memcmp( pAddrForJmp, (PBYTE)tForJMP + (pAddrForJmp - (PBYTE)pTmp1ForJMP), lengthForJMP ) ) {
if ( TRUE == bSigure ) {
// 到这里,从不同变成了相同,已经是第2次出项相同了
// 记录出现变化的地址,和不同代码段的长度
break ;
}
// 到这里,肯定是第一次出现相同,然后一直继续
uAddrSigure = (PBYTE)(pAddrForJmp + lengthForJMP) ; // 记录出现变化的起始地址
continue ;
} else {
// 到这里,肯定是出项了不同,然后一直继续
bSigure = TRUE ;
uLen += lengthForJMP ; // 记录不同代码段的长度
continue ;
}
}
DbgPrint("JMP Type Modify; len = %d/n",uLen);
// 开始恢复.
由于项目需要,驱动中要做所有的事情,所以我负责的一个小小的模块自然要全部在驱动中实现;
小小的模块中一个小小的Inline Hook检测部分当然也不例外. 不过是要把某个函数调用链下所有调用过的函数都扫一遍,看是否存在恶意程序的干扰,自然用个深度递归就搞定,可是移植到驱动中,扫描是没问题,就怕那些变态的HOOK恢复不过来,还好,经过一小段时间的算法改进,差不多实现了. 当然,"实现了"和"产品级"是不可同日而语的,嘿嘿,但是总算前进了一小步吧,同时也期待wy同学的进展...
还有,堆栈回溯也很好玩,其实没啥难度,关键是要仔细的理解,结合windbg+vm,然后自己写个驱动,下断点调试下,就知道那些寄存器中的东西,写code就简单了.这样做主要是回溯定位出恶意程序的模块,结合搜索隐藏模块那些东西,自然能找到他们...
哎,高端调试很强大,稍微跟下,就能知道很多东西,看来以后得多学习~~~~
//
// 像 "微点/KV 2008"的JMP类型的HOOK,可能会在JMP前后留下一堆nop.
// 所以必须精确计算出要恢复的长度,无奈项目需要,检测模块全部得在
// 驱动中完成,所以把以前在R3写的艰难的移植到了驱动中,测试了下,还算
// 稳定,哎,一般到驱动做全模块的HOOK检测,稳定性降低了不少啊...
// -- sudami 08/10/01
//
![](http://hiphotos.baidu.com/sudami/pic/item/37d86b738200e3068601b040.jpg)
![](http://hiphotos.baidu.com/sudami/pic/item/b6260c5490f78d4e574e0040.jpg)
对于其中的计算被Patch掉的长度,我是这样做的:
// 计算出要恢复的长度
pTmp1ForJMP = p - 10 ; // 从JMP的前10字节开始对比
tForJMP = (DWORD)pTmp1ForJMP - (DWORD)g_pKernelBase + (DWORD)hMod;
lengthForJMP = 0 ;
for( pAddrForJmp = (PBYTE)(void*)pTmp1ForJMP;
pAddrForJmp < (PBYTE)(void*)pTmp1ForJMP + 0x20;
pAddrForJmp += lengthForJMP)
{
lengthForJMP = Disasm(pAddrForJmp, &sForJMP);
if( 0 == lengthForJMP ) {
pAddrForJmp++;
continue;
}
if( 0 == memcmp( pAddrForJmp, (PBYTE)tForJMP + (pAddrForJmp - (PBYTE)pTmp1ForJMP), lengthForJMP ) ) {
if ( TRUE == bSigure ) {
// 到这里,从不同变成了相同,已经是第2次出项相同了
// 记录出现变化的地址,和不同代码段的长度
break ;
}
// 到这里,肯定是第一次出现相同,然后一直继续
uAddrSigure = (PBYTE)(pAddrForJmp + lengthForJMP) ; // 记录出现变化的起始地址
continue ;
} else {
// 到这里,肯定是出项了不同,然后一直继续
bSigure = TRUE ;
uLen += lengthForJMP ; // 记录不同代码段的长度
continue ;
}
}
DbgPrint("JMP Type Modify; len = %d/n",uLen);
// 开始恢复.
相关文章推荐
- 检测内核已加载模块的所有导出函数是否被inlinehook
- INLINE HOOK过驱动保护的理论知识和大概思路
- Android使用switch模块进行GPIO口检测(一)-->LINUX驱动部分
- Win64 驱动内核编程-23.Ring0 InLineHook 和UnHook
- 基于linux switch模块的HDMI检测状态驱动
- 简单的INLINE HOOK检测
- 驱动学习----RootKits---InlineHook
- 某同学的inline hook检测程序简单逆向分析
- XP中Inline HOOK 8042驱动实现键盘钩子的方法
- Linux驱动编程 step-by-step (六) 用户地址检测 简单模块调试 以及一些杂项
- 分享补丁模块(带源码)InlinePatch,Hook,内存DLL注入 都有哦
- INLINE HOOK过简单驱动保护的理论知识和大概思路
- 【转】 xx_学驱动 -- INLINE HOOK 过简单驱动保护、、
- xx_学驱动 -- INLINE HOOK 过简单驱动保护、、
- Linux驱动编程 step-by-step (六) 用户地址检测 简单模块调试 以及一些杂项
- linux驱动编译进内核或模块配置
- ACCDET模块耳机检测的原理
- MATLAB中的检测跟踪模块
- 大小端检测模块
- ZF2小TIP:使用事件驱动为模块快速设置模板