////////////////////////////////////////////////////////////////////////////////////////////
文件名称:手脱加“壳中壳”的病毒
目标程序:未知壳名、未知壳版本
操作环境:Windows XP-SP2
使用工具:Ollydbg 1.10版
编写作者:Coderui
编写时间:2007-8-21
联系方式:coderui@163.com
作者博客:http://hi.baidu.com/coderui
---------------------------------------------------------------------------------------------
前言:
其实,这种“壳中壳”具体名字我还真就不清楚,只是在分析病毒时,正好遇见有个病毒样本加的就是这种壳。开始拿过来使用PEiD查提示未知壳,后来在手脱跟踪时,到了“壳中壳”的最后见到了壳作者留下的信息“xiaohui qq112807930”,接下来就飞出壳,到了程序的真正入口点。顺便到网上查了下作者“xiaohui qq112807930”,搜索到有关《小辉的PE加密》程序,想必就是这个程序加的壳吧。
说明:
个人感觉这个“壳中壳”还不错,里边有很多值得学习参考的东东。它把压缩壳和加密壳的简单特征结合在一起使用,这样的样本壳很少有。这样的壳很适合菜鸟提升自己,作为进级时的过度练习样本壳来使用很不错。在网上粗略的翻了一下,发现没有脱这种壳的手脱教程,所以特写此文,希望读者有所收获。本文以手脱记录的形式来描述脱壳过程,可能写的会很粗略,并且只会解释重点的地方。
注意:
如果大家分析的是应用软件加的壳,跑飞几次没什么关系。但如果分析的是病毒,那么就要千万小心了,因为有些未知病毒可能破坏力非常大的(比如PE感染型病毒)。不过最好还是养成仔细分析、细心调试的好习惯比较好。
分析:
简要介绍一下我分析的这个病毒,它加了两种保护壳,一种加密壳、一种压缩壳。加密壳在里,压缩壳在外,那么我们就要先手脱外边的压缩壳后,再脱里边的加密壳。不过这两种壳都查不出名字,我也没见过。那么到底里边的加密壳是《小辉的PE加密》壳呢?还是外边的压缩壳是《小辉的PE加密》壳呢?还是加密壳与压缩壳两个模块是一起的,都属于《小辉的PE加密》壳呢?
《小辉的PE加密》壳我没有,也不知道是什么样子的,呵呵。不过那段壳作者留下的信息“xiaohui qq112807930”是在里边的加密壳中,而且里边的加密壳与外边的压缩壳有着明显的分界线,个人感觉只有里边的加密壳是《小辉的PE加密》壳,至于外边的压缩壳,可能是某种优秀压缩壳的变种。
---------------------------------------------------------------------------------------------
手脱记录:
(OD设置为不忽略任何异常。[F2]:下软断点、[F4]:执行到当前代码处、[F7]:单步步入、[F8]单步步过、[F9]运行。)
00413518 > 65:9B WAIT ; 多余的前缀(病毒载入后停在这里,也就是“壳中壳”外边压缩壳的入口点),单步[F8]向下走。
0041351A 66:9B WAIT ; 多余的前缀
0041351C 3E: PREFIX DS: ; 多余的前缀
0041351D 36:9B WAIT ; 多余的前缀
0041351F 9C PUSHFD
00413520 60 PUSHAD
00413521 E8 00000000 CALL 70.00413526 ; 这里是陷阱,需要[F7]单步步入进去。
00413526 5D POP EBP ; 步入后来到这里后,单步[F8]向下走。
00413527 81ED A7000000 SUB EBP,0A7
0041352D ^ EB BE JMP SHORT 70.004134ED ; 走到这里以后,不要按[F8]回跳。
0041352F 8BDF MOV EBX,EDI ; 按[F4]执行到当前代码处,然后再单步[F8]向下走。
00413531 83C7 04 ADD EDI,4
00413534 B9 00000000 MOV ECX,0
00413539 57 PUSH EDI
.
.
.
0041355E 83F9 00 CMP ECX,0
00413561 74 05 JE SHORT 70.00413568 ; 到了这里有个向下的小跳,单步[F8]跳。
00413563 83C3 08 ADD EBX,8
00413566 ^ EB C5 JMP SHORT 70.0041352D
00413568 68 00800000 PUSH 8000 ; 跳到这里后,继续单步[F8]向下走。
0041356D 6A 00 PUSH 0
0041356F FFB5 31FEFFFF PUSH DWORD PTR SS:[EBP-1CF]
.
.
.
00413590 8A07 MOV AL,BYTE PTR DS:[EDI]
00413592 47 INC EDI
00413593 2C E8 SUB AL,0E8
00413595 3C 01 CMP AL,1
00413597 ^ 77 F7 JA SHORT 70.00413590 ; 到了这里有个循环回跳,不要跳。
00413599 8B07 MOV EAX,DWORD PTR DS:[EDI] ; 按[F4]执行到当前代码处,然后再单步[F8]向下走。
.
.
.
004135B1 86C4 XCHG AH,AL
004135B3 EB 0A JMP SHORT 70.004135BF ; 到了这里有个向下的小跳,单步[F8]跳。
004135B5 8A5F 04 MOV BL,BYTE PTR DS:[EDI+4]
004135B8 86C4 XCHG AH,AL
004135BA C1C0 10 ROL EAX,10
004135BD 86C4 XCHG AH,AL
004135BF 2BC7 SUB EAX,EDI ; 跳到这里后,继续单步[F8]向下走。
004135C1 03C6 ADD EAX,ESI
.
.
.
004135C5 83C7 05 ADD EDI,5
004135C8 80EB E8 SUB BL,0E8
004135CB 8BC3 MOV EAX,EBX
004135CD ^ E2 C6 LOOPD SHORT 70.00413595 ; 到了这里有个循环回跳,不要跳。
004135CF E8 2A010000 CALL 70.004136FE ; 按[F4]执行到当前代码处,然后再单步[F8]向下走。
004135D4 8D8D 4DFEFFFF LEA ECX,DWORD PTR SS:[EBP-1B3]
004135DA 8B41 08 MOV EAX,DWORD PTR DS:[ECX+8]
004135DD 83F8 00 CMP EAX,0
004135E0 0F84 81000000 JE 70.00413667 ; 到了这里有个向下的大跳,单步[F8]跳。
.
.
.
00413667 8DBD 09FEFFFF LEA EDI,DWORD PTR SS:[EBP-1F7] ; 跳到这里后,继续单步[F8]向下走。
0041366D 8B17 MOV EDX,DWORD PTR DS:[EDI]
0041366F 8DBD 65FEFFFF LEA EDI,DWORD PTR SS:[EBP-19B]
00413675 8B07 MOV EAX,DWORD PTR DS:[EDI]
00413677 EB 45 JMP SHORT 70.004136BE ; 到了这里有个向下的中跳不要跳,我们向下找两处代码进行下断点,下完断点后按[F9]运行就会停到飞向里边加密壳的关键跳转处
; 问题:我想知道这些下断点的东东怎么判断出来的?如果没提示,自己怎么去找要下断点的代码位置呢?
; 回答:本来我也想尽力写的详细些,但是我书面表达能力很弱,感觉自己用这种手脱记录的文件表达不清楚,所以就直接给出关键的下断位置了。
; 大家有看到反汇编代码中有的注解是“未知命令”吧?它们有些都是在跟踪时动态解密代码的,如果全部记录上来很麻烦,重复的代码还会很多,那样怕把初学者说的更迷糊了。
; 当你真正对脱壳入门后,找这样的断点就很简单了。没有反调试和反跟踪的壳,就是一顿下关键断,接着一顿[F9]执行,就会停到飞向程序真正入口点的关键跳转代码位置的。
; 使用自己的思想,结合前辈的经验,多加练习,经验会很快丰富起来的。这样再去脱“未知壳”或“壳中壳”就很容易了。
; 重点在学会手脱时跟踪的方法,怎么去跟、去对付各种的汇编指令,如果都掌握熟练的话,脱什么壳(虚拟机壳除外)都是一样的步骤,至于壳的名字根本就无关紧要。
; 最后在丰富自己的反反调试和反反跟踪的经验,那么你就无敌了,呵呵!
00413679 5A POP EDX
0041367A 5B POP EBX
0041367B 59 POP ECX
0041367C 5E POP ESI
0041367D 83C3 0C ADD EBX,0C
00413680 E2 56 LOOPD SHORT 70.004136D8
00413682 8BC5 MOV EAX,EBP
00413684 05 03020000 ADD EAX,203
00413689 EB 05 JMP SHORT 70.00413690
0041368B 90 NOP
0041368C AD LODS DWORD PTR DS:[ESI]
0041368D FE ??? ; 未知命令
0041368E FFFF ??? ; 未知命令
00413690 8B9D 7B020000 MOV EBX,DWORD PTR SS:[EBP+27B]
00413696 C785 7B020000 0>MOV DWORD PTR SS:[EBP+27B],0
004136A0 03D8 ADD EBX,EAX
004136A2 8BC5 MOV EAX,EBP
004136A4 05 BD010000 ADD EAX,1BD
004136A9 2BD8 SUB EBX,EAX
004136AB 899D 35020000 MOV DWORD PTR SS:[EBP+235],EBX
004136B1 61 POPAD
004136B2 9D POPFD
004136B3 E9 00000000 JMP 70.004136B8 ; 第一处下断点的地方,[F2]下软断点。这里就是飞向里边加密壳的关键跳转,目前的跳转地址不是真正的飞向里边加密壳的关键跳转地址。等代码执行到这里时,才会显示出正确的地址。
004136B8 90 NOP
004136B9 90 NOP
004136BA AD LODS DWORD PTR DS:[ESI]
004136BB FE ??? ; 未知命令
004136BC FFFF ??? ; 未知命令
004136BE 8BDD MOV EBX,EBP
004136C0 81EB 08000000 SUB EBX,8
004136C6 33C9 XOR ECX,ECX
004136C8 8A0B MOV CL,BYTE PTR DS:[EBX]
004136CA 83F9 00 CMP ECX,0
004136CD 74 28 JE SHORT 70.004136F7
004136CF 43 INC EBX
004136D0 8DB5 09FEFFFF LEA ESI,DWORD PTR SS:[EBP-1F7]
004136D6 8B16 MOV EDX,DWORD PTR DS:[ESI]
004136D8 56 PUSH ESI
004136D9 51 PUSH ECX
004136DA 53 PUSH EBX
004136DB 52 PUSH EDX
004136DC 56 PUSH ESI
004136DD FF33 PUSH DWORD PTR DS:[EBX]
004136DF FF73 04 PUSH DWORD PTR DS:[EBX+4]
004136E2 8B43 08 MOV EAX,DWORD PTR DS:[EBX+8]
004136E5 03C2 ADD EAX,EDX
004136E7 50 PUSH EAX
004136E8 FF95 ADFEFFFF CALL DWORD PTR SS:[EBP-153]
004136EE ^ EB 89 JMP SHORT 70.00413679
004136F0 59 POP ECX
004136F1 5E POP ESI
004136F2 83C3 0C ADD EBX,0C
004136F5 ^ E2 E1 LOOPD SHORT 70.004136D8
004136F7 61 POPAD
004136F8 9D POPFD
004136F9 - E9 02D9FFFF JMP 70.00411000 ; 第二处下断点的地方,[F2]下软断点。(其实这个地址“00411000”就是压缩壳里边的加密壳的入口点地址)。
.
.
.
004136A2 8BC5 MOV EAX,EBP
004136A4 05 BD010000 ADD EAX,1BD
004136A9 2BD8 SUB EBX,EAX
004136AB 899D 35020000 MOV DWORD PTR SS:[EBP+235],EBX
004136B1 61 POPAD
004136B2 9D POPFD
004136B3 - E9 48D9FFFF JMP 70.00411000 ; 上边[F9]运行后,就会停在这里(第一个断点上),看地址现在变了吧,这个就是里边加密壳真正的入口地址。接着,我们[F8]单步执行。
; 有朋友心理会有疑问:“那么下的第二处断点有什么用处呢?”回答:“怕程序跑飞了,因为是病毒,留个保险,呵呵”。
004136B8 90 NOP
004136B9 90 NOP
004136BA AD LODS DWORD PTR DS:[ESI]
004136BB FE ??? ; 未知命令
004136BC FFFF ??? ; 未知命令
004136BE 8BDD MOV EBX,EBP
004136C0 81EB 08000000 SUB EBX,8
004136C6 33C9 XOR ECX,ECX
004136C8 8A0B MOV CL,BYTE PTR DS:[EBX]
004136CA 83F9 00 CMP ECX,0
004136CD 74 28 JE SHORT 70.004136F7
.
.
.
00411000 65 DB 65 ; 跳到了这里,这里就是里边加密壳的入口。
; 因为OD把这个段识别为数据段了,所以显示为现在这样的代码。我们按[Ctrl+A],OD会把本段刷新为反汇编代码段。
00411001 E9 DB E9
00411002 07 DB 07
00411003 00 DB 00
00411004 00 DB 00
00411005 00 DB 00
00411006 00 DB 00
00411007 00 DB 00
00411008 00 DB 00
00411009 00 DB 00
0041100A 90 DB 90
0041100B 90 DB 90
0041100C 90 DB 90
0041100D 60 DB 60 ; CHAR '`'
.
.
.
00411000 65 DB 65 ; 刷新为代码段后,显示成现在这个样子。开始继续手脱里边的加密壳,单步[F8]向下走。
00411001 . E9 07000000 JMP 70.0041100D
00411006 00 DB 00
00411007 00 DB 00
00411008 00 DB 00
00411009 00 DB 00
0041100A 90 NOP
0041100B 90 NOP
0041100C 90 NOP
0041100D > 60 PUSHAD ; 单步[F8]会跳到这里,继续单步[F8]向下走。
0041100E . E8 03000000 CALL 70.00411016 ; 这里[F7]单步步入。
00411013 . 0055 00 ADD BYTE PTR SS:[EBP],DL
00411016 /$ 58 POP EAX ; 单步步入后来到这里,继续单步[F8]向下走。
00411017 |. 40 INC EAX
00411018 |. 40 INC EAX
00411019 |. EB 01 JMP SHORT 70.0041101C ; 单步[F8]向下小跳。
0041101B | FF DB FF
0041101C |> 61 POPAD ; 小跳到这里后,继续单步[F8]向下走。
0041101D |. 60 PUSHAD
0041101E |. 9C PUSHFD
0041101F |. 9D POPFD
00411020 |. 61 POPAD
00411021 |. E9 00000000 JMP 70.00411026 ; 单步[F8]向下小跳。
00411026 |> 8D05 00004100 LEA EAX,DWORD PTR DS:[410000] ; 小跳到这里后,继续单步[F8]向下走。
0041102C |. 50 PUSH EAX
0041102D \. C3 RETN ; 单步[F8]返回。
.
.
.
00410000 . 83C1 01 ADD ECX,1 ; 返回到这里后,继续单步[F8]向下走。
00410003 . 83E9 01 SUB ECX,1
00410006 . EB FF JMP SHORT 70.00410007 ; 这里会单步[F8]两次才跳出去。
00410008 F3 DB F3
00410009 . 5B POP EBX ; 跳到这里后,继续单步[F8]向下走。
.
.
.
0041001F . 60 PUSHAD
00410020 . E8 00000000 CALL 70.00410025 ; 这里[F7]单步步入。
00410025 /$ 58 POP EAX ; 单步步入后来到这里,继续单步[F8]向下走。
00410026 |. 83E8 06 SUB EAX,6
00410029 |. 83C0 30 ADD EAX,30
0041002C |. 8BD8 MOV EBX,EAX
0041002E |. 83C0 10 ADD EAX,10
00410031 |. 8BC8 MOV ECX,EAX
00410033 |. 53 PUSH EBX
00410034 |. 51 PUSH ECX
00410035 |. 83C4 04 ADD ESP,4
00410038 |. 83C4 04 ADD ESP,4
0041003B |. 33DB XOR EBX,EBX
0041003D |. 33C9 XOR ECX,ECX
0041003F |. 33C0 XOR EAX,EAX
00410041 |. EB 00 JMP SHORT 70.00410043 ; 单步[F8]向下小跳。
00410043 |> 61 POPAD ; 小跳到这里后,继续单步[F8]向下走。
00410044 |. EB 07 JMP SHORT 70.0041004D ; 单步[F8]向下小跳。
00410046 | FF DB FF
00410047 | FF DB FF
00410048 | FF DB FF
00410049 | FF DB FF
0041004A | FF DB FF
0041004B | FF DB FF
0041004C | 3D DB 3D ; CHAR '='
0041004D |> EB 1E JMP SHORT 70.0041006D ; 小跳到这里后,继续单步[F8]向下小跳。
0041004F |. 78 69 61 6F 6>ASCII "xiaohui",0 ; 显示作者名称的ASCII为"xiaohui"。
00410057 | 00 DB 00
00410058 | 90 NOP
00410059 | 90 NOP
0041005A | 90 NOP
0041005B | 90 NOP
0041005C | 90 NOP
0041005D | 90 NOP
0041005E | 90 NOP
0041005F |. 71 71 31 31 3>ASCII "qq112807930",0 ; 显示作者QQ号的ASCII为"qq112807930"。
0041006B | 00 DB 00
0041006C | 00 DB 00
0041006D |> 60 PUSHAD ; 小跳到这里后,继续单步[F8]向下走。
0041006E |. 9C PUSHFD
0041006F |. 9D POPFD
00410070 |. 61 POPAD
00410071 |. E9 00000000 JMP 70.00410076 ; 单步[F8]向下小跳。
00410076 |> 8D05 0F214000 LEA EAX,DWORD PTR DS:[40210F] ; 小跳到这里后,继续单步[F8]向下走。
0041007C |. 50 PUSH EAX
0041007D \. C3 RETN ; 这里就是飞向最里边病毒程序的真正入口点地址,[F8]飞。
0041007E 65 DB 65 ; CHAR 'e'
0041007F . E9 07000000 JMP 70.0041008B
00410084 00 DB 00
.
.
.
0040210F /. 55 PUSH EBP ; (初始 cpu 选择),这个就是病毒程序的真正入口地址,现在就可以DUMP程序了,脱出来后的病毒是VC++ 6.0编写的。
00402110 |. 8BEC MOV EBP,ESP
00402112 |. 6A FF PUSH -1
00402114 |. 68 28314000 PUSH 70.00403128
00402119 |. 68 90224000 PUSH 70.00402290 ; JMP 到 MSVCRT._except_handler3; SE 处理程序安装
0040211E |. 64:A1 0000000>MOV EAX,DWORD PTR FS:[0]
---------------------------------------------------------------------------------------------
后记:
“壳中壳”就这样搞定了,不知道输入表有没有被破坏,因为是病毒,我也就不运行了。如果被破坏了的话,使用ImportREC修复就行,再使用LordPE优化。
完美的脱壳、修复、优化结束,呵呵。也带大家认识了那个叫作《小辉的PE加密》的壳,据说这个壳是收费的,而且口碑还不怎么好,呵呵。
这个我们就不管拉,反正拿来给菜鸟们做入门练习是个不错的样本壳,呵呵。
---------------------------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////////////////
[课程]Android-CTF解题方法汇总!