接下來要做的是Function call在Stack當中會有怎樣的變化,我們一樣寫一支小程式。
在使用GCC時一樣會關閉防護,我們直接來看GDB和IDA逆向出來的結果。
前面就是將Stack拉出該有的空間,再來就是將字串放到RAX當中,GDB和IDA都是同樣的ASCII Code,我們來驗證一下是不是我們輸入的call A
最前面的0A是換行的意思。
和之前不同的地方在程式這次的輸出是使用了printf,在A function中才使用puts,另外一點是以GDB為例,這次的字串不只是直接丟到RAX,再從RAX丟到Stack中讓程式從Stack拿字串輸出。
這次的步驟到RAX丟入Stack中後,是把Stack放字串的位址丟到RAX,再把這串字串位址送到RSI,然後將RIP相對位址+0xe7a送到RDI當中,最後把EAX設0後呼叫printf。
怎麼會多了一坨噁心的東西在這邊,其實主要是因為變成了printf而不是puts了,更詳細的說明會在明天仔細說。
我們看到IDA這邊,它前面的步驟與GDB相似,一樣是把Stack放字串的位址丟到RAX,不一樣的是把字串位址送到RDX中,這個如同我們之前提到過的Windows x64 Calling convention 和System V x86-64 psABI的差異,最後把Format丟入RAX中,而Format內放的是"%s"字串,其實這與GDB一樣,最後把這個"%s"字串放入RCX。
也就是說IDA顯示的printf輸出,是需要RDX和RCX的值,而GDB需要RSI和RDI的值,與puts不同的點就在於printf需要兩個參數。
最後一點是GDB在Call任何Function以及程式結束時,EAX都需要為0,而IDA只有在程式結束時才需要EAX為0。