|
論壇說明 |
歡迎您來到『史萊姆論壇』 ^___^ 您目前正以訪客的身份瀏覽本論壇,訪客所擁有的權限將受到限制,您可以瀏覽本論壇大部份的版區與文章,但您將無法參與任何討論或是使用私人訊息與其他會員交流。若您希望擁有完整的使用權限,請註冊成為我們的一份子,註冊的程序十分簡單、快速,而且最重要的是--註冊是完全免費的! 請點擊這裡:『註冊成為我們的一份子!』 |
|
主題工具 | 顯示模式 |
2006-02-13, 12:57 PM | #1 (permalink) |
榮譽會員
|
實踐ASProtect 2.1x SKE脫殼(街頭籃球客戶端)
實踐ASProtect 2.1x SKE脫殼(街頭籃球客戶端)
純粹的照貓畫虎,高手就不用浪費時間看了。 感謝loveboom的教學《ASPROTECT 2.x 脫殼系列》! 感謝mirrormask的《學習ASProtect 2.1x SKE 脫殼》一文! 感謝shoooo的指教! 工具:OllyICE,Lord-PE,ImportREC. 聲明:這個脫文幾乎就是loveboom的《ASPROTECT 2.x 脫殼系列之一》的翻版。 好,現在切入正題,我盡可能說的詳細一些。有些地方,我還是一知半解,所以可能解釋有誤,還望高手斧正。 首先,因為街頭籃球使用的HackShield系統。HackSield系統的反偵錯功能很強。 所以,如果讓其載入了Hackshield的系統,那麼客戶端主程序FreeStyle.exe在OD下就跑不起來了. 我沒有能力去搞掉hackShield系統,所以我把HackShield的目錄改名,讓其無法載入HackShield. 然後,可以用OD載入Freestyle.exe,忽略所有異常。看看能不能跑起來。 我這裡能夠跑起來,執行後載入HackShield的時候,程序會告知無法載入,等待你點一下確定,然後就結束了。 最後提醒一點:如果載入了HackShield用OD偵錯,好像會引起當機. 不過,這時候程序已經完全從殼裡面解了出來.所以脫殼的目的是可以達到的. 用OD載入Freestyle.exe. 會停在這裡: /////////////////////////////////////////////////////////////////////// 00401000 >/$ 68 01F06E00 push 006EF001 00401005 |. E8 01000000 call 0040100B 0040100A \. C3 retn 0040100B $ C3 retn 0040100C E4 db E4 0040100D 24 db 24 ; CHAR '$' 0040100E 2A db 2A ; CHAR '*' ...後面全是亂七八糟的資料,不用管. ///////////////////////////////////////////////////////////////////////////////// !!!:記住隱藏OD.(用HideOD插件) 脫殼的第一步,就是找到OEP. 說明 找到OEP的方法很多,比如ESP定律,2次記憶體映射斷點等等. 這裡可以使用這個方法. 先忽略除非法訪問記憶體異常外的所有異常.然後按F9(執行程序).應該會有異常出現按shift+F9忽略.注意記住你忽略了多少次異常後程序開始執行.(可以設定忽略所有異常,清空LOG,然後然程序跑,跑起來後,看LOG數一數異常紀錄的個數就能知道有幾次異常)(我這是22次,如果沒數錯~) 然後重新載入.忽略除非法訪問記憶體異常外的所有異常,最後一次異常發生時,給程式碼段下斷點(方法:ALT+M,然後找到freestyle的程式碼段,選後按一下F2),然後shift+F9忽略異常. 這時就停在了OEP了: /////////////////////////////////////////////////////////////////////////// 00626777 . 55 push ebp ; FreeStyl.0046637E 00626778 . 8BEC mov ebp, esp 0062677A . 6A FF push -1 0062677C . 68 18B16500 push 0065B118 00626781 . 68 B0B46200 push 0062B4B0 ; SE 處理程序安裝 00626786 . 64:A1 0000000>mov eax, fs:[0] 0062678C . 50 push eax 0062678D . 64:8925 00000>mov fs:[0], esp 00626794 . 83EC 58 sub esp, 58 00626797 . 53 push ebx 00626798 . 56 push esi 00626799 . 57 push edi 0062679A . 8965 E8 mov [ebp-18], esp 0062679D . FF15 B0206500 call [6520B0] ; kernel32.GetVersion //////////////////////////////////////////////////////////////////////////// 記下OEP備以後用:這裡是00626777. 好了OEP就找到了. 然後就是IAT了. 看到上面的call [6520B0] ;kernel32.GetVersion那麼就去去006520B0,向上看找找以一大堆00結尾在哪裡,在向下看同樣找找零結尾在哪裡.發現IAT從00652000開始到0065247C結束,而且沒有加密. 判斷加密的方法,我是去看程式碼段最後面的一些整齊排列jmp [xxxxxxx]看看有沒有被一定數量的相同call xxxxxxxx(xxxxxxxx一般是同一個數)隔開.如果沒有,8成是沒加密.因為call xxxxxxx就是殼的解密函數. 這個程序沒有。而且IAT位址看起來都沒有問題: ////////////////////////////////////////////////////////////////////////////// 這個就是IAT: 00652000 1B C4 DC 77 83 78 DA 77 F0 6B DA 77 00 00 00 00 能w儀趙餶趙.... 00652010 26 D9 18 6D 00 00 00 00 24 49 37 00 00 00 00 00 &?m....$I7..... 00652020 98 6E EF 77 8A 5A EF 77 D6 E8 EF 77 00 60 EF 77 榥飛奪飛驟飛.`飛 00652030 52 D4 EF 77 90 5B EF 77 97 5D EF 77 49 5E EF 77 R燥w恿飛梋飛I^飛 00652040 7C 8B F0 77 1D 8E F0 77 B3 BF F0 77 2D 6C EF 77 |嬸w庰w晨饂-l飛 00652050 60 B2 F1 77 B8 85 EF 77 33 8C EF 77 FB 5E EF 77 `柴w竻飛3岋w鴞飛 00652060 49 92 EF 77 00 00 00 00 B3 22 30 76 A6 3A 30 76 I掞w....?0v?0v 00652070 66 55 30 76 F3 29 30 76 82 5B 30 76 F8 6F 30 76 fU0v?0v完0v鴒0v 00652080 8E 4D 30 76 2B 47 30 76 00 00 00 00 53 30 82 7C 嶮0v+G0v....S0徠 00652090 A9 26 82 7C FB 2C 82 7C 7C 36 81 7C 3D 04 93 7C ?徠?徠|6亅=搢 006520A0 D4 05 93 7C 0D E0 80 7C 16 1E 80 7C A2 CA 81 7C ?搢.鄝||6亅 006520B0 AB 14 81 7C EE 1E 80 7C 5C E8 81 7C 94 22 82 7C ?亅?|\鑱|?徠 006520C0 E1 EA 81 7C 40 7A 95 7C 5D 99 80 7C E0 C6 80 7C ね亅@z賅]檧|嗥| 006520D0 52 70 82 7C 8B C2 85 7C 84 E5 81 7C 7C 2F 81 7C Rp徠嬄厊勫亅|/亅 006520E0 6E 9C 80 7C 3F FF 81 7C 28 9C 80 7C BD E4 81 7C n渶|?|(渶|戒亅 006520F0 A9 2C 81 7C 64 B6 80 7C F4 97 80 7C AC 92 80 7C ?亅d秬|鱸|瑨| 00652100 86 03 81 7C FD 79 93 7C 59 35 81 7C E6 2B 81 7C ?亅齳搢Y5亅?亅 00652110 43 99 80 7C 2A E8 81 7C 0E 18 80 7C 19 90 83 7C C檧|*鑱||悆| 00652120 D7 EF 80 7C EC E9 80 7C 66 EA 80 7C 4E A3 80 7C 罪|扉|f陘|N└ 00652130 93 D2 80 7C 94 97 80 7C 42 24 80 7C 57 B3 80 7C 撘|敆|B$|W硛| 00652140 C1 C9 80 7C 79 E0 81 7C 77 9B 80 7C 8D 3A 86 7C 遼|y鄟|w泙|?兩 00652150 B7 47 86 7C 63 4C 81 7C A1 97 83 7C AD 9C 80 7C 褉兩cL亅t億瓬| 00652160 A1 9F 80 7C 8A 18 93 7C ED 10 92 7C 05 10 92 7C ||?搢?抾抾 00652170 90 72 DD 00 C4 2F 88 7C 66 AA 80 7C 7B 97 80 7C 恟??坾f獉|{檳| 00652180 5C 9B 85 7C 8D 2C 81 7C 29 B5 80 7C 9F 0F 81 7C \泤|?亅)祤|?亅 00652190 31 03 93 7C 8F 0C 81 7C 8D B7 80 7C 6C 94 80 7C 1搢?亅嵎|l攢| 006521A0 24 1A 80 7C 76 09 81 7C C7 A0 80 7C 51 28 81 7C $|v.亅莀|Q(亅 006521B0 FC B7 80 7C B2 AC 80 7C ED CB 81 7C 17 A4 80 7C ?T|鉑|硭亅C| 006521C0 DA 56 82 7C 6B 17 80 7C 72 17 81 7C 50 F8 81 7C 赩徠k|r亅P鴣| 006521D0 C0 9F 80 7C ED 70 83 7C 7E D4 80 7C E3 12 81 7C 罒|韕億~讋|?亅 006521E0 53 C1 81 7C AE 94 83 7C 80 A4 80 7C B9 8C 83 7C S羶|當億C|箤億 006521F0 58 CD 80 7C CB D8 81 7C 57 BB 80 7C C4 CE 80 7C X蛝|素亅W粈|奈| 00652200 2B 2E 83 7C 29 9F 80 7C 81 9A 80 7C 14 9B 80 7C +.億)焵|仛|泙| 00652210 29 29 81 7C 10 11 81 7C 6A 48 81 7C 78 2C 81 7C ))亅亅jH亅x,亅 00652220 23 CC 81 7C 5F 48 81 7C 19 62 82 7C B3 9E 80 7C #虂|_H亅b徠| 00652230 2F 08 81 7C 37 97 80 7C F5 9B 80 7C 50 97 80 7C /亅7檳|鯖|P檳| 00652240 A9 CC 80 7C 3F DC 81 7C 8A 2B 86 7C 69 10 81 7C ┤|?職|?兩i亅 00652250 CF C6 80 7C A6 0D 81 7C ED 09 93 7C 49 AA 80 7C 掀|?亅?搢I獉| 00652260 0F 2B 81 7C 40 03 93 7C 00 3C 86 7C 00 00 00 00 +亅@搢.<兩.... 00652270 60 9A 00 10 30 9B 00 10 50 96 00 10 90 96 00 10 `?0?P?意. 00652280 80 91 00 10 F0 93 00 10 C0 96 00 10 80 99 00 10 ?饟.樽.? 00652290 20 99 00 10 A0 3A 00 10 A0 3A 00 10 A0 90 00 10 ??.?._?. 006522A0 10 93 00 10 40 92 00 10 00 40 00 10 E0 38 00 10 ?@?.@.?. 006522B0 B0 94 00 10 A0 91 00 10 10 94 00 10 50 9A 00 10 皵._?.?P? 006522C0 90 9A 00 10 B0 9A 00 10 D0 99 00 10 40 97 00 10 誤.皻.袡.@? 006522D0 80 95 00 10 70 96 00 10 20 97 00 10 10 9B 00 10 ?p? ?? 006522E0 F0 9A 00 10 A0 40 00 10 70 3B 00 10 00 10 00 10 饸._@.p;... 006522F0 F0 10 00 10 40 10 00 10 B0 11 00 10 80 3F 00 10 ?.@.?.?. 00652300 D0 3A 00 10 A0 39 00 10 A0 96 00 10 F0 96 00 10 ?.?._?.饢. 00652310 C0 3B 00 10 A0 3E 00 10 30 3C 00 10 80 3E 00 10 ?.?.0<.>. 00652320 40 40 00 10 40 40 00 10 40 40 00 10 60 3E 00 10 @@.@@.@@.`>. 00652330 20 38 00 10 D0 3A 00 10 D0 3A 00 10 00 3B 00 10 8.?.?..;. 00652340 90 38 00 10 10 9A 00 10 30 9A 00 10 00 00 00 00 ?.?0?.... 00652350 20 49 0F 77 C2 4B 0F 77 50 48 0F 77 95 D2 11 77 Iw翱wPHw曇w 00652360 D9 66 0F 77 C0 48 0F 77 3B 4C 0F 77 A8 4C 0F 77 賓w繈w;Lw↙w 00652370 C3 CA 11 77 55 4C 0F 77 00 00 00 00 85 CB D1 77 檬wULw....吽褀 00652380 9A F3 D2 77 60 DA D1 77 33 B9 D1 77 AE B6 D1 77 沔襴`諮w3寡w褀 00652390 1B C0 D1 77 9D 8F D1 77 EA 04 D5 77 AD A8 D1 77 姥w琶褀?誻褀 006523A0 C2 D7 D1 77 DA C6 D3 77 09 B6 D1 77 1D B6 D1 77 倫褀諂觲.堆w堆w 006523B0 F6 8B D1 77 6C C9 D1 77 B8 96 D1 77 24 13 D2 77 鰦褀l裳w笘褀$襴 006523C0 3E 0B D2 77 0D D6 D1 77 F9 D7 D1 77 5D 94 D1 77 > 襴.盅w褀]斞w 006523D0 6C BF D1 77 5E 02 D2 77 A4 D8 D1 77 E6 37 D2 77 l墾w^襴デ褀?襴 006523E0 EA DA D1 77 EE D4 D1 77 41 BD D1 77 C6 B5 D1 77 賁褀鈐褀A窖w頻褀 006523F0 11 12 D2 77 00 00 00 00 FF 19 BD 77 50 1A BD 77 襴....絯P絯 00652400 BA 18 BD 77 00 00 00 00 5B 4E B1 76 00 00 00 00 絯....[N眝.... 00652410 66 2B A2 71 41 3F A2 71 D4 4F A2 71 00 00 00 00 f++AA?設設.... 00652420 80 E8 D3 6D 00 00 00 00 10 AA 11 21 70 A0 11 21 櫨m....!pp! 00652430 20 A6 12 21 20 A2 11 21 30 A1 11 21 60 A8 11 21 ! !00!``! 00652440 A0 A5 11 21 00 A5 11 21 90 B5 11 21 70 34 11 21 __!..!惕!p4! 00652450 60 AC 11 21 70 AE 11 21 00 AB 11 21 A0 A4 11 21 ``!pp!..!__! 00652460 C0 36 11 21 00 00 00 00 36 EE 9A 76 37 2A 9B 76 !....6巽v7*泇 00652470 C3 FA 9A 76 BA 61 A0 76 00 00 00 00 00 00 00 00 銘歷篴_v........ ///////////////////////////////////////////////////////////////////////////////// 好了,知道了IAT從00652000開了,大小為:047C 紀錄下來。 現在到了脫殼最困難麻煩的地方了. 大家知道vc的程序,一般OEP後面就是GetVersion後接著就是GetStartInfo.我們看看這個程序的OEP處了程式碼. /////////////////////////////////////////////////////////////////////////////////////////////// 00626777 . 55 push ebp ; FreeStyl.0046637E 00626778 . 8BEC mov ebp, esp 0062677A . 6A FF push -1 0062677C . 68 18B16500 push 0065B118 00626781 . 68 B0B46200 push 0062B4B0 ; SE 處理程序安裝 00626786 . 64:A1 0000000>mov eax, fs:[0] 0062678C . 50 push eax 0062678D . 64:8925 00000>mov fs:[0], esp 00626794 . 83EC 58 sub esp, 58 00626797 . 53 push ebx 00626798 . 56 push esi 00626799 . 57 push edi 0062679A . 8965 E8 mov [ebp-18], esp 0062679D . FF15 B0206500 call [6520B0] ; kernel32.GetVersion 006267A3 . 33D2 xor edx, edx 006267A5 . 8AD4 mov dl, ah 006267A7 . 8915 8CA86E00 mov [6EA88C], edx 006267AD . 8BC8 mov ecx, eax 006267AF . 81E1 FF000000 and ecx, 0FF 006267B5 . 890D 88A86E00 mov [6EA888], ecx 006267BB . C1E1 08 shl ecx, 8 006267BE . 03CA add ecx, edx 006267C0 . 890D 84A86E00 mov [6EA884], ecx 006267C6 . C1E8 10 shr eax, 10 006267C9 . A3 80A86E00 mov [6EA880], eax 006267CE . 6A 01 push 1 006267D0 . E8 3F750000 call 0062DD14 006267D5 . 59 pop ecx 006267D6 . 85C0 test eax, eax 006267D8 . 75 08 jnz short 006267E2 006267DA . 6A 1C push 1C 006267DC . E8 C3000000 call 006268A4 006267E1 . 59 pop ecx 006267E2 > E8 E53E0000 call 0062A6CC 006267E7 . 85C0 test eax, eax 006267E9 . 75 08 jnz short 006267F3 006267EB . 6A 10 push 10 006267ED . E8 B2000000 call 006268A4 006267F2 . 59 pop ecx 006267F3 > 33F6 xor esi, esi 006267F5 . 8975 FC mov [ebp-4], esi 006267F8 . E8 DE6B0000 call 0062D3DB 006267FD . E8 FE979B00 call 00FE0000 ;!!!!!!!!!到殼裡面去了 00626802 . 91 xchg eax, ecx 00626803 . A3 D4CD6E00 mov [6ECDD4], eax 00626808 . E8 60720000 call 0062DA6D 0062680D . A3 70A86E00 mov [6EA870], eax 00626812 . E8 09700000 call 0062D820 00626817 . E8 4B6F0000 call 0062D767 0062681C . E8 0E040000 call 00626C2F 00626821 . 8975 D0 mov [ebp-30], esi 00626824 . 8D45 A4 lea eax, [ebp-5C] 00626827 . 50 push eax 00626828 . E8 D3979B00 call 00FE0000 ;!!!!!!!!到殼裡面去了 0062682D . C7 E8 DC 6E 0>ascii "氰體",0 00626832 00 db 00 00626833 89 db 89 00626834 45 db 45 ; CHAR 'E' 00626835 9C db 9C 後面又是亂七八糟的資料,不用管 /////////////////////////////////////////////////////////////////////////////////////////////// 看到了GetVersion了,但是GetStartInfo在哪呢呢沒有~ 但是你應改發現有兩個call 00FE0000. 給據loveboom的教導,知道這是殼把原來CALL API改成了CALL xxxxxxxx,這個call xxxxxxxx會到殼程式碼裡面. (不同電腦上面好像xxxxxxxx都不一樣).我這裡是00FE0000. 現在就是要修復成CALL 正確的API.怎麼才能得到這個正確的位址呢.當然只有跟進去看. 不過由於被改了的地方實在太多,人工修復幾乎不可能.所以必須寫個程序來修復. 這就是Patch. 下面大概講一下patch的原理.後面會將詳細的操作. patch的方法很多,下面是loveboom提供的方法. 先來整理一下思法,我們要把call xxxxxxxx改稱正確的call API. 就必須有一張表.裡面一一對應記錄著call xxxxxxxx的位址->正確的API的位址. 有了這個表,我們就可以快速的把所有call xxxxxxxx改稱正確的call api了. 所以,第一次patch就是為了得到這張表. 怎麼得到呢,對於ASPr殼,當進入call xxxxxxxx後,殼會把這個call xxxxxxxx改成正確的call API然後跳回原地,就地進入api. 當然這中間有複雜的算法和繁多的花指令.所以想要逆向得到這個正確的API太麻煩.可以借用殼的程式碼,在它解出來正確的位址的時候我們把它截取,儲存下來. patch的準備工作: 先重新載入freestyle.exe 先來到OEP,找一個call xxxxxxxx(這裡是call 00FE0000) 因為aspr要把call xxxxxxxx改成正確的所以我們在上面下記憶體寫入斷點(這裡是在006267FD上面下記憶體寫入斷點). F9執行 斷在了這裡: /////////////////////////////////////////////////// 00DE5C9B 57 push edi 00DE5C9C 6A 00 push 0 00DE5C9E 8D4D E0 lea ecx, [ebp-20] 00DE5CA1 8B45 F4 mov eax, [ebp-C] 00DE5CA4 8B40 3C mov eax, [eax+3C] 00DE5CA7 8B55 FC mov edx, [ebp-4] 00DE5CAA E8 D1130000 call 00DE7080 ;********** 00DE5CAF 8945 FC mov [ebp-4], eax 00DE5CB2 8B45 E0 mov eax, [ebp-20] 00DE5CB5 8B00 mov eax, [eax] 00DE5CB7 E8 D0E6FFFF call 00DE438C 00DE5CBC 8BD0 mov edx, eax 00DE5CBE 0255 DF add dl, [ebp-21] 00DE5CC1 8B4D FC mov ecx, [ebp-4] 00DE5CC4 8B45 F4 mov eax, [ebp-C] 00DE5CC7 E8 80040000 call 00DE614C 00DE5CCC 8945 FC mov [ebp-4], eax 00DE5CCF 8B45 F4 mov eax, [ebp-C] 00DE5CD2 8B40 24 mov eax, [eax+24] 00DE5CD5 8B55 F4 mov edx, [ebp-C] 00DE5CD8 0382 E0000000 add eax, [edx+E0] 00DE5CDE 0145 1C add [ebp+1C], eax 00DE5CE1 8B45 FC mov eax, [ebp-4] 00DE5CE4 2B45 1C sub eax, [ebp+1C] 00DE5CE7 83E8 05 sub eax, 5 00DE5CEA 8B55 1C mov edx, [ebp+1C] 00DE5CED 42 inc edx 00DE5CEE 8902 mov [edx], eax ;斷在了這裡!!!! 00DE5CF0 EB 01 jmp short 00DE5CF3 00DE5CF2 E8 8B45F883 call 84D6A282 /////////////////////////////////////////////////// 向上看,找到: ////////////////////////////////////////////////////// 00DE5C9E 8D4D E0 lea ecx, [ebp-20] 00DE5CA1 8B45 F4 mov eax, [ebp-C] 00DE5CA4 8B40 3C mov eax, [eax+3C] 00DE5CA7 8B55 FC mov edx, [ebp-4] 00DE5CAA E8 D1130000 call 00DE7080 ////////////////////////////////////////////////////// 跟隨進入call 00DE7080 ///////////////////////////////////////////////////// 00DE7080 55 push ebp 00DE7081 8BEC mov ebp, esp 00DE7083 83C4 E4 add esp, -1C 00DE7086 53 push ebx 00DE7087 56 push esi 00DE7088 57 push edi 00DE7089 894D F4 mov [ebp-C], ecx 00DE708C 8955 F8 mov [ebp-8], edx 00DE708F 8945 FC mov [ebp-4], eax 00DE7092 33C0 xor eax, eax 00DE7094 8945 F0 mov [ebp-10], eax 00DE7097 B8 00070000 mov eax, 700 00DE709C E8 A3B4FDFF call 00DC2544 ;********** 00DE70A1 8945 E4 mov [ebp-1C], eax ////////////////////////////////////////////////////// 再跟隨進入call 00DC2544 /////////////////////////////////////////////////////// 00DC2544 85C0 test eax, eax 00DC2546 74 0A je short 00DC2552 00DC2548 FF15 1890DE00 call [DE9018] ;***!!!!**** 00DC254E 09C0 or eax, eax 00DC2550 74 01 je short 00DC2553 00DC2552 C3 retn ////////////////////////////////////////////////////// 看見 call [DE9018]了嗎吗為什麼要跟這麼深,因為修改這裡的程式碼不會被殼查出來. 這個地方的call [DE9018]我們就能把它改成其他的call從而改變程序的流程. 紀錄call [DE9018]的位址,這裡是: 00DC2548 FF15 1890DE00 call [DE9018] 這個是第一次patch的操作: 重新載入,斷GetModuleHandleA(用硬體斷點).當第二次斷下後.清除硬體斷點.F8一路返回,遇見jmp就F4到下一行程式碼.一會就能看見,如下的程式碼: //////////////////////////////////////// 00DF15C1 61 popad 00DF15C2 75 08 jnz short 00DF15CC 00DF15C4 B8 01000000 mov eax, 1 00DF15C9 C2 0C00 retn 0C 00DF15CC 68 DC89DE00 push 0DE89DC 00DF15D1 C3 retn /////////////////////////////////////// retn執行以後,到了 /////////////////////////////////////////// 00DE89DC 55 push ebp ; 殼的OEP 00DE89DD 8BEC mov ebp, esp 00DE89DF 83C4 B4 add esp, -4C 00DE89E2 B8 D487DE00 mov eax, 0DE87D4 00DE89E7 E8 50CCFDFF call 00DC563C 00DE89EC E8 DBAAFDFF call 00DC34CC ////////////////////////////////////////// 停在了殼的OEP處,搜尋如下指令: MOV [EBP],EAX PUSH 0A 會找到一處: 00DE5F7B 8945 00 mov [ebp], eax ;在這裡下硬體執行斷點,斷在這裡.EIP現在指向這裡 00DE5F7E 6A 0A push 0A 00DE5F80 E8 8FCEFEFF call 00DD2E14 00DE5F85 8BC8 mov ecx, eax 00DE5F87 038B E4000000 add ecx, [ebx+E4] 然後F9執行,會斷在00DE5F7B mov [ebp], eax; (不過有時候斷不下來,直接就跑飛了,下F2斷點反而能斷下了,不知道是什麼原因,哪位牛人能解釋一下.) 斷下了後,就開始第一次patch了: 為了方便寫程序,就近選個地方寫程式碼,當然要先儲存原來的程式碼,不過OD有復原修改的功能,就不用專門儲存了. 用插件申請一塊記憶體,作為儲存上面提到的那張表的空間,有這種功能的插件很多.HideOD也有.我申請到的是01020000 ///////////////////////////////////////////////// 00DE5F7B EB 43 jmp 00DE5FC0 ; 注意這裡被修改指向我們自己寫的程式碼.EIP還是指向這裡 00DE5F7D 90 nop 00DE5F7E 6A 0A push 0A 00DE5F80 E8 8FCEFEFF call 00DD2E14 00DE5F85 8BC8 mov ecx, eax 00DE5F87 038B E4000000 add ecx, [ebx+E4] 00DE5F8D 8BD6 mov edx, esi 00DE5F8F 8BC3 mov eax, ebx 00DE5F91 E8 9EE5FFFF call 00DE4534 00DE5F96 FF0C24 dec dword ptr [esp] 00DE5F99 03B3 E4000000 add esi, [ebx+E4] 00DE5F9F 833C24 00 cmp dword ptr [esp], 0 00DE5FA3 ^ 0F87 55FEFFFF ja 00DE5DFE 00DE5FA9 53 push ebx ;改完,寫完程式碼後這裡下F2斷點 00DE5FAA E8 5D000000 call 00DE600C 00DE5FAF 0183 EC000000 add [ebx+EC], eax 00DE5FB5 B0 01 mov al, 1 00DE5FB7 83C4 24 add esp, 24 00DE5FBA 5D pop ebp 00DE5FBB 5F pop edi 00DE5FBC 5E pop esi 00DE5FBD 5B pop ebx 00DE5FBE C3 retn 00DE5FBF 90 nop 00DE5FC0 53 push ebx ;選的這裡,最近的地方. 開這開始寫 00DE5FC1 51 push ecx 00DE5FC2 B9 00415100 mov ecx, 01020000 ;這裡數位,填寫你想儲存這個表的位址.我申請到的位址是01020000,我就儲存這 00DE5FC7 8339 00 cmp dword ptr [ecx], 0 00DE5FCA 75 06 jnz short 00DE5FD2 00DE5FCC C701 10415100 mov dword ptr [ecx], 01020010;這裡填寫儲存位址+10h,這裡就是01020000h+10h=01020010h 00DE5FD2 8B19 mov ebx, [ecx] 00DE5FD4 4D dec ebp 00DE5FD5 892B mov [ebx], ebp 00DE5FD7 83C3 04 add ebx, 4 00DE5FDA 8919 mov [ecx], ebx 00DE5FDC 45 inc ebp 00DE5FDD 59 pop ecx 00DE5FDE 5B pop ebx 00DE5FDF 8945 00 mov [ebp], eax 00DE5FE2 ^ EB 9A jmp short 00DE5F7E ;這裡就寫完了 /////////////////////////////////////////////////// 寫完程式碼,下好斷點.F9執行.停在了 00DE5FA9 53 push ebx 這時把儲存的資料複製一份儲存備用.我從01020000複製的資料如下: /////////////////////////////////////////////////////////////////////////////////////////////// 3C 02 04 01 00 00 00 00 00 00 00 00 00 00 00 00 89 8A 48 00 D0 D1 48 00 8A D3 48 00 67 1F 49 00 06 20 49 00 20 20 49 00 39 20 49 00 75 20 49 00 E3 20 49 00 92 21 49 00 C4 24 49 00 3E EA 4B 00 59 EB 4B 00 E0 C0 4E 00 87 16 4F 00 C9 46 55 00 7A 47 55 00 88 A0 55 00 3D 16 56 00 A8 16 56 00 C7 16 56 00 E7 16 56 00 98 2A 56 00 BE C6 56 00 D2 C6 56 00 E2 C6 56 00 E2 C7 56 00 57 C8 56 00 62 C8 56 00 E0 C8 56 00 F8 C8 56 00 0B C9 56 00 B6 CA 56 00 BB DA 58 00 BB DB 58 00 07 38 59 00 73 38 59 00 9A F7 59 00 F5 F7 59 00 2D F8 59 00 9D BF 5A 00 FC C3 5A 00 42 D3 5B 00 61 D3 5B 00 30 8B 5F 00 36 8B 5F 00 3C 8B 5F 00 F2 F4 60 00 BC 06 61 00 64 0F 61 00 6B 0F 61 00 79 94 61 00 02 9A 61 00 2E 9B 61 00 88 9B 61 00 B3 9B 61 00 19 9C 61 00 44 9C 61 00 51 9C 61 00 6A 9C 61 00 95 9C 61 00 A2 9C 61 00 AF 9C 61 00 D6 9C 61 00 E4 9D 61 00 F1 9D 61 00 FE 9D 61 00 54 3D 62 00 EF 3F 62 00 2E 63 62 00 58 63 62 00 FD 67 62 00 28 68 62 00 4B 68 62 00 93 6C 62 00 9A 6C 62 00 5F 73 62 00 73 73 62 00 F6 73 62 00 1A 74 62 00 30 74 62 00 74 74 62 00 5C 79 62 00 91 79 62 00 A3 79 62 00 15 7B 62 00 26 83 62 00 BC 83 62 00 40 84 62 00 C3 8A 62 00 0B A7 62 00 78 A7 62 00 0E C6 62 00 84 C7 62 00 99 C7 62 00 24 C8 62 00 90 CD 62 00 F5 CD 62 00 39 D4 62 00 E4 D4 62 00 47 D5 62 00 55 D5 62 00 8C D5 62 00 43 D8 62 00 8C DB 62 00 A9 DB 62 00 20 DC 62 00 80 DC 62 00 17 DE 62 00 ED DE 62 00 F4 DE 62 00 15 09 63 00 5E 09 63 00 E0 13 63 00 FC 13 63 00 14 14 63 00 F5 18 63 00 74 19 63 00 A7 1A 63 00 C7 1C 63 00 1B 1E 63 00 4F 1E 63 00 3F 27 63 00 86 39 63 00 7E 3C 63 00 94 3C 63 00 D5 3D 63 00 39 40 63 00 2D 41 63 00 D3 41 63 00 7E 48 63 00 AB 4E 63 00 D9 4F 63 00 6A 55 63 00 50 58 63 00 62 8F 63 00 83 8F 63 00 93 8F 63 00 AE 8F 63 00 00 00 00 00 /////////////////////////////////////////////////////////////////////////////////////////////// 然後復原所有修改,F9繼續執行.來到OEP 如果不幸跑飛,也沒有關係.反正表已經拿到了. 重新載入freestyle.exe,來到OEP處,停在這裡. 第二次patch準備: 要得到兩行程式碼及其位址的訊息. 第一個就是上面提到的: 00DC2548 FF15 1890DE00 call [DE9018] 這個位址有可能變化,但是幾率不大. 第二個有點煩: 用了多態技術,一旦重新加所在位址就會變.不過還好,變化的範圍不是很大. 第二個程式碼是: 00FF00BA 9D popfd 00FF00BB 5C pop esp 00FF00BC FF6424 FC JMP DWORD PTR SS:[ESP-4] 不能直接搜尋,因為用了多態技術,可能搜不到. 第一次找這個指令可以這樣(以後就直接到附近找,注意識別花指令): 回憶在call xxxxxxxx上,下記憶體寫入斷點那裡 我們斷在了(不記得了就去看看前面): ////////////////////////////////////////////// 00DE5C9B 57 push edi 00DE5C9C 6A 00 push 0 00DE5C9E 8D4D E0 lea ecx, [ebp-20] 00DE5CA1 8B45 F4 mov eax, [ebp-C] 00DE5CA4 8B40 3C mov eax, [eax+3C] 00DE5CA7 8B55 FC mov edx, [ebp-4] 00DE5CAA E8 D1130000 call 00DE7080 ;********** 00DE5CAF 8945 FC mov [ebp-4], eax 00DE5CB2 8B45 E0 mov eax, [ebp-20] 00DE5CB5 8B00 mov eax, [eax] 00DE5CB7 E8 D0E6FFFF call 00DE438C 00DE5CBC 8BD0 mov edx, eax 00DE5CBE 0255 DF add dl, [ebp-21] 00DE5CC1 8B4D FC mov ecx, [ebp-4] 00DE5CC4 8B45 F4 mov eax, [ebp-C] 00DE5CC7 E8 80040000 call 00DE614C 00DE5CCC 8945 FC mov [ebp-4], eax 00DE5CCF 8B45 F4 mov eax, [ebp-C] 00DE5CD2 8B40 24 mov eax, [eax+24] 00DE5CD5 8B55 F4 mov edx, [ebp-C] 00DE5CD8 0382 E0000000 add eax, [edx+E0] 00DE5CDE 0145 1C add [ebp+1C], eax 00DE5CE1 8B45 FC mov eax, [ebp-4] 00DE5CE4 2B45 1C sub eax, [ebp+1C] 00DE5CE7 83E8 05 sub eax, 5 00DE5CEA 8B55 1C mov edx, [ebp+1C] 00DE5CED 42 inc edx 00DE5CEE 8902 mov [edx], eax ;斷在了這裡!!!! 00DE5CF0 EB 01 jmp short 00DE5CF3 00DE5CF2 E8 8B45F883 call 84D6A282 ////////////////////////////////////////////// 這個時候用條件跟蹤,當遇到POPFD的時候暫停.就能跟到 //////////////////////////////////////////// 00FF00BA 9D popfd 00FF00BB 5C pop esp 00FF00BC FF6424 FC JMP DWORD PTR SS:[ESP-4] ;紀錄這行程式碼 //////////////////////////////////////// 下面就是第二次patch: 重新載入,來到OEP ,先確定上面提到的兩行程式碼的訊息: 直接去00DC2548發現程式碼沒有變: 00DC2548 FF15 1890DE00 call [DE9018] 然後去00FF00BC,應該已經變了. 果然JMP [ESP-4]變到了00FF00AE; 訊息已經足夠了. 開始寫程式碼. 找程式碼段後面的空白處寫patch程式碼,現在EIP指向OEP /////////////////////////////////////////////////////////////////////////////////////// 00651100 60 pushad 00651101 B9 10000201 mov ecx, 1020010 ;這裡的數填那張表儲存的位址+10h 00651106 8B19 mov ebx, [ecx] 00651108 83FB 00 cmp ebx, 0 0065110B 74 15 je short 00651122 0065110D FFE3 jmp ebx 0065110F 8B15 08000201 mov edx, [1020008] 00651115 66:C703 FF15 mov word ptr [ebx], 15FF 0065111A 8953 02 mov [ebx+2], edx 0065111D 83C1 04 add ecx, 4 00651120 ^ EB E4 jmp short 00651106 00651122 33C0 xor eax, eax 00651124 B0 E8 mov al, 0E8 00651126 BF 00104000 mov edi, <模組入口點> 0065112B B9 00102500 mov ecx, 251000 ;這裡填程式碼段的大小 00651130 F2:AE repne scas byte ptr es:[edi] 00651132 83F9 00 cmp ecx, 0 00651135 74 3C je short 00651173 00651137 8B1F mov ebx, [edi] 00651139 8D5C3B 04 lea ebx, [ebx+edi+4] 0065113D 81FB 00104000 cmp ebx, <模組入口點> 00651143 ^ 72 EB jb short 00651130 00651145 81FB 02106600 cmp ebx, 00661002 ;這裡填程式碼段結束的位址 0065114B ^ 77 E3 ja short 00651130 0065114D 66:813B FF15 cmp word ptr [ebx], 15FF 00651152 ^ 75 DC jnz short 00651130 00651154 817B 02 00206>cmp dword ptr [ebx+2], 00652000 ;IAT的起始位址 0065115B ^ 72 D3 jb short 00651130 0065115D 817B 02 78246>cmp dword ptr [ebx+2], 00652478 ;IAT的結束位址-4 00651164 ^ 77 CA ja short 00651130 00651166 66:C703 FF25 mov word ptr [ebx], 25FF 0065116B 83C7 04 add edi, 4 0065116E 83E9 04 sub ecx, 4 00651171 ^ EB BD jmp short 00651130 00651173 61 popad ....... 00651178 dd 83116500 ;這裡的數位就是下面函數的第一句指令的位址(小頭順序) ........ 00651180 90 nop 00651181 90 nop 00651182 90 nop 00651183 60 pushad 00651184 8BC2 mov eax, edx 00651186 B9 80040000 mov ecx, 480 ;IAT的大小+4 0065118B BF 00206500 mov edi, 00652000 IAT的起始位址 00651190 F2:AF repne scas dword ptr es:[edi] 00651192 83EF 04 sub edi, 4 00651195 893D 08000201 mov [1020008], edi;儲存表的位址+8 0065119B 61 popad 0065119C FF15 1890DE00 call [DE9018] ;剛才00DC2548 FF15 1890DE00 call [DE9018] 中被call尋址的位址 006511A2 C3 retn 006511A3 90 nop ///////////////////////////////////////////////////////////////////////////////////// 這些patch程序都是loveboom所寫,根據需要修改相應的數值,如果不清楚有些數是怎麼來的,可以去看看上面.和去看看loveboom的文章. 當然,問問別人是最快的解決方式. 然後: 把上面提到的 00DC2548 FF15 1890DE00 call [DE9018] 程式碼改成: 00DC2548 FF15 1890DE00 call [651178] 就是讓他進入我們的patch程式碼的第二個函數。 寫一段ODScript: //////////////////////////////////////////////////////////////////////// //fixed aspr 2.x var addr start: run l1: cmp eip,00FF00AE ;這裡的數位是上面提到的jmp [esp-4]的位址,這裡是00ff00AE jne l2 mov addr,esp sub addr,4 mov [addr],0065110F 這個數位是上面patch2程式碼中jmp ebx後面那句的位址,這裡是 jmp start l2: ret ///////////////////////////////////////////////////////////////////////// 儲存成OD指令碼. 然後把EIP從哦OEP改向我們patch程式碼的第一句,這裡是: 00651100 60 pushad 然後要在上面提到的jmp [esp-4]的位址,這裡是00ff00AE上面下硬體執行斷點。 其次,在patch結束句,這裡是 00651173 61 popad上面 下F2斷點。 最後執行指令碼。等待一段時間,指令碼執行完畢後,清除掉所有的修改。 dump,修復IAT. 就大功告成了。 PS: 我從看教學到脫殼成功一共用了30小時的時間,分4天。 前幾個小時,都是學習PE文件。通過這次脫殼,讓我對PE文件有了比較深的認識。原來都是一知半解。 脫殼對我等菜鳥來說是個很艱苦的工程,關鍵要有毅力和耐心。 現在目標是繞過載入HackShield. |
__________________ |
|
送花文章: 3,
|