現在我們看回原本的程式,現在準備要Call A這個Function了,要看在Call function時,Stack上的狀態。
先看一下呼叫前的狀態,GDB的Stack會在de70~de80之間,IDA會在CBE0~CC10之間。
下一步後來看看有哪些地方改變了,GDB的RSP多了一行0x4011a9,這邊要記得用Little Endian來看,那0x4011a9其實是Call A的下一行的Address,意思就是程式如果在轉跳到其他Function前,會先將Return回來下一行的Address給存起來,這邊要注意,這就是CALL與JMP的差異,JMP不會去儲存這個,要跳就直接跳了。
再來是IDA的部分,可以看到RSP多了1004010D4,也是紀錄等等Return回去RIP應該指向哪(RIP會指向下一行程式的Address),這裡的RIP是指向100401080,也就是Function A的第一行。
接下來就是做PUSH RBP,GDB把RBP 的Address de80給放進去了,IDA也是將RBP的CC10放到了Stack當中。
接下來就是將現在的RSP覆蓋掉現在的RBP,也就是說把現在的RSP當成RBP,GDB將剛剛的de60放到了RBP內,IDA把CBD0放到了RBP內,可以看到現在的RSP和RBP值是相同的,最後就是將RSP減出對應的空間,變成新的RSP和RBP空間給轉跳的Function來做使用。
所以當我們在Call function時,Stack會先儲存等等Return回來RIP該去哪,以及儲存跳過來的RBP,才會開始規劃新的Stack空間給Function使用。