2017-2018-1 20155336 《信息安全系統設計基礎》第五周學習總結
2017-2018-1 20155336 《信息安全系統設計基礎》第五周學習總結
學習目標
- 理解逆向的概念
- 掌握X86匯編基礎,能夠閱讀(反)匯編代碼
- 了解ISA(指令集體系結構)
- 理解函數調用棧幀的概念,並能用GDB進行調試
教材學習內容總結
-
本章概述:
本周學習了c提供的抽象層下面的東西,了解機器級編程。通過編譯器產生機器級程序的匯編代碼表示,我們了解了編譯器和它的優化能力,還有一些機器、數據類型和指令集。機器級程序和它們的匯編代碼表示與C程序的差別很大。程序是以指令序列來表示的,每條指令都完成一個單獨的操作。編譯器必須使用多條指令來產生和操作各種數據結構。 用字節代碼作為程序的低級表示,優點是相同的代碼可以在許多不同的機器上執行。
-
x86經歷的尋址方式:
- DOS時代的平坦模式,不區分用戶空間和內核空間,不安全。
- 8086的分段模式
- IA32的帶保護模式的平坦模式。
-
程序編碼和數據格式:
- 使用GCC編譯時候命令行中加入 -o1使用第一級優化 、-o2使用第二級優化
- gcc -S xxx.c -o xxx.s獲得匯編代碼,也可以用objdump -d xxx反匯編; 註意函數前兩條和後兩條匯編代碼,所有函數都有,建立函數調用棧幀。
- b:8位、w:16位、l:32位。
- 註意: 64位機器上想要得到32代碼:gcc -m32 -S xxx.c
- 格式的註解:ATT和Intel匯編代碼格式。
- 理解寄存器%eax、%ecx、%edx、%ebx為通用寄存器,%esi和%edi可以用來操作數組,%esp和%edp可以操作指針。
- MOV指令是使用最頻繁的指令,註意不能直接從一個內存地址MOV到另一個內存地址,要在寄存器中中轉一下。
- 註意棧頂元素的地址是所有棧中元素地址中最低的。
- 指針就是地址,局部變量保存在寄存器中。
-
算數和邏輯操作:
- leal指令,加載有效地址,是movl指令的一個變形
- 一元操作只有一個操作數,既是源又是目的。
- 註意二元操作,源操作數是第一個,目的操作數是第二個,註意減法操作後-前
- 移位操作先可以給出移位量,第二項再給出要移位的數值。
-
控制:
- 用jump指令可以改變一組機器代碼指令的執行順序。對於switch語句可以采用jump table跳轉表來完成跳轉。
- 條件碼寄存器用來設置跳轉的條件位的。
- leal不改變條件碼寄存器。
- SET指令根據計算t=a-b設置條件碼。
- 有條件跳轉(if、while、for)註意看條件碼寄存器和無條件跳轉(goto)。
- if-else結構:使用了goto語句。
- 循環結構:do-while是最基本的循環結構,其他的循環首先會轉換成do-while來產生循環代碼。每次循環會測試表達式,如果測試為真(非零)繼續循環。c語言中三種形式的循環do-while、while和for都可以用一種簡單策略來翻譯,產生包含一個或多個條件分支的代碼。控制條件轉移為循環翻譯成機器代碼提供了基本機制。
- switch的jt表中引用&&作為新的指針,執行switch語句的關鍵步驟是通過跳轉表來訪問代碼位置。
-
過程:
- IA32程序用程序棧來支持過程調用。註意:棧是向低地址增長的。
- 棧幀結構:用來傳遞參數、儲存返回信息、保存寄存器、以及本地存儲
- call/ret; 函數返回值存在%eax中
- leave指令可以使棧做好返回的準備
- 程序寄存器是唯一能被所有過程共享的資源。
教材學習中的問題和解決過程
-
對於數據格式的知識
在書p111頁給了數據格式,在匯編代碼的後綴。在之後學習mov指令的時候,其中有一個指令movl $Ox4050,%eax ,可是在之後使用中發現movl指令對於雙精度浮點數可以進行傳送。後來看書,知道了匯編代碼也使用後綴‘l’`來表示4字節整數和8字節雙精度浮點數。其實並不會產生歧義,因為浮點數使用的是一組完全不同的指令和寄存器。
-
對於尋址模式
首先在對於%eax和(%eax)有點疑問,不知道二者樣子相同,二者具體有什麽不同,後來通過看書上p113的表格,其中有寄存器Ea,操作數值是R[Ea],儲存器(Ea)操作數值是M[R[Ea]]。雖然二者看起來樣子很相似,但本質還是不一樣的,一個是寄存器,另一個則表示緩存器,二者所代表的值也是不同的。
-
對於棧
棧在數據結構中就有所接觸,遵循先進後出的原則。但是對於為什麽棧底的地址大,棧頂的地址值小?如果這樣那麽棧就不會很大嗎?通過網上百度,解決了這一問題。在Windows下,棧是向低地址擴展的數據結構,是一塊連續的內存區域。這句話的意思是棧頂的地址和棧的最大容量是系統預先規定好的,在Windows下棧的大小是固定的空間(1M或2M)超過棧的剩余空間會提示overflow。就類似於數組中的內個i,stack[i],入棧後i-1,出棧後i+1,i始終指向棧頂。
-
對於Switch語句
起初書上給的例子是有開關100、102~104、106,通過匯編代碼,首先將106與100做差值運算,這樣就會簡化匯編語言的操作。可是對於這個例子102 開關之後沒有break;既沒有跳出語句,會繼續操作103的代碼,匯編語言是怎麽實現的?通過自己動手操作了書上的例子後,兩種情況有不同的目的地址,將這兩個代碼塊都匯總到將result加11的代碼,這樣就解決了問題。
代碼練習以及問題
-
P107
- 利用vim編寫一個xxx.c文件
- gcc -S xxx.c得到匯編文件xxx.s
- 利用vim進入xxx.s或者利用cat xxx.s查看xxx.s的內容
-
P108反匯編練習
- 利用gcc -c xxx.c產生二進制文件xxx.o
- 利用objdump -d xxx.o來看到反匯編後的內容
-
教材P121練習題3.9驗算反饋
- 練習題給出匯編代碼,要求補全C語言代碼,補全後,下圖為實際驗算
課後作業中的問題和解決過程
-
習題3.1
其中有一個是260(%ecx,%edc)計算值,一直把260當作十進制運算,可是沒有結果,後來發現運算時需要將其轉換為16進制再次參與運算,這樣260=Ox104這樣答案也就得到了。
-
習題3.2
指令的補全,對於mov指令格式為mov s,d,將s傳送給d。但是對於MOV %eax,(%eax) 為什麽是MOVL而不是MOVW?後來知道%ax為寄存器16位,%eax是擴展寄存器32位,這樣就需要傳送雙字,就需要MOVL指令。
-
習題3.29
對於switch語句的匯編代碼,最初在做的時候存在序號問題,後來仔細查閱了解C語言中case對應的序號對應著跳轉表中的序號,要註意的是候跳轉表中的序號從0開始的!
代碼托管
其他(感悟、思考等,可選)
這周在本章下了很多時間,也補了很多匯編語言的功課,總之還是要去認認真真去對待每一個章節的知識點,這樣才能融匯貫通。
學習進度條
| | 代碼行數(新增/累積)| 博客量(新增/累積)|學習時間(新增/累積)|重要成長|
| -------- | :----------------:|:----------------:|:---------------: |:-----:|
| 目標 | 5000行 | 30篇 | 400小時 | |
| 第一周 | 200/200 | 2/2 | 20/20 | |
| 第二周 | 300/500 | 2/4 | 18/38 | |
| 第三周 | 500/1000 | 3/7 | 22/60 | |
| 第四周 | 300/1300 | 4/9 | 15/90 | |
嘗試一下記錄「計劃學習時間」和「實際學習時間」,到期末看看能不能改進自己的計劃能力。這個工作學習中很重要,也很有用。 耗時估計的公式 :Y=X+X/N ,Y=X-X/N,訓練次數多了,X、Y就接近了。
參考:軟件工程軟件的估計為什麽這麽難,軟件工程 估計方法
-
計劃學習時間:15小時
-
實際學習時間:15小時
(有空多看看現代軟件工程 課件 軟件工程師能力自我評價表)
參考資料
- 《深入理解計算機系統V3》學習指導
- ...
2017-2018-1 20155336 《信息安全系統設計基礎》第五周學習總結