前段时间在UC论坛看到《Module Spoof - Spoof location of DLL》这篇帖子,乍一看,很是好奇,之前有模块踩踏,现在又来了个模块欺骗,是不是又有什么新鲜玩意儿,刚好这个帖子又是五月之星,不妨看一下。
具体细节部分,放到正文中用再说,首先从整体上了解一下此技术。
核心目的:通过技术手段隐藏模块位置,使得从外部无法获取到模块的真实地址,即便修改了模块函数功能,在内部并不会起作用。
核心思想:模块加载回调 + hook 关键函数 + 模块的手动映射。
前提条件:这种方法只适用于动态加载的模块( 通过LoadLibrary调用 ),而不适用于静态加载的模块。
如下图所示,被隐藏模块在进程中存在两处映射,一处是通过动态加载到内存中,另外一处则是通过手动映射加载至内存,进程内部所有对此模块内函数的调用都来自手动映射部分。
正文
注册回调
通过LdrRegisterDllNotification注册dll加载回调,当首次动态加载dll时候,回调触发。
NTSTATUS NTAPI LdrRegisterDllNotification(
_In_ ULONG Flags,
_In_ PLDR_DLL_NOTIFICATION_FUNCTION NotificationFunction,
_In_opt_ PVOID Context,
_Out_ PVOID *Cookie
);
比较重要的是第二和第四参数,第二参数为注册的回调函数,第四参数为回调函数标识符,在LdrUnregisterDllNotification使用,最好记得卸载否则可能发生意外情况。
在回调被调用时候,主要做两件事情
• 手动进行模块再映射,保存重映后的模块基址
• hook入口点
hook关键函数
正常来说,加载模块为了使用其导出函数,并通过一些windows api来获取并执行导出,比如GetProcAddress ,GetModuleHandle/LoadLibrary等,这些函数就是关键函数,我们通过hook这些函数返回手动映射模块相关信息,而非正常加载的模块,比如模块基址或者函数地址。具体hook函数可以自己指定,如下是原作者hook的函数
hook LoadLibraryExW:随后进程内部若想获取手动映射的模块基址,都应使用LoadLibraryExW(或者下面两个函数),而非LoadLibraryA/LoadLibraryW
hook GetModuleHandleW和hook GetModuleHandleExW同上,用来获取模块基址
hook GetProcAddress:获取指定模块函数地址,如果是被隐藏的模块,则返回位于手动映射模块中的函数地址。
我们以GetModuleHandleW hook为例,首先校验参数是否为零或者并非隐藏模块名,这种情况下直接返回正常模块的地址,否则返回手动映射的模块基址。
动态加载模块
最后我们通过调用LoadLibraryA/LoadLibraryW动态加载需要隐藏的模块,当然调用LoadLibraryExW也是可以的,但是需要在Hook中做处理,当需要隐藏的模块没有手动映射时,调用原始LoadLibraryExW
随后触发如下逻辑:
总结
代码中还有一部分用来检测是否有外部进程访问对外模块,被称为模块蜜罐,所以这是一种偏防守类型的技术,可以用来做软件防护。另外此技术用到的都是很成熟的技术,比如hook和手动映射,如果平时有积累的话重写还是比较轻松的。
引用
https://www.unknowncheats.me/forum/anti-cheat-bypass/633575-module-spoof-spoof-location-dll.html
https://github.com/Oliver-1-1/ModuleSpoof
推荐站内搜索:最好用的开发软件、免费开源系统、渗透测试工具云盘下载、最新渗透测试资料、最新黑客工具下载……
还没有评论,来说两句吧...