Blaze Media Pro5.05脫殼+基本修復CC(int3)+破解

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

Blaze Media Pro5.05脫殼(armadillo)+基本修復CC(int3)+破解(一)


Blaze Media Pro 是一款造型新穎,功能齊全的多媒體工具。5.05是它的最新版。它的脫殼不算太難。我搞過它的4.6版、5.03直到5.05版,但cc一直沒法搞定。到現在也不能說是完全修復了。我覺得現在的armadillo殼的cc應該沒有什麼辦法可以完美修復。當然這是我個人的看法,請大俠高手們指正。我修復cc的方法完全沒有技術性,高手們莫笑啊。

下載地址:google或百度找

工具:ollydbg、ultraedit、winhex、lordpe、ImportREC1.6f等。

平臺:winxp


一、脫殼

這個軟體是vb編寫的,IAT從401000開始。因此不好用mysqladm大俠的方法,但可以使用Ricardo Narvaja或tDasm的方法。Ricardo Narvaja的方法是經典方法,但太麻煩且有限制。這兒我用tDasm的方法(參見文章Armadillo 3_6主程式脫殼)。謝謝tDasm大俠。

先找oep,下he WaitForDebugEvent和he WriteProcessMemory能很快找到oep=41a528。

在OD中重開程式,下硬體斷點:he WaitForDebugEvent,執行停住。回到殼空間,查詢常數FFFFFFF8,得到結果:

009EAE36   OR EAX, FFFFFFF8
009EAE51   OR EDX, FFFFFFF8
009EAE7A   OR ECX, FFFFFFF8
009EB350   OR EDX, FFFFFFF8
009EB36B   OR ECX, FFFFFFF8
009EB393   OR EAX, FFFFFFF8

在009EAE36上雙擊,來到這程式碼處,朝上幾行看:


009EADEA    CMP DWORD PTR SS:[EBP-A30], 0     //這就是tDasm大俠文中提到的關鍵程式碼。
009EADF1    JL BMP.009EB0A0
009EADF7    MOV ECXDWORD PTR SS:[EBP-A30]
009EADFD    CMP ECXDWORD PTR DS:[A177BC]
009EAE03    JGE BMP.009EB0A0
009EAE09    MOV EDXDWORD PTR SS:[EBP-9BC]
009EAE0F    AND EDX, 0FF
009EAE15    TEST EDXEDX
009EAE17    JE BMP.009EAECA
009EAE1D    PUSH 0
009EAE1F    MOV ESIDWORD PTR SS:[EBP-A30]
009EAE25    SHL ESI, 4
009EAE28    MOV EAXDWORD PTR SS:[EBP-A30]
009EAE2E    AND EAX, 80000007
009EAE33    JNS SHORT BMP.009EAE3A
009EAE35    DEC EAX
009EAE36    OR EAX, FFFFFFF8
009EAE39    INC EAX
009EAE3A    XOR ECXECX

.....

009EAEA4    MOV EDXDWORD PTR DS:[A177AC]
009EAEAA    LEA EAXDWORD PTR DS:[EDX+ESI*4]
009EAEAD    PUSH EAX
009EAEAE    MOV ECXDWORD PTR SS:[EBP-A30]
009EAEB4    PUSH ECX
009EAEB5    CALL BMP.009ECFCA
009EAEBA    ADD ESP, 0C
009EAEBD    AND EAX, 0FF
009EAEC2    TEST EAXEAX


在009EADEA處下一硬體執行斷點,執行停住。 按照tDasm的方法,修改程式碼為:

009EAEBD    INC DWORD PTR DS:[12EB40]
009EAEC3    MOV DWORD PTR DS:[A177C0], 1
009EAECD    JMP BMP.009EADEA
009EAED2    NOP
            

把12EB40處置0,去掉所有硬體斷點,並在9eb0a0處下斷,執行,停住。好,所有程式碼都強制解壓完成。


如果你是xp系統,那麼你可以用DebugActiveProcessStop把子程式和父程式脫開。如果你是2000系統,你就直接dump吧。我這兒脫離子程式:

009EB0A0    PUSH 0D44
009EB0A5    CALL kernel32.DebugActiveProcessStop
009EB0AA    NOP


這時系統會出現錯誤提示框,你可以選除錯(當然事先要把ollydbg設定為just-in-time debuger),或者不理提示,直接開啟另一個OD來attach子程式。附加上後程式後,會出錯,到不了程式空間。沒關係,你要記住程式碼已經完全解壓。ctrl+g,輸入41a528,來到oep處。

接下來我們有三件事要做:修復IAT、dump主程式、dump動態解壓程式碼。查一下即知,IAT在401000~40150c。開啟ImportREC1.6f,選上子程式看看,只有一個錯誤指標:13cd485(401064處)。回到OD,ctrl+g來到13cd485處:

013CD485    PUSH EBP
013CD486    MOV EBPESP
013CD488    PUSH -1
013CD48A    PUSH 13EB680
013CD48F    PUSH 13EA7F0                             ; JMP to msvcrt._except_handler3
013CD494    MOV EAXDWORD PTR FS:[0]
013CD49A    PUSH EAX
013CD49B    MOV DWORD PTR FS:[0], ESP
013CD4A2    SUB ESP, 10
013CD4A5    PUSH EBX
013CD4A6    PUSH ESI
013CD4A7    PUSH EDI
013CD4A8    MOV DWORD PTR SS:[EBP-18], ESP
013CD4AB    XOR ESIESI
013CD4AD    PUSH 13F0B48                             ; ASCII "MSVBVM60.DLL"
013CD4B2    CALL DWORD PTR DS:[13EB0C8]              ; kernel32.GetModuleHandleA
013CD4B8    TEST EAXEAX
013CD4BA    JE SHORT 013CD4CA
013CD4BC    PUSH 13F0B3C                             ; ASCII "__vbaEnd"
013CD4C1    PUSH EAX
013CD4C2    CALL DWORD PTR DS:[13EB0CC]              ; kernel32.GetProcAddress
013CD4C8    MOV ESIEAX
013CD4CA    AND DWORD PTR SS:[EBP-4], 0
013CD4CE    TEST ESIESI
013CD4D0    JE SHORT 013CD4E8
013CD4D2    CALL ESI
013CD4D4    JMP SHORT 013CD4E8
013CD4D6    PUSH 1
013CD4D8    POP EAX
013CD4D9    RETN

很顯然這是函式__vbaEnd,OK,IAT可以修復了。


下面用lordpe把主程式dump出來吧,但別急著把od關掉。好,再回到OD,alt+m開啟記憶體視窗,找到使用者空間的最高段,我這兒是20c0000,大小20000。cltr+g來到這:

020C0000    XCHG ECXESI
020C0002    XCHG EBXECX
020C0004    JPE SHORT 020C0008
020C0006    JPE SHORT 020C001F
020C0008    XCHG EBXECX
020C000A    JA SHORT 020C000E
020C000C    JA SHORT 020C0020
020C000E    XCHG ECXESI
020C0010    PUSH 419D96                              ; JMP to MSVBVM60.__vbaExceptHandler
020C0015    JMP BMP.005FE66B
020C001A    NOT ECX
020C001C    JGE SHORT 020C001E
020C001E    XCHG EAXECX
020C001F    JNB SHORT 020C0021
020C0021    BSWAP EDX
020C0023    JBE SHORT 020C0027
020C0025    JBE SHORT 020C005D
020C0027    NOT EDX
020C0029    XCHG AXCX
020C002B    XCHG SISI
020C002E    XCHG AXCX
020C0030    MOV ECXECX
020C0032    NOT EDX


看看,armadillo把程式中的一部分程式碼加上垃圾程式碼移到一動態空間,dump出來的主程式沒有這些程式碼是不可能執行的。因此把這些程式碼也dump出來吧。

現在的任務就要把這些重組起來。用lordpe在主程式中加一個section,VOffset設定為020C0000,大小設定為10000。用winhex把dump出來的020C0000處程式碼放回主程式。這樣可以保證其中的跳轉地址不會改變。具體操作我就不說了,請參考有關的資料。


現在程式脫殼工作已經結束,接下來就是最麻煩的cc修復了。

(二)cc修復

下面我嘗試著來修復CC。cc實際上就是int3指令,armadillo把程式中的一些跳轉指令改成int3。子程式執行到int3時發生異常,父程式可以捕捉到,然後計算出子程式該不該跳轉,如果跳轉,跳轉量是多少,如果不跳轉,下一條指令應從哪裡開始。透過getthreadcontext和setthreadcontext函式來干預子程式的執行。因此程式脫殼後,裡面的int3指令不修覆成原本的跳轉指令,程式是不可能執行起來的。

但問題是:脫殼程式中哪些cc是int3指令,哪些cc是資料呢?原先版本的armardillo可以完全區分開來,但現在的版本好像不能夠區分,至少我沒有找到方法,不知高手們是採用什麼辦法的。從技術角度來講,armadillo可以不用區分。我們試想一下:armardillo可以把原程式中所有跳轉指令都改成int3,然後連同程式中的cc資料一起進行計算得到一張總表。在加殼時卻只隨機選一些跳轉指令改成int3,但使用的還是那張總表。程式完全可以執行。但我們怎麼才能知道總表中哪些是跳轉指令呢?我覺得不能,因此也就很難完美修復。

我想到修復的方法有兩種,一是在OD中執行加殼程式,設定條件記錄斷點,然後把程式所有的功能都執行一遍,得到子程式發生int3的地址。二是設計一程式碼分析器,分析脫殼程式中哪些是int3指令,哪些不是。這兩種方法都不能算是完美修復。我的方法是借用OD來找到int3。


我們的目標是得到四個表:int3地址表、跳轉型別表、跳轉量表及跳轉指令長度表。有了這四個表,我們就可以修復cc了。


我們先看第一張int3地址表。在od中開啟脫殼程式,從401000~98cfff都是程式的內容,包括程式碼和資源。armadillo把它們放在同一節中。查詢二進位制55 8b ec(PUSH EBP  MOV EBPESP)找到程式碼開始的部分在5fe660。把5fe660~98cfff選上然後複製到檔案中,用ultraedit開啟檔案,選上“列出包含字串的行”,查詢文字int3。ok,找到如下形式的int3:

0060063E    CC              INT3
0060063F    CC              INT3
0060D481    CC              INT3
0060D482    CC              INT3
0060D483    CC              INT3
.....

使用ultraedit的列編輯功能編輯成:

3E 06 60 00 
3F 06 60 00 
81 D4 60 00 
82 D4 60 00 
83 D4 60 00 
84 D4 60 00 
.....

當然這裡面有很多都是不符合條件的,是int3原始表。先儲存好,下面要用。


在OD中重新開啟BMP.exe。下he GetThreadContext,執行,第二次停住時,看堆疊窗:

0012DA78   009EBC88  /CALL to GetThreadContext from BMP.009EBC82
0012DA7C   00000050  |hThread = 00000050 (window)
0012DA80   0012E10C  pContext = 0012E10C

在follow in dump 來到0012E10C。按alt+f9回到使用者空間。


0012E1AC  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0012E1BC  00 00 00 00 64 EE 12 00 DC 37 79 00 1B 00 00 00  ....d?.?y....
0012E1CC  46 02 00 00 24 EE 12 00 23 00 00 00 00 00 00 00  F..$?.#.......

12e1c4處的7937dc就是子程式發生的第一個int3地址+1,我們可以用OD把脫殼程式開啟看看,執行出的第一個錯也是那。 0012E1CC處的246是子程式的Flag暫存器內容。


009EBC82    CALL DWORD PTR DS:[<&KERNEL32.GetThreadC>; 
009EBC88    PUSH EAX                                  //停在這,這條指令到009EBCCA都是垃圾指令
009EBC89    NOT EAX
009EBC8B    BSWAP EAX
009EBC8D    POP EAX
009EBC8E    JNB SHORT BMP.009EBC90
009EBC90    PUSHFD
009EBC91    PUSHAD


009EBCC1    MOV EAX, C80F9D61
009EBCC6    NOT ECX
009EBCC8    BSWAP EAX
009EBCCA    NOT ECX
009EBCCC    MOV DWORD PTR SS:[EBP-1468], 0
009EBCD6    PUSH -1
009EBCD8    PUSH 4
009EBCDA    LEA EDXDWORD PTR SS:[EBP-13AC]         ; [12e1c4]=7937dc,子程式發生int3的地址+1
009EBCE0    PUSH EDX
009EBCE1    CALL BMP.009D4F90                        ; 對int3地址運算
009EBCE6    ADD ESP, 0C
009EBCE9    MOV DWORD PTR SS:[EBP-1194], EAX         ; 運算結果
009EBCEF    MOV EAXDWORD PTR SS:[EBP-1194]
009EBCF5    XOR EDXEDX
009EBCF7    MOV ECX, 10
009EBCFC    DIV ECX                                  ; 運算結果除以10
009EBCFE    MOV DWORD PTR SS:[EBP-1198], EDX         ; 取餘數
009EBD04    MOV EDXDWORD PTR SS:[EBP-13AC]         ; int3地址+1
009EBD0A    PUSH EDX
009EBD0B    MOV EAXDWORD PTR SS:[EBP-1198]         ; 前面得到的餘數
009EBD11    CALL DWORD PTR DS:[EAX*4+A15838]         ; 再次運算。
009EBD18    ADD ESP, 4
009EBD1B    MOV DWORD PTR SS:[EBP-1468], EAX         ; 運算結果,將用於在table1(int3地址計算結果表)中查詢
009EBD21   >MOV DWORD PTR SS:[EBP-146C], 0
009EBD2B    MOV ECXDWORD PTR SS:[EBP-1198]
009EBD31    MOV EDXDWORD PTR DS:[ECX*4+A176D4]
009EBD38    MOV DWORD PTR SS:[EBP-118C], EDX
009EBD3E    MOV EAXDWORD PTR SS:[EBP-146C]
009EBD44    CMP EAXDWORD PTR SS:[EBP-118C]
009EBD4A    JGE SHORT BMP.009EBDA8
009EBD4C    MOV EAXDWORD PTR SS:[EBP-118C]
009EBD52    SUB EAXDWORD PTR SS:[EBP-146C]
009EBD58    CDQ
009EBD59    SUB EAXEDX
009EBD5B    SAR EAX, 1
009EBD5D    MOV ECXDWORD PTR SS:[EBP-146C]
009EBD63    ADD ECXEAX
009EBD65    MOV DWORD PTR SS:[EBP-1470], ECX
009EBD6B    MOV EDXDWORD PTR SS:[EBP-1198]         ; 前面得到的餘數
009EBD71    MOV EAXDWORD PTR DS:[EDX*4+A1768C]     ; [A1768C]開始的是table1地址表,根據前面得到的餘數找到table1的地址
009EBD78    MOV ECXDWORD PTR SS:[EBP-1470]
009EBD7E    MOV EDXDWORD PTR SS:[EBP-1468]
009EBD84    CMP EDXDWORD PTR DS:[EAX+ECX*4]
009EBD87    JBE SHORT BMP.009EBD9A
009EBD89    MOV EAXDWORD PTR SS:[EBP-1470]
009EBD8F    ADD EAX, 1
009EBD92    MOV DWORD PTR SS:[EBP-146C], EAX
009EBD98    JMP SHORT BMP.009EBDA6
009EBD9A    MOV ECXDWORD PTR SS:[EBP-1470]
009EBDA0    MOV DWORD PTR SS:[EBP-118C], ECX
009EBDA6    JMP SHORT BMP.009EBD3E
009EBDA8    PUSHAD                                   ; eax=查表結果(前面運算結果在table1中的序號)
009EBDA9    NOP                                                              
     
.......                                              //nop掉垃圾指令
                                                         
009EBDCB    NOP                                                              
009EBDCC    NOP                                                              
009EBDCD    POPAD                                                           
009EBDCE    MOV EDXDWORD PTR SS:[EBP-1198]          前面的餘數                            
009EBDD4    MOV EAXDWORD PTR DS:[EDX*4+A1768C]     ; table1地址            
009EBDDB    MOV ECXDWORD PTR SS:[EBP-146C]                                 
009EBDE1    MOV EDXDWORD PTR DS:[EAX+ECX*4]                                
009EBDE4    CMP EDXDWORD PTR SS:[EBP-1468]         ; 再比較一下,看是否相等
009EBDEA    JNZ BMP.009EC102                                                 
  
........                                              // 垃圾指令     

 
009EBE47    MOV EAXDWORD PTR SS:[EBP-1198]          前面的餘數 
009EBE4D    MOV ECXDWORD PTR DS:[EAX*4+A17714]     ; table2(跳轉型別代號表)
009EBE54    MOV EDXDWORD PTR SS:[EBP-146C]
009EBE5A    XOR EAXEAX
009EBE5C    MOV ALBYTE PTR DS:[ECX+EDX]            ; 得到跳轉型別代號
009EBE5F    MOV DWORD PTR SS:[EBP-1488], EAX
009EBE65    MOV EAXDWORD PTR SS:[EBP-1488]
009EBE6B    CDQ
009EBE6C    AND EDX, 0F
009EBE6F    ADD EAXEDX
009EBE71    SAR EAX, 4
009EBE74    MOV DWORD PTR SS:[EBP-1480], EAX
009EBE7A    MOV ECXDWORD PTR SS:[EBP-1488]
009EBE80    AND ECX, 8000000F
009EBE86    JNS SHORT BMP.009EBE8D
009EBE88    DEC ECX
009EBE89    OR ECX, FFFFFFF0
009EBE8C    INC ECX
009EBE8D    MOV DWORD PTR SS:[EBP-1484], ECX
009EBE93    MOV EDXDWORD PTR SS:[EBP-1480]
009EBE99    CMP EDXDWORD PTR SS:[EBP-1484]
009EBE9F    JNZ SHORT BMP.009EBEBC
009EBEA1    MOV EAXDWORD PTR SS:[EBP-1484]
009EBEA7    ADD EAX, 1
009EBEAA    AND EAX, 8000000F
009EBEAF    JNS SHORT BMP.009EBEB6
009EBEB1    DEC EAX
009EBEB2    OR EAX, FFFFFFF0
009EBEB5    INC EAX
009EBEB6    MOV DWORD PTR SS:[EBP-1484], EAX
009EBEBC    MOV ECXDWORD PTR SS:[EBP-1488]
009EBEC2    MOV EDXDWORD PTR SS:[EBP-1480]
009EBEC8    MOV EAXDWORD PTR DS:[ECX*4+A16ED0]
009EBECF    XOR EAXDWORD PTR DS:[EDX*4+A1125C]
009EBED6    MOV ECXDWORD PTR SS:[EBP-1484]
009EBEDC    XOR EAXDWORD PTR DS:[ECX*4+A1125C]
009EBEE3    MOV DWORD PTR SS:[EBP-1478], EAX
009EBEE9    MOV EDXDWORD PTR SS:[EBP-13A4]         ; 子程式context的flag暫存器內容
009EBEEF    AND EDX, 0FD7
009EBEF5    PUSH EDX
009EBEF6    MOV EAXDWORD PTR SS:[EBP-1488]         ; 跳轉型別代號
009EBEFC    MOVSX ECXBYTE PTR DS:[EAX+A15730]
009EBF03    CALL DWORD PTR DS:[ECX*4+A15838]
009EBF0A    ADD ESP, 4
009EBF0D    MOV DWORD PTR SS:[EBP-1474], EAX
009EBF13    MOV EDXDWORD PTR SS:[EBP-13B8]          子程式context的ecx內容        
009EBF19    PUSH EDX
009EBF1A    MOV EAXDWORD PTR SS:[EBP-1474]
009EBF20    PUSH EAX
009EBF21    CALL DWORD PTR SS:[EBP-1478]
009EBF27    ADD ESP, 8
009EBF2A    PUSH EAX
009EBF2B    MOV ECXDWORD PTR SS:[EBP-1488]
009EBF31    MOVSX EDXBYTE PTR DS:[ECX+A15730]
009EBF38    CALL DWORD PTR DS:[EDX*4+A15878]           
009EBF3F    ADD ESP, 4
009EBF42    MOV DWORD PTR SS:[EBP-147C], EAX
009EBF48    MOV EAXDWORD PTR SS:[EBP-147C]
009EBF4E    AND EAX, 1
009EBF51    TEST EAXEAX                            //經過若干次複雜計算最後得到子程式在7937dc處是跳呢(eax=1),還是不跳(eax=0)
009EBF53    JE BMP.009EC007
009EBF59    PUSHAD


009EBF7E    POPAD                     
009EBF7F    MOV ECXDWORD PTR SS:[EBP-1198]           //如果eax=1,到這
009EBF85    MOV ECXDWORD PTR DS:[ECX*4+A1764C]
009EBF8C    MOV EAXDWORD PTR SS:[EBP-146C]
009EBF92    XOR EDXEDX
009EBF94    MOV ESI, 10
009EBF99    DIV ESI
009EBF9B    MOV EAXDWORD PTR SS:[EBP-146C]
009EBFA1    MOV ECXDWORD PTR DS:[ECX+EAX*4]
009EBFA4    XOR ECXDWORD PTR SS:[EBP+EDX*4-1170]    //得到跳轉量
009EBFAB    MOV EDXDWORD PTR SS:[EBP-13AC]           
009EBFB1    ADD EDXECX
009EBFB3    MOV DWORD PTR SS:[EBP-13AC], EDX          //重新設定context



009EC012    MOV EAXDWORD PTR SS:[EBP-1198]          //如果eax=0,到這
009EC018    MOV ECXDWORD PTR DS:[EAX*4+A17758]
009EC01F    MOV EDXDWORD PTR SS:[EBP-146C]
009EC025    XOR EAXEAX
009EC027    MOV ALBYTE PTR DS:[ECX+EDX]             //得到下一條指令的距離
009EC02A    MOV ECXDWORD PTR SS:[EBP-13AC]
009EC030    ADD ECXEAX
009EC032    MOV DWORD PTR SS:[EBP-13AC], ECX         //重新設定context


好,知道這些後,我們要對上段程式碼進行大修改。
 
下面是修改好的程式碼:

××××××
009EBC88    PUSH ESP                                   //下面程式碼修改401000開始的空間讀寫屬性,使得可寫。  
009EBC89    PUSH 4
009EBC8B    PUSH BMP.00578000
009EBC90    PUSH BMP.00401000
009EBC95    CALL DWORD PTR DS:[<&KERNEL32.VirtualPro>; kernel32.VirtualProtect
009EBC9B    NOP
            
009EBC9F    NOP
009EBCA0    MOV EAXDWORD PTR DS:[500000]              //[500000]中是原始int3表計數器
009EBCA5    MOV EAXDWORD PTR DS:[EAX*4+401000]        //401000開始放置int3原始表
009EBCAD    TEST EAXEAX            
009EBCAF    JE BMP.009EC045                             //int3原始表到最後?是則結束。
009EBCB5    LEA EDXDWORD PTR SS:[EBP-13AC]
009EBCBB    INC EAX
009EBCBC    MOV DWORD PTR DS:[EDX], EAX
009EBCBE    INC DWORD PTR DS:[500000]
009EBCC4    NOP
××××××


009EBCCB    NOP
009EBCCC    MOV DWORD PTR SS:[EBP-1468], 0
009EBCD6    PUSH -1
009EBCD8    PUSH 4
009EBCDA    LEA EDXDWORD PTR SS:[EBP-13AC]         ;
009EBCE0    PUSH EDX
009EBCE1    CALL BMP.009D4F90                        ;
009EBCE6    ADD ESP, 0C
009EBCE9    MOV DWORD PTR SS:[EBP-1194], EAX         ; 
009EBCEF    MOV EAXDWORD PTR SS:[EBP-1194]
009EBCF5    XOR EDXEDX
009EBCF7    MOV ECX, 10
009EBCFC    DIV ECX                                  ; 
009EBCFE    MOV DWORD PTR SS:[EBP-1198], EDX         ;
009EBD04    MOV EDXDWORD PTR SS:[EBP-13AC]         ;
009EBD0A    PUSH EDX
009EBD0B    MOV EAXDWORD PTR SS:[EBP-1198]         ; 
009EBD11    CALL DWORD PTR DS:[EAX*4+A15838]         ; 
009EBD18    ADD ESP, 4
009EBD1B    MOV DWORD PTR SS:[EBP-1468], EAX         ;
009EBD21    MOV DWORD PTR SS:[EBP-146C], 0
009EBD2B    MOV ECXDWORD PTR SS:[EBP-1198]
009EBD31    MOV EDXDWORD PTR DS:[ECX*4+A176D4]
009EBD38    MOV DWORD PTR SS:[EBP-118C], EDX
009EBD3E    MOV EAXDWORD PTR SS:[EBP-146C]
009EBD44    CMP EAXDWORD PTR SS:[EBP-118C]
009EBD4A    JGE SHORT BMP.009EBDA8
009EBD4C    MOV EAXDWORD PTR SS:[EBP-118C]
009EBD52    SUB EAXDWORD PTR SS:[EBP-146C]
009EBD58    CDQ
009EBD59    SUB EAXEDX
009EBD5B    SAR EAX, 1
009EBD5D    MOV ECXDWORD PTR SS:[EBP-146C]
009EBD63    ADD ECXEAX
009EBD65    MOV DWORD PTR SS:[EBP-1470], ECX
009EBD6B    MOV EDXDWORD PTR SS:[EBP-1198]         ;
009EBD71    MOV EAXDWORD PTR DS:[EDX*4+A1768C]     ;
009EBD78    MOV ECXDWORD PTR SS:[EBP-1470]
009EBD7E    MOV EDXDWORD PTR SS:[EBP-1468]
009EBD84    CMP EDXDWORD PTR DS:[EAX+ECX*4]
009EBD87    JBE SHORT BMP.009EBD9A
009EBD89    MOV EAXDWORD PTR SS:[EBP-1470]
009EBD8F    ADD EAX, 1
009EBD92    MOV DWORD PTR SS:[EBP-146C], EAX
009EBD98    JMP SHORT BMP.009EBDA6
009EBD9A    MOV ECXDWORD PTR SS:[EBP-1470]
009EBDA0    MOV DWORD PTR SS:[EBP-118C], ECX
009EBDA6    JMP SHORT BMP.009EBD3E
009EBDA8    NOP                                      ; 
009EBDA9    NOP
009EBDAA    MOV EDXDWORD PTR SS:[EBP-1198]
009EBDB0    MOV EAXDWORD PTR DS:[EDX*4+A1768C]
009EBDB7    MOV ECXDWORD PTR SS:[EBP-146C]               
009EBDBD    MOV EDXDWORD PTR DS:[EAX+ECX*4]
009EBDC0    CMP EDXDWORD PTR SS:[EBP-1468]
009EBDC6    JNZ BMP.009EBCA0                          //這段程式碼我把它的位置朝前挪了,修改了跳轉量
009EBDCC    NOP
009EBDCD    NOP


××××××
009EBDCE    MOV EAXDWORD PTR DS:[500004]            //符合條件的int3計數器
009EBDD3    LEA EDXDWORD PTR SS:[EBP-13AC]
009EBDD9    MOV EDXDWORD PTR DS:[EDX]
009EBDDB    MOV DWORD PTR DS:[EAX*4+405F00], EDX      //符合條件的int3地址從405F00開始放
009EBDE3    NOP

                                                      //下面這段程式碼是為了得到跳轉型別而增加的,目的是得到009EBF75處我自編函式需要的東西
009EBDEA    NOP                                      
009EBDEB    MOV EAX, BMP.0050000C                    //50000C中是計數器        
009EBDF0    XOR ECXECX
009EBDF2    MOV DWORD PTR DS:[EAX], ECX              //計數器置0              
009EBDF4    MOV DWORD PTR DS:[EAX+4], ECX            //context的ecx=0
009EBDF7    MOV DWORD PTR DS:[EAX+C], ECX             //context的flag=0
009EBDFA    INC ECX
009EBDFB    MOV DWORD PTR DS:[EAX+8], ECX            //context的ecx=1        
009EBDFE    MOV DWORD PTR DS:[EAX+10], ECX           //flag的cf=1
009EBE01    MOV DWORD PTR DS:[EAX+14], 4             //pf=1
009EBE08    MOV DWORD PTR DS:[EAX+18], 40            //zf=1
009EBE0F    MOV DWORD PTR DS:[EAX+1C], 80            //sf=1
009EBE16    MOV DWORD PTR DS:[EAX+20], 800           //of=1
009EBE1D    LEA EAXDWORD PTR SS:[EBP-1464]
009EBE23    MOV ECXDWORD PTR DS:[50000C]             
009EBE29    MOV EDXDWORD PTR DS:[ECX*4+500010]
009EBE31    CMP ECX, 1
009EBE34    JG SHORT BMP.009EBE3E
009EBE36    MOV DWORD PTR DS:[EAX+AC], EDX
009EBE3C    JMP SHORT BMP.009EBE44
009EBE3E    MOV DWORD PTR DS:[EAX+C0], EDX
009EBE44    NOP
××××××

009EBE46    NOP
009EBE47    MOV EAXDWORD PTR SS:[EBP-1198]
009EBE4D    MOV ECXDWORD PTR DS:[EAX*4+A17714]     
009EBE54    MOV EDXDWORD PTR SS:[EBP-146C]
009EBE5A    XOR EAXEAX
009EBE5C    MOV ALBYTE PTR DS:[ECX+EDX]            ; 
009EBE5F    MOV DWORD PTR SS:[EBP-1488], EAX
009EBE65    MOV EAXDWORD PTR SS:[EBP-1488]
009EBE6B    CDQ
009EBE6C    AND EDX, 0F
009EBE6F    ADD EAXEDX
009EBE71    SAR EAX, 4
009EBE74    MOV DWORD PTR SS:[EBP-1480], EAX
009EBE7A    MOV ECXDWORD PTR SS:[EBP-1488]
009EBE80    AND ECX, 8000000F
009EBE86    JNS SHORT BMP.009EBE8D
009EBE88    DEC ECX
009EBE89    OR ECX, FFFFFFF0
009EBE8C    INC ECX
009EBE8D    MOV DWORD PTR SS:[EBP-1484], ECX
009EBE93    MOV EDXDWORD PTR SS:[EBP-1480]
009EBE99    CMP EDXDWORD PTR SS:[EBP-1484]
009EBE9F    JNZ SHORT BMP.009EBEBC
009EBEA1    MOV EAXDWORD PTR SS:[EBP-1484]
009EBEA7    ADD EAX, 1
009EBEAA    AND EAX, 8000000F
009EBEAF    JNS SHORT BMP.009EBEB6
009EBEB1    DEC EAX
009EBEB2    OR EAX, FFFFFFF0
009EBEB5    INC EAX
009EBEB6    MOV DWORD PTR SS:[EBP-1484], EAX
009EBEBC    MOV ECXDWORD PTR SS:[EBP-1488]
009EBEC2    MOV EDXDWORD PTR SS:[EBP-1480]
009EBEC8    MOV EAXDWORD PTR DS:[ECX*4+A16ED0]
009EBECF    XOR EAXDWORD PTR DS:[EDX*4+A1125C]
009EBED6    MOV ECXDWORD PTR SS:[EBP-1484]
009EBEDC    XOR EAXDWORD PTR DS:[ECX*4+A1125C]
009EBEE3    MOV DWORD PTR SS:[EBP-1478], EAX
009EBEE9    MOV EDXDWORD PTR SS:[EBP-13A4]         ;
009EBEEF    AND EDX, 0FD7
009EBEF5    PUSH EDX
009EBEF6    MOV EAXDWORD PTR SS:[EBP-1488]         ;
009EBEFC    MOVSX ECXBYTE PTR DS:[EAX+A15730]
009EBF03    CALL DWORD PTR DS:[ECX*4+A15838]
009EBF0A    ADD ESP, 4
009EBF0D    MOV DWORD PTR SS:[EBP-1474], EAX
009EBF13    MOV EDXDWORD PTR SS:[EBP-13B8]
009EBF19    PUSH EDX
009EBF1A    MOV EAXDWORD PTR SS:[EBP-1474]
009EBF20    PUSH EAX
009EBF21    CALL DWORD PTR SS:[EBP-1478]
009EBF27    ADD ESP, 8
009EBF2A    PUSH EAX
009EBF2B    MOV ECXDWORD PTR SS:[EBP-1488]
009EBF31    MOVSX EDXBYTE PTR DS:[ECX+A15730]
009EBF38    CALL DWORD PTR DS:[EDX*4+A15878]
009EBF3F    ADD ESP, 4
009EBF42    MOV DWORD PTR SS:[EBP-147C], EAX
009EBF48    MOV EAXDWORD PTR SS:[EBP-147C]
009EBF4E    AND EAX, 1
009EBF51    NOP
009EBF52    NOP

×××××××
009EBF53    MOV ECXDWORD PTR DS:[50000C]
009EBF59    MOV DWORD PTR DS:[ECX*4+500010], EAX   //得到的eax從500010開始放。
009EBF61    INC ECX
009EBF62    MOV DWORD PTR DS:[50000C], ECX         //計數器+1
009EBF68    CMP ECX, 7
009EBF6B    JLE BMP.009EBE1D                      //迴圈8次
009EBF71    NOP
009EBF72    NOP
009EBF73    PUSHAD
009EBF74    PUSHFD
009EBF75    CALL BMP.009EC050                      //我編的判斷跳轉型別的函式,後面有說明
009EBF7A    POPFD
009EBF7B    POPAD
009EBF7C    NOP
××××××

009EBF7E    NOP
009EBF7F    MOV ECXDWORD PTR SS:[EBP-1198]        
009EBF85    MOV ECXDWORD PTR DS:[ECX*4+A1764C]
009EBF8C    MOV EAXDWORD PTR SS:[EBP-146C]
009EBF92    XOR EDXEDX
009EBF94    MOV ESI, 10
009EBF99    DIV ESI
009EBF9B    MOV EAXDWORD PTR SS:[EBP-146C]
009EBFA1    MOV ECXDWORD PTR DS:[ECX+EAX*4]
009EBFA4    XOR ECXDWORD PTR SS:[EBP+EDX*4-1170]
009EBFAB    NOP
009EBFAC    NOP
009EBFAD    MOV EAXDWORD PTR DS:[500004]        
009EBFB2    MOV DWORD PTR DS:[EAX*4+40FD00], ECX       ;跳轉量從40FD00開始放
009EBFBA    NOP
......      
            
009EC011    NOP
009EC012    MOV EAXDWORD PTR SS:[EBP-1198]          
009EC018    MOV ECXDWORD PTR DS:[EAX*4+A17758]
009EC01F    MOV EDXDWORD PTR SS:[EBP-146C]
009EC025    XOR EAXEAX
009EC027    MOV ALBYTE PTR DS:[ECX+EDX]
009EC02A    NOP
009EC02B    NOP
009EC02C    MOV ECXDWORD PTR DS:[500004]
009EC032    MOV BYTE PTR DS:[ECX+414C00], AL            ;不跳,下條指令偏移量從414C00開始放     
009EC038    NOP
009EC039    NOP
009EC03A    INC DWORD PTR DS:[500004]
009EC040    JMP BMP.009EBCA0
009EC045    NOP


說明:

×××××××之間的程式碼是我新增上去的。

其中call 009EC050是我自己編的判斷跳轉型別程式碼,需要8個輸入量:yecx0,yecx1,yflag0,ycf1,ypf1,yzf1,ysf1,yof1。
yecx0是context中ecx=0,armadillo計算出的值(1或0,分別表示跳或不跳),yecx1是ecx=1對應的值,其它類似。


程式碼流程:

if(yecx0 XOR yecx1)  -> JECXZ
else if(ypf0 XOR ypf1)
{
  if(ypf0)    ->JNP
  else        ->JP 
}
else if(yzf0 XOR yzf1)
{
  if(ycf0 XOR ycf1)
    {
    if(yzf0)  ->JNBE
    else      ->JBE
    }
  else if(ysf0 XOR ysf1)
    {
    if(yzf0)  ->JNLE
    else      ->JLE
    }
  else
    {
    if(yzf0)  ->JNE
    else      ->JE
    }
}
else if(ysf0 XOR ysf1)
{
  if(yof0 XOR yof1)
    {
    if(yof0)  ->JNL
    else      ->JL
    }
  else 
    {
    if(ysf0)  ->JNS
    else      ->JS
    }  
}
else if(yof0 XOR yof1)
{
  if(yof0)    ->JNO
  else        ->JO
}
else if(ycf0 XOR ycf1)
{
  if(ycf0)    ->JNB
  else        ->JB
}
else if(yzf0) ->JMP
else          ->NOP

其中yzf0、ysf0、yof0...等於yflag0。


具體程式碼(中間的nop是預留的,以便增加程式碼):
 
009EC050    MOV EDIDWORD PTR DS:[500004]         //有效int3的計數器
009EC056    ADD EDI, BMP.0040AE00                 //跳轉型別從40AE00開始放
009EC05C    MOV EDX, BMP.0050000C
009EC061    MOV EAXDWORD PTR DS:[EDX+4]
009EC064    MOV EBXDWORD PTR DS:[EDX+8]
009EC067    XOR EBXEAX
009EC069    JE SHORT BMP.009EC07A
009EC06B    NOP
009EC06C    NOP
009EC06D    MOV BYTE PTR DS:[EDI], 0E3            
009EC070    JMP BMP.009EC195
009EC075    NOP
009EC076    NOP
009EC077    NOP
009EC078    NOP
009EC079    NOP
009EC07A    MOV EAXDWORD PTR DS:[EDX+C]
009EC07D    MOV EBXDWORD PTR DS:[EDX+14]
009EC080    XOR EBXEAX
009EC082    JE SHORT BMP.009EC0A1
009EC084    TEST EAXEAX
009EC086    JE SHORT BMP.009EC094
009EC088    NOP
009EC089    NOP
009EC08A    MOV BYTE PTR DS:[EDI], 7B
009EC08D    JMP BMP.009EC195
009EC092    NOP
009EC093    NOP
009EC094    MOV BYTE PTR DS:[EDI], 7A
009EC097    JMP BMP.009EC195
009EC09C    NOP
009EC09D    NOP
009EC09E    NOP
009EC09F    NOP
009EC0A0    NOP
009EC0A1    MOV EBXDWORD PTR DS:[EDX+18]
009EC0A4    XOR EBXEAX
009EC0A6    JE SHORT BMP.009EC109
009EC0A8    NOP
009EC0A9    NOP
009EC0AA    MOV EBXDWORD PTR DS:[EDX+10]
009EC0AD    XOR EBXEAX
009EC0AF    JE SHORT BMP.009EC0CB
009EC0B1    TEST EAXEAX
009EC0B3    JE SHORT BMP.009EC0C1
009EC0B5    NOP
009EC0B6    NOP
009EC0B7    MOV BYTE PTR DS:[EDI], 77
009EC0BA    JMP BMP.009EC195
009EC0BF    NOP
009EC0C0    NOP
009EC0C1    MOV BYTE PTR DS:[EDI], 76
009EC0C4    JMP BMP.009EC195
009EC0C9    NOP
009EC0CA    NOP
009EC0CB    MOV EBXDWORD PTR DS:[EDX+1C]
009EC0CE    XOR EBXEAX
009EC0D0    JE SHORT BMP.009EC0EC
009EC0D2    TEST EAXEAX
009EC0D4    JE SHORT BMP.009EC0E2
009EC0D6    NOP
009EC0D7    NOP
009EC0D8    MOV BYTE PTR DS:[EDI], 7F
009EC0DB    JMP BMP.009EC195
009EC0E0    NOP
009EC0E1    NOP
009EC0E2    MOV BYTE PTR DS:[EDI], 7E
009EC0E5    JMP BMP.009EC195
009EC0EA    NOP
009EC0EB    NOP
009EC0EC    TEST EAXEAX
009EC0EE    JE SHORT BMP.009EC0FC
009EC0F0    NOP
009EC0F1    NOP
009EC0F2    MOV BYTE PTR DS:[EDI], 75
009EC0F5    JMP BMP.009EC195
009EC0FA    NOP
009EC0FB    NOP
009EC0FC    MOV BYTE PTR DS:[EDI], 74
009EC0FF    JMP BMP.009EC195
009EC104    NOP
009EC105    NOP
009EC106    NOP
009EC107    NOP
009EC108    NOP
009EC109    MOV EBXDWORD PTR DS:[EDX+1C]
009EC10C    XOR EBXEAX
009EC10E    JE SHORT BMP.009EC144
009EC110    NOP
009EC111    NOP
009EC112    MOV EBXDWORD PTR DS:[EDX+20]
009EC115    XOR EBXEAX
009EC117    JE SHORT BMP.009EC12D
009EC119    TEST EAXEAX
009EC11B    JE SHORT BMP.009EC126
009EC11D    NOP
009EC11E    NOP
009EC11F    MOV BYTE PTR DS:[EDI], 7D
009EC122    JMP SHORT BMP.009EC195
009EC124    NOP
009EC125    NOP
009EC126    MOV BYTE PTR DS:[EDI], 7C
009EC129    JMP SHORT BMP.009EC195
009EC12B    NOP
009EC12C    NOP
009EC12D    TEST EAXEAX
009EC12F    JE SHORT BMP.009EC13A
009EC131    NOP
009EC132    NOP
009EC133    MOV BYTE PTR DS:[EDI], 79
009EC136    JMP SHORT BMP.009EC195
009EC138    NOP
009EC139    NOP
009EC13A    MOV BYTE PTR DS:[EDI], 78
009EC13D    JMP SHORT BMP.009EC195
009EC13F    NOP
009EC140    NOP
009EC141    NOP
009EC142    NOP
009EC143    NOP
009EC144    MOV EBXDWORD PTR DS:[EDX+20]
009EC147    XOR EBXEAX
009EC149    JE SHORT BMP.009EC162
009EC14B    TEST EAXEAX
009EC14D    JE SHORT BMP.009EC158
009EC14F    NOP
009EC150    NOP
009EC151    MOV BYTE PTR DS:[EDI], 71
009EC154    JMP SHORT BMP.009EC195
009EC156    NOP
009EC157    NOP
009EC158    MOV BYTE PTR DS:[EDI], 70
009EC15B    JMP SHORT BMP.009EC195
009EC15D    NOP
009EC15E    NOP
009EC15F    NOP
009EC160    NOP
009EC161    NOP
009EC162    MOV EBXDWORD PTR DS:[EDX+10]
009EC165    XOR EBXEAX
009EC167    JE SHORT BMP.009EC180
009EC169    TEST EAXEAX
009EC16B    JE SHORT BMP.009EC176
009EC16D    NOP
009EC16E    NOP
009EC16F    MOV BYTE PTR DS:[EDI], 73
009EC172    JMP SHORT BMP.009EC195
009EC174    NOP
009EC175    NOP
009EC176    MOV BYTE PTR DS:[EDI], 72
009EC179    JMP SHORT BMP.009EC195
009EC17B    NOP
009EC17C    NOP
009EC17D    NOP
009EC17E    NOP
009EC17F    NOP
009EC180    TEST EAXEAX
009EC182    JE SHORT BMP.009EC190
009EC184    NOP
009EC185    NOP
009EC186    MOV BYTE PTR DS:[EDI], 0EB
009EC189    JMP SHORT BMP.009EC195
009EC18B    NOP
009EC18C    NOP
009EC18D    NOP
009EC18E    NOP
009EC18F    NOP
009EC190    MOV BYTE PTR DS:[EDI], 90
009EC193    NOP
009EC194    NOP
009EC195    RETN

 
在009EC045處下斷,執行之前,記得把int3原始表複製到401000開始處。執行停住。從405f00到419b00有四個表:

405f00~40ae00  int3地址表
40ae00~40fd00  跳轉型別表
40fd00~414c00  跳轉量表
414c00~419b00  跳轉命令長度表

把405f00~419b00複製下來儲存好。接下來要用。

Blaze Media Pro5.05脫殼(armadillo)+基本修復CC(int3)+破解(三)


繼續修復cc。

在(二)中我們得到了四張表 :

int3地址表 (實際地址+1)   
跳轉型別表      
跳轉量表        
跳轉命令長度表 (實際長度-1)


在OD中開啟已脫殼程式,現在殼已經是垃圾了,我們就用用它的空間吧。把前面儲存的連續的四個表複製到殼開始的空間,我這兒是9d1000。得到:
9d1000~9d5f00  int3地址表
9d5f00~9dae00  跳轉型別表
9dae00~9dfd00  跳轉量表
9dfd00~9e4c00  跳轉命令長度表


隨便找個地方寫入下列程式碼:

009E4C04    XOR ECXECX
009E4C06    MOV EAXDWORD PTR DS:[ECX*4+9D1000]         //取出int3地址
009E4C0E    CMP EAX, 0
009E4C11    JE SHORT dumped_.009E4C80
009E4C13    MOVZX EDXBYTE PTR DS:[ECX+9D5F00]          //跳轉型別
009E4C1A    MOV EBXDWORD PTR DS:[ECX*4+9DAE00]         //跳轉量
009E4C22    MOVZX EDIBYTE PTR DS:[ECX+9DFD00]          //跳轉命令長度
009E4C29    DEC EAX
009E4C2A    INC ECX
009E4C2B    CMP DWORD PTR DS:[EAX], EC8B55CC             //進一步排除無效的int3
009E4C31    JE SHORT dumped_.009E4C06
009E4C33    CMP BYTE PTR DS:[EAX-1], 0CC
009E4C37    JE SHORT dumped_.009E4C06
009E4C39    CMP BYTE PTR DS:[EAX+1], 0CC
009E4C3D    JE SHORT dumped_.009E4C06
009E4C3F    NOP
009E4C40    CMP EDI, 1
009E4C43    JNZ SHORT dumped_.009E4C4E
009E4C45    MOV BYTE PTR DS:[EAX], DL                             //短跳轉
009E4C47    DEC BL
009E4C49    MOV BYTE PTR DS:[EAX+1], BL
009E4C4C    NOP
009E4C4D    NOP
009E4C4E    CMP EDI, 5
009E4C51    JNZ SHORT dumped_.009E4C64
009E4C53    MOV BYTE PTR DS:[EAX], 0F                             //條件長跳轉
009E4C56    ADD DL, 10
009E4C59    MOV BYTE PTR DS:[EAX+1], DL
009E4C5C    SUB EBX, 5
009E4C5F    MOV DWORD PTR DS:[EAX+2], EBX
009E4C62    NOP
009E4C63    NOP
009E4C64    CMP EDI, 4
009E4C67    JNZ SHORT dumped_.009E4C79
009E4C69    CMP DL, 0EB
009E4C6C    JNZ SHORT dumped_.009E4C79
009E4C6E    MOV BYTE PTR DS:[EAX], 0E9                           //絕對長跳轉
009E4C71    SUB EBX, 4
009E4C74    MOV DWORD PTR DS:[EAX+1], EBX
009E4C77    NOP
009E4C78    NOP
009E4C79    JMP dumped_.009E4BFA
009E4C7E    NOP
009E4C7F    NOP
009E4C80    NOP
               
在009E4C04處New origin here,在009E4C80下斷,執行停住。修復了大部分int3。把修復好的程式另存為一檔案。

現在工作結束了嗎?答案是沒有。你執行修復的檔案看看,還出錯。如下程式碼:


006539B4    85C9            TEST ECXECX
006539B6    CC              INT3
006539B7    7A C7           JPE SHORT dumped_.00653980
006539B9    45              INC EBP
006539BA    FC              CLD
006539BB    2E:0000         ADD BYTE PTR CS:[EAX], AL
006539BE    00CC            ADD AHCL                        //這裡的cc也是int3
006539C0    B7 8A           MOV BH, 8A
006539C2    71 0A           JNO SHORT dumped_.006539CE


把006539B6處的int3修復好以後,變成如下程式碼:

006539B4    85C9               TEST ECXECX
006539B6    75 12              JNZ SHORT dumped_1.006539CA
006539B8    C745 FC 2E000000   MOV DWORD PTR SS:[EBP-4], 2E
006539BF    CC                 INT3
006539C0    B7 8A              MOV BH, 8A
006539C2    71 0A              JNO SHORT dumped_1.006539CE

這時在006539BF處的在OD才顯示正確的int3。

怎麼辦?你得把修復的檔案按照(二)(三)中的步驟再來一遍。麻煩吧。經過兩次修復後,程式終於可以正常執行了,但有些功能不能用,還沒破解。


(三)破解

 破解我就不詳細說了。vb程式,挺麻煩的。

 1、功能破解:
                                                                                                                                                                                         
   從401000開始查詢unicode碼“DAYSLEFT”,在4876b0。在4876c8處有一unicode碼“20",改成0即可。                                                                                        
                                                                                                                 
 2、about選單顯示: 
                                                                                            
   從401000開始查詢unicode碼“Registered to”,在49e904。然後查詢命令“push 49e904”可以定位about選單的程式碼。     
                                                                                                                 
  00842120    PUSH dumped_c.0049E904                   ; UNICODE "Registered To:  "              
  00842125    PUSH EDX                                                                           
  00842126    MOV EBXDWORD PTR DS:[ESI]                                                        
  00842128    CALL DWORD PTR DS:[<&msvbvm60.__vbaStrCa>; msvbvm60.__vbaStrCat                    
                                                                                                 
  修改:                                                                                         
  00841F4F    JE dumped_c.0084216F        JE->JNE                                                
                                                                                                 
  00841FF2    JE BMP_crac.008420AE        JE->JNE                                               
   
   
   
 pyzpyz
 2004.4.22

相關文章