【问题标题】:Randomizing registers随机化寄存器
【发布时间】:2015-11-26 12:16:21
【问题描述】:

如果不满足某些条件,我想通过跳转到随机位置来使程序崩溃。我也想通过像

这样的语句来随机化寄存器
asm("rdtsc \n");
asm ("movq %rax, %r15 \n");
...
asm ("xor %rbp, %r13 \n");
...

有没有更好/更隐蔽的方法来做到这一点?我很担心,因为rdtsc 不是程序中经常出现的语句。调用它也会不断产生类似的结果。除此之外,我还能以某种方式清除/随机化堆栈内容吗?

【问题讨论】:

  • 制作一个堆栈展开代码,在每个级别随机化堆栈帧...

标签: c gcc assembly 64-bit inline-assembly


【解决方案1】:

如果你只是想崩溃,你随机选择的目的地可能跳到合法的地方。只需运行ud2 指令 (0F 0B),这保证会在未来的每个 x86 CPU 上导致无效指令异常(导致 SIGILL)。即它是保留的,因此未来的指令集扩展将永远不会在指令开头使用该两字节序列。

如果您关心高质量随机性以阻止任何潜在的回溯或核心转储,请调用随机数生成器来填充随机数据缓冲区(或仅重复一个 32 位随机值)。用该垃圾数据填充所有寄存器。在 32 位代码中,您可以使用 popa 指令用垃圾数据填充所有寄存器。在 64 位模式下,您必须手动加载它们。

然后用该数据在堆栈上乱涂乱画,因此当您尝试写入未映射的地址时,您的程序最终会因段错误而停止(因为您已超出堆栈区域)。

你可以用 rep stosd 或其他东西来涂鸦。

就“隐秘性”而言,您需要更详细地说明您的威胁模型是什么,以及您试图阻止任何人学习/做些什么。即防止有人修改您的二进制文件以免以这种方式崩溃?

【讨论】:

    【解决方案2】:

    除了 Peter Cordes 的建议之外,我还要补充一点,OP 希望对负责这种混淆的代码保持超出范围(stealthier)。导致崩溃的指令需要在其他地方,否则混淆代码会从崩溃转储中显而易见,并且代码很容易修补以移除炸弹。

    一个相当简单的解决方案是从一个公共库函数(如readstrlen)中找到RET 操作码,然后通过将地址压入堆栈并执行RET 语句来跳转到那里。这个解决方案并不完美:存在存储执行跟踪的高级调试器,并且能够从崩溃位置回溯到混淆器。为了解决这个问题,您可能更愿意进入一个无限循环而不是崩溃,但该循环很容易找到并移除。

    您还可以在您的应用中嵌入一些复杂的代码,通过随机执行许多不同的函数来计算一段时间,并将其用作从混淆器跳转到的蜜罐。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-22
      • 1970-01-01
      • 1970-01-01
      • 2013-11-06
      • 1970-01-01
      相关资源
      最近更新 更多