ARM Copy MEM II標準殼脫殼

【目     標】:傳奇外掛1.07
【工     具】:Olydbg1.1(diy版)、LORDPE、ImportREC1.6F
【任     務】: ARM 3.6或以下版本的COPYMEM II標準殼
【操作平臺】:WinXP sp2
【作     者】: LOVEBOOM[DFCG][FCG][US]
【相關鏈接】: ……

【簡要說明】: 這是一個ARM3.6或以下版本的COPYMEM II殼來的,殼沒有亂序,也沒有抽殼代碼的。所以比較容易。
【詳細過程】:
OD設置:忽略全部異常用修改過的OD(必須PATCH過OutputDebugStringA漏洞),隱藏OD,忽略LOCKX(C000001E),如下圖:
脫殼過程分爲四部分:找OEPDUMP程序、修復IAT,修復優化主程序。
第一部分:找OEP
用OD載入目標程序:
0056E379 >/$  55            PUSH EBP                                 ;  殼入口
0056E37A  |.  8BEC          MOV EBP,ESP
……
因爲3.7以下版本的ARM不會檢測全部API的CC斷點。所以可以直接下斷BP。先下BP
WaitForDebugEvnet斷點,然後F9運行,到這裏停下:
7C85A268 >  8BFF            MOV EDI,EDI                              ; 第一次停這裏,停下後注意觀察堆棧.
7C85A26A    55              PUSH EBP
7C85A26B    8BEC            MOV EBP,ESP
……
 
 
 
 
停下後去除CC斷點,看看堆棧的信息:
注意ESP+4處的地址,在dump窗口中顯示該地址信息:
再下bp WaiteProcessMemory斷點並運行,斷下後看看我們剛纔地DUMP窗口中就可以找到程序有OEP了。
OEP在1C處,這個程序的OEP也就是4014AC,記下先。到這裏第一部分就算完成了。
第二部分:DUMP程序
知道OEP後,如果你現在直接去follow 4014AC的話,你將什麼都得不到,看看剛纔斷下地方的堆棧信息,我們可以得到我們要用的東西:
先算出真正代碼所在的位置,計算方法爲:OEP減去堆棧ESP+8處的address 401000加上ESP+0C處的Buffer 003c64b8,(至於爲什麼,可以去參考相關的文章。)所以這個程序的OEP代碼爲:4014AC-401000+003C64B8=003C6964.
003C6964   /EB 10           JMP SHORT 003C6976                       ; 這裏就是程序原OEP代碼
003C6966   |66:623A         BOUND DI,DWORD PTR DS:[EDX]
003C6969   |43              INC EBX
003C696A   |2B2B            SUB EBP,DWORD PTR DS:[EBX]
003C696C   |48              DEC EAX
以前有關文章到這裏後要再處理下再DUMP,不過這個程序不用處理的,附以前文章裏說的處理地方,你也可以直接跳過這一步到NEXT1處。
下面以這個爲例說說處理的情況.先看堆棧:
0012D98C   0056C421  /CALL to WriteProcessMemory from MLEx.0056C41B
0012D990   0000004C  |hProcess = 0000004C (window)
0012D994   00401000  |Address = 401000
0012D998   003C64B8  |Buffer = 003C64B8
0012D99C   00001000  |BytesToWrite = 1000 (4096.)
0012D9A0   0012DAA8  /pBytesWritten = 0012DAA8
0012D9A4   00000002
0012D9A8   00000002
0012D9AC   0012F5A4
0012D9B0   00000000
0012D9B4   00000000
0012D9B8   00000000
0012D9BC   00000000
0012D9C0   00000000
0012D9C4   00000000
0012D9C8   00000000
0012D9CC   00000000
0012D9D0   00000000
0012D9D4   00000000
0012D9D8   00000000
0012D9DC   00000000
0012D9E0   00000000
0012D9E4   00000000
0012D9E8   00000000
0012D9EC   00000000
0012D9F0   00000000
0012D9F4   00000000
0012D9F8   00000000
0012D9FC   00000000
0012DA00   00000000
0012DA04   0012BDA4
0012DA08   00000000
0012DA0C   7C9305C8  RETURN to ntdll.7C9305C8 from ntdll.7C922F2F
0012DA10   005EC790  MLEx.005EC790
0012DA14   0012BE70
0012DA18   7C930551  RETURN to ntdll.7C930551 from ntdll.7C9305A2
0012DA1C   00561378  MLEx.00561378
0012DA20   7C93056D  RETURN to ntdll.7C93056D from ntdll.7C92EE02
0012DA24   0012BEC4
0012DA28   00000000
0012DA2C   00000000
0012DA30   00000000
0012DA34   00000000
0012DA38   00000020
0012DA3C   0012C368
0012DA40   0012BDEC
0012DA44   004A6C1C  MLEx.004A6C1C
0012DA48   0012C7FC
0012DA4C   0012BE20
0012DA50   00000039
0012DA54   004C1AB5  MLEx.004C1AB5
0012DA58   0012BE20
0012DA5C   0012BE08
0012DA60   004A6E3B  MLEx.004A6E3B
0012DA64   0012BE20
0012DA68   00000039
0012DA6C   0012C368
0012DA70   00000001
0012DA74   00000000
0012DA78   0012C340
0012DA7C   004A77D8  MLEx.004A77D8
0012DA80   0012BE20
0012DA84   828BF055
0012DA88   003C74B8
0012DA8C   003C74B8
0012DA90   5C3A4431
0012DA94   75636F44
0012DA98   00000020
0012DA9C   00401000  MLEx.00401000
0012DAA0   00000020
0012DAA4   003C74B8
0012DAA8   00001000
0012DAAC   003C74B8
0012DAB0  /0012DAE4
0012DAB4  |0056B12E  RETURN to MLEx.0056B12E from MLEx.0056B475
0012DAB8  |00000000
在0012DAB4處右鍵跟隨:
在代碼窗口中到這裏:
0056B129   .  E8 47030000   CALL 0056B475                            ;  這個CALL處理解碼
0056B12E   >  83C4 0C       ADD ESP,0C                               ;  跟隨到這裏
……
到這裏後CTRL+F查找命令:CALL 0056B475共會找到兩處(如果ARM3.7或以上版本,會有好幾個的),第二個地方爲:
0056B3E4   .  E8 8C000000   CALL 0056B475                            ;  第二個地方
0056B3E9   .  83C4 0C       ADD ESP,0C
0056B3EC   .  9C            PUSHFD
0056B3ED   .  60            PUSHAD
……
第二地方NOP掉就行了:
0056B3E4      90            NOP                                      ;  第二個地方
0056B3E5      90            NOP
0056B3E6      90            NOP
0056B3E7      90            NOP
0056B3E8      90            NOP
0056B3E9   .  83C4 0C       ADD ESP,0C
處理完畢。
 
 
 
l         NEXT1:
到這裏後,修改一下代碼就要DUMP了,讓程序掛起來才能DUMP出來,用和SICE的方法一樣改EIP爲JMP EIP就行了。
修改003C6964:
003C6964   /EB 10           JMP SHORT 003C6976
003C6966   |66:623A         BOUND DI,DWORD PTR DS:[EDX]
003C6969   |43              INC EBX
003C696A   |2B2B            SUB EBP,DWORD PTR DS:[EBX]
修改爲:
003C6964  - EB FE           JMP SHORT 003C6964
003C6966    66:623A         BOUND DI,DWORD PTR DS:[EDX]
003C6969    43              INC EBX
003C696A    2B2B            SUB EBP,DWORD PTR DS:[EBX]
003C696C    48              DEC EAX
這然後讓程序“掛起來”,打開LORDPE選擇第二個進程,然後選擇ARMDUMP的插件,
選擇好後就可以dump full程序。第二部分完畢。
 
第三部分:修復IAT
代碼已經DUMP下來了,我們現在要修復IAT。關閉前面打開的OD,然後用OD載入剛纔DUMP的程序,在OEP附件找到一下IAT的地起位置。比較簡單的找到的地址533000(起始位置前一點不用擔心搞錯J)。記得地址後,用OD再次載入目標,下斷:bp DebugActiveProcess,運行後斷下,就可以看到PROCESS ID了。到這裏後,再開一個OD來附加這個PROCESS。附加後中斷在系統中,按F9運行,運行中按F12停止就可以到殼代碼處,因爲那裏的代碼是死循環的:-)
0056E379 >- EB FE           JMP SHORT <ModuleEntryPoint>                停在這裏
0056E37B    EC              IN AL,DX                                 ; I/O command
暫停後把EP代碼改回去,改成558B(push ebp,mov ebp,esp),其實到了這裏殼就像是一個雙進程標準殼了,按雙進程標準殼的方法就可以獲取到IAT。具體方法:
改回代碼後直接下斷BP OpenMutexA,F9運行後中斷然後清除斷點記下ESP+C的內容。
在一空白處寫入以下代碼:
00401000    60              PUSHAD
00401001    9C              PUSHFD
00401002    68 F0FB1200     PUSH 12FBF0                              ; ASCII "168::DAC4C6C5E3"
00401007    33C0            XOR EAX,EAX
00401009    50              PUSH EAX
0040100A    50              PUSH EAX
0040100B    E8 2FDB407C     CALL kernel32.CreateMutexA
00401010    9D              POPFD
00401011    61              POPAD
00401012  - E9 04DC407C     JMP kernel32.OpenMutexA
把EIP定位到代碼處(Ctrl+*),寫完代碼後更改OD異常設置:
打開內存訪問錯誤異常。然後F9運行程序,內存異常斷下後,忽略全部的異常並下斷Bp GetModuleHandleA+5,Shit+f9忽略異常繼續運行,API斷下後,取消斷點,ALT+F9執行返回到用戶代碼:
00CA532B    FF15 A450CC00   CALL DWORD PTR DS:[CC50A4]               ; kernel32.GetModuleHandleA
00CA5331    8B0D 60D8CC00   MOV ECX,DWORD PTR DS:[CCD860]            ; 返回到這裏
00CA5337    89040E          MOV DWORD PTR DS:[ESI+ECX],EAX
00CA533A    A1 60D8CC00     MOV EAX,DWORD PTR DS:[CCD860]
00CA533F    393C06          CMP DWORD PTR DS:[ESI+EAX],EDI
00CA5342    75 16           JNZ SHORT 00CA535A
00CA5344    8D85 B4FEFFFF   LEA EAX,DWORD PTR SS:[EBP-14C]
00CA534A    50              PUSH EAX
00CA534B    FF15 B850CC00   CALL DWORD PTR DS:[CC50B8]               ; kernel32.LoadLibraryA
00CA5351    8B0D 60D8CC00   MOV ECX,DWORD PTR DS:[CCD860]
00CA5357    89040E          MOV DWORD PTR DS:[ESI+ECX],EAX
00CA535A    A1 60D8CC00     MOV EAX,DWORD PTR DS:[CCD860]
00CA535F    393C06          CMP DWORD PTR DS:[ESI+EAX],EDI
00CA5362    0F84 AD000000   JE 00CA5415                              ; 這裏Magic jmp 改爲JMP
;改爲JMP 00CA5415
00CA5368    33C9            XOR ECX,ECX
00CA536A    8B03            MOV EAX,DWORD PTR DS:[EBX]
修改完後ALT+M打開內存頁面,在text段下斷:
下斷完畢F9就到OEP處:
004014AC    6D              INS DWORD PTR ES:[EDI],DX                ; 中斷在這裏,雖然到這裏代碼不能用,但可以獲取到正確的IAT
004014AD    66:16           PUSH SS
……
斷下後用ImportREC對PROCESS進行IAT修復操作,IAT的開始地址用我們上面記下的533000-400000=133000,大小可以寫大一點(當然你也可以計算的).cut無效的指針再FIXDUMP就行了。附圖:
修復IAT完畢(注:如果是3.7X或以上版本還有亂序,操作多一點)。
 
 
 
第四部分:修復程序/優化
程序現在已經基本搞完了,現在做一點收尾的工作。關掉兩個OD,用lordpe改回OEP的代碼。把沒有用的段清除掉然後用LordPE FIXDUMP一下:
 
Finished!J .
 
Greetz:
 Fly.Jingulong,yock,tDasm.David.hexer,hmimys,ahao.UFO(brother).alan(sister).all of my friends and you!
 
By loveboom[DFCG][FCG][US]
Email:loveboom#163.com
Date:2006-3-27 16:57
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章