【问题标题】:Understanding Decompiled Assembly Code了解反编译的汇编代码
【发布时间】:2017-08-18 21:26:42
【问题描述】:

我试图从汇编中理解这段代码,

int32_t phase_5(char * str) {
    int32_t v1 = 0;
    if (strlen(str) != 4) {
        // 0x8049153
        alert_henchmen(5);
        v1 = 0;
        // branch -> 0x80491a6
    }
    while (true) {
        int32_t * v2 = (int32_t *)(4 * v1 + (int32_t)&g2); // 0x8049192_0
        char * v3 = (char *)(v1 + (int32_t)str);
        int32_t v4 = 0;
        int32_t v5 = 0; // 0x01516
        // branch -> 0x8049175
        int32_t v6; // bp+014
        while (true) {
            char v7 = *(char *)(v4 + (int32_t)"4l6aiqhor20x"); // 0x8049188
            v6 = v5;
            if ((int32_t)*v3 == (int32_t)v7) {
                // 0x804918f
                v6 = *v2 == v4 ? 1 : v5;
                // branch -> 0x80491a2
            }
            int32_t v8 = v4 + 1; // 0x80491a2
            if (v8 >= 12) {
                // break -> 0x80491ac
                break;
            }
            v4 = v8;
            v5 = v6;
            // continue -> 0x8049175
        }
        // 0x80491ac
        if (v6 % 256 != 1) {
            // 0x80491b7
            alert_henchmen(5);
            // branch -> 0x80491c3
        }
        int32_t v9 = v1 + 1; // 0x80491c3
        if (v9 >= 4) {
            // break -> 0x80491cd
            break;
        }
        v1 = v9;
        // continue -> 0x80491a6
    }
    // 0x80491cd
    return confirm_phase(5, str);
}

我只是不确定这条线是做什么的:

int32_t * v2 = (int32_t *)(4 * v1 + (int32_t)&g2) 

还有这一行:

char v7 = *(char *)(v4 + (int32_t)"4l6aiqhor20x")

int32_t 是什么意思?

【问题讨论】:

  • 这意味着将该值转换为 32 位整数。
  • @DavidGrayson 对于 C 问题,请不要链接到 C++ 文档。

标签: c assembly int32


【解决方案1】:

int32_t<stdint.h>中定义的类型之一;它是一个 32 位宽的有符号整数类型,具有 2 的补码表示,没有填充位。

反编译器似乎采用了最短路径,而实际上并未了解如何编写惯用的 C 代码。代码本身甚至可能不是有效的 C,因为我认为它可能不符合 C 的严格别名要求。

这里例如:

int32_t * v2 = (int32_t *)(4 * v1 + (int32_t)&g2); // 0x8049192_0

g2的地址值转换为int32_t;然后将值 4 * v1 添加到其中;并且将得到的整数转换为指向int32_t 的指针。这是一种人为的写法

int32_t *v2 = ((int32_t *)&g2) + v1;

或者;如果g2 已经声明为int32_t 的数组,那么写就足够了

int32_t *v2 = g2 + v1;

总而言之,代码将g2的地址转换为指向int32_t的指针,然后将指针赋值给v1th(从0开始)int32_t中连续 int32_ts 的数组,其中第一个是该指针处的数组,进入 v2

再次,

char v7 = *(char *)(v4 + (int32_t)"4l6aiqhor20x")

代码是直截了当但不可移植的代码(它在 64 位处理器中不起作用!)

char v7 = "4l6aiqhor20x"[v4];

即字符串"4l6aiqhor20x"中的v4th字符的值被分配给v7

【讨论】:

    【解决方案2】:

    我不完全确定您的问题是什么,但我会尽力帮助回答,通过解释当程序员写东西时,他或她知道的每一行都有一个目的 - 例如,如果他们想写一条消息,他们可能会调用变量“myMessage”。但是,此信息不包含在最终结果中。因此,反编译器不会知道将其称为“myMessage”,而只会分配一个内存地址(由 & 引用表示)或随机变量名称(由上面的 v 表示)。通过一些详细的检查,你可以弄清楚那部分代码具体做了什么,但没有像“myMessage”这样的提示,你可能需要处理和映射整个程序才能真正理解它。

    所以对于代码行: int32_t * v2 = (int32_t *)(4 * v1 + (int32_t)&g2)

    只能说取4,乘以v1,加到变量g2的地址上。结果是存储在 v2 中的 32 位地址。因为这里没有说明 g2 甚至是什么的参考资料,所以您可能会开始在我的回答中看到基本原理。由于它是 32 位(4 字节),这可以解释乘以 4,也许 v1 是一个计数器。

    【讨论】:

      猜你喜欢
      • 2011-06-16
      • 2015-12-21
      • 2013-06-04
      • 1970-01-01
      • 2017-12-20
      • 1970-01-01
      • 2017-08-17
      • 2015-03-22
      • 1970-01-01
      相关资源
      最近更新 更多