2011年9月14日星期三

[轉載]ACProtect1.41保護技術分析


作 者: 鄧韜
時 間: 2011-09-11,20:48:02
鏈接: http://bbs.pediy.com/showthread.php?t=139995

這個殼很老了,但是還是來分析下它所使用的保護技術,這個殼是使用加密解密三的SMC那章的保護技術,依次循環解碼,分幾個段,由當前段解碼加密後的字節碼,放到下一個執行段,當前段解碼執行完成後,執行下一段解出來的代碼,每段解碼代碼中包含了花指令,代碼變形,迷惑等等,當解壓到最後一段代碼的時候,這個殼就直接一個JMP跳到Oep了,我們脫這個殼分為兩個步驟,
第一步:清除花指令
第二部:查找迷惑變形代碼
我們首先清除花指令,花指令的清除比較簡單,比如下面這段代碼

代碼:
00405000 > 60 PUSHAD
00405001 EB 01 JMP SHORT 00405004 ; JMP SHORT 00405004
00405003 E8 0F810100 CALL 0041D117
00405008 0000 ADD BYTE PTR DS:[EAX],AL
那個JMP那裡跳到405004,這裡沒的405004,有405003,所以405003就是一個花指令了我們直接二進制編輯NOP掉,這樣依次循環下去,我們就能清除花指令了,實際上那個JMP指令也是無用的,我們第一段解碼代碼清除後總結下花指令的組合方式
花指令清除後,變形代碼的清除。
下面這段代碼模擬JMP指令
代碼:
00405016 /7E 03 JLE SHORT 0040501B
00405018 |7F 01 JG SHORT 0040501B
下面這段代碼清除花指令後可以直接NOP掉,因為他什麼作用都沒的,用來迷惑我們的
代碼:
0040502A 50 PUSH EAX
0040502B E8 01000000 CALL 00405031 ; 花指令,下指令的開始字節NOP掉
00405030 - 76 83 JBE SHORT 00404FB5
花指令後的代碼
0040502A 50 PUSH EAX ; 保存EAX的值
0040502B E8 01000000 CALL 00405031 ; Call會壓入下個地址到堆棧,esp-4
00405030 90 NOP
00405031 83C4 04 ADD ESP,4 ; 恢復堆棧,ESP+4
00405034 58 POP EAX ; 恢復EAX的值
下面這段代碼也是什麼作用都沒的,也是用來迷惑我們的

代碼:
00405036 E8 01000000 CALL 0040503C
0040503B - 7C 83 JL SHORT 00404FC0 ; 花指令
0040503D 04 24 ADD AL,24
清除後的代碼
00405036 E8 01000000 CALL 0040503C ; Call會壓入下個地址到堆棧,esp-4
0040503B 90 NOP ; 花指令
0040503C 830424 06 ADD DWORD PTR SS:[ESP],6 ; 下條指令的地址加上6,CALL的下一條指令到RETN剛好6字節,所以目標地址就是RETN後一條指令
00405040 C3 RETN
這種情況下的JMP指令也是可以NOP掉的

代碼:
00405043 /EB 01 JMP SHORT 00405046 ; 直接跳到XXXX地址,其下的代碼到目標地址之間的代碼是無效的
00405045 |90 NOP ; 花指令
無用代碼
代碼:
0040508B E8 01000000 CALL 00405091
00405090 90 NOP
00405091 83C4 04 ADD ESP,4
不可以NOP的代碼
代碼:
004050BD /0F83 05000000 JNB 004050C8 ; 不可NOP
004050C3 |66:81E2 73A2 AND DX,0A273
004050C8 \EB 01 JMP SHORT 004050CB ; 可以NOP
另一種情況
代碼:
00405101 /7C 03 JL SHORT 00405106
00405103 |7D 01 JGE SHORT 00405106 ; 模擬JMP,跳到下面的jmp
00405105 |90 NOP
00405106 \E9 06000000 JMP 00405111 ; 跳到另一個地址,其模擬JMP指令開始的地方到目標地址的上個指令都是無效
0040510B 46 INC ESI ; 無效
0040510C B8 6D9231A7 MOV EAX,A731926D ; 無效
這是我第一段的解碼指令清除後的代碼,
代碼:
00405000 > 60 PUSHAD
00405001 90 NOP ; JMP SHORT 00405004
00405002 90 NOP
00405003 90 NOP
00405004 0F81 01000000 JNO 0040500B
0040500A 41 INC ECX
0040500B 4A DEC EDX
0040500C F9 STC
0040500D F8 CLC
0040500E FC CLD
0040500F 66:8BF7 MOV SI,DI
00405012 46 INC ESI
00405013 66:8BF0 MOV SI,AX
00405016 7E 03 JLE SHORT 0040501B
00405018 7F 01 JG SHORT 0040501B
0040501A 90 NOP
0040501B 4A DEC EDX
0040501C 90 NOP
0040501D 90 NOP
0040501E 90 NOP
0040501F 0F8A 05000000 JPE 0040502A
00405025 BE 004176CF MOV ESI,CF764100
0040502A 90 NOP ; 保存EAX的值
0040502B 90 NOP ; Call會壓入下個地址到堆棧,esp-4
0040502C 90 NOP
0040502D 90 NOP
0040502E 90 NOP
0040502F 90 NOP
00405030 90 NOP
00405031 90 NOP ; 恢復堆棧,ESP+4
00405032 90 NOP
00405033 90 NOP
00405034 90 NOP ; 恢復EAX的值
00405035 46 INC ESI
00405036 90 NOP ; Call會壓入下個地址到堆棧,esp-4
00405037 90 NOP
00405038 90 NOP
00405039 90 NOP
0040503A 90 NOP
0040503B 90 NOP ; 花指令
0040503C 90 NOP ; 下條指令的地址加上6,CALL的下一條指令到RETN剛好6字節,所以目標地址就是RETN後一條指令
0040503D 90 NOP
0040503E 90 NOP
0040503F 90 NOP
00405040 90 NOP
00405041 8BF0 MOV ESI,EAX
00405043 90 NOP ; 直接跳到XXXX地址,其下的代碼到目標地址之間的代碼是無效的
00405044 90 NOP
00405045 90 NOP ; 花指令
00405046 87D6 XCHG ESI,EDX
00405048 90 NOP
00405049 90 NOP
0040504A 90 NOP
0040504B 90 NOP
0040504C 90 NOP
0040504D 90 NOP
0040504E 90 NOP
0040504F 90 NOP
00405050 90 NOP
00405051 90 NOP
00405052 90 NOP
00405053 33D7 XOR EDX,EDI
00405055 90 NOP
00405056 90 NOP
00405057 90 NOP
00405058 90 NOP
00405059 90 NOP
0040505A 90 NOP
0040505B 90 NOP
0040505C 90 NOP
0040505D 90 NOP
0040505E 90 NOP
0040505F 90 NOP
00405060 FC CLD
00405061 90 NOP
00405062 90 NOP
00405063 90 NOP
00405064 85EA TEST EDX,EBP
00405066 90 NOP ; JMP,直接跳到目標地址,其現在的代碼到目標之間的代碼直接NOP
00405067 90 NOP
00405068 90 NOP
00405069 90 NOP
0040506A 90 NOP ; 花指令
0040506B 77 02 JA SHORT 0040506F
0040506D 1BEB SBB EBP,EBX
0040506F 90 NOP
00405070 90 NOP
00405071 90 NOP
00405072 90 NOP
00405073 90 NOP
00405074 46 INC ESI
00405075 90 NOP
00405076 90 NOP
00405077 90 NOP
00405078 D3D6 RCL ESI,CL
0040507A 90 NOP
0040507B 90 NOP
0040507C 90 NOP
0040507D 90 NOP
0040507E 90 NOP
0040507F 90 NOP
00405080 90 NOP
00405081 90 NOP
00405082 90 NOP
00405083 90 NOP
00405084 90 NOP
00405085 81F5 E0CDFA12 XOR EBP,12FACDE0
0040508B 90 NOP
0040508C 90 NOP
0040508D 90 NOP
0040508E 90 NOP
0040508F 90 NOP
00405090 90 NOP
00405091 90 NOP
00405092 90 NOP
00405093 90 NOP
00405094 46 INC ESI
00405095 90 NOP
00405096 90 NOP
00405097 90 NOP
00405098 90 NOP
00405099 90 NOP
0040509A 90 NOP
0040509B 90 NOP
0040509C 90 NOP
0040509D 90 NOP
0040509E 90 NOP
0040509F 90 NOP
004050A0 87EA XCHG EDX,EBP
004050A2 90 NOP
004050A3 90 NOP
004050A4 90 NOP
004050A5 90 NOP
004050A6 90 NOP
004050A7 F9 STC
004050A8 90 NOP
004050A9 90 NOP
004050AA 90 NOP
004050AB 46 INC ESI
004050AC 90 NOP
004050AD 90 NOP
004050AE 90 NOP
004050AF 90 NOP
004050B0 90 NOP
004050B1 C1FA 75 SAR EDX,75
004050B4 90 NOP
004050B5 ​​90 NOP
004050B6 90 NOP
004050B7 90 NOP
004050B8 90 NOP
004050B9 90 NOP
004050BA 90 NOP
004050BB 90 NOP
004050BC 90 NOP
004050BD 0F83 05000000 JNB 004050C8 ; 不可NOP
004050C3 66:81E2 73A2 AND DX,0A273
004050C8 90 NOP ; 可以NOP
004050C9 90 NOP
004050CA 90 NOP
004050CB 66:8BD7 MOV DX,DI
004050CE 90 NOP
004050CF 90 NOP
004050D0 90 NOP
004050D1 90 NOP
004050D2 90 NOP
004050D3 90 NOP
004050D4 90 NOP
004050D5 90 NOP
004050D6 90 NOP
004050D7 66:8BD3 MOV DX,BX
004050DA 90 NOP
004050DB 90 NOP
004050DC 90 NOP
004050DD 66:D3CE ROR SI,CL
004050E0 90 NOP
004050E1 90 NOP
004050E2 90 NOP
004050E3 F9 STC
004050E4 68 C1514000 PUSH 004051C1
004050E9 7A 01 JPE SHORT 004050EC
004050EB 40 INC EAX
004050EC 5A POP EDX
004050ED 78 03 JS SHORT 004050F2
004050EF 79 01 JNS SHORT 004050F2
004050F1 90 NOP
004050F2 40 INC EAX
004050F3 BF 4047AA83 MOV EDI,83AA4740
004050F8 66:13F3 ADC SI,BX
004050FB 81EF 4AB300E0 SUB EDI,E000B34A
00405101 90 NOP
00405102 90 NOP
00405103 90 NOP ; 模擬JMP,跳到下面的jmp
00405104 90 NOP
00405105 90 NOP
00405106 90 NOP ; 跳到另一個地址,其模擬JMP指令開始的地方到目標地址的上個指令都是無效
00405107 90 NOP
00405108 90 NOP
00405109 90 NOP
0040510A 90 NOP
0040510B 90 NOP ; 無效
0040510C 90 NOP ; 無效
0040510D 90 NOP
0040510E 90 NOP
0040510F 90 NOP
00405110 90 NOP
00405111 BD F1933A56 MOV EBP,563A93F1
00405116 8BDF MOV EBX,EDI
00405118 81C5 576CC5A9 ADD EBP,A9C56C57
0040511E 90 NOP
0040511F 90 NOP
00405120 90 NOP
00405121 90 NOP
00405122 90 NOP
00405123 90 NOP
00405124 90 NOP
00405125 90 NOP
00405126 90 NOP
00405127 90 NOP
00405128 90 NOP
00405129 85F3 TEST EBX,ESI
0040512B 87C3 XCHG EBX,EAX
0040512D 8B0A MOV ECX,DWORD PTR DS:[EDX]
0040512F 90 NOP
00405130 90 NOP
00405131 90 NOP
00405132 90 NOP
00405133 90 NOP
00405134 66:8BDA MOV BX,DX
00405137 66:D3C6 ROL SI,CL
0040513A 03CF ADD ECX,EDI
0040513C 90 NOP
0040513D 90 NOP
0040513E 90 NOP
0040513F 90 NOP
00405140 90 NOP
00405141 90 NOP
00405142 90 NOP
00405143 90 NOP
00405144 90 NOP
00405145 90 NOP
00405146 90 NOP
00405147 43 INC EBX
00405148 66:D3CE ROR SI,CL
0040514B C1C1 08 ROL ECX,8
0040514E 90 NOP
0040514F 90 NOP
00405150 90 NOP
00405151 90 NOP
00405152 90 NOP
00405153 90 NOP
00405154 90 NOP
00405155 90 NOP
00405156 90 NOP
00405157 90 NOP
00405158 90 NOP
00405159 90 NOP
0040515A 90 NOP
0040515B 90 NOP
0040515C 90 NOP
0040515D 90 NOP
0040515E 90 NOP
0040515F 90 NOP
00405160 90 NOP
00405161 90 NOP
00405162 90 NOP
00405163 90 NOP
00405164 90 NOP
00405165 83EA FC SUB EDX,-4
00405168 030A ADD ECX,DWORD PTR DS:[EDX]
0040516A 83EA 04 SUB EDX,4
0040516D 90 NOP
0040516E 90 NOP
0040516F 90 NOP
00405170 90 NOP
00405171 90 NOP
00405172 90 NOP
00405173 90 NOP
00405174 90 NOP
00405175 90 NOP
00405176 46 INC ESI
00405177 890A MOV DWORD PTR DS:[EDX],ECX
00405179 90 NOP
0040517A 90 NOP
0040517B 90 NOP
0040517C 0F8A 04000000 JPE 00405186
00405182 66:B8 8BA0 MOV AX,0A08B
00405186 81EF 737F09E2 SUB EDI,E2097F73
0040518C 90 NOP
0040518D 90 NOP
0040518E 90 NOP
0040518F 90 NOP
00405190 90 NOP
00405191 66:BE 3699 MOV SI,9936
00405195 83C2 04 ADD EDX,4
00405198 90 NOP
00405199 90 NOP
0040519A 90 NOP
0040519B 90 NOP
0040519C 90 NOP
0040519D 90 NOP
0040519E 90 NOP
0040519F 90 NOP
004051A0 90 NOP
004051A1 90 NOP
004051A2 83C5 FF ADD EBP,-1
004051A5 ^ 0F85 82FFFFFF JNZ 0040512D ; 向上跳轉
下面總結花指令的方式,當有一個JMP指令跳到一個XXXX地址的時候,這個地址不管是不是花指令,其JMP指令到目標地址的上一條指令都是無效的,有模擬JMP指令的時候也是如此,比如Jg Jle指令這樣的代碼到目標地址的上一條指令之間的代碼都是無效的,我們這樣依次清除下去就能看到全部外殼段的代碼了,這段代碼比較長,是依次循環解碼的,就不依依給出了,下面說下脫殼的方法,當裝載進程序後,下一個硬件訪問(hr)斷點,其地址指向ESP​​,這裡是hr 0012FFA4,當我們斷點下好以後,按13次F9就間接跳到OEP了,
跳向OEP的代碼
代碼:
0041C105 61 POPAD
0041C106 EB 01 JMP SHORT 0041C109
0041C108 90 NOP
0041C109 - FF25 4BC14100 JMP DWORD PTR DS:[41C14B] ; GUI1.00401000
來到Oep後我們發現輸入表被加密了,看下代碼:

代碼:
00401000 6A 00 PUSH 0
00401002 E8 27000000 CALL 0040102E ; GetModuleHandleA
00401007 6A 00 PUSH 0
00401009 68 09304000 PUSH 00403009 ; ASCII "Test"
0040100E 68 00304000 PUSH 00403000 ; ASCII "UnpackMe"
00401013 6A 00 PUSH 0
00401015 E8 08000000 CALL 00401022 ; MessageBoxA
0040101A 6A 00 PUSH 0
0040101C E8 07000000 CALL 00401028 ; ExitProcess
00401021 CC INT3
00401022 - FF25 0C204000 JMP DWORD PTR DS:[40200C] ; JMP函數地址,這裡是外殼添加的代碼的地址
00401028 - FF25 04204000 JMP DWORD PTR DS:[402004] ; JMP函數地址,這裡是外殼添加的代碼的地址
0040102E - FF25 00204000 JMP DWORD PTR DS:[402000] ; JMP函數地址,這裡是外殼添加的代碼的地址
代碼:
0040501D 68 09C50F67 PUSH 670FC509
00405022 813424 48728F1B XOR DWORD PTR SS:[ESP],1B8F7248
00405029 C3 RETN ; 返回到7C80B741 (kernel32.GetModuleHandleA)
現在修復輸入表,我們直接把JMP那個地址的內容改為函數的地址,示例
代碼:
00401000 . 6A 00 PUSH 0 ; /pModule = NULL
00401002 . E8 27000000 CALL 0040102E ; \GetModuleHandleA
00401007 . 6A 00 PUSH 0 ; /Style = MB_OK|MB_APPLMODAL
00401009 . 68 09304000 PUSH 00403009 ; |Title = "Test"
0040100E . 68 00304000 PUSH 00403000 ; |Text = "UnpackMe"
00401013 . 6A 00 PUSH 0 ; |hOwner = NULL
00401015 . E8 08000000 CALL 00401022 ; \MessageBoxA
0040101A . 6A 00 PUSH 0 ; /ExitCode = 0
0040101C . E8 07000000 CALL 00401028 ; \ExitProcess
00401021 CC INT3
00401022 $- FF25 0C204000 JMP DWORD PTR DS:[40200C] ; DS:[0040200C]=77D507EA (user32.MessageBoxA)
00401028 .- FF25 04204000 JMP DWORD PTR DS:[402004] ; DS:[00402004]=7C81CB12 (kernel32.ExitProcess)
0040102E $- FF25 00204000 JMP DWORD PTR DS:[402000] ; DS:[00402004]=7C81CB12 (kernel32.ExitProcess)
,然後使用LoadPE重建PE,修復成功,運行程序OK,分析完畢

没有评论:

发表评论