# Day14 - 史上最強Debugger - 人體肉眼 Debugger {%hackmd theme-dark %} 今天,準備要開始逆向程式碼。在介紹工具之前,先來解說逆向工程的邏輯。基本上,對於逆向,有很多現成的工具可以直接套用,但許多有其極限(當然,有工具可以提升效率,我沒有說要完全摒棄工具)。但就對於想透過組合語言來解釋程式碼而言,不仰賴工具仍可以練習自己的組合語言語感。因此,很多時候透過交叉比對,更可以解釋狀況。以下,我將講解如何將程式碼一步步拼湊回來。 我會先提供一份已經逆向過的程式碼截圖,讀者可以挑戰可否在不使用工具下,理解程式碼的運作邏輯?接著會提供透過 GDB 輔助動態追蹤的過程與解答,讓讀者比較是否與自己的理解相同。 ## 路上撿到程式碼 情境引導:在通往偉大的航道,你撿到一支程式碼,執行後發現它是一支會驗證使用者輸入的程式(如下圖)。到底驗證過後能獲得什麼秘辛呢?好奇的你,真的好想知道。於是,你隨意輸入一段內文(LET ME IN),發現錯誤。果然沒那那麼簡單就可以拿到擁有世界上的一切的「海賊王」哥爾·D·羅傑的寶藏。你忽然想到,最近不是有學過逆向嗎?何不來逆逆看?  ## 被逆向的程式碼 下圖是透過 GDB 逆向的程式碼,想請問讀者這段程式碼到底在做什麼? 讀者可以拿出紙與筆,畫出以下程式碼的運作流程圖。花一點時間,消化這幾天所看到的知識,若忘記可以往回翻,或查閱相關資料。重點是,若想提升組合語言的識別能力,不要輕易的直接看解答,先讓大腦思考一下。我去成大上課的時候,聽到 Jserv 大大的名言,跟大家分享: >「如果你把游泳池當作浴缸泡著,再泡幾年還是不會游泳」 >– jserv  ## 拼湊程式碼 經過與海軍奮鬥的一番掙扎後,我們現在來講解一下如何肉眼識別程式碼。 先看下圖,其實我們看到組合語言密密麻麻,也不是每一個都是重點。我把重點用紅筆標示起來於下圖。讀者可能會問,那什麼是重點?重點就在每次的比較、跳躍與呼叫其他函式。比方說記憶體結尾是 5cc 的地方,有一個 cmp 指令,接著 5d0 的 jne;還有 5ea 的地方,有一個 call 的指令,後面還寫著 \<printf@plt>。這些都是重點,因為我們逆向的時候,想知道到底什麼條件下會觸發這些事情?觸發後做了什麼事?  於是,透過上述方法,就可以簡略畫出程式運作圖(如下圖)。可以知道,總共有三個區域,分別是白色、紅色、綠色的區塊。分別對應三種情況。首先,白色區塊代表的就是驗證全部通過後的結果(找到寶藏),而紅色代表的是第一個驗證沒過的下場,綠色表的是第二個驗證沒過的下場。簡單來說,就是要走在白色這條主線上,才能通關成功!  透過與 GDB 的動態追蹤,可以得到下圖結果。紅色的 1 代表,沒通過參數個數驗證,綠色的 2 代表通過參數個數驗證,卻沒通過驗證碼的驗證,紫色的 3 代表驗證全部,安全達陣!  ## 原始程式碼 以下是哥爾·D·羅傑的寶藏。解答公布: ```c= #include <string.h> #include <stdio.h> int main(int argc, char *argv[]) { if(argc==2) { printf("Checking License: %s\n", argv[1]); if(strcmp(argv[1], "APTX-4869")==0) { printf("Access Granted!\n"); } else { printf("WRONG!\n"); } } else { printf("Usage: <key>\n"); } return 0; } ``` ## 結論 恭喜找到 ONE PIECE!動態追蹤程式程式碼蠻有趣的,雖然有點累、甚至有很多看不懂的情況,但了解背後邏輯94爽。明天,將會講解如何透過工具解讀程式碼。
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up