天草脱壳视频学习笔记
天草殼世界學習筆記:
1.OD的查找支持模糊查找 ?? 比如 要查找 E82091FBFFA1B8? 可模糊查找:E8??91FBFF??B8
2.OD的插件idaficator 可以支持回滾 就是記錄你的操作記錄往回走 相當于一個跳轉或者CALL以后 可以跳回去看? 鼠標左鍵 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]” 這個軟件。
更新中。。。
轉載于:https://blog.51cto.com/whatday/1382370
總結
以上是生活随笔為你收集整理的天草脱壳视频学习笔记的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Struts2核心工作原理解析
- 下一篇: SVN钩子--hook