了解反编译汇编代码

时间:2017-03-26 04:18:43

标签: c assembly int32

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

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是什么意思?

2 个答案:

答案 0 :(得分:0)

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

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

你只能说它需要4,乘以v1,然后将它加到变量g2的地址。结果是存储在v2中的32位地址。因为这里没有提到g2甚至是什么的参考,那么你可能会开始在我的答案中看到基本原理。由于它是32位(4字节),这可以解释乘以4,也许v1是一个计数器。

答案 1 :(得分:0)

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的指针,然后将指针指定给 v1 (0-基于)int32_t在连续int32_t s的数组中,其中第一个是该指针的一个v2

再次,

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

直接 - 但不可移植的代码(在64位处理器中不起作用!)代码

char v7 = "4l6aiqhor20x"[v4];

即。字符串v4"4l6aiqhor20x"个字符的值已分配给v7

相关问题