逆向入門噩夢之堆棧(軟件安全攻防反匯編反調(diào)試)
什么是堆棧
? ??其實 堆 和 棧是2個概念 ,在內(nèi)存中 堆是在有一段存放的空間的 x86當中 大概占1M左右。而棧呢是 每次準備進入call 之前在內(nèi)存中開辟的一段地址空間。我們說的堆棧其實指得是棧 ,就像我們說土狗 他是狗 ,說老婆餅 他是餅 一樣的意思
?? ? 在計算機領域,堆棧是一個不容忽視的概念,堆棧是一種數(shù)據(jù)結構。堆棧都是一種數(shù)據(jù)項按序排列的數(shù)據(jù)結構
為什么要學習堆棧
? 經(jīng)常有學員來問咱們這個問題 ,這個這么復雜這么難,我為啥要學他??! 可以跳過嘛
咱們在實戰(zhàn)當中 經(jīng)常要求分析代碼 正向程序員寫代碼肯定是多層調(diào)用的 10幾層call 更是常有的事,不學習堆棧 你都沒發(fā)追數(shù)據(jù)了,而且你對程序的結構 內(nèi)存的理解程度是一個很大的缺失部分,沒有這樣的理解 恐怕后面是很難往下學習的
拆解堆棧

如上 一個最簡單的c++的 加法函數(shù),咱們看他的反匯編代碼

這里有個細節(jié)要注意一下 我們發(fā)現(xiàn)他參數(shù)壓入堆棧的順序 是從右往左的
那他為啥不是從左往右呢,這里其實涉及到函數(shù)調(diào)用約定的問題,咱們后面的課程都有講到的,這里 從右向左壓棧,不是規(guī)定,也不是因為棧先進后出的特性。在《c和指針》中已經(jīng)說明了從右向左壓棧的原因,這樣可以保證生成匯編語言時這些參數(shù)相對于BP指向的棧位置的偏移量是固定的。
C方式參數(shù)入棧順序(從右至左)的好處就是可以動態(tài)變化參數(shù)個數(shù)。
我們在進入call內(nèi)部去看

第一步 把ebp壓棧
第二部 mov ebp,esp
第三部 提升堆??臻g,用來存放本層call的局部變量
第四部 保存各個寄存器,因為接下來本層call就要使用這些寄存器了,先把他壓入棧中
第五部 執(zhí)行本層call的代碼了
咱們在來繼續(xù)看后面的

第六步 ?還原寄存器 因為本層call的代碼執(zhí)行完了 寄存器的任務也完成了,就把剛進來時候的寄存器的值從堆棧里面彈出來吧,因為咱們要出去 返回到之前的堆??臻g了去了 咱們進來時候寄存器是啥樣 出去的時候 還得啥樣 需要還原回來 不然寄存器就崩潰了
第七步 任務完成了 咱們把剛進call時候開辟的堆??臻g也拉下來 還原回來
第八步 ?mov esp ,ebp ?同樣是還原回來
第九步 彈出ebp ?同上
第十步 ret回上一層了
這樣就完美的 走完了一個call了,從進入call 到出call ?寄存器 堆棧地址并沒發(fā)生任何變化,就跟沒進去過一樣 不留下一片云彩。其中還是有好幾個細節(jié)要注意的,大家需要自己做一遍才能深刻體會!
微塵網(wǎng)絡安全專注分享網(wǎng)絡安全 x64 c++ 逆向 反匯編 反調(diào)試 HOOK 注入 封包 內(nèi)存等技術公眾號