天草脫殼視訊學習筆記(逆向 OD)

whatday發表於2013-05-30

天草殼世界學習筆記:

1.OD的查詢支援模糊查詢 ?? 比如 要查詢 E82091FBFFA1B8  可模糊查詢:E8??91FBFF??B8

2.OD的外掛idaficator 可以支援回滾 就是記錄你的操作記錄往回走 相當於一個跳轉或者CALL以後 可以跳回去看  對著idaficator 工具欄的第一個按鈕 點選滑鼠左鍵  或 ESC 可以回滾上一步 滑鼠右鍵可以回滾下一步

3.StrongOD外掛的二進位制無空格複製功能 在OD中選中程式碼 ctrl+shift+x 複製二進位制無空格位元組 8B45EC8B088B09894D985051 如果是OD自身二進位制複製如下8B 45 EC 8B 08 8B 09 89 4D 98 50 51是有空格的

4.OD中的跳轉修改 不用修改程式碼 直接修改標誌暫存器標誌Z就可以 雙擊修改

5.StrongOD複製地址功能 ctrl+x

6.利用ctrl+B二進位制搜尋 多觀察多搜尋 各個編譯器的開頭OEP(Original Entry Point)特徵便於定位

7.OD指令碼利用 用於脫殼等一切動作

8.找OEP的一個方法 尋在程式結尾時的ExitProcess 因為結尾附近就是OEP 根據編譯語言特點觀察一下就可以找到OEP

9.StrongOD填充NOP 鍵盤1是填充1個NOP 2是填充2個NOP 3是填充3個NOP 以此類推

10.softDefender加密殼 一般有這樣幾步驟 1.先載入dll得到函式地址存放在記憶體上 2.再進行相應的地址加密 3.把加密後的地址放入IAT 所以最好的時機就是在2-3之間 這裡既有IAT的地址 又有加密的地址 又有真實的地址 修改部分判斷就可以達到不加密的結果

11.OD中更新的內容會變紅 這樣不方便看 可以用右鍵備份-》更新備份 來取消變紅 有時候為了追蹤SMC程式碼自修改,也需要讓它變紅,這個時候可以在該段中,修改一些指令,修改後的指令就會變紅,單步SMC變化的程式碼也會變紅,再撤銷先前修改的,這時候每個SMC的程式碼都會繼續變紅了,方便觀察。

 

12.ACProtect殼的亂序系統,把OEP開頭處的程式碼分佈執行了 在它殼裡邊繞來繞去 但是最終還是執行了這麼幾條指令 可以對程式碼段下記憶體斷點 這樣可以找出程式本身的call

 

13.IDAFicator的多行彙編功能Rote 可以將多行彙編程式碼寫入OD中 但是版本是1.2 如果用最新的2.0 2.0需要配置RadAsm 這個比較複雜 期待2.0的配置

14.在OD指令碼中有許多功能沒有指令碼指令 可以用模擬鍵盤的方式來執行 比如ctrl+f2重新載入 本來的指令碼命令式reset 可以用key 71,0,1來代替 但是這裡重新載入以後指令碼也跟著載入了 感覺這個命令沒什麼用處

15.因為脫殼逆向的工具比較多 比較雜亂 所以所有的工具可以用 音速啟動 這個軟體進行歸類

16.在OD中需要分析一個函式的時候 可以把EIP設定到這個函式執行 但是應該把EIP設定到這個函式的call而不是這裡函式裡邊 這個原因很好理解 比如EIP停在OEP開頭就好比在執行程式碼第一句話 現在需要分析一個函式的細節 當然是直接跳到這個函式的執行的語句 然後再進入這個函式分析 如果直接把EIP指向這個函式裡邊 會造成棧的不平衡

17.StrongOD有個建立記憶體空間的功能快捷鍵是ALT+Q 在臨時執行一些測試程式碼的時候可以用到

 

18.在尋找OEP時 如果殼已經做了變化 比如多型程式碼 這個時候就可以用相應工具環境建立一個無殼的程式 進行對比解密

 

19.有些殼修改了段屬性從而控制訪問許可權 比如沒有寫屬性 OD的CTRL+B就不好用了 所以需要在 Memory map中把需要用到的段屬性進行修改

20.OD中 在使用ctrl+B搜尋時 如果是對反彙編視窗進行的它只會對該段進行搜尋 如果實在Memory map中搜尋的 它會從指定段往後搜尋其他段

21.如果遇見花指令的時候 可以通過 花指令去除器 來去除花指令 但是需要注意的是 1.殼是否有檢查花指令的程式碼,如果有檢測去除以後要出錯 2.花指令所要不然去除許可權為完全訪問 在去除花指令 防止去除花指令後程式崩潰

22.對於有重定位功能的殼 可以使用 1.補區段的方法 2.跳過重定位程式碼 dump段 補充PE頭 補充資源 方法1步驟比較少但不完美 方法2步驟比較多相對完美

23.Obsidium這樣的殼IAT修復可以使用函式跟進的方法 就是把EIP設定到這個模擬函式的開頭 然後一步一步跟進得到真實的函式 這個和10點中的IAT解密方法不同

24.在OD中如果需要定位某個系統函式入口點 只需要直接CTRL+G輸入API名稱 比如需要定位VirtualProtect 只需要直接ctrl+G 就可以到達VirtualProtect入口點

25.在OD中使用ctrl+g可以跟隨到相應地址 但是有時候如果是A-F開頭的 會顯示 未知標示符 這個時候需要在字母前補充0來說明這個標示符是一個十六進位制的地址

26.在執行OD指令碼中 在指令碼暫停狀態下 雙擊相應的行 執行點將設定到這行 如果按下ESC 指令碼將重新停在開頭處 所有變數值全部清空

27.在執行OD指令碼時,如果縮小OD視窗 或最小化視窗 可以加快OD指令碼的執行速度 這裡很容易理解 介面重新整理開銷減少了 速度自然快了

28.有時候用OD除錯程式的時候 出現程式崩潰 並不一定是程式的驗證 有可能是OD或者外掛的問題造成的 這個時候應該儘量保證OD及其外掛的更新

29.OD外掛的編寫如果實在比較高的平臺比如WIN8 VS2012等 寫出的差價不能再XP上執行 因為需要MSVCR110.DLL 但是XP最多支援MSVCR100.DLL 所以可能的話用VS2010編寫應該可以解決

30.OD外掛bookmark可以使用 比較方便 設定一個地址為書籤0 書籤1 然後ALT+0 ALT+1 可以切換到書籤所在的地址 設定一個書籤的快捷鍵是ALT+SHIFT+數字 感覺像星際爭霸裡邊的編隊一樣 很方便

31.在解決加密IAT時 一般找到了一處加密的特徵碼後可以直接在OD中搜尋這個特徵碼 看看其他地方還有沒有 這是因為寫程式的時候各個加密IAT的最後一個功能一般都是覆蓋 這樣一來很可能是一樣的程式碼形式 所以編譯成彙編程式碼也是一樣 典型的例子就是The Enigma Protector v1.65的 mov dword ptr ds:[edx+eax*4+4],ecx 特徵碼

32.在使用OD的memory map時需要注意 列出的地址 大小有可能是通過2次或者多次 VirtualAlloc得到的結果 比如當看到結果是 地址=01730000 大小=00024000時如果只監視VirtualAlloc 分配size=00024000時 這樣很可能找不到匹配的 但最後又的確存在這塊記憶體 這就是因為這塊記憶體是由2次分配完成的 第一次 addr=01730000 size=4000 第二次 addr=1734000 size=20000 最後在OD memory map中就看到了 addr=01730000 size=24000 還有就是因為記憶體對齊的作用如果用VirtualAlloc申請記憶體12CD0 會看到13000的大小結果 這點也要注意觀察

33.在一些非彙編寫或SDK直接編寫的程式中 一般不會直接呼叫系統API 所以斷點API一般是在程式語言所封裝的函式中 如delphi MFC 這個時候如果要替換函式或者修改函式 一定要找到外層呼叫 也就是原始碼中的呼叫地址 如果是加殼程式這個call一般會被替換掉 總之是找不到這個call的呼叫點 這個call retn後也是在加密程式碼中 這樣可以確定原始碼和程式語言框架的一個分界點 這也是外層呼叫點

34.有些時候針對程式彈出一個對話方塊設定斷點時需要注意,程式很多時候彈出的不是對話方塊 是視窗這個時候用建立對話方塊的API斷不下來的,所以需要對視窗的ShowWindow進行斷點

35.在使用OD斷點時 入F2 硬體 及其記憶體斷點 需要明白其原理 F2斷點就是int3 這個殼程式是可以檢測的 如果是硬體斷點 就是硬體斷點暫存器dr0-dr3 簡稱drx 這個殼程式也是可以清除的 雖然OD的外掛如PhantOm可以保護硬體斷點 但是這期間需要時間的 很可能在這段時間EIP已經走過了斷點處 所以這個時候如果在其前邊下一個F2這樣就可以給 OD外掛充足時間來重新保護drx(雙斷點法的原理~OD外掛會保護除錯暫存器,也就是保護硬體斷點,但是不能在異常清除以後馬上恢復,需要時間,雙斷點法就是要程式用API的F2斷點不斷中斷下來 給OD外掛恢復硬體斷點的時間~) 當然如果用記憶體斷點就不會出現這個對抗了 但是會比較慢 因為每次OD都會對比

36.Process Monitor用於觀察程式行為很方便,通過檢視每條記錄的堆疊資訊可以得到API的呼叫情況

37.在OD中查詢字串 OD外掛Ultra String不一定什麼時候都好用 可以結合OD自帶的字串參考來用

38.一般一個支援多語言的軟體 它都有各種語言的語言檔案 如果是需要根據字串定位 就需要找到相應的語言檔案 在看對應的ID是多少比如

    <message>
        <original>Loading project settings...</original>
        <translated>載入專案設定……</translated>
    </message>
    “載入專案設定”的ID就是“Loading project settings...” 所以在記憶體中搜尋就應該搜素“Loading project settings...”

 

39.定位程式的某些特徵碼時應該先考慮 文字形式的特徵碼 程式碼形式的特徵碼容易發現變化

 

40.有些EXE中捆綁了DLL 可以用Exeinfo PE來提取DLL 具體步驟:Rip->Ripper(search EXE PE inside EXE)執行以後 EXE存在的DLL就會被提取到EXE所在目錄,同時這個工具也是一個很好的查殼軟體和PEID互相搭配效果不錯

41.關於脫殼後的優化可以參考http://blog.csdn.net/whatday/article/details/8785778 這篇文章 步驟比較多 優化的地方比較多 一個總的原則就是儘量讓脫殼後的檔案和沒加殼的原檔案一樣PE頭一樣 各個區段一樣

42.觀察一個DLL是否可以正常執行可以用OD載入來測試,也可以用Dll LoadEx這個工具來測試

43.修改PE檔案的基地址可以用PE32.Relocate工具 PE檔案的基地址是在編譯的時候就設定好了的 如果直接用PE編輯工具修改基地址會造成 重定位的程式碼無效 這個工具可以把每次需要重定位的地方進行相應的修改

44.對於繫結了DLL的殼來說,如果要解除捆綁 第一步,讓程式完全跑起來,dump DLL所在的記憶體,Exeinfo提取DLL,這個時候雖然提取的DLL可能不完整或者被加密,但是可以通過Exeinfo的日誌看到有幾個DLL其RVA是多少。第二步,分別在DLL的RVA下斷點 得到解碼後的完整DLL,這個時候可以單獨分析DLL檔案了

45.查詢一般IAT加密的方法:1.來到一個替換後的CALL(比如004069F4-FF25 48DDC901 jmp dword ptr [0x1C9DD48]),記錄起地址設為A(004069F4),過載OD,在地址A+2下記憶體寫入斷點(A+2是[]中的值設為B),執行監測得到寫入B時的程式碼地址。  2.設該程式碼所在的函式設為C,在C的開頭部分可以看到一個列表首地址(mov ebp,0xB203D4  mov eax, dword ptr [ebp])設這個地址為D(0xB203D4),這個列表就是需要替換的函式地址列表,這個和匯入表原理類似,過載OD,在D下記憶體寫入斷點,執行。 3.這個時候可以得到 一個申請完D列表的記憶體未寫入值的 時機,在D下記憶體寫入斷點,就可以來到 IAT加密的函式了。

46.test彙編指令需要注意和cmp的區別,test是and的意思,具體要換成二進位制來看,有時候也可以取巧的分析,比如test edi,0x1   je 00AF9C55這種情況下更多可以看成cmp edi,0x1 jne 00AF9C55,je jne容易混淆出錯。

47.對於IAT比較大比較零散的情況下 如果直接用ImportREC進行重建IAT會增大脫殼後的檔案,Universal Import Fixer(UIF)可以把零散的IAT重新放到新的位置上 並且合併起來 這樣有效的利用空間 更有利於脫殼後的使用。

48.在OD介面上對著IDAFicator外掛的按鈕點右鍵 可以自定義按鍵功能,加入IDAFicator外掛後,在OD的工具欄上會出現"工具" "常用斷點"兩個選單項。 不是所有的外掛最新就好,最新的版本有可能有各種bug,在更新外掛的時候一定要先備份現有的外掛

49.在記憶體中抓取DLL 有2種 一種是被記憶體對映了的,一種是原始的,記憶體對映的過程 一般是原始檔案把PE頭複製給對映檔案,再把每個區段複製,原始檔案的好處的原始的大小,記憶體對映檔案的好處是最後都修改為了 SectionAlignment == FileAlignment == 1000 這樣一來方便以後的操作不用換算 但是大小增大,多了修改節區的操作

50.很多從記憶體提取的檔案,比如資原始檔都是二進位制的,可以用 010 Editor直接 "編輯->貼上自->十六進位制文字"(ctrl+shift+v) 來寫入,在儲存檔案的時候還可以儲存沒有檔名的檔案比如 .messages 這個檔案資源管理器是不能建立的,010 Editor這個軟體就可以建立.

51.在修復IAT的時候如果比較分散或者不是FF25的形式(jmp [xxx]),可以用UIF修復一下,UIF可以把API呼叫的地方搜尋蒐集起來在一個記憶體段新建一張IAT表,然後把程式中的程式碼都改為FF25呼叫這個IAT的形式,所以也要在UIF以後才能dump,有了完整的IAT表,importREC也便於修復了。

52.有時候脫了殼,用PEID還是顯示Nothing found *,有可能是PE可選頭中的聯結器版本號修改造成的,程式可以執行,但查殼查不到,可以PE Tools修改PE Optional,如果是Delphi程式可修改為主連結器02副連結器19 這個具體值可以通過檢視相應編譯器的正常程式獲得。

53.code replace的跟蹤,如果是一次偷取一條指令(比如 RLPack),可以觀察堆疊和暫存器的變化,有些指令是操作的記憶體比如MOV,所以也可以跟蹤下看看具體做了什麼,發生了什麼改變,從而推算出這條指令是什麼。

54.在使用OD指令碼的asm命令寫指令時發現 它生成的編碼和在OD裡邊直接寫彙編指令的編碼有些不一樣,比如"mov     dword ptr [0x44F664], eax",用asm生成的結果是 0044CABE    8905 64F64400   mov     dword ptr [0x44F664], eax 如果是在OD裡邊直接寫是0044CABE    A3 64F64400     mov     dword ptr [0x44F664], eax 一個是8905 一個是A3 因為指令長度不一樣這點造成很多問題,在還原code replace時就不能還原為原始的指令,解決方法是用wrta寫到檔案,然後自己手動用OD寫入,如果程式碼多可以用IDAFicator寫入。

55.一些殼脫殼後需要修改段屬性,比如RLPack,這裡指的是不完美脫殼,區段屬性一般寫改為。

56.對於原始區段沒有被刪除的加密後的軟體來說,可以用標準的方法跑OEP,1,記憶體寫入斷點輸入表段,2,記憶體訪問斷點程式碼段,這樣一般就可以到OEP了。

57.Trial Reset這個軟體可以清除殼軟體的註冊資訊,便於反覆實驗破解。

58.pespin殼的指令變形比較有亮點,主要用於控制流程,如下:

    dec    ecx                    ;每次減一
    pushfd                        ;結果對應符號暫存器的ZF位
    shr     dword ptr [esp], 0x6            ;右移6為 是ZF位 判斷dec結果的
    not     dword ptr [esp]                ;當ecx為0時,ZF為1的,取反就為0 和ecx保持一致
    and     dword ptr [esp], 0x1            ;如果ecx為0 結果也為0 [esp]也為0了 很好的反應了結果
    pop     eax                    ;把結果放到EAX中
    ...
    lea     eax, dword ptr [eax+ebp+0xED910CA6]    ;雖然EAX的值只差1 但是恰好對應了2個程式碼流程 這樣也就實現了比較跳轉
    jmp    eax                    ;跳轉到相應的流程
   這段程式碼亮點在於利用棧來計算儲存,減少了cmp JNZ等的利用,讓人不能一下看出程式流程,有花指令的效果。所以看到pushfd指令不要慣性思維認為是儲存環境。

 

59.雙程式的殼(比如pespin)的分離,可以對CreateMutexA進行斷點(原理是兩個程式通過一個約定好的有名稱的互斥量,來探知對方的存在),然後修改結果讓其認為已啟動了程式,這樣流程就不會執行CreateProcessA,流程改變了有可能到異常的程式碼上(比如 INT1 INT3等),這時有2個方法解決  第一,可以想象成在一個函式中,直接跳處函式,這樣就跳過錯誤程式碼,返回點在棧裡邊可以找到。第二,可以想象成是一個if語句,讓流程不執行裡邊的語句 所以跳過這些語句繼續執行,這個執行點一般就在異常點後邊不遠處。建議使用第二種方法,直接返回函式有些操作沒有執行到有可能發生錯誤。

 

60.有些殼中使用SEH改變流程來遮蔽除錯,原理是:註冊SEH後殼程式故意造異常,如果有偵錯程式則中斷到偵錯程式,不會進入異常回撥,恰好異常回撥就是程式的流程,這樣一來程式就終止了,讓人不能一下跟蹤到流程,解決方法是回撥函式下斷,shift+F9 避免了除錯中斷異常。

61.關於多執行緒殼驗證注意事項,A.分析多執行緒可以設定 OD設定->事件->中斷於新執行緒,勾選上後調式多執行緒立馬方便了,出來一個執行緒od就斷下,然後慢慢跟蹤,跑OD指令碼不要勾選,因為流程隨時會因為新執行緒建立而改變。B.patch程式碼比OD指令碼效率高很多,OD指令碼修改程式碼有可能被多執行緒檢測出來,但patch程式碼效率高,在多執行緒檢查前就結束了。

62.OD中的ctrl+g輸入API名稱可直達API地址,StrongOD加強了它的選項功能,但輸入API時需要注意,有些API在多個DLL中都存在,比如Kernel32.CreateThread和KernelBa.CreateThread,同時存在於2個dll中,但最終都呼叫的KERNELBA.CreateRemoteThreadEx,如果用ctrl+g定位CreateThread就會來到KernelBa中,但程式中大多呼叫的是kernel32的,所以這裡設定斷點就斷不下來,方法1,這種情況可以再跟進一層API比如在CreateRemoteThreadEx中設定斷點,這樣就能斷下來了。從而也可以發現程式本身呼叫的哪個API,也可以直接修改程式碼 比如 call kernel32.CreateFileA這樣也能看到API地址,然後在撤銷修改。方法2,直接ctlr+g 輸入kernel32.CreateThread就會到達kernel32中的那個CreateThread了。

63.在執行比較大的OD指令碼時,有可能出現不穩定或BUG或終止程式,這時儘量把指令碼寫得高效,少斷點少比較,或者分成多個指令碼執行,避免OD或指令碼外掛出現類似於堆疊溢位的問題而崩潰。

64.PE檔案脫殼執行如果出錯按照順序排錯,匯入表 資源表 TLS檢視是否正確 清除重定位表-》檢視PE頭中資料是否正確-》OD跟蹤PE檔案找出原因。

65.對殼中的地址定位最好不要使用硬編碼,因為硬體軟體的不同會造成地址改變,地址定位用特徵碼比較好。指令碼中定位DLL硬編碼程式碼的方法:

    gpi CURRENTDIR                //得到目錄
    mov zpdll,$RESULT
    add zpdll,"ZProtect.dll"        //得到全路徑
    gpa "CreateFileA", "kernel32.dll"    //對每個檔案的開啟下斷
    mov pcreatefile, $RESULT
    bphws pcreatefile, "x"
    findzpdll:
    esto
    len [[esp+4]]                //得到開啟檔案的路徑長度
    readstr [[esp+4]], $RESULT        //得到當前開啟的檔案
    scmp $RESULT,zpdll            //比較是監控的檔案
    jne findzpdll
    bphwcall
    mov dllbase,edi                //得到DLL檔案PE頭VA
   得到基地址後載入硬編碼的偏移地址,就可以定位了,但是一般會因為硬體軟體的不同而定位不準。推薦特徵碼定位。

 

66.在殼中對驗證程式碼的修改,找到一處以後可以通過此處特徵碼搜尋,有可能有多個地方都用了這個驗證,這樣到達一勞永逸,不漏掉的效果。

 

67.SMC的patched法主要是說:在不脫殼的情況下進行破解,加密的程式程式碼是被加密了的,等待它解密以後才能進行修改,解碼後地址就是一個問題,我們的破解補丁是肯定基於地址的,所以要修改我們自己的破解程式碼,如果解碼函式是多重解碼,比如A地址解碼到B地址,B解碼到C。。。等等,這樣我們追蹤地址也需要一重一重跟蹤,每次都需要修改我們的程式碼,SMC由此而得,雖然寫的是補丁程式碼,但是由於地址不確定還需要寫段程式碼來修改補丁程式碼,所以叫做SMC法。

68.OD指令碼的find命令和findmem命令的區別在於 前者只能查詢一個記憶體段內的資料,後者查詢所有記憶體段,前者查詢對於變數的解析成字串,後者對變數解析成十六進位制。

69.善用棧資訊視窗,OD棧視窗可以看出執行過的系統API,雖然不像WinDbg這樣直接,在棧視窗中不斷往對起始地址檢視就能看到從啟動EXE到現在執行的API了,當然前提是這個執行緒,不同執行緒棧也不一樣的。除了系統API可以看到執行的函式及其返回點,一般的殼變形花指令 流程跳轉等等的確在反彙編視窗跟蹤容易混亂,但是這些招數對於棧視窗是無效的,棧視窗中的返回點 和系統API點都是標紅了的很容易區分,監控這些返回點也可以掌握整個程式的流程了,至少ZProtect1.49殼是這樣的.

70.檢視/修改 Winlicense/Themida 保護過檔案的水印,可以用“Winlicense/Themida Watermark Manager [1.1]” 這個軟體。

 

更新中。。。

相關文章