assembly - 在跳转目标基于动态环境值的情况下如何构建控制流图?

标签 assembly x86 reverse-engineering control-flow-graph

在研究逆向工程时,我经常想到,因为我可以传递任何位置(我有权访问)作为参数,一个带有一些非硬编码或“非确定性”目标的跳转指令(因为它之前没有定义)由程序明确)可以瞄准任何地方。所以如果我加载 EAX使用基于说的值,操作系统版本的字符串并执行 jmp eax那么似乎任何试图生成控制流图的工具都不知道目标在哪里(它可以基于您当前的环境,但这可能会导致程序中的某些路径中断)。
我错过了什么吗?因为如果我正确理解这一点,似乎我在 IDA 中打开的每个恶意软件都会这样做(基于他们对目标环境了解的某些条件),但我没有看到像这样损坏的控制流图。再说一次,我对逆向工程很陌生。

最佳答案

事实上,正如您已经猜到的,形式为 JMP EAX 的指令可能会跳转到任何地方,因此会破坏您尝试逆向工程的程序的 CFG(也就是说,您不会从当前基本块中退出到已知代码段的弧)。
但是,编译器很少发出绝对间接跳转。当他们这样做时,它们通常用于为 switch 生成的跳转表。声明。如果我们谈论的是间接调用(或 jmp 尾调用),那么我们也有函数指针,您会看到形式为 CALL EAX 的指令。 (在 C++ 中很常见,即 vtables )。对于 switch例如,为了正确处理其输入变量或表达式的所有可能值(例如 int ),通常会有一些代码确保该值在使用它来索引之前处于给定范围内代码指针数组,然后绝对间接跳转到寄存器(或者更常见的是 jmp [table + eax*4] ,也许在 EAX 上做了一些数学运算之后)。
对于这种情况,使用的习语种类和编译器实现(即生成什么机器码)通常是众所周知的,因此反汇编器和反编译器可以检测它们并找出输入约束和跳转表的位置,因此正确的目的地(这就是 IDA/HexRays 所做的)。然而,有时这对于您的反汇编器/反编译器来说是不可能的或者只是太难弄清楚(例如,编译器使用了不同的未知语义,或者程序员故意尝试使逆向工程更加困难)。

关于assembly - 在跳转目标基于动态环境值的情况下如何构建控制流图?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69968121/

相关文章:

c++ - .exe 文件中的数据段有哪些限制?

c++ - 获取内存段信息

c - 简单的 C 内核 char 指针不工作

performance - 生产者-消费者在超同级与非超同级之间共享内存位置的延迟和吞吐量成本是多少?

c++ - 对二进制文件的内容进行逆向工程?

c++ - 如何消除 RICHEDIT 控件的 MessageBeep?

assembly - 汇编语言中的阶乘

c++ - 在函数中更改数组值 - 内联汇编

android - 保护我的应用程序安全免受反汇编程序的侵害

assembly - 为什么这个 PowerPC 指令序列似乎同时设置了 cr0 和 cr1?