逆向入门--第一次的HelloWorld
終于算是慢慢的爬入了逆向的大門,夢想雖遠,堅持就好
記第一次簡單的逆向過程
首先貼出CrackMe的源碼,很簡單的一個if而已
#include <stdio.h> #inclued <stdlib.h>int main(int argc, char **argv) { char passWord[8] = {"pass"};char word[8] ;gets(word);if(strncmp(passWord, word, 8) == 0){printf("authorized !\n");}return 0; }代碼很簡單,輸對了就打印
(當然這個還存在緩沖區(qū)溢出,這個后面講)
開始Crack
因為我們的EXE文件是標準的PE( Portable Executable )
所以我們使用IDA(靜態(tài)分析調(diào)試工具)對文件進行查看
IDA 相當與我們的地圖一樣的作用
這個就是我們的IDA 加載之后的程序 ,當然是匯編,的形式
第一行可以看到,是main的入口
很多人都是認為程序是從main函數(shù)開始 的,其實不然,程序真正的入口我們稱之為OEP(original entry point)
然后我們向下讀代碼,
30 地址之前的就是我們的變量地址分配,
ebp,exp也就是我們常提起的bp 和 sp 的extend版本
31到36是我們的棧初始化
- 30 基址壓棧
- 31 基址賦值
- 33 對棧指針做掩碼??(沒弄懂這個作用)
- 36 對棧頂指針做減法,即分配??臻g 20*16 個字節(jié)
- 39 call _main (這里才是真正的進入了main函數(shù)中去)
39往后main里
- 3E 就是變量賦值 可以看到 str1的值是 -8h (這里就很好解釋了棧地址是如何向低地址增長的),后面的字符串當時我還沒反應(yīng)過來,其實是端序的問題,在Win里 都是大端格式,所以向下增長 的時候字符串要反過來
- 46 這里就是對字符串后面添加 \0 作為結(jié)束符
- 4E ~52 原理同上分配buffer(IDA已經(jīng)自動注釋,美哉)
- 55 就是調(diào)用我們的gets函數(shù)
- 5A~6E 就是strncmp的參數(shù)配置,str1 str2 maxcount這三個
- 71 調(diào)用strncmp函數(shù)
76 這個比較重要 這里的顯然是不改變eax的值的,那么他的作用是什么呢? 就是設(shè)置flag寄存器的狀態(tài)
test 的作用不同于 cmp ,cmp 相當于算數(shù)相減,而test 是邏輯相與
所以這里只有eax為0h的時候 才會出現(xiàn) 設(shè)置Z位為1
- 78這里就是我們核心的一句! jnz就是不為零就調(diào)轉(zhuǎn),而下面就是我們的puts 得到的函數(shù),所以要想成功破解,這里的就必須不能跳轉(zhuǎn)!
- 7A 字符串壓棧,
- 81 打印
- 86~8B 就是我們的return 0了
eax 默認的就是傳遞的第一個參數(shù)
到此程序的靜態(tài)解讀告一段落
下面就是我們使用ollydbg進行動態(tài)調(diào)試,或者直接使用UE對pe文件進行修改(直接改jnz的匯編碼即可) Ollydbg:  (2333 ollydbg 看著還是挺帥的) 這里的地址,可以在ida里面找到; 下面就是修改那個jnz了,反正什么都行
- jz 剛好相反
- nop 啥都不動向下執(zhí)行
那就Nop吧 隨便改一改
可見我們的authorized已經(jīng)打印出來了
本次簡單逆向也是告一段落了
附加
下面附件一點:
* 緩沖區(qū)溢出問題*
因為上面剛剛好有匯編的代碼,這樣解釋起來就是變得簡單了
可以看到,棧的空間分配是連續(xù)的,所以我的緩沖區(qū)給的大小是8 那么這樣的話,他地址會基于棧地址來減去八個字節(jié),然而,gets() 函數(shù)是不會判斷緩沖區(qū)大小的,所以會把我們的輸入直接寫到地址。
所以,漏洞就產(chǎn)生了,
str1,str2 是地址連續(xù)的兩個8字節(jié)的空間,那么我們只要輸入一個16字節(jié)對稱的字符串,就可以完美繞過!
效果如上!
寫在最后的話
送給大家一句話吧: 鴻鵠志高而難酬,終而還是妥協(xié)泯然眾人
“”小鎮(zhèn)青年何必遠方?“” 于是我走出了這個熟悉的地方
總結(jié)
以上是生活随笔為你收集整理的逆向入门--第一次的HelloWorld的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 逆向入门--何为OEP
- 下一篇: CTF入门--请输入密码