如何將機器碼還原為 C?
依靠自動化工具(例如hexray或者hopper等等)自動來做這件事效果的確比較差,看了下其他答案大多都在討論自動化的解決方案。其實在實際工程上大多數逆向(也就是所謂的機器碼轉成c)的工作是由人力來完成的。簡單介紹下其中難易點和知識需求。
難易點:
逆向工程的過程我分為兩大種,一種是「參考型」,一種是「學習型」。「參考型」指的是根據目標程序的輸入輸出基本可以推斷出這個程序是如何寫的,只需要通過看看程序中的字串信息,再確認下某幾個具體細節,就能基本重新寫出來一個(實際工程上可能只需要一部分的功能代碼),這類多見於惡意程序,競品分析等的分析工作。完成這項工作大多需要逆向者對目標程序所涉及到的知識有過學習。
「學習型」的大意是對要逆向的目標程序「如何實現某個功能」毫無概念,這就需要了解其具體實現演算法。與「參考型」相反在看到目標程序之初無法」腦補「出具體實現細節,需要在程序中找到實現對應演算法的部分,進行比較細的分析。這類多見於對漏洞利用,編寫keygen,還原VM保護等等。這項工作相對」參考型「會比較耗費時間。
知識需求:
在實際逆向過程中,除了對目標程序所用平台的彙編語言的理解之外。對編譯目標程序所用的編譯器的學習也至關重要,甚至可能需要精確到編譯器的版本,可以減少實際工作時不少重複工作,尤其對於VB, Delphi這類。更為重要的是對編譯器所採用的優化演算法的學習,不僅是對程序流程上的優化,計算過程上的優化也很重要。總結一下,逆向的過程就是:腦補目標程序某過程實現—&>確認是否和腦補出來的一樣 || 精確還原某部分實現—&>根據腦補(還原)出來的實現細節用熟悉的計算機高級語言寫出來。這個確實是個大坑,完整的反編譯成可編譯的C代碼基本上是不可能的,都是搞成偽C代碼,只能用來看看流程,要編譯的話需要人工做大量的修改..隨便發幾個鏈接吧,其中有一些我也在倒騰.1. IDA Pro第一個肯定要是逆向界的老大IDA Pro了,他的hexray插件支持x86/x64/arm/arm64/mips的反編譯,在一個函數上按一下F5就出來(偽)C代碼了,還可以在反編譯出來的代碼上下斷點調試,就問你怕不怕...不過這貨貴的要死(所有插件都加上應該要3w+軟妹幣),所以這裡發個demo版的,限制很多,不能保存分析結果支持的文件格式和CPU架構很少沒有F5基本上就是個殘廢,可以拿來玩玩.
2. Hopper
跟IDA挺像的一個玩意,不過功能少很多,相應的也便宜不少,好像也沒什麼特別的地方,有興趣的可以自己去看一下3. exetoc國內大牛劉濤濤搞的,過去的TRW2000的作者,現在貌似不咋出現了,開源的,看雪上也很多人研究這個東西,代碼寫的比較爛,一堆MFC的玩意,不過可能是因為時間太過久遠的原因.放兩個看雪上的鏈接:【分享】劉濤濤的EXEToC的代碼【原創】反編譯程序ExeToc 2011v1.01 (源代碼)【分享】《反編譯器C-Decompiler關鍵技術的研究和實現》4. Retargetable Decompiler一個在線反編譯的東東,也有IDA插件(需要註冊才能下載),個人感覺某些情況下比IDA的還有好用.原理好像是先講二進位程序弄成LLVM IR,然後再IR的基礎上反編譯成C代碼.5. GitHub - joelpx/plasma: Interactive disassembler for x86/ARM/MIPS. Generates indented pseudo-code with colored syntax code.
一個py寫的反編譯工具,功能在標題里都寫清楚了..6. Snowman既可以當IDA插件也可以單獨使用的反編譯工具,開源,很值得研究.7. REC Decompiler免費不開源,bug一堆,反彙編一個exe後在反彙編代碼上右鍵選decompile即可得到偽C代碼8. Relyze - Interactive x86 and x64 reverse engineering and analysis收費工具,效果和界面都很不錯,有試用版可以下載.不開優化還是可能的
難度不亞於把一鍋牛肉丸還原成一頭牛……
哎呀抖個機靈就不要點贊了,請看R大的怎麼將二進位代碼轉換為中間代碼(IR)呢? - RednaxelaFX 的回答
先給題主放個傳送門:怎麼將二進位代碼轉換為中間代碼(IR)呢? - RednaxelaFX 的回答把機器碼反編譯到C代碼是個大坑啊。
最快速和有效的解決方法是做這樣一個機器,把輪子哥塞進去,每次使用從投幣口投一張萌妹子照片,然後輪子哥就開始給你人肉反編譯了(逃
怎麼這麼多人前仆後繼啊~我們F5就夠了
可以試試我寫的工具:DLL to C目前已經實現了生成數據結構和反彙編,我保證會進一步升級。下載地址:http://www.dll-decompiler.com
有這種需求的,一般有兩種目的,分開來說吧
1 僅僅只是功能實現。比如說,你要破解一個軟體,人家軟體的註冊流程假如是 輸入名字name-&> 計算出key,然後跟輸入的key做對比。
如果你是做算號器,僅僅需要把「計算出key」給實現,而不想知道計算方法的話,那就簡單了。一般做法,ida找到 計算 函數,然後dump出函數來,用asm編譯成obj,然後跟c代碼編譯的obj link還有中做法就是用c寫模擬,比如 mov eax, 10你就可以 int eax; eax=10,依此類推吧。我就干過這個,這麼整簡單好調試。當然,這方法局限性還很大,一般適用於純計算的東西,因為中間不會調用其它函數,尤其是又調用代碼裡面某個類成員函數值了,就很麻煩了2 需要讀懂邏輯的
這個沒啥好說了,動用所有的baidu,google資源吧,比如先看看裡面有沒有table表之類,有就好辦了,丟網上一搜,沒準就是md5,crc之類演算法,知道演算法就好辦了,自己找個同類演算法用。或者看到某些通用字元串或者函數調用,丟網上一搜,知道這個是openssl的某個文件里的函數,然後進去瞅瞅吧。畢竟上面兩種情況是灰常灰常罕見的,大多數情況,代碼就是作者自己視線的,這種情況下,ida pro讀彙編+F5 反c + od動態+大腦+時間吧,沒其他方法了。如果想知道架構方法,那麼是另外種方式了
就醬寫一個ACM演算法程序,然後開o3編譯,讀一讀彙編你就知道有多困難了,o3出來的東西和你一開始寫的完全不是一碼事
用機器學習做一下…
這個非常麻煩,我以前上ICS的時候就做過這事。ICS有一個實驗是拆炸彈,就是給你一個可執行文件,要求你輸入幾個字元串。用objdump反彙編炸彈後,最後一關的彙編代碼又臭又長,頭都大了,後來我人肉把那串彙編翻譯成了偽C語言,足足花了2天。後來想想,我能成功主要是因為炸彈文件反彙編後的代碼很」直白」,教材(CSAPP)第三章講解的技巧都用得上,如果編譯器優化程度高(比如O3)的話,估計就不行了。
求導很容易,求積分要困難的多
f5
兩個整數相乘很容易,分解一個大整數的因數很難。差不多就這意思吧
這個問題的難度在於反編譯的粒度,看你要的是將機器碼還原成等價的C代碼,還是要得到C代碼的原始語義呢?舉一個可能不太恰當的例子,比如一段代碼將兩個數相減,然後判斷結果是否為0,原始語義其實是想比較兩個數字是否相等。前者比較容易實現,但後者就比較困難了,一個不太理想的實現方法是針對一些C語言中的結構做特殊處理,但如果涉及到編譯器的優化就不太管用了。
目前的水平是達不到的。事實上,c源碼在編譯時會丟失信息,像變數名函數名大多都是不保留的,而且在編譯器優化的情況下一些邏輯也會發生很大的改變,所以單純面對彙編碼或者部分反編譯的代碼,哪怕是讓人工來看都很難找回原有邏輯,一般都要動態調試加靜態分析來找出邏輯的,這種活機器現在還很難去做。如果目前一定要找一個解決方案的話,已經商用的最好的應該就是IDA pro了吧,在去殼去混淆之後f5可以看到抽象出來的偽代碼。
IDA已經很牛逼了,不過還是沒有辦法還原成c源碼,不過作為偽代碼看看邏輯已經足夠了
大坑,實驗室同門做了好久。最後發了幾篇所謂頂級paper就不了了之了,實際上原型完全沒法看。
我目前機器碼轉c的方法是先轉彙編再手工轉C, 效率很低需要反覆編譯對比
推薦閱讀: