C語言程式與x86組合語言的關係
緣由
前段時間,嘉義大學資訊工程系受人敬重的王教授寄給我一份關於防範buffer overflow的相關文章, 這文章十分的棒,裡頭大致上提到如何藉由一個特殊的數值來防範overflow造成之不可預期影響。 不過該篇文章舉例時不是採取高階語言,而是使用x86_64組合語言(AT&T風格)的角度進行解釋
技術處理
在理解x86_64組合語言之後,
我使用除錯工具gdb把編譯好的c語言二進制檔
作為理解x86_64組合語言的範本
以下是我學習過程的一個紀錄
-------------------------
GDB除錯指令
觀看某個暫存器內容:info register 暫存器名稱
觀看某個位址內容:info address 位址
觀看某個變數位址:p &變數名稱
檢查位址內儲存的數值:x/s 位址
-------------------------
這是一段C語言
1 #include<stdio.h>
2
3 int main(){
4 int a=1;
5 }
-------------------------
使用到的指令
push:一般用於將函數的基址( base address放入stack )來達成函數呼叫的效果
mov:將某個數值或某個暫存器的內容,放入令一個暫存器
movl:將某個數值或某個暫存器的內容,放入令一個暫存器,但長度為32bit,即一個int長。
pop:將stack中的數值取出
retq:將stack的數值取出,跳到取出的指令位址,使程式按照上個函數的下一條指令執行,此函數執行完畢的意思
-------------------------
編譯成x86組合語言
並且以AT&T格式展示後
1 0x0000555555555129 <+0>: endbr64
2 0x000055555555512d <+4>: push %rbp //將基址放入堆疊
3 0x000055555555512e <+5>: mov %rsp,%rbp
4 0x0000555555555131 <+8>: movl $0x1,-0x4(%rbp)
5 0x0000555555555138 <+15>: mov $0x0,%eax
6 0x000055555555513d <+20>: pop %rbp
7 0x000055555555513e <+21>: retq
-------------------------
1.在程式開始前rbp的位置在 0x0,rsp的位置在0x7fffffffde70
2.將rbp放入堆疊
3.此時rbp的位址被堆疊暫存器rsp覆蓋,rbp為0x7fffffffde70
4.將1數值存入0x7fffffffde6c,0x7fffffffde6c:0x00000001
5.基於某種原因將eax暫存器歸零
6.rbp變回一開始的位址0x0
7.結束main()函數