我有這個......奇怪的問題,我拼命尋找解決方案。獲取正確的參數指針
我們這個例子:(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
(這個例子是很不穩定的,例如通過將一個printf中富,GCC始終打印「我們得到了一個BEAF 「。Clang ..不是..)
上面的例子只是我嘗試和明確的方法。
我真正的問題(和我的目標)如下: 如何提取arg_a的原始地址,即調用者(主)通過使用CLANG從foo函數中將0xbe00推入棧中的地址? (海灣合作委員會是不是一個選項,雖然它仍然很有趣)
感謝您的時間!
編輯:爲了使問題更有意義,提出富可變參數...
聽起來就像你試圖粉碎堆棧。 (Tsk tsk。)你已經做出了一些假設,不會像一般情況那樣起作用。就在我頭頂的一些不好的假設:堆棧的順序,甚至有一個堆棧[編譯器可以註冊通過值,如果他們想要],並存在已知值在該內存中用於調試/溢出檢測。 –
你是正確的!由於代碼將使用MIPS工具鏈進行編譯(通常會通過寄存器$ 4- $ 7中的前4個參數),事情看起來更難...... 請參閱我編輯的編輯.. – yanyan