c - 如何从 C 源代码和 asm 输出逆向工程结构细节?

标签 c linux gcc assembly

我正在尝试了解这个问题的解决方案:

给定下面的 C 代码和编译器的 asm 输出,AB 是什么?

答案:A是5,B是6。

我猜必须进行某种除法,因为 96 和 48 都可以被 6 整除,而 20 可以被 5 整除。

编辑:我在网上找到了这个答案的解释。但是我不确定它是否准确
"一个字符从任意字节开始

short 仅从 EVEN 字节开始

一个 int 从 BYTE 开始,但可以被 4 整除

long 从 BYTE 开始,可以被 8 整除

str1.w 很长,从 5 到 8 开始

str1.x 可能有 184 或 180

str2.p 是 int 从值 8 开始,因此 str1.array 包含 5 到 8 个字节

str2.q short 可能是14到20

str2.z 可能是 32

字符 w[A][B] 和整数 X

8184

Str2.

短[B] int p doublez[B] 短 q

20 4 8 9

因此 A=5 和 B=6 的值"

代码如下:

// #define A  ??   // 5
// #define B  ??   // 6, but the question is how to figure that out from the asm
typedef struct {
    char w[A][B];
    int x;
} str1;

typedef struct {
    short y[B];
    int p;
    double z[B];
    short q; 
} str2;

void doSub(str1 *t, str2 *u) {
    int v1 = u->p;
    int v2 = u->q;
    t->x = v1-v2;
}

为 doSub 过程生成的汇编代码:

# t in %rdi, u in %rsi
doSub:
    movswl   96(%rsi), %edx
    movl     20(%rsi), %eax
    subl     %edx, %eax
    movl     %eax, 48(%rdi)
    ret

最佳答案

汇编代码告诉您 C 代码中使用的字段的偏移量。因此,您可以看出

offsetof(str1, x) == 48
offsetof(str2, p) == 20
offsetof(str2, q) == 96

现在让我们看看p。它在 y 之后并且 sizeof(short) 可能是 2(除非这是一个非常不寻常的机器或编译器),所以这告诉我们 B*2 + padding == 20。所以 B 最多为 10,可能不会小于 8。

查看 qsizeof(double) 可能是 8(同样,除非不寻常),所以 20 + sizeof(int) + 8*B +填充 == 96。如果 sizeof(int) == 4(常见,尽管 int 的不同大小比 short/double 更常见),这给了我们 8*B + padding == 72。所以 B 最多为 9。由于 short 的对齐限制可能比 double 少,因此可能没有填充,给 B==9,一致在 p

之前有 2 个字节的填充

查看 strsizeof(char) == 1(总是),所以 A*9 + padding = 48。所以 A 最可能的值是 5,有 3 个字节的填充。

当然,编译器可以自由添加它想要的任何填充,因此 AB 的任何更小的值都是可能的,尽管会造成浪费。

关于c - 如何从 C 源代码和 asm 输出逆向工程结构细节?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36466018/

相关文章:

困惑 : Pointers and character arrays in C

python - python中的多服务器监视器/自动重启器

linux - 在启动脚本中使用 screen

c++ - VS2015 和 GCC 5.4.0 中的 Constexpr 阶乘编译结果

c++ - 更新 ubuntu 10.4 后无法将 errno.h 与 gcc/g++ 一起使用

c++ - OS X 上的 LLVM 与 clang

c - 使用 GNU SGL 库生成随机数

c - yacc 从非终端获取零值

windows - OpenSSL的交叉编译

c++ - 将用户名和密码传递给 CryptRetrieveTimeStamp 函数