20145210《信息安全系統設計基礎》第05周學習總結


20145210《信息安全系統設計基礎》第05周學習總結

教材內容總結

1.X86 尋址方式經歷三代:
•DOS時代的平坦模式,不區分用戶空間和內核空間,很不安全
•8086的分段模式
•IA32的帶保護模式的平坦模式

2.Intel與ATT格式的不同:
•Intel代碼省略了指示大小的后綴
•Intel代碼省略了寄存器名字前的“%”符號
•Intel代碼用不同的方式來描述存儲器中的位置。
•在帶有多個操作數的指令情況下,列出操作數的順序相反

3.64位機器上想要得到32代碼:gcc -m32 -S xxx.c
4.MAC OS中沒有objdump, 有個基本等價的命令otool
5.Ubuntu中 gcc -S code.c (不帶-O1) 產生的代碼更接近教材中代碼(刪除"."開頭的語句)

6.二進制文件可以用od 命令查看,也可以用gdb的x命令查看。
有些輸出內容過多,我們可以使用 more或less命令結合管道查看,也可以使用輸出重定向來查看:
od code.o | more
od code.o > code.txt

7.操作數的三種類型:
•立即數,也就是常數值。
•在ATT格式的匯編代碼中,立即數的書寫方式是“”后跟一個用標准C表示法表示的整數。任何一個能放進32 位字中的數值都可以用做立即數,不過匯編器在可能時會使用一個或兩個字節的編碼。

8.寄存器,表示某個寄存器的內容
9.存儲器,根據計算出來的地址(有效地址)訪問某個存儲器的位置。
10.有效地址的計算方式: Imm(Eb,Ei,s) = Imm + R[Eb] + R[Ei]*s
(注意:ATT格式中的方向:第一個是源操作數,第二個是目的操作數)

11.棧
•后進先出原則
•push壓棧,pop出棧
•棧頂:總是從這端插入和刪除元素
•棧頂元素的地址是最低的
•棧指針%esp保存着棧頂元素的地址

12.lean指令
•lean是加載有效地址指令
•指令形式實際上並沒有引用存儲器,它的第一個操作數其實是將有效地址寫入到目的操作數
•可以為后面的存儲器引用產生指針,簡潔的表述普通算數操作。

13.目的操作數必須是一個寄存器。

14.過程
過程調用:
•進入,為過程的局部變量分配空間
•將數據(以過程參數和返回值的形式)和控制從代碼的一部分傳遞到另一部分。
•退出,釋放這些空間。

15.轉移控制
call
•call指令和轉移指令相似,同樣分直接和間接,直接調用的目標是標號,間接調用的目標是*后面跟一個操作數指示符,和JMP一樣。
•call指令的效果是將返回地址入棧,並跳轉到被調用過程的起始處。返回地址是還在程序中緊跟在call后面的那條指令的地址。
ret
•ret指從棧中彈出地址,並跳轉到這個位置。
•在上學期的匯編語言學習中,call和ret常被用來進行子函數、子模塊的調用。

實驗樓代碼練習:

將C語言文件編譯成匯編文件並查看匯編文件內的內容:

刪除以.開頭的語句之后:

注釋棧幀情況:

反匯編代碼分析:

首先進入gdb調試環境,在虛擬機上輸入如下命令生成帶有調試信息的elf文件,然后進入gdb調試:

(gdb)layout asm
(gdb)b main

然后使用

(gdb)si

逐條指令執行並觀察寄存器變化:

分析結果如下:
對於main函數:

pushl %ebp
movl %esp,%ebp

把當前的ebp值入棧,再把ebp入棧后的esp中的值放入ebp,此時,esp和ebp都指向同一個內存地址,此時棧中的情況如圖:

pushl $8  //當前esp減4,然后把寬度為4的數值10放入esp當前指向的內存中
call SY  //調用函數指令,把當前eip的值入棧,然后跳轉到SY函數的第一條指令開始執行
addl $4,%esp

此時棧中的情況如圖:

對於SY函數:

pushl %ebp
movl %esp,%ebp
  //保存當前棧環境,為SY函數開辟新的棧空間
pushl 8(%ebp)  //把當前ebp中的數值加8后作為內存地址,並把該內存地址指向的內存空間的數值“10”放入棧中
call YSY  //調用函數指令,當前eip入棧,跳轉到YSY的第一條指令
addl $4,%esp

首先保存當前棧環境,為SY函數開辟新的棧空間
再把當前ebp中的數值加8后作為內存地址,並把該內存地址指向的內存空間的數值“8”放入棧中
再調用函數指令,當前eip入棧,跳轉到YSY的第一條指令
此時棧中情況如圖:

對於YSY函數:

pushl %ebp
movl %esp,%ebp
  //保存當前棧環境,開辟新的棧空間
movl 8(%ebp),%eax  //將ebp中數值加8后作為內存地址,並將該內存地址指向的內存空間的數值8放入eax寄存器中
addl $3,%eax  //將把eax中的值加3再放回eax
popl %ebp  //從棧中獲取舊的esp值,並放入ebp寄存器
ret  //從esp所指內存處獲取值作為eip,然后跳轉到eip中存放的地址繼續執行

此時,函數YSY已經返回,其返回值存儲在eax寄存器中,返回值為11
此時棧中情況如圖:

返回到函數SY中:

addl $4,%esp  //回收棧空間,棧空間收縮4個字節
leave  //釋放SY函數使用的棧空間
ret  //函數SY返回,程序回到main函數繼續執行

此時eax函數存放的是函數SY的返回值11,棧中情況如圖:

回到main函數繼續執行:

addl $4,%esp  //棧收縮4個字節,回收棧空間
addl $1,%eax  //將eax中的值加1后放回eax,執行后eax中的值為12
leave
ret

通過gdb單步調試及print /x $***可以查詢到相應寄存器的內容以及執行的指令

得到%ebp,%esp,eax寄存器的變化:

教材學習中遇到的問題

練習3.2:指令后綴主要根據什么來確定?參照了教材的例子以及練習題的答案,對於指令后綴的確定還是找不到標准

代碼托管情況

代碼托管鏈接


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM