我正在尝试了解这个问题的解决方案:
给定下面的 C 代码和编译器的 asm 输出,A
和 B
是什么?
答案: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。
查看 q
,sizeof(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
查看 str
,sizeof(char) == 1
(总是),所以 A*9 + padding = 48
。所以 A
最可能的值是 5,有 3 个字节的填充。
当然,编译器可以自由添加它想要的任何填充,因此 A
和 B
的任何更小的值都是可能的,尽管会造成浪费。
关于c - 如何从 C 源代码和 asm 输出逆向工程结构细节?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36466018/