スタック ポインタの値を指定すると、関数に渡された引数の値を特定できますか? スタック フレームに格納されている引数はどこにありますか。
たとえば、 Linux プラットフォームのアーキテクチャでgcc
コンパイル済みの ELF バイナリを実行するとします。x86
int foo(int a, int b)
{
...
}
foo(a,b)
から呼び出され、現在main()
指しているスタック ポインター (SP) の値を知っていますfoo()
。引数a
との値を取得するにはどうすればよいb
ですか?
編集: スタックが小さなアドレスから大きなアドレスに成長し、引数が を使用して右から左に渡されるcdecl
場合、次のように args 値を取得できますか:
b = *(SP + 1);
a = *(SP + 2);
EDIT : 次のプログラムは、上記のアーキテクチャと仕様を使用してa
、関数 args の値を出力します。b
void foo(int a, int b)
{
int i;
register int stackptr asm("sp");
int *sp = (int *)stackptr;
printf("\n\ta=%d b=%d\n", a, b);
for (i=0; i<16; i++) {
printf("*(sp + %d) = %d\n", i, *(sp +i));
}
}
int main()
{
foo(3, 8);
foo(9, 2);
foo(1, 4);
return 0;
}
上記のコードの出力は次のとおりです。
a=3 b=8
*(sp + 0) = 134514016
*(sp + 1) = 0
*(sp + 2) = 0
*(sp + 3) = 134513373
*(sp + 4) = 8239384
*(sp + 5) = 134513228
*(sp + 6) = 6
*(sp + 7) = -1076716032
*(sp + 8) = 134513456
*(sp + 9) = 0
*(sp + 10) = -1076715960
*(sp + 11) = 134513759
*(sp + 12) = 3 //value of arg a
*(sp + 13) = 8 //value of arg b
*(sp + 14) = 134513817
*(sp + 15) = 10612724
a=9 b=2
*(sp + 0) = 134514016
*(sp + 1) = 0
*(sp + 2) = 0
*(sp + 3) = 134513373
*(sp + 4) = 8239384
*(sp + 5) = 134513228
*(sp + 6) = 6
*(sp + 7) = -1076716032
*(sp + 8) = 134513456
*(sp + 9) = 0
*(sp + 10) = -1076715960
*(sp + 11) = 134513779
*(sp + 12) = 9 //value of arg a
*(sp + 13) = 2 //value of arg b
*(sp + 14) = 134513817
*(sp + 15) = 10612724
a=1 b=4
*(sp + 0) = 134514016
*(sp + 1) = 0
*(sp + 2) = 0
*(sp + 3) = 134513373
*(sp + 4) = 8239384
*(sp + 5) = 134513228
*(sp + 6) = 6
*(sp + 7) = -1076716032
*(sp + 8) = 134513456
*(sp + 9) = 0
*(sp + 10) = -1076715960
*(sp + 11) = 134513799
*(sp + 12) = 1 //value of arg a
*(sp + 13) = 4 //value of arg b
*(sp + 14) = 134513817
*(sp + 15) = 10612724
関数の引数がSP のオフセット 12から格納されるのはなぜですか? また、オフセット 0 から 10 の値は常に同じであり、オフセット 11 の値は function の呼び出しごとに 20 ずつ増加しますfoo()
。
更新:フレーム ポインター アドレスを取得する組み込み関数gcc
があることがわかりました
void * __builtin_frame_address (unsigned int level)
__builtin_frame_address(0)
関数の引数から始まるオフセットで値を出力すると、 offset 2
. この動作が常に一貫していることを確認するにはどうすればよいですか?