脱一个PECompact2.X的壳

来源:互联网 发布:霍布斯鲍姆 知乎 编辑:程序博客网 时间:2024/05/17 02:45

RamSmash 手动脱壳+破解
作者:enolaZ
软件说明:这个软件是优化内存用的,注册与未注册在功能上没有区别,但未注册版本会每小时弹出一个要求注册的NAG窗口,当选择REGISTER NOW的BUTTON后会打开注册网页(有时好象是一堆。。)
破解目的:手动脱壳去掉该NAG窗口
声明: 本文纯属学习交流,请不要随意散布或用于商业用途。在下菜鸟一只,欢迎各位高手批评指教

 

用OD加载,停在入口处
00401000 > $ B8 7CAF5900    MOV EAX,RamSmash.0059AF7C    ;SEH的handle地址,在此HANDLER地址                                                         ; 设断
00401005   . 50             PUSH EAX                 
00401006   . 64:FF35 000000>PUSH DWORD PTR FS:[0]                   
0040100D   . 64:8925 000000>MOV DWORD PTR FS:[0],ESP     ;在这里建立了SEH chain
00401014   . 33C0           XOR EAX,EAX
00401016   . 8908           MOV DWORD PTR DS:[EAX],ECX   ;出现内存读异常
00401018   . 50             PUSH EAX
00401019   . 45             INC EBP
0040101A   . 43             INC EBX
0040101B   . 6F             OUTS DX,DWORD PTR ES:[EDI]              
0040101C   . 6D             INS DWORD PTR ES:[EDI],DX               
0040101D   . 70 61          JO SHORT RamSmash.00401080
0040101F   . 637432 00      ARPL DWORD PTR DS:[EDX+ESI],ESI
00401023   . 8E13           MOV SS,WORD PTR DS:[EBX]                
00401025   . FC             CLD

004016处shift+F9来到之前设断的handler地址处

0059AF7C   B8 019D59F0      MOV EAX,F0599D01
0059AF81   8D88 9E120010    LEA ECX,DWORD PTR DS:[EAX+1000129E]
0059AF87   8941 01          MOV DWORD PTR DS:[ECX+1],EAX
0059AF8A   8B5424 04        MOV EDX,DWORD PTR SS:[ESP+4]
0059AF8E   8B52 0C          MOV EDX,DWORD PTR DS:[EDX+C]
0059AF91   C602 E9          MOV BYTE PTR DS:[EDX],0E9
0059AF94   83C2 05          ADD EDX,5
0059AF97   2BCA             SUB ECX,EDX
0059AF99   894A FC          MOV DWORD PTR DS:[EDX-4],ECX
0059AF9C   33C0             XOR EAX,EAX               ;执行到这里后回头看看                                                           ; 00401016,变成了JMP                                                                 ; RamSmash.0059AF9F


0059AF9E   C3               RETN                      ;不要F7或F8这条语句,否则                                                       ; 会迷失在系统代码里。对                                                          ; 0059af9f设断F9运行
0059AF9F   B8 78563412      MOV EAX,12345678          ;中断在这里

F8一路跟下去,来到
0059B01A   FFD7             CALL EDI                            ;F7跟进去
0059B01C   8985 3F130010    MOV DWORD PTR SS:[EBP+1000133F],EAX
0059B022   8BF0             MOV ESI,EAX
0059B024   8B4B 14          MOV ECX,DWORD PTR DS:[EBX+14]
0059B027   5A               POP EDX
0059B028   EB 0C            JMP SHORT RamSmash.0059B036
0059B02A   03CA             ADD ECX,EDX
0059B02C   68 00800000      PUSH 8000
0059B031   6A 00            PUSH 0
0059B033   57               PUSH EDI
0059B034   FF11             CALL DWORD PTR DS:[ECX]
0059B036   8BC6             MOV EAX,ESI
0059B038   5A               POP EDX
0059B039   5E               POP ESI
0059B03A   5F               POP EDI
0059B03B   59               POP ECX
0059B03C   5B               POP EBX
0059B03D   5D               POP EBP
0059B03E   FFE0             JMP EAX      ;这里就是跳向OEP的语句,但是现在我们不能直接设断                                          ; 然后F9,shift+F9。至于为什么,下面会提到

现在我们在0059B01A   FFD7             CALL EDI 用F7进去

继续F8来到:
003F0AE2   8B85 291F0010    MOV EAX,DWORD PTR SS:[EBP+10001F29] ;                                                         ;kernel32.IsDebuggerPresent      
003F0AE8   85C0             TEST EAX,EAX
003F0AEA   74 07            JE SHORT 003F0AF3
003F0AEC   FFD0             CALL EAX                                
003F0AEE   85C0             TEST EAX,EAX                             ;改为XOR EAX,EAX  
003F0AF0   74 01            JE SHORT 003F0AF3

继续F8
003F0B40   8B4E 34          MOV ECX,DWORD PTR DS:[ESI+34]
003F0B43   85C9             TEST ECX,ECX                             ;ECX的值是IAT的地址的首地址,改为XOR ECX,ECX
003F0B45   0F84 89000000    JE 003F0BD4                              ;强制跳(JMP)
003F0B4B   034E 08          ADD ECX,DWORD PTR DS:[ESI+8]
003F0B4E   51               PUSH ECX
003F0B4F   56               PUSH ESI
003F0B50   E8 47060000      CALL 003F119C

跳到003F0BD4后,继续F8
003F0C0E   57               PUSH EDI                                
003F0C0F   E8 37070000      CALL 003F134B                            ;F7进去

003F134B   55               PUSH EBP
003F134C   8BEC             MOV EBP,ESP
003F134E   83C4 FC          ADD ESP,-4
003F1351   53               PUSH EBX
003F1352   57               PUSH EDI
003F1353   56               PUSH ESI
003F1354   E8 00000000      CALL 003F1359
003F1359   5B               POP EBX
003F135A   81EB 341C0010    SUB EBX,10001C34
003F1360   8B45 08          MOV EAX,DWORD PTR SS:[EBP+8]    ;将ImageBase=00400000传给EAX
003F1363   0340 3C          ADD EAX,DWORD PTR DS:[EAX+3C]   ;[eax+3c]里是OEP的VA地址,因                                                            ; 此EAX里就是OEP的地址了
003F1366   33C9             XOR ECX,ECX

现在在0059B03E   FFE0      JMP EAX设断F9到此,跳转就能来到OEP了。
然后DUMP,ImportREC。脱壳完毕

之所以之前说不能直接在此设断,是因为在003F0AEE和003F0B43处的修改是必须的,否则在003F1360处的[ebp+8]就成了40000000而003F1363也会产生内存读异常,即使改了CONTEXT.EIP跳过,最终的0059B03E  JMP EAX也会跳到一个不可执行的地址40094254。其实这个壳的结构应该就是PECompcat2.X的,但PECompact2.X的我也脱过,可以下断点后直接F9,SHIFT+F9来到OEP,似乎是没用上面所说的这个情况的

脱壳完了后,用W32Dasm打开,用string reference看下程序中的字符串。好,该加密的都加了,但却看到了一个有用的信息:
“RamSmash Evaluation Time Over!RamSmash......"这一大段字符串,而这恰恰是NAG窗口的内容.现在点击这个字符串来到00491D58的
地址,果然在下面就是打开注册网页的代码。
于是再用OD打开程序,直接在00491D58处

00491D58  |. BA A01D4900    MOV EDX,ram_.00491DA0      ;  ASCII "RamSmash Evaluation Time Over!

                                                      ;RamSmash is limited to a 60 minute demonstration, please register
                                                       ; to remove this time limit restriction.  The RamSmash application
                                                       ; will automatically restart again for another 60 minute trial.

                                                      ; Would y"...
00491D5D  |. E8 AA59FDFF    CALL ram_.0046770C
00491D62  |. A1 E0814900    MOV EAX,DWORD PTR DS:[4981E0]
00491D67  |. 8B00           MOV EAX,DWORD PTR DS:[EAX]
00491D69  |. 8B10           MOV EDX,DWORD PTR DS:[EAX]
00491D6B  |. FF92 EC000000  CALL DWORD PTR DS:[EDX+EC]
00491D71  |. 48             DEC EAX
00491D72  |. 75 20          JNZ SHORT ram_.00491D94
00491D74  |. 6A 05          PUSH 5                                   ; /IsShown = 5
00491D76  |. 6A 00          PUSH 0                                   ; |DefDir = NULL
00491D78  |. 6A 00          PUSH 0                                   ; |Parameters = NULL
00491D7A  |. 68 A81E4900    PUSH ram_.00491EA8                       ; |FileName = "http://www.swiftdog.com/store/?product=ramsmash"
 00491D7F  |. 68 D81E4900    PUSH ram_.00491ED8                       ; |Operation =                                                                      ;"open"
00491D84  |. A1 6C814900    MOV EAX,DWORD PTR DS:[49816C]            ; |
00491D89  |. 8B00           MOV EAX,DWORD PTR DS:[EAX]               ; |
00491D8B  |. 8B40 30        MOV EAX,DWORD PTR DS:[EAX+30]            ; |
00491D8E  |. 50             PUSH EAX                                 ; |hWnd
00491D8F  |. E8 F401FCFF    CALL ram_.00451F88                       ; /ShellExecuteA
00491D94  |> B0 01          MOV AL,1
00491D96  /. C3             RETN

好了,到这里,基本就可以算是成功了,可以用HIEW把00491D5D,00191D6B,00491D71,00491D8F 给NOP掉,也可以跳过他们。
然后就不会弹出NAG窗口了。收工。。。
 

其实这个壳就是PEC2.X,如果用了隐藏OD的插件,应该就可以不用修改03FF0AEE的指令,也就可以用脱PEC2.X的通用办法了