首页
社区
课程
招聘
[原创]手脱UPX-Scrambler RC1.x壳
发表于: 2008-1-9 10:26 3756

[原创]手脱UPX-Scrambler RC1.x壳

2008-1-9 10:26
3756
////////////////////////////////////////////////////////////////////////////////////////////
文件名称:手脱UPX-Scrambler RC1.x壳
目标程序:病毒样本“Trojan/VB.cxg”木马程序
操作环境:Windows XP-SP2
使用工具:Ollydbg 1.10版
编写作者:Coderui
编写时间:2008年01月09日
联系方式:coderui@163.com
作者博客:90eK9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8X3S2A6i4K6u0W2j5X3q4A6k6s2g2Q4x3X3g2U0L8$3#2Q4x3V1k6U0L8$3c8W2M7Y4g2A6

---------------------------------------------------------------------------------------------
介绍:

    UPX-Scrambler RC1.x为压缩壳,可能算是UPX的变形壳吧?反正很容易手脱,适合初学者。以前没写过关于这个壳的脱文,今天写出来和大家分享下,希望对想要学习脱壳并且是刚入门的朋友有帮助。我把壳完整的反汇编代码都贴上来了,对于练习的样例程序随便找个就行,手脱原理都一样。我下边所写的是简单的单步跟踪的方法,其实有经验的朋友可以直接不用跟踪,把代码向下拉一拉(就一小段代码,不是很长的,很容易看到),就看到跨段跳的JMP了,在上边[F2]下断后,然后[F9]运行,再[F8]一次就是程序真正的入口了。
---------------------------------------------------------------------------------------------
OD设置:(OD设置为不忽略任何异常。[F2]:下软断点、[F4]:执行到当前代码处、[F7]:单步步入、[F8]单步步过、[F9]运行。)
请按照注解顺序观看(00)-(01)-(02)…(99),不然很容易混乱。

00412C9F >  90              NOP                                      ; (00)载入后停在这里。我们[F8]单步步过。
00412CA0    61              POPAD
00412CA1    BE 00F04000     MOV ESI,B64_943_.0040F000
00412CA6    8DBE 0020FFFF   LEA EDI,DWORD PTR DS:[ESI+FFFF2000]
00412CAC    57              PUSH EDI
00412CAD    83CD FF         OR EBP,FFFFFFFF
00412CB0    EB 10           JMP SHORT B64_943_.00412CC2              ; (01)[F8]向下跳。
00412CB2    EB 00           JMP SHORT B64_943_.00412CB4
00412CB4  ^ EB EA           JMP SHORT B64_943_.00412CA0
00412CB6  ^ EB E8           JMP SHORT B64_943_.00412CA0
00412CB8    8A06            MOV AL,BYTE PTR DS:[ESI]
00412CBA    46              INC ESI
00412CBB    8807            MOV BYTE PTR DS:[EDI],AL
00412CBD    47              INC EDI
00412CBE    01DB            ADD EBX,EBX
00412CC0    75 07           JNZ SHORT B64_943_.00412CC9
00412CC2    8B1E            MOV EBX,DWORD PTR DS:[ESI]               ; (02)跳到这里,我们[F8]单步步过。
00412CC4    83EE FC         SUB ESI,-4
00412CC7    11DB            ADC EBX,EBX
00412CC9  ^ 72 ED           JB SHORT B64_943_.00412CB8               ; (03)这里会循环回跳N次,我们不要跳。
00412CCB    B8 01000000     MOV EAX,1                                ; (04)我们[F4]:执行到当前代码处,然后[F8]单步步过。
00412CD0    01DB            ADD EBX,EBX
00412CD2    75 07           JNZ SHORT B64_943_.00412CDB              ; (05)[F8]向下跳。
00412CD4    8B1E            MOV EBX,DWORD PTR DS:[ESI]
00412CD6    83EE FC         SUB ESI,-4
00412CD9    11DB            ADC EBX,EBX
00412CDB    11C0            ADC EAX,EAX                              ; (06)跳到这里,我们[F8]单步步过。
00412CDD    01DB            ADD EBX,EBX
00412CDF  ^ 73 EF           JNB SHORT B64_943_.00412CD0
00412CE1    75 09           JNZ SHORT B64_943_.00412CEC              ; (07)[F8]向下跳。
00412CE3    8B1E            MOV EBX,DWORD PTR DS:[ESI]
00412CE5    83EE FC         SUB ESI,-4
00412CE8    11DB            ADC EBX,EBX
00412CEA  ^ 73 E4           JNB SHORT B64_943_.00412CD0
00412CEC    31C9            XOR ECX,ECX                              ; (08)跳到这里,我们[F8]单步步过。
00412CEE    83E8 03         SUB EAX,3
00412CF1    72 0D           JB SHORT B64_943_.00412D00               ; (09)[F8]向下跳。
00412CF3    C1E0 08         SHL EAX,8
00412CF6    8A06            MOV AL,BYTE PTR DS:[ESI]
00412CF8    46              INC ESI
00412CF9    83F0 FF         XOR EAX,FFFFFFFF
00412CFC    74 74           JE SHORT B64_943_.00412D72
00412CFE    89C5            MOV EBP,EAX
00412D00    01DB            ADD EBX,EBX                              ; (10)跳到这里,我们[F8]单步步过。
00412D02    75 07           JNZ SHORT B64_943_.00412D0B              ; (11)[F8]向下跳。
00412D04    8B1E            MOV EBX,DWORD PTR DS:[ESI]
00412D06    83EE FC         SUB ESI,-4
00412D09    11DB            ADC EBX,EBX
00412D0B    11C9            ADC ECX,ECX                              ; (12)跳到这里,我们[F8]单步步过。
00412D0D    01DB            ADD EBX,EBX
00412D0F    75 07           JNZ SHORT B64_943_.00412D18              ; (13)[F8]向下跳。
00412D11    8B1E            MOV EBX,DWORD PTR DS:[ESI]
00412D13    83EE FC         SUB ESI,-4
00412D16    11DB            ADC EBX,EBX
00412D18    11C9            ADC ECX,ECX                              ; (14)跳到这里,我们[F8]单步步过。
00412D1A    75 20           JNZ SHORT B64_943_.00412D3C
00412D1C    41              INC ECX
00412D1D    01DB            ADD EBX,EBX
00412D1F    75 07           JNZ SHORT B64_943_.00412D28              ; (15)[F8]向下跳。
00412D21    8B1E            MOV EBX,DWORD PTR DS:[ESI]
00412D23    83EE FC         SUB ESI,-4
00412D26    11DB            ADC EBX,EBX
00412D28    11C9            ADC ECX,ECX                              ; (16)跳到这里,我们[F8]单步步过。
00412D2A    01DB            ADD EBX,EBX
00412D2C  ^ 73 EF           JNB SHORT B64_943_.00412D1D              ; (17)这里会回跳,我们不要跳。
00412D2E    75 09           JNZ SHORT B64_943_.00412D39              ; (18)我们[F4]:执行到当前代码处,然后[F8]跳。
00412D30    8B1E            MOV EBX,DWORD PTR DS:[ESI]
00412D32    83EE FC         SUB ESI,-4
00412D35    11DB            ADC EBX,EBX
00412D37  ^ 73 E4           JNB SHORT B64_943_.00412D1D
00412D39    83C1 02         ADD ECX,2                                ; (19)跳到这里,我们[F8]单步步过。
00412D3C    81FD 00F3FFFF   CMP EBP,-0D00
00412D42    83D1 01         ADC ECX,1
00412D45    8D142F          LEA EDX,DWORD PTR DS:[EDI+EBP]
00412D48    83FD FC         CMP EBP,-4
00412D4B    76 0F           JBE SHORT B64_943_.00412D5C
00412D4D    8A02            MOV AL,BYTE PTR DS:[EDX]
00412D4F    42              INC EDX
00412D50    8807            MOV BYTE PTR DS:[EDI],AL
00412D52    47              INC EDI
00412D53    49              DEC ECX
00412D54  ^ 75 F7           JNZ SHORT B64_943_.00412D4D             ; (20)这里会回跳,我们不要跳。
00412D56  ^ E9 63FFFFFF     JMP B64_943_.00412CBE                   ; (21)我们[F4]:执行到当前代码处。
                                                                    ; (22)这里JMP的回跳地址是00412CBE,从00412CBE到00412D56这个范围里,会有“00412CC9处的JB跳转”、“00412CFC处的JE跳转”和“00412D4B处的JBE跳转”会跳出这个范围。
                                                                    ; (23)经过详细计算机后,我们可以排除“00412CC9处的JB跳转”,因为它没有危险,不会跑飞。
                                                                    ; (24)接下来我们要在“00412CFC处的JE”跳转后的地址00412D72下断点,还要在“00412D4B处的JBE”跳转后的地址00412D5C下断点。
00412D5B    90              NOP                                     ; (27)现在我们可以大胆的在这里按[F4]执行到当前代码处了,因为我们已经把所有有可能跑飞的边界都下上断点了(貌似“天罗地网”的说)。
00412D5C    8B02            MOV EAX,DWORD PTR DS:[EDX]              ; (25)这里要[F2]下断。 (28)我们上边[F4]后果然跑飞了,程序停在了这里的断点上。看看计算机好跳转的范围并下好所有的断点是不是很重要的基础啊?呵呵!我们现在[F2]取消这里的断点后,继续[F8]单步步过吧。
00412D5E    83C2 04         ADD EDX,4
00412D61    8907            MOV DWORD PTR DS:[EDI],EAX
00412D63    83C7 04         ADD EDI,4
00412D66    83E9 04         SUB ECX,4
00412D69  ^ 77 F1           JA SHORT B64_943_.00412D5C
00412D6B    01CF            ADD EDI,ECX
00412D6D  ^ E9 4CFFFFFF     JMP B64_943_.00412CBE                   ; (29)这里会回跳,我们不要跳,依然要计算好跳转的范围。计算完毕后,发现没有超出跳转范围的可以跳转语句,那么我们就不需要下任何断点了。
00412D72    5E              POP ESI                                 ; (26)这里要[F2]下断。 (30)现在我们可以同样大胆的在这里按[F4]执行到当前代码处了,成功执行到这里了吧?呵呵!我们现在[F2]取消最开始在这里下的断点后,继续[F8]单步步过吧。
00412D73    89F7            MOV EDI,ESI
00412D75    B9 EE030000     MOV ECX,3EE
00412D7A    8A07            MOV AL,BYTE PTR DS:[EDI]
00412D7C    47              INC EDI
00412D7D    2C E8           SUB AL,0E8
00412D7F    3C 01           CMP AL,1
00412D81  ^ 77 F7           JA SHORT B64_943_.00412D7A              ; (31)这里会回跳,我们不要跳。
00412D83    803F 02         CMP BYTE PTR DS:[EDI],2                 ; (32)我们[F4]:执行到当前代码处,然后[F8]单步步过。
00412D86  ^ 75 F2           JNZ SHORT B64_943_.00412D7A
00412D88    8B07            MOV EAX,DWORD PTR DS:[EDI]
00412D8A    8A5F 04         MOV BL,BYTE PTR DS:[EDI+4]
00412D8D    66:C1E8 08      SHR AX,8
00412D91    C1C0 10         ROL EAX,10
00412D94    86C4            XCHG AH,AL
00412D96    29F8            SUB EAX,EDI
00412D98    80EB E8         SUB BL,0E8
00412D9B    01F0            ADD EAX,ESI
00412D9D    8907            MOV DWORD PTR DS:[EDI],EAX
00412D9F    83C7 05         ADD EDI,5
00412DA2    89D8            MOV EAX,EBX
00412DA4  ^ E2 D9           LOOPD SHORT B64_943_.00412D7F           ; (33)这里是个回跳的循环语句,我们不要跳。
00412DA6    8DBE 00000100   LEA EDI,DWORD PTR DS:[ESI+10000]        ; (34)计算了下上边回跳循环语句的范围,发现我们可以直接[F4]:执行到当前代码处,然后[F8]单步步过。
00412DAC    8B07            MOV EAX,DWORD PTR DS:[EDI]
00412DAE    09C0            OR EAX,EAX
00412DB0    74 45           JE SHORT B64_943_.00412DF7
00412DB2    8B5F 04         MOV EBX,DWORD PTR DS:[EDI+4]
00412DB5    8D8430 EC310100 LEA EAX,DWORD PTR DS:[EAX+ESI+131EC]
00412DBC    01F3            ADD EBX,ESI
00412DBE    50              PUSH EAX
00412DBF    83C7 08         ADD EDI,8
00412DC2    FF96 28320100   CALL DWORD PTR DS:[ESI+13228]           ; (35)这个CALL是调系统“kernel32.dll”里的“LoadLibraryA”函数,所以我们可以[F8]单步步过。
00412DC8    95              XCHG EAX,EBP
00412DC9    8A07            MOV AL,BYTE PTR DS:[EDI]
00412DCB    47              INC EDI
00412DCC    08C0            OR AL,AL
00412DCE  ^ 74 DC           JE SHORT B64_943_.00412DAC
00412DD0    89F9            MOV ECX,EDI
00412DD2    79 07           JNS SHORT B64_943_.00412DDB             ; (36)[F8]向下跳。
00412DD4    0FB707          MOVZX EAX,WORD PTR DS:[EDI]
00412DD7    47              INC EDI
00412DD8    50              PUSH EAX
00412DD9    47              INC EDI
00412DDA    B9 5748F2AE     MOV ECX,AEF24857                        ; (37)跳到这里,我们[F8]单步步过。
00412DDF    55              PUSH EBP
00412DE0    FF96 2C320100   CALL DWORD PTR DS:[ESI+1322C]           ; (38)这个CALL是调系统“kernel32.dll”里的“GetProcAddress”函数,所以我们可以[F8]单步步过。
00412DE6    09C0            OR EAX,EAX
00412DE8    74 07           JE SHORT B64_943_.00412DF1
00412DEA    8903            MOV DWORD PTR DS:[EBX],EAX
00412DEC    83C3 04         ADD EBX,4
00412DEF  ^ EB D8           JMP SHORT B64_943_.00412DC9             ; (39)这里是个回跳的循环语句,我们不要跳。
                                                                    ; (40)发现需要在“00412DF7”地址处下断点。
00412DF1    FF96 30320100   CALL DWORD PTR DS:[ESI+13230]           ; (42)我们[F4]:执行到当前代码处,发现程序停在了“00412DF7”地址处的断点上。
00412DF7    60              PUSHAD                                  ; (41)这里要[F2]下断。 (43)我们[F8]单步步过。
00412DF8  - E9 4FECFEFF     JMP B64_943_.00401A4C                   ; (44)[F8]后跨段大跳。
00412DFD    0000            ADD BYTE PTR DS:[EAX],AL
00412DFF    0000            ADD BYTE PTR DS:[EAX],AL
00412E01    0000            ADD BYTE PTR DS:[EAX],AL
00412E03    0000            ADD BYTE PTR DS:[EAX],AL
00412E05    0000            ADD BYTE PTR DS:[EAX],AL
00412E07    0000            ADD BYTE PTR DS:[EAX],AL
00412E09    0000            ADD BYTE PTR DS:[EAX],AL
00412E0B    0000            ADD BYTE PTR DS:[EAX],AL
00412E0D    0000            ADD BYTE PTR DS:[EAX],AL
00412E0F    0000            ADD BYTE PTR DS:[EAX],AL
00412E11    0000            ADD BYTE PTR DS:[EAX],AL
            .
            .
            .
00401A4C    68 542C4000     PUSH B64_943_.00402C54                  ; (45)这里就是程序的真正入口点了,DUMP出来吧。
00401A51    E8 F0FFFFFF     CALL B64_943_.00401A46                  ; (46)这个CALL会JMP到“MSVBVM60.ThunRTMain”,VB程序明显的入口调用连接库的特征。
00401A56    0000            ADD BYTE PTR DS:[EAX],AL
00401A58    0000            ADD BYTE PTR DS:[EAX],AL
00401A5A    0000            ADD BYTE PTR DS:[EAX],AL
00401A5C    3000            XOR BYTE PTR DS:[EAX],AL
00401A5E    0000            ADD BYTE PTR DS:[EAX],AL
00401A60    3800            CMP BYTE PTR DS:[EAX],AL
00401A62    0000            ADD BYTE PTR DS:[EAX],AL
00401A64    0000            ADD BYTE PTR DS:[EAX],AL
00401A66    0000            ADD BYTE PTR DS:[EAX],AL
---------------------------------------------------------------------------------------------
总结:

    DUMP后,使用PEID查壳为“Microsoft Visual Basic 5.0 / 6.0”,可以直接运行(@_@我可怜的系统啊~~),不需要修复输入表。
---------------------------------------------------------------------------------------------

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回