Re: [問題] 函式的參數

作者: Killercat (殺人貓™)   2014-06-18 04:39:56
edit:由於x64下cdecl會學fastcall把特定型別的args放register去傳
所以這問題應該是無解。
簡單的說,以下方的code為例子,根本不可能拿到正確的&a
編譯器在發現你試圖取址a/b的時候 會把他們從esi/edi(都是x64的register)
拷貝出來以後隨意丟在一個無法預期的位置讓你去取址
以這邊來講,就是丟一個離function frame stack 16byte的位置
所以本題應該是無解,而且當args不是int的時候他傳法不見得會相同
重點asm放在這給大家參考一下
movl $30, %esi
movl $20, %edi
call _Z8testCallii
作者: chuckAI (心的方向)   2014-06-18 09:25:00
謝謝 killer大 雖然很多專業名詞看不懂 但文中的意思是原宣告的參數a,b 位置會有offset的現象 但會隨著硬體有所不同.. 我這樣的理解應該是對的吧..
作者: Killercat (殺人貓™)   2014-06-18 09:50:00
簡單的說 a b都會跟__builtin_frame_address有一段固定的距離 你可以試試看用這段距離去取值但是我不知道他因為什麼而不同就是
作者: Jockey66666 (往事已成追憶)   2014-06-18 11:21:00
好文
作者: AstralBrain   2014-06-18 13:48:00
你的測試環境是linux x64吧, int應該會用register傳a本來放在rdi, b在rsi因為你要取址, compiler才在stack上隨便找個地方放a,b要放在哪裡已經不歸calling convention管了
作者: Killercat (殺人貓™)   2014-06-18 14:18:00
所以gcc會因為我執行__builtin_frame_address(0)所以隨便找一個地方先把arg stack dump出來嗎? 好詭異的行為
作者: AstralBrain   2014-06-18 14:22:00
因為你要&a, 所以把a從rdi搬到stack上
作者: Killercat (殺人貓™)   2014-06-18 14:27:00
我懂了 你是說他在compile time發現我要對a取址所以會多作一些額外的行為,把他從真正的frame stack搬出來對吧?因為就我理解用register傳應該只有fastcall會這樣玩...我回去試試看用別的型別 感謝欸 仔細看了一下 -S 你是對的 不過我這邊是放esi/edi
作者: AstralBrain   2014-06-18 14:32:00
x64因為多了一大堆register, 前幾個參數會跟fastcall一樣用register傳
作者: Killercat (殺人貓™)   2014-06-18 14:33:00
了解 看了一下.s的確也是如此.... 感謝!
作者: AstralBrain   2014-06-18 14:36:00
rsi/rdi是筆誤XD int是32bit所以會用e開頭的register
作者: Killercat (殺人貓™)   2014-06-18 14:46:00
不過這樣說的話 其實本來問題應該是無解了...因為型別不同他會用不同方法去傳 很傷腦筋
作者: AstralBrain   2014-06-18 14:58:00
所以交給gdb去撈debug symbol又快又方便 XD
作者: azureblaze (AzureBlaze)   2014-06-18 15:08:00
http://ideone.com/P2QxLN 印參數從caller比較簡單吧..
作者: Killercat (殺人貓™)   2014-06-18 15:08:00
可是request是說要從callee... 所以才有這篇文章囧
作者: azureblaze (AzureBlaze)   2014-06-18 15:15:00
我覺得他不見得只能改callee,可能只是想偏了...如果型態不定數量不定那麻煩事還更多沒reflection做這種事吃力不討好
作者: Killercat (殺人貓™)   2014-06-18 15:17:00
callee確定是不可行的了 這年頭連直接對frame stack hack的最後希望都沒了 還能怎麼搞 :D大概就剩下Astral說的拿debug symbol拖出來鞭屍了

Links booklink

Contact Us: admin [ a t ] ucptt.com