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