目标程序
程序下载:
解压密码:9unk
程序简介:本程序使用 API 函(IsDebuggerPresent)数检测 x64dbg。
任务目标:绕过反调试机制,正确运行程序。
方法一(修改指令)
使用 “F9” 运行程序的时候,程序自动停止调试,如下图所示(此时应该考虑软件可能是用 API 函数-IsDebuggerPresent 来检测调试软件)。
重新加载程序到主模块,并使用 “ctrl+N” 查看程序的 API。此时可以看到 IsDebuggerPresent 这个 API。
双击 IsDebuggerPresent 跳转到汇编窗口,并设置 “F2” 断点。
“F9” 运行到断点处,此时的 eax=0 。
“ctrl+f9” 运行程序到返回处,此时的 eax=1 。
尝试把 eax 的值改为 0,并运行程序看看。
如上图所示程序运行成功,我们重新加载程序,运行到断点处。
“F8” 单步运行程序到 ret 处,可以看到此时程序运行在 kernel32.dll 处。
继续单步执行,此时程序返回到主模块。可以看到此时程序的第一个指令就是判断 eax 是否等于 0,下一个指令就是根据返回值做出相应的操作。
把 “je” 指令 改成 “jmp” 无条件跳转指令。
另存文件,并测试程序是否能正常运行。
方法二(修改内存数据)
FS 寄存器
FS 寄存器指向当前活动线程的 TEB 结构(线程结构)
偏移 | 说明 |
---|---|
000 | 指向SEH链指针 |
004 | 线程堆栈顶部 |
008 | 线程堆栈底部 |
00C | SubSystemTib |
010 | FiberData |
014 | ArbitraryUserPointer |
018 | 指向 TEB 自身(镜像地址) |
020 | 进程PID |
024 | 线程ID |
02C | 指向线程局部存储指针 |
030 | PEB 结构地址(进程结构) |
034 | 上个错误号 |
PEB 结构
PEB(Process Envirorment Block Structure)进程环境信息块,这里包含了一些进程信息。这个结构体中主要包含了调试信息,获取到这个调试信息就能知道程序是否被调试。
1 | typedef struct _PEB { |
我们看到第一个参数定义了 2 个字节,到第二个参数(调试状态)是结构体的第 3 个字节。
IsDebuggerPresent 函数运行原理
在这里 IsDebuggerPresent 函数有两条指令:
1 | mov eax, dword ptr fs:[0x00000030] |
第一个命令:当前 fs 寄存器,选择 030 的偏移(PEB 结构)
第二个命令:传送 [eax+2] 内存地址的字节给 eax 寄存器
可以看到这里将第三个字节 “01” 存到了 eax 中。1 表示程序被调试
修改特殊字节实现反调试
该方法在程序刚刚启动的时候就可以定位到特殊字节,现在把该字节修改为 0
继续 “F9” 运行程序
方法三(插件)
SharpOD x64
将 SharpOD 插件放到相应的 plugins 目录中,并重启 x64dbg
选中 插件 —> SharpOD x64 —> Options —> 勾选 “Hide PEB” —> “save”
重启 x64dbg,加载运行程序
reference
- 本文标题:x64dbg-反调试一
- 本文作者:9unk
- 创建时间:2020-12-30 18:26:28
- 本文链接:https://9unkk.github.io/2020/12/30/x64dbg-fan-diao-shi-yi/
- 版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!