我有这个......奇怪的问题,我正在拼命寻找解决方案。
我们有这个例子:(为 32 位系统制作)
#include <stdio.h>
//unsigned foo(unsigned arg_a, unsigned arg_b) {
unsigned foo(unsigned arg_a, ...) {
unsigned *temp = (unsigned *)((unsigned)&arg_a + 4);
return *temp + arg_a;
}
int main(void) {
int i = foo(0xbe00, 0x00af);
printf("We got a %x\n", i);
return 0;
}
函数 foo 有 2 个参数。目标是根据 arg_a 的地址“猜测”arg_b 的地址。这是基于调用者 (main) 将 arg_a 和 arg_b 推入堆栈的假设(因此 (int)&arg_b - (int)&arg_a == 4 )。
根据编译器和优化级别,输出会有所不同,如下所示:
gcc -g -Wall -O0 test.c
./a.out
We got a beaf
gcc -g -Wall -O1 test.c
./a.out
We got a beaf
gcc -g -Wall -O2 test.c
./a.out
We got a 80542b0
gcc -g -Wall -O3 test.c
./a.out
We got a 80542b0
clang -g -Wall -O0 test.c
./a.out
We got a 8054281
clang -g -Wall -O1 test.c
./a.out
We got a 805423f
clang -g -Wall -O2 test.c
./a.out
We got a b768d9d6
clang -g -Wall -O3 test.c
./a.out
We got a b76899d6
(这个例子非常不稳定,例如通过在 foo 中放置一个 printf,gcc 总是打印“We got a beaf”。Clang.. not..)
上面的例子只是我尝试清楚的方式。
我真正的问题(和我的目标)如下:如何提取 arg_a 的原始地址,即调用者(主)通过使用 foo 函数内部的 CLANG 将 0xbe00 推入堆栈的地址?(gcc 不是一个选项,虽然它仍然很有趣)
谢谢你的时间!
编辑:使 foo 可变参数以使问题更有意义...