-
-
[原创]Ryuk勒索病毒反调试记录
-
2020-11-4 16:36
2775
-
前言
反调试属于反逆向技术,顾名思义,你想逆我的程序,我给你加点料,至少让你没有那么顺利。反调试针对的是调试器,在分析Ryuk勒索病毒的时候遇到一次反调试,记录一下。
过程
进入程序一开始就遇到了ZwQueryInformationProcess,通过网页端的MSDN查询发现没有多少参考信息,无奈只能寻求网页相关文章。最终找到关于这个API函数的一些重要信息(以下来源于网络):
NTSTATUS WINAPI ZwQueryInformationProcess(
_In_ HANDLE ProcessHandle,
_In_ PROCESSINFOCLASS ProcessInformationClass,
_Out_ PVOID ProcessInformation,
_In_ ULONG ProcessInformationLength,
_Out_opt_ PULONG ReturnLength
);
该函数第二个参数ProcessInformationClass设定特定的值,函数执行结果会保存在第三个参数ProcessInformation中。第二个参数为枚举类型,其中与反调试相关的参数有ProcessDebugPort(0x07),ProcessDebugObject-Handle(0x1E),ProcessDebugFlags(0x1F)。
ProcessDebugFlags
第一次调用ZwQueryInformationProcess,使用了0x1F作为第二个参数值,通过查询实际为ProcessDebugFlags。ProcessDebugFlags (0x1F)参数返回EPROCESS结构体的NoDebugInherit的相反数,意思是当调试器存在时, 返回值为0, 不存在时则返回1。
结果为1,表明此时不存在调试器(实质此时正在调试)。
PEB
接着使用了PEB作为反调试的手段,如使用FS:[30]寻址PEB,偏移加2找到BeingDebugged(+0x2),同样的可以通过IsDebuggerPresent() API可以获取PEB.BeingDebugged的值,若为1则表示进程处于被调试状态,由于ollydbg自身带有的插件对该反调试进行了限制,所以基本不用理会,会自动置为0。
ProcessDebugPort
随着慢慢的调试,第二次也调用ZwQueryInformationProcess,使用了0x7作为第二个参数值,通过查询实际为ProcessDebugPort。
ProcessDebugPort(0x7),非调试状态下debugport等于0,由于第三个参数的地址存在异常,执行完后并不能如期获得结果,不过这里是故意触发异常,但由于该异常后续没有被人为处理,此处并不影响后续的调试。
ProcessDebugObjectHandle
接着第三次调用ZwQueryInformationProcess,使用了0x1E作为第二个参数值,通过查询实际为ProcessDebugObjectHandle。第二个参数为ProcessDebugObjectHandle时,第三个参数返回为被调试对象句柄,当返回NULL时说明进程处于非调试状态。
执行结果为0x40,不为NULL,说明处于调试状态。
所以需要修改这个参数来绕过反调试,当不修改的时候,后续的逻辑如下,直接触发异常导致程序退出。
对该处的值进行修改后,经过分支直接跳过异常代码。
会执行到正常的函数内部
反调试如何过?
最后只需修改最后一个调用的ZwQueryInformationProcess的第三个参数ProcessInformation的值为0即可
整个流程图
[CTF入门培训]顶尖高校博士及硕士团队亲授《30小时教你玩转CTF》,视频+靶场+题目!助力进入CTF世界