私はこれを持っています...奇妙な問題と私は必死に解決策を探しています。
この例があります:(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は常に「Wegotabeaf」を出力します。Clang..ではありません。)
上記の例は、明確にするための私の方法です。
私の本当の質問(および私の目標)は次のとおりです。arg_aの元のアドレス、つまり、foo関数内からCLANGを使用して、呼び出し元(メイン)がスタックに0xbe00をプッシュしたアドレスを抽出するにはどうすればよいですか?(gccはオプションではありませんが、それでも興味深いです)
お時間をいただきありがとうございます!
編集:質問がより意味をなすようにfooを可変個引数にしました...