ZC: 如何確定被調試程序已經來到了 未加殼的程序中?
ZC: 視頻中是使用判斷集中語言的特征
ZC: 我的方法:上面的方式 + ESP平衡
?
1、第1課
(1)、單步跟蹤(原則:向下的跳轉==>正常F8,向上的跳轉==>F4跳過(或者用F2 達到相同效果))
【930】【05:10】一般來說,很大跨度的跳轉,就跳到OEP了
(2)、ESP定律法【1616】【08:58】
【1733】【09:37】"pushad"之后,設置 硬件訪問WORD斷點
(3)、2次內存鏡像法【2235】【12:23】
【2332】【12:55】找程序段的第1個".rsrc"節 --> F2 --> (shift)F9
【2468】【13:41】在地址"0x00401000"處F2?--> (shift)F9
【2486】【13:45】再單步執行
(4)、一步直達法【2553】【14:10】
該 方法不是上面殼 都可以用的。
一般適用于 絕大部分的UPX殼 和 aspack殼
【2653】【1442】反匯編窗口 --> 右鍵 --> 查找 --> 命令 (Ctrl+F),直接查找"PUSHAD"指令對應的"POPAD"指令
【2750】【15:15】可選框"整個段塊(E)" 我們一般不勾選它
【2802】【15:33】下斷 (F2 和 F4 的方式 都可以),然后接著單步
?
脫殼的兩種方法:【1010】【05:35】
OD插件
方式1【1065】【05:55】
方式2【1093】【06:02】 該方式有時會出現假死的現象,稍等一會就好了
LoadPE【1171】【06:28】:修正鏡像大小-->完整轉存
【1335】【07:23】ImportREC(輸入表重建程序)
?
ZC: 貌似 “Import REConstructor v1.6 最終版” 在 Win7x64 環境下,按鈕“獲取輸入表”得到的信息不太全... 在XP下 就是OK的...
?
2、第2課
基礎脫殼教程2:手脫ASPACK殼
ASPack 2.12 -> Alexey Solodovnikov
工具:PEID和OD
6種方法脫
方法1:單步跟蹤
方法2:ESP定律
方法3:一步直達
【2165】【07:12】這里 直接搜索"popad",搜到的結果不一定是和開頭的"pushad"是配套的,如何判斷哪個"popad"是配套的?看下面有沒有 大跨度的跳轉?(ZC: 貌似不太靠譜啊...作為 備用方法吧...)
方法4:2次內存鏡像
方法5:模擬跟蹤
tc eip<xxxxxx
【3000】【10:00】".aspack"節 包含"SFX","imports","relocations" (ZC: 這是啥意思?它把 導入表 和 重定位表 都打包了?)
【3090】【10:18】"tc eip<00430000",此時 OD的左上角 顯示 "跟蹤"兩個字,說明OD已經在自動跟蹤了,等一會 就會跳到OD的OEP去了。這個方法比較慢 (ZC: 視頻中 沒有等待跟蹤結束... 他說?等一會 就會跳到OD的OEP去了,就算沒有跳到OEP也可以繼續單步跟)
方法6:SFX
【3543】【11:47】OD --> 選項 --> 調試設置 --> SFX -->【3678】【12:15】選擇"塊方式跟蹤真正入口(不準確)",當然 有的要選"字節方式跟蹤真正入口(很慢)" 視具體情況而定 --> OD重載一下 --> OD自動跳到了程序的入口點,來到了真正的OEP
?
【2795】【09:18】方法5 和?方法6 都可以 歸類為 模擬跟蹤法,共同之處 就是讓OD自動去查找程序的OEP,當然也有不同之處
?
3、第3課
基礎脫殼教程3:手脫NSPACK(北斗)
nSPack 1.3 -> North Star/Liu Xing Ping
NsPacK V3.7 -> LiuXingPing *
at GetVersion
?
ESP定律法
單步跟蹤法
【1428】【04:45】2次內存鏡像法。找不到"QQ個性網"的".rsrc"節,找不到".rsrc"節就不能用內存鏡像法了嗎?當然不是。
【1580】【05:15】理解PE知識的都知道,程序運行過程中 是從上向下開始解壓的。我們以前先在".rsrc"節下斷點,然后再在0x00401000處下斷點,它把資源段解壓完畢之后,code段當然也已經解壓完畢。【1700】【05:40】既然沒有找到資源文件,∴我們直接在0x00401000處下斷點 (ZC: 這個有點跳tong啊...不是應該在code段的下面一個節上下斷點,然后第2次再在code段[0x00401000處]上下斷點的嗎?),【1745】【05:48】斷下來的地方是0x003F0273,然后 再來 單步跟。【2020】【06:43】來到殼的出口。【2045】【06:49】來到OEP。
ZC: 這里不理解的點:在"code"節(也就是0x00401000處)下了斷點,為什么斷下來的地方是0x003F0273?難道是 殼把代碼放置到那邊 然后在運行?
? 【2080】【06:55】用模擬跟蹤法的話,輸入"tc eip<00430000"
?
【2386】【07:57】這個殼(程序"nspack 1.3.exe"的殼)比較特殊,我們還可以使用一種比較巧妙的方法。北斗使用VC++寫的,于是可以直接下這個斷點"at GetVersion"
【2590】【08:38】單步一下。(ZC: 來到用戶代碼領空后) 向上拉一下,發現 這就是OEP
ZC:?"nspack 1.3.exe"就是加殼程序,它用自己把自己加了一下殼
【2727】【09:05】這種方法,一般情況下適合于 北斗3.0以前的殼
?
【2915】【09:43】PEiD上面也沒發現的時候,看"EP區段" 這里是"nsp0" 也就是nspack 也就是北斗,它的EP區段顯示為北斗的殼
?
4、第4課
基礎脫殼教程4:手脫FSG殼
FSG 2.0 -> bart/xt
重點為修復
手動、查找IAT
00425000 77DA6BF0 ADVAPI32.RegCloseKey
00425280 7C838DE8 kernel32.LCMapStringA
?
【210】【01:10】注意這里的連續3個跳轉.【258】【01:25】仔細觀察這個無條件跳轉,脫殼多了 經驗多了 就知道 殼作者為了防止被脫殼 不會直接將OEP的地址以明文顯示 一般都是放在寄存器中,我們運行到這里試一下,【350】【01:56】來到OEP
ZC: 這里 他鎖定JMP的講解 還是理由不充分,應該只是懷疑然后驗證一下(大膽假設,小心驗證),然后 得到結論 這個JMP確實很關鍵
?
【550】【03:05】講授“手動、查找IAT”
【760】【04:13】OD命令"d 425210"
ZC: 貌似 如果這里鍵入命令"dd 425210"的話 只會顯示數值,而?"d 425210" 會顯示注釋(里面是API名字) 。錯了,兩者效果差不多,不知有何區別?還是說"d"后面不跟"w"/"c"/"d"等(如"dd"/"dc"/"dw"等)的話,默認就是"dd"?
【870】【04:50】向下拉,拉到什么地方呢,就是下面全是0的位置
【890】【04:56】拉到這個位置(ZC: 他說要拉到"下面全是0的位置",但是 這里明顯不是 他所說的位置啊...)
ZC: 這里 OD中的手動查到的 IAT是這樣的,那么 用LoadPE查看 加了殼的exe的IAT 是什么樣子的呢?用LoadPE查看 用LoadPE脫了殼的exe的IAT 是什么樣子的呢?
【1045】【05:48】importREC1.6中?IAT的大小 的懶惰設置方式:直接填入 16進制的 1000。 當然 輸入 1000 之后,會帶來很多的垃圾指針
【1133】【06:17】"顯示無效函數"(ZC: 注意此時顯示的 無效指針的ptr為0x7FFFFFFF,這樣的指針估計就是垃圾指針 應該不可能有這樣的指針的 而且還是多個指針都是0x7FFFFFFF),直接“剪切指針”
?
【1233】【06:50】以后遇到修復完之后 還是無法運行的時候,我們可以用這種方法去嘗試一下。
?
【1450】【08:05】(ZC: 前面講解了 單步跟蹤法 和 ESP定律法)這里講解另一種方法,暫且稱之為 特殊的ESP定律法(沒有遵循 堆棧平衡。ZC: 這樣也行?)
【1550】【08:35】開始操作
【1600】【08:53】重新來(ZC: ESP: 0x12FFC4-->0x47A1E8-->0x47A208) 【1640】【0906】看此時的堆棧
ZC: pushad/popad 各個寄存器的順序是什么?
【1755】【09:45】ZC: 反匯編窗口-->某條指令處-->右鍵-->斷點--> 可以設置各種斷點 (注意 其中有一個 硬件執行斷點)。ZC: 當有時候 F2/F4 都沒有效果的時候,可以使用這里的設置斷點的方式。
ZC: 有時,上面的設置斷點的方式也不行... 我的情況就是這樣,弄來弄去 感覺像是在單步執行 而且還會跳到系統代碼空間去執行... 很無奈...
ZC: 我這里找到另一種方式,可以行的通:
ZC: "dd 指令所在地址"-->在 數據窗口中設置 硬件執行斷點--> (Shift)F9 (或者直接設置硬件執行斷點 "he 指令所在地址")
5、第5課 (用9中方法來脫殼)
基礎脫殼教程5:手脫PECompact2.X的殼
PECompact 2.x -> Jeremy Collake
1、單步
2、ESP定律
【578】【03:12】介紹幾種 比較特殊的方式,問我為什么要這么做,我也沒法告訴大家...
ZC: 我的理解,下面的幾種 bp api的方式,肯定是研究過 這個殼的源碼,知道這個殼用了這幾個api 。
3、BP VirtualFree 【568】【03:38】
SHIFT+F9,取消斷點
ALT+F9 (這個快捷鍵是 OD-->調試-->返回到用戶代碼(U))
查找 push 8000(特征碼) 【750】【04:10】push?8000 這個 特征碼,我們記住,可以以后脫強殼的時候 我們還會用到 【815】【04:30】在反匯編窗口 直接搜索"push 8000"
運行到這
單步跟
4、BP VirtualFree 【915】【05:05】
兩次SHIFT+F9?
中斷后取消斷點,Alt+F9返回
單步走。
5、【1100】【06:06】
0040A86D > B8 74DE4500 mov eax,qqspirit.0045DE74
bp 0045de74
【1260】【06:59】這里,如果我們單步的話,程序走到"retn",程序就跑起來了,∴ 我們在"retn"的下一行設置斷點?(ZC: 這個說法有點扯淡吧?單步走程序就會跑飛,而F2+Shift&F9+F2 就不會跑飛?在OD里面,直接運行到所選位置,不是一條一條匯編指令執行的?有什么特殊?是OD的問題 還是 程序里面對單步調試做了處理?)(ZC: 根據 “【2330】【12:55】”處的現象,這里使用 類似F4的方式 純粹是 經過N次測試后的結論,而非理論分析的結果,∵ "retn"后面的指令 完全有可能不會執行,從這里看 沒有十足的證據能夠證明程序一定會執行"retn"下面的指令)
6、【1420】【07:52】
bp VirtualAlloc SHIFT+F9運行 【1515】【08:25】
取消斷點
ALT+F9
向下拉,看到JMP。運行到這
7、最后一次異常法; 【1685】【09:20】
取消所有異常。
2次跑飛。
找SE句柄
轉到SE xxxx處 (ZC: 或者 堆棧窗口"SE處理程序"處-->右鍵-->反匯編窗口中跟隨)
F2 --> Shift+F9 --> F2
【2015】【11:11】Ctrl+G "0045DE74",來到的地址就是 “【1260】【06:59】”處
8、兩次內存 【2255】【12:30】ZC: 這里有".rsrc"節
【2325】【12:53】第2次在0x00401000處設置斷點,然后來到的地址也是 “【1260】【06:59】”處
【2330】【12:55】然后我們單步跟 (ZC: 這里又 單步跟 了...然后 轉了幾下 程序跑飛了...)
【2480】【13:45】ZC: 這里,可以看到,2次內存斷點 就隔了幾個指令的位置... 而且 也就是“【1260】【06:59】”處
ZC: 2次內存鏡像法,每次斷下來的指令地址 值得研究一下,看看是否符合 我的理解... (經測試查看 這里斷下來 實際上效果就相當于內存訪問斷點被斷下來)
9、at GetVersion 【2855】【15:50】
ZC: 利用的是 被加殼程序是 VC++程序,里面 一般會調用?GetVersion
6、
7、
8、
?