pwnable_start & ciscn_2019_es_2 & ez_pz_hackover_2016 & pwn2_sctf_2016


  花了兩天時間做了這四道題,感覺收獲很多。但是這種收獲感覺寫文章寫不出自己的思路,就錄制了一個視頻。

  pwnable_start

  這道題考察了系統調用,shellcode的編寫,和動態調試的知識。

ciscn_2019_es

  這道題考了棧轉移,先泄露棧地址,再棧轉移回去寫rop鏈。

ez_pz_hackover_2016

 

  這道題打開學習到的也是動調,發現動態調試真的有用。

pwn2_sctf_2016

  這道題本來不計划放到視頻中的,錄着錄着亂了。。。這里有一個符號判斷的問題,感覺視頻中沒有講清楚,這里補充一下。

  

   這里是一個v2和32比較大小,v2是等於atoi(&nptr),其實看v2也能看出來,v2是int類型,沒有刻意標明是無符號類型,所以在這里就是有符號類型。

  有符號int:-2^31 ~ 2^31-1,即-2147483648 ~ 2147483647。4字節。

  當我們輸入-1的時候,實際上的二進制保存的是1111 1111,1111 1111,1111 1111,1111 1111,這里的第一個1其實用來表示正負的。

  所以這里的-1假如轉換成無符號的時候大小就是2147483648+2147483647==4294967295

  也就是題目中的這個樣子。而我們再看這道題的匯編是怎么寫的。

  這里要用cmp指令,我們就先來看一下cmp指令的知識。

cmp(compare)指令進行比較兩個 操作數的大小
例:cmp  oprd1,oprd2
為第一個操作減去第二個操作數,
但不影響第兩個操作數的值
它影響flag的CF,ZF,OF,AF,PF
我們怎么判斷大小呢?
若執行指令后
ZF=1 這個簡單,則說明兩個數相等,因為zero為1說明結果為0
當無符號時:
CF=1 則說明了有進位或 借位,cmp是進行的減操作,故可以看出為借位,所以,此時oprd1<oprd2
CF=0 則說明了無借位,但此時要注意ZF是否為0,若為0,則說明結果不為0,故此時oprd1>oprd2
當有符號時:
若SF=0,OF=0 則說明了此時的值為正數,沒有溢出,可以直觀的看出,oprd1>oprd2
若SF=1,OF=0 則說明了此時的值為負數,沒有溢出,則為oprd1<oprd2
若SF=0,OF=1 則說明了此時的值為正數,有溢出,可以看出oprd1<oprd2
若SF=1,OF=1則說明了此時的值為負數,有溢出,可以看出oprd1>oprd2
最后兩個可以作出這種判斷的原因是,溢出的本質問題:
兩數同為正,相加,值為負,則說明溢出
兩數同為負,相加,值為正,則說明溢出
故有,正正得負則溢出,負負得正則溢出
兩數相減,同號,則不溢出;兩數為異號,結果與減數符號相同,則溢出。

 

 偷了張圖,感覺更直觀了。。。

  上面是直接從百度百科復制過來的,感覺講的很清楚了。

  所以這道題輸入-1的時候,SF=0,OF=1。

  這個時候我們再看jle指令,轉移條件寄存器描述是ZF=1 OR SF≠OF。

  在這里,很明顯是是要跳轉的,所以

 

  這里就直接跳轉過來了,就繞過了這個判斷。感覺這里就算是講清楚了。視頻已經在審核中了,等審核完我就把視頻扔上來了。真的是感覺學到了好多東西呢。

 

 


免責聲明!

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



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