系統(tǒng)級編程-lab5_第1頁
系統(tǒng)級編程-lab5_第2頁
系統(tǒng)級編程-lab5_第3頁
系統(tǒng)級編程-lab5_第4頁
系統(tǒng)級編程-lab5_第5頁
已閱讀5頁,還剩2頁未讀 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、Practice1 上周做了,復制過來。前面得key1=3、key2=777下面我們繼續(xù)往后面看代碼,并且通過提示我們了解到我們需要想辦法使程序進入并執(zhí)行msg2 = extract_message2(start, stride);但是從正常的程序邏輯上看,我們無法使msg1為空而順利進入到條件碼中。那么我們需要考慮應該在process_keys34中做出調(diào)整。我們能否在執(zhí)行完process_keys34后偷偷的改變msg1的值呢?在看了這段函數(shù)的代碼后,我們發(fā)現(xiàn)這個函數(shù)中兩個變量的范圍相差太大了,一個是全局變量message(msg1的實際指向),一個是局部變量key3。那么我們需要換一個思

2、路,能否讓函數(shù)在返回的時候直接跳轉(zhuǎn)到目標代碼呢?如果要這么做,我們就需要修改程序在運行過程中的棧幀結(jié)構(gòu)中的存儲數(shù)據(jù)了?,F(xiàn)在讓我們來分析一下程序在調(diào)用process_keys34之前的棧幀結(jié)構(gòu):從匯編碼中我們可以看到在調(diào)用之前整個棧幀結(jié)構(gòu)中數(shù)據(jù)的存儲細節(jié)。首先是將參數(shù)key3、key4壓入棧中保存,然后在傳入這些參數(shù)。然而這些參數(shù)的傳遞都是傳地址的,所以我們在process_keys34中可以通過&key3的相對定位來改動調(diào)用者的棧幀數(shù)據(jù)。在這之前讓我們來想想調(diào)用時的棧幀結(jié)構(gòu):我們可以看到,如果我們能夠修改返回地址使它返回到我們期望的位置就可以了。那么我們現(xiàn)在需要確定這個返回地址相對于k

3、ey3的距離是多少,通過圖我們可以看到這個地址就在key3的下面,只需要在key3基礎(chǔ)上減一(這個減一是在int下的,實際上在地址層面應該是-4)就好了。所以我們得到了key3的值-1.另外我們需要感謝出題者,他一直給我們提供充足的相對數(shù)據(jù)。在這里我們只需要在原返回地址上面加上一個合適的值就好了。從上圖中,我們可以看到原先的返回地址和我們需要抵達的返回地址0040138e是原先保存在棧幀中的返回地址,而我們期望程序返回時直接到達0x004013bb。這樣我們就得到了key4的具體值:Key4=(0x004013bb-0040138e)/4=45。所以key1234分別就是 3 777 -1 4

4、5。Practice200951850 push ebp將ebp壓入棧頂位置。EIP跳到00951851。棧頂ESP變?yōu)?091FD6800951851 movebp,esp將ESP的值賦值給EBP,棧底EBP變?yōu)?091FD6800951853 sub esp,0D8h將ESP的值減小0D8h,變?yōu)?0D2FBF800951859 push ebx0095185A push esi0095185B push edi將當前的EBX,ESI,EDI值逐個壓入到棧里。得到ESP為00D2FBECMain()0095185C lea edi,ebp-0D8hEDI=EBP-0D8h為與棧底相隔0D8

5、hbytes的位置00951862 mov ecx,36h將ECX賦值為36h.00951867 mov eax,0CCCCCCCCh將EAX賦值為0CCCCCCCCh0095186C rep stosdwordptres:edi從EDI的位置開始賦值,每次EDI+4,ECX-1,直到ECX為0為止。執(zhí)行完后EDI=00D2FCD0、EFL=000002120095186E movdwordptr a,1將1賦值給a的位置00951875 movdwordptr b,2將2賦值給b的位置0095187C moveax,dwordptr b將(b位置中的)2賦值給EAX=000000020095

6、187F push eax將EAX放入棧中, ESP變?yōu)?0D2FBE800951880 movecx,dwordptr a將(a位置中的)1賦值給ECX=0000000100951883 push ecx將ecx壓入棧頂,ESP變?yōu)?0D2FBE400951884 call swap1 (0951307h)執(zhí)行swap1函數(shù)00951889 add esp,8ESP加8,ESP變?yōu)?0D2FBEC0095188C moveax,dwordptr b將(b位置中的)2賦值給EAX=000000020095188F push eax將eax壓入棧頂,esp變?yōu)?0D2FBE800951890 m

7、ovecx,dwordptr a將(a位置中的)1賦值給ECX=0000000100951893 push ecx將ecx壓入棧頂,esp變?yōu)?0D2FBE400951894 push 956B30h00951899 call _printf (0951325h)調(diào)用printf()函數(shù)EAX = 00000015 EBX = 7ED8F000 ECX = 0D0AE50D EDX = 5447181C ESI = 00951046 EDI = 00D2FCD0 EIP

8、60;= 0095189E ESP = 00D2FBE0 EBP = 00D2FCD0 EFL = 000002440095189E add esp,0Ch棧頂ESP置為ESP+0Ch,清除之前放入的形參009518A1 lea eax,bEax = b(00D2FCBC)009518A4 push eax將eax壓入棧頂,esp變?yōu)?0D2FBE8009518A5 lea ecx,aEcx=a(00D2FCC8)009518A8 push ecx將ecx壓入棧頂,esp變?yōu)?0D2FBE4009518A9 call swa

9、p2 (0951339h) 跳轉(zhuǎn)執(zhí)行swap2函數(shù)009518AE add esp,8 棧頂ESP置為ESP+8,清除之前放入的形參009518B1 moveax,dwordptr b將(b位置中的)1賦值給EAX=00000001009518B4 push eax將eax壓入棧頂,esp變?yōu)?0D2FBE8009518B5 movecx,dwordptr a將(a位置中的)2賦值給ECX=00000002009518B8 push ecx將ecx壓入棧頂,esp變?yōu)?0D2FBE4009518B9 push 956B30h 009518BE call _printf (0951325h)調(diào)用

10、printf()函數(shù)EAX = 00000015 EBX = 7ED8F000 ECX = 0D0AE50D EDX = 5447181C ESI = 00951046 EDI = 00D2FCD0 EIP = 009518C3 ESP = 00D2FBE0 EBP = 00D2FCD0 EFL = 00000244009518C3 add esp,0Ch棧頂ESP置為ESP+0Ch,清除之前放入

11、的形參009518D7 pop eax009518D8 pop edx009518D9 pop edi009518DA pop esi009518DB pop ebx棧壓出EDI,ESI,EBX以前的值放入EDI,ESI,EBX中009518DC add esp,0D8h ESP = ESP+0D8h 009518E2 cmpebp,esp比較EBP和ESP009518E4 call _RTC_CheckEsp (0951113h)檢查函數(shù)有沒有出錯009518E9 movesp,ebpESP = EBP009518EB pop ebpEBP = 棧頂壓出的值009518EC ret跳轉(zhuǎn)執(zhí)行棧

12、頂壓出的值指向的代碼Practice3  題目中已經(jīng)說了,“分析這個程序,可以得知,正常情況下,這個函數(shù)會在getbuf中,調(diào)入getxs函數(shù)讀入數(shù)字對,然后不管任何情況下,都會對test函數(shù)返回0x1,”那我們該怎么辦了?我們馬上可以想到在getbuf這個函數(shù)里定義的char buf16上做手腳,可以看到在getxs函數(shù)里的while循環(huán),結(jié)束條件只是以回車或者是eof結(jié)束符為判斷標準,所以,根本沒對char輸入的數(shù)量做判斷!這樣的話,我們可以輸入多于16個的數(shù),從而緩沖區(qū)溢出!   在這里還是提一下幀棧結(jié)構(gòu),如下:+-+高地址|函數(shù)參數(shù) n 個 &#

13、160;   |+-+|函數(shù)參數(shù)第 n-1 個   |+-+|     .     |     .      |     .     |+-+|函數(shù)參數(shù)第1個    |+-+|return 返回地址  

14、0;  |+-+|ebp指針入棧      | +-+|local var(局部變量)   |+-+|        others |+-+低地址   按照上面說的函數(shù)棧的存放情況,在getbuf這個函數(shù)里,函數(shù)參數(shù)沒有,我們不管,然后就是return返回地址,然后就是ebp指針,然后就是char buf16。+-+低地址|return 返回地址  

15、;    |+-+|ebp指針入棧       | +-+|    buf15     |+-+|    buf14      |+-+      :      :    

16、0; :+-+|     buf0     |+-+|    others |+-+高地址  如果我們對buf溢出,能改寫ebp和return地址!下面看看,ebp是多少,return地址是多少。  要知道這里的%ebp存的是test函數(shù)的%ebp,因而我們在調(diào)試的時候就可以在test函數(shù)得到%ebp的值,它應該是我們寫入的buf16-buf19的值,而且它要保持原來的值,不然返回之后就亂套了,在我機器上是0x0040100f。這個很容易,解決了第一步。

17、下面我們再來看返回地址,先看一段匯編碼(不同的機器有所不同):   在getbuf()返回后,肯定會接著執(zhí)行0040126a,我們能讓它從這執(zhí)行嗎?當然不行!不然就要push eax,那是我們不想看到的,因為eax的值就是1。因而我們會想到能不能跳過這?當然能,改返回地址??!順水推舟,我們通過buf數(shù)組來覆蓋返回地址。此時,我們想要它直接跳到00401271處,因而可以通過設(shè)置buf19-buf22的值來覆蓋返回地址。  到了考慮如何加進deadbeef了,在返回后,將直接執(zhí)行push  offset string "getbuf returned 0x%xn" (0042301c),沒eax怎么行了?不然printf函數(shù)就少了參數(shù)。再回到幀棧結(jié)構(gòu)一下,printf在調(diào)用之前,要壓入?yún)?shù),先壓入val,再壓入offset string "getbuf returned 0x%xn",也就是說參數(shù)val(等同那個eax)在offset string "getbuf returned 0x%xn“之上,而且緊挨著。此時我們可以想到,既然返回之后(返回地址及其以下的元素都已彈出,返回地址的上一個字節(jié)成了棧頂)就執(zhí)行push  offset s

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論