SoftDefender主程式脫殼

看雪資料發表於2015-11-15

呵呵,昨天朋友過生日,玩的盡興,今天早上6點才回來 :P ,休息好了,把關於SoftDefender 主程式脫殼手記附上

借Fly兄的格式用用,Fly兄的破文生成器能不能給我一份??
PS:這個殼實際是國產軟體,我最近才知道的……

SoftDefender V1.12 DEMO 主程式脫殼
  
  
  
下載地址:  http://www.softdefender.com/setup.exe  
應用平臺:  Win 98/ME/NT/2000/XP/2003  
軟體大小:  600 K  

【軟體簡介】:Soft Defender is a powerful tool securing products against crackers.It was designed with ease of use and high speed as a priority without sacrificing high levels of protection.With Soft Defender, your application can have anticrack, antidebug, antidisassemble, antidump, anti-apihook, file integrity checking functions in seconds. It requires no source code editing or your registration algorithm changing. In addition, Soft Defender is a perfect exe file compressor, which can reduce the file size of 32-bit Windows programs by as much as 50%. 

【作者宣告】:只是感興趣,沒有其他目的。失誤之處敬請諸位大俠賜教! 

【除錯環境】:WinXP、Ollydbg1.09、PEiD、LordPE、ImportREC 1.6.0 Final 

―――――――――――――――――――――――――――――――――  
【脫殼過程】: 

廢話不說,直接進入主題,我這裡的A和B都是必須的喲

          ★★★★★★★★★★★★ 
★★★★★ A、對於父程式的跟蹤分析★★★★★ 
          ★★★★★★★★★★★★ 

用OD載入SoftDefender.exe,隱藏好IsDebuggerPresent標記,斷在入口點:
<ModuleEn> /74 07           je short SoftDefe.004D1009      ;這實際就是個Jmp嘛~,這個殼裡大量用到這樣的變形Jmp
004D1002   |75 05           jnz short SoftDefe.004D1009      ;
004D1004   |1932            sbb dword ptr ds:[edx], esi
004D1006   |67:E8 E8741F75  call 756C84F4                            ; Superfluous prefix
004D100C    1D E8683944     sbb eax, 443968E8

直接下斷 bp ZwQueryInformationProcess (嘿嘿,這個特殊,殼不檢查前5個位元組),F9,OD斷下,這個我們不需要,再F9,OD又斷下
ZwQueryIn>/$  B8 9A000000   mov eax, 9A                ;斷在這
77F7603A  |.  BA 0003FE7F   mov edx, 7FFE0300
77F7603F  |.  FFD2          call edx
77F76041  .  C2 1400       retn 14

執行到返回,再F8到這
004D8FAE    85C0            test eaxeax          ;返回到這,F8
004D8FB0    75 08           jnz short SoftDefe.004D8FBA    ;這裡一定要跳,在004D8FBA用New Origin here,或者用Fly兄的修改標誌暫存器也可以,最好的方法自然是前面一步修改eax的值為非0
004D8FB2    8B4424 08       mov eaxdword ptr ss:[esp+8]
004D8FB6    85C0            test eaxeax
004D8FB8    75 0E           jnz short SoftDefe.004D8FC8
004D8FBA    E8 4BFFFFFF     call SoftDefe.004D8F0A    ;Jmp to here
004D8FBF    85C0            test eaxeax
004D8FC1    75 05           jnz short SoftDefe.004D8FC8

現在我們在命令欄裡輸入follow GetTickCount,反彙編視窗顯示
GetTickCo>  BA 0000FE7F     mov edx, 7FFE0000                        
77E5A2A0    8B02            mov eaxdword ptr ds:[edx]
77E5A2A2    F762 04         mul dword ptr ds:[edx+4]
77E5A2A5    0FACD0 18       shrd eaxedx, 18
77E5A2A9    C3              retn         ;這裡按F4,當然你也可以在這裡做點小手腳 :twisted: 
F8返回
004D8171    894424 0C       mov dword ptr ss:[esp+C], eax
004D8175    8B4424 10       mov eaxdword ptr ss:[esp+10]
004D8179    83F8 04         cmp eax, 4

在[esp+C]處下記憶體訪問斷點,  注意這裡開始有分岔路咯~F9 Go,OK,OD斷在這
004D6F27    8A0411          mov albyte ptr ds:[ecx+edx]
004D6F2A    8801            mov byte ptr ds:[ecx], al
004D6F2C    41              inc ecx
004D6F2D    4E              dec esi
004D6F2E  ^ 75 F7           jnz short SoftDefe.004D6F27
004D6F30    8BC7            mov eaxedi

此時去掉記憶體斷點。
呵呵,看到這個表示我們是在除錯父程式,下面父程式要做的事是建立臨時檔案,寫入前面GetTickCount所得值的加密值,再CreateProcessA建立子程式,隨後自己退出,CreateProcessA我們沒辦法跟進去,不過主導思想是既然CreateProcessA是執行同一個檔案,那麼儲存好現在的現場,用OD再次載入SoftDefender模擬子程式,OK,我們可以用follow CloseHandle
CloseHandl>  64:A1 18000000  mov eaxdword ptr fs:[18]   ;No BreakPoint here :wink: 
77E5A6F6     8B48 30         mov ecxdword ptr ds:[eax+30]
77E5A6F9     8B4424 04       mov eaxdword ptr ss:[esp+4]
77E5A6FD     83F8 F4         cmp eax, -0C
77E5A700   ^ 0F84 7E93FFFF   je kernel32.77E53A84
只要你不在第一句下斷點就沒問題,F9 Go,斷在你下斷的地方,這個CloseHandle實際是關閉臨時檔案的控制程式碼,如果父程式始終不CloseHandle的話系統是不會取消這個核心的,這樣也方便我們後面對子程式的除錯嘛 :P 

到此,父程式的工作已經完成了,我們留著這個OD
==========================================
          ★★★★★★★★★★★★★ 
★★★★★ B、對於子程式的跟蹤分析 ★★★★★ 
          ★★★★★★★★★★★★★ 


新開一個OD,再次載入SoftDefender.exe
前面的過程和父程式一樣,繞過ZwQueryInformationProcess的Anti,到前面我說的分岔路口那,當你再[esp+C]處下記憶體訪問斷點後,F9 Go,稍等一會,OD會斷在這
004D81E2    8B4C24 0C       mov ecxdword ptr ss:[esp+C]   ;Stop here
004D81E6    8B5424 08       mov edxdword ptr ss:[esp+8]
004D81EA    2BCA            sub ecxedx
004D81EC    81F9 401F0000   cmp ecx, 1F40
004D81F2    72 66           jb short SoftDefe.004D825A   ;一定要跳!
呵呵,這個父子程式的時間差,過長的話子程式就執行父程式的作用,寫入新值,CreateProcessA另一個新的程式…………
004D81F4    83FF 03         cmp edi, 3
004D81F7    74 25           je short SoftDefe.004D821E
004D81F9    6A 00           push 0

跳到這裡,怎麼修改程式執行軌道我就不再說了
004D825A    5F              pop edi
004D825B    B8 08000000     mov eax, 8
004D8260    5E              pop esi
004D8261    81C4 40010000   add esp, 140
004D8267    C3              retn

OK,F9吧,程式執行了,我們成功模擬了子程式,興奮不??
我們千辛萬苦繞過那些Anti,這麼一個F9就全完了????OEP,Import都還沒搞定那…………
是的,全完了,不過我們也可以獲得一個重要的情況,外殼會自己清除關鍵程式碼,向上翻,會發現有很長一段都是
004D137B    0000            add byte ptr ds:[eax], al
其實就是00,被清除了的程式碼,這裡是我們找OEP的關鍵
重複子程式前面的過程,最後不要F9了,而是在其中某一個地方,比如
004D1487處下一個硬寫斷點(這個位置我沒有試,我每次都是隨機選的)
F9 Go,直到斷在下面這個位置為止
004D5E78    F3:AA           rep stos byte ptr es:[edi]
004D5E7A    C3              retn
F8執行到retn,下面就是要返回到OEP了,如果你要是一高興用F8按下去,那將是一個惡夢,因為我們這個時候看看棧堆
0012EB90   0044D3DD  SoftDefe.0044D3DD
0012EB94   0044D3A3  SoftDefe.0044D3A3
0012EB98   0044D399  SoftDefe.0044D399
0012EB9C   0044D374  RETURN to SoftDefe.0044D374 from SoftDefe.00447CF1
0012EBA0   0044D31C  RETURN to SoftDefe.0044D31C from SoftDefe.00403480

…… …… ……

0012FFB4   00429790  SoftDefe.00429790
0012FFB8   00429760  SoftDefe.00429760
0012FFBC   004296CA  SoftDefe.004296CA
0012FFC0   0042966D  SoftDefe.0042966D    ;這裡才是目的地,飛向光明之顛?? :lol: 
0012FFC4   004D5748  SoftDefe.004D5748
0012FFC8   77D64F70  user32.77D64F70

OK,G 0042966D吧
0042966D    FF15 688F1400   call dword ptr ds:[148F68]   ;注意這個call,進去看看
00429673    64:A1 00000000  mov eaxdword ptr fs:[0]
00429679    50              push eax
0042967A    64:8925 0000000>mov dword ptr fs:[0], esp
00429681    83EC 58         sub esp, 58

進入call [148F68]後
00169BB0    58              pop eax---------------------------------------
00169BB1    55              push ebp
00169BB2    8BEC            mov ebpesp
00169BB4    6A FF           push -1                     Stolen Byte!!!
00169BB6    68 E02C4500     push 452CE0
00169BBB    68 48C74200     push 42C748
00169BC0    FFE0            jmp eax   -------------------------------------

而pop eax和jmp eax實際就是retn的變形,將Stolen Byte還原
00429664    55              push ebp
00429665    8BEC            mov ebpesp
00429667    6A FF           push -1
00429669    68 E02C4500     push 00452CE0
0042966E    68 48C74200     push 0042C748
00429673    64:A1 00000000  mov eaxdword ptr fs:[0]
00429679    50              push eax
0042967A    64:8925 0000000>mov dword ptr fs:[0], esp

好了,這個時候可以用LordPE來Dump了

下面讓我們看看輸入表,基本都被修改了,除了幾個只有一個引用函式的Dll沒有被加密,我們的目標就是――――修復它 :lol: 
用ImportRec的trace Level 3還有17個沒有修復,自己模擬跟蹤一下就知道了 :wink: 
我是透過修改程式裡的一個記憶體值達到防止ImportTable被破壞的
這裡就是恢復並修改ImportTable的程式碼了
004D88E7    52              push edx
004D88E8    50              push eax
004D88E9    57              push edi
004D88EA    E8 6DF5FFFF     call SoftDefe.004D7E5C
004D88EF    8B8424 40040000 mov eaxdword ptr ss:[esp+440]   ;我要改這個地址的值為0 :o  :o 
004D88F6    85C0            test eaxeax
004D88F8    0F84 BA010000   je SoftDefe.004D8AB8   ;這裡跳的話就不會破壞Import Table了
004D88FE    8B4424 18       mov eaxdword ptr ss:[esp+18]
004D8902    85C0            test eaxeax
004D8904    74 10           je short SoftDefe.004D8916
004D8906    8B4C24 10       mov ecxdword ptr ss:[esp+10]
004D890A    57              push edi
004D890B    51              push ecx
004D890C    E8 90160000     call SoftDefe.004D9FA1
004D8911    E9 AD010000     jmp SoftDefe.004D8AC3

…… …… ……

004D8A90    E8 24E5FFFF     call SoftDefe.004D6FB9
004D8A95    85C0            test eaxeax
004D8A97    75 0C           jnz short SoftDefe.004D8AA5
004D8A99    68 8E764000     push SoftDefe.0040768E
004D8A9E    E8 E0D3FFFF     call SoftDefe.004D5E83
004D8AA3    EB 1E           jmp short SoftDefe.004D8AC3
004D8AA5    8B5424 10       mov edxdword ptr ss:[esp+10]
004D8AA9    57              push edi
004D8AAA    52              push edx
004D8AAB    E8 35EAFFFF     call SoftDefe.004D74E5
004D8AB0    50              push eax
004D8AB1    E8 B3F8FFFF     call SoftDefe.004D8369
004D8AB6    EB 0B           jmp short SoftDefe.004D8AC3
004D8AB8    8B4424 10       mov eaxdword ptr ss:[esp+10]
004D8ABC    57              push edi
004D8ABD    50              push eax
004D8ABE    E8 22EAFFFF     call SoftDefe.004D74E5
004D8AC3    33C9            xor ecxecx
004D8AC5    8906            mov dword ptr ds:[esi], eax    ;這裡就寫入了

所以要想辦法讓它在那能斷下來,在
004D81E2    8B4C24 0C       mov ecxdword ptr ss:[esp+C]   ;Stop here
004D81E6    8B5424 08       mov edxdword ptr ss:[esp+8]
004D81EA    2BCA            sub ecxedx
004D81EC    81F9 401F0000   cmp ecx, 1F40
004D81F2    72 66           jb short SoftDefe.004D825A   ;一定要跳!

跳完以後,如果在004D88EF處直接下硬執行斷點有問題,估計和OD本身有關,可能是個Bug,要先在0044E000處下記憶體斷點,F9,會斷下,之後按4次F9後再在004D88EF處下硬執行斷點,再F9,等斷在004D88EF時,修改[esp+440]的值為0,取消硬斷點以及記憶體斷點,再g 42966d,如果程式停住了就暫停一下再繼續執行,就能到OEP了,這個時候就可以用ImportREC來修復了,一個壞的都沒有,是不是很爽啊 :lol: 

OK,Fix Dump吧,然後最佳化一下

相關文章