首页 文章

你最喜欢的反调试技巧是什么?

提问于
浏览
25

在我以前的雇主,我们使用了第三方组件,它基本上只是一个DLL和一个头文件 . 该特定模块在Win32中处理打印 . 然而,制造该组件的公司破产了,所以我无法报告我发现的错误 .

所以我决定自己修复bug并启动调试器 . 我很惊讶地发现几乎无处不在的反调试代码,通常 IsDebuggerPresent ,但引起我注意的是:

; some twiddling with xor 
    ; and data, result in eax 
    jmp eax 
    mov eax, 0x310fac09 
    ; rest of code here

乍一看,我刚刚跨过了被叫两次的例程,然后事情就变成了香蕉 . 过了一会儿,我意识到这个小小的结果总是一样的,即jmp eax总是直接跳到 mov eax, 0x310fac09 指令中 . 我解剖了字节,它是 0f31rdtsc 指令,用于测量DLL中某些调用之间的时间 .

所以我对SO的问题是: What is your favourite anti-debugging trick?

10 回答

  • 3

    在合法的外观中计算跳跃,但真正隐藏了实际的指令指令是我的最爱 . 无论如何,它们很容易被人类检测到,但是自动化工具经常弄乱它 .

    替换堆栈上的返回地址也是浪费时间的好时机 .

  • 1

    使用nop通过调试器删除程序集是一个有用的技巧 . 当然,放回代码要困难得多!

  • 6

    我最喜欢的技巧是为一个不起眼的微处理器编写一个简单的指令仿真器 .

    然后将为微处理器编译复制保护和一些核心功能(GCC在这里是一个很好的帮助),并作为二进制blob链接到程序中 .

    这背后的想法是,普通x86代码中不存在复制保护,因此无法进行反汇编 . 您无法删除整个模拟器,因为这会从程序中删除核心功能 .

    破解程序的唯一机会是对微处理器仿真器的工作进行逆向工程 .

    我已经使用MIPS32进行仿真,因为它很容易模拟(只需要500行简单的C代码) . 为了使事情更加模糊,我没有使用原始的MIPS32操作码 . 相反,每个操作码都与它自己的地址xor'ed .

    复制保护的二进制文件看起来像垃圾数据 .

    强烈推荐!在裂缝出现之前花了超过6个月(这是一个游戏项目) .

  • 27

    我一直是许多RCE社区的成员,并且在黑客攻击和破解方面做得很好 . 从我的时间开始,我意识到这种脆弱的技巧通常是不稳定的,而且相当无用 . 大多数通用的反调试技巧都是特定于操作系统的,根本不是“可移植的” .

    在前面提到的示例中,您可能使用内联汇编和 naked 函数 __declspec ,两者在x64架构上进行编译时都不受MSVC支持 . 当然,仍然有办法实现上述技巧,但任何已经反转足够长时间的人都能在几分钟内发现并击败这一技巧 .

    因此,我建议不要在使用 IsDebuggerPresent API进行检测之外使用反调试技巧 . 相反,到目前为止,我已经在保护我的代码方面做了很多工作 .

  • 3

    关闭作为调试器附加到父级的子进程并修改关键变量 . 用于保持子进程驻留并使用调试器内存操作作为某种键操作的IPC的加分点 .

    在我的系统上,您无法将两个调试器附加到同一进程 .

    关于这一个的好处是,除非他们试图篡改任何东西没有破坏 .

  • 2

    参考未初始化的内存! (和其他黑魔法/ vodoo ......)

    这是一个非常酷的读物:http://spareclockcycles.org/2012/02/14/stack-necromancy-defeating-debuggers-by-raising-the-dead/

  • 0

    最现代的混淆方法似乎是虚拟机 .

    您基本上可以获取目标代码的一部分,并将其转换为您自己的字节码格式 . 然后添加一个小型虚拟机来运行此代码 . 正确调试此代码的唯一方法是为VM的指令格式编写仿真器或反汇编程序代码 . 当然,你也需要考虑性能 . 太多的字节码会使您的程序比本机代码运行得慢 .

    现在大多数旧技巧都没用了:

    • Isdebugger存在:非常蹩脚,容易修补

    • 其他调试器/断点检测

    • Ring0东西:用户不喜欢安装驱动程序,实际上你可能会破坏系统上的东西等等 .

    • 每个人都知道或者使你的软件不稳定的其他微不足道的东西 . 请记住,即使一个破解使你的程序不稳定但它仍然有效,这种不稳定性将归咎于你 .

    如果您真的想自己编写VM解决方案(有很好的销售程序),请不要只使用一种指令格式 . 使其具有多态性,以便您可以让代码的不同部分具有不同的格式 . 这样,只需编写一个模拟器/反汇编程序就无法破解所有代码 . 例如,一些人提供的MIPS解决方案似乎很容易被破解,因为MIPS指令格式已有详细记录,IDA等分析工具已经可以对代码进行反汇编 .

    List of instruction formats supported by IDA pro disassembler

  • 6

    我希望人们编写的软件既可靠又可靠,并且可以做广告宣传的软件 . 他们还以合理的价格以合理的许可证出售它 .

    我知道我浪费了太多时间处理那些复杂的供应商许可方案只会给客户和供应商带来问题 . 我始终建议避开这些供应商 . 在核电站工作,我们被迫使用某些供应商的产品,因此被迫必须处理他们的许可计划 . 我希望有一种方法可以回到我个人浪费时间来处理他们未能给我们提供有效许可产品的尝试 . 这似乎是一个小问题,但对于那些因自己的利益而过于棘手的人来说似乎是一件困难的事情 .

  • 4

    我是第二个虚拟机建议 . 我实现了一个MIPS I模拟器,它现在可以执行使用mipsel-elf-gcc生成的二进制文件 . 添加到代码/数据加密功能(AES或您选择的任何其他算法),自我模拟的能力(因此您可以使用嵌套模拟器),并且您有一个非常好的代码混淆器 .

    选择MIPS I的一个很好的特点是1)它易于实现,2)我可以用C编写代码,在我的桌面上调试它,并在完成后只为MIPS交叉编译 . 无需调试自定义操作码或手动编写自定义VM的代码 .

  • 2

    我个人最喜欢的是Amiga,那里有一个协处理器(Blitter)独立于处理器进行大量数据传输;将指示该芯片清除所有存储器,并从定时器IRQ复位 .

    连接动作重放盒式磁带时,停止CPU将意味着Blitter将继续清除内存 .

相关问题