本文以Safengine Protector v2.3.x.0为例, 提供了一种C++代码快速恢复Safengine的Shadow DLL的方法, 没啥技术含量, 仅希望能给各位一点参考.
Shadow DLL是一种加密壳常见的反Hook/反下断方案, 工作原理简言之就是自行加载系统DLL, 并重定向受保护程序的API调用到相应处理过的Shadow DLL, 由此绕开了对原有系统DLL的调用, 阻止对系统DLL的下断和拦截. 详细请参阅半斤八两前辈的文章【原创】Kill Safengine Shadow Dll(附源码)
那如何恢复呢?上面那篇文章已经讲得非常清楚了, 本文只是补充了一点, 即快速恢复.
有时候我们只对特定的API感兴趣, 那么我们大可通过PE结构直接确定该API在物理文件中的位置(File Offset), HOOK NtReadFile拦截壳对系统DLL文件的读取, 接着在特定位置使用0xFF25 jmp到系统DLL, 完成恢复.
拦截部分, 我的做法是HOOK NtCreateFile, NtReadFile, NtClose以确定壳正在加载那个DLL, 这种方法感觉最为简单高效, 无须额外的API调用(仅仅HOOK NtReadFile你无法直接判断打开的是什么文件), 然后可能你还要记录读取的位置, 因为SE壳会分多次, 而不是一次性读入, 如果特定位置恰好在分块位置, 你就需要特殊处理.
下面附上由Export Name确定对应File Offset的方法, 可算是本文的核心代码:
static DWORD KiGetFileOffset(LPVOID lpBaseOfImage, LPCSTR lpTargetFuncName)
{
auto lpNtHeader = Rtl