BmJanpanese 3.0手记
kongfoo/2003.12.8
fly发表了一篇EXEStealth 2.7的脱壳文章,所用目标是大嘴
日语1.0版,并给出了下载地址。由于想学习一下日文,到时打到
日本时不会不知道鬼子们说什么。所以去下载地址看看,已经是
3.0版了。但PEiD查还是EXEStealth 2.72-2.73 ->WebToolMaster
壳。好,打开fly的文章跟着做:
(载入后准备工作:isdebug->hide,options->只留memory access
violatoin)载入后停在下面,和文章中大嘴日语的代码不同,但
和第四部分‘ExeStealth V2.72主程序ExeStealth2.exe脱壳’相
同,就跟着这部分做。(哪么说壳是ASProtect的壳了)
00ED0060 > EB 00 JMP SHORT BmJapane.00ED0062
00ED0062 EB 2F JMP SHORT BmJapane.00ED0093
00ED0064 53 PUSH EBX
00ED0065 68 61726577 PUSH 77657261
00ED006A 61 POPAD
00ED006B 72 65 JB SHORT BmJapane.00ED00D2
00ED006D 202D 20457865 AND BYTE PTR DS:[65784520],CH
00ED0073 53 PUSH EBX
00ED0074 74 65 JE SHORT BmJapane.00ED00DB
00ED0076 61 POPAD
00ED0077 6C INS BYTE PTR ES:[EDI],DX ; I/O command
00ED0078 74 68 JE SHORT BmJapane.00ED00E2
00ED007A 00EB ADD BL,CH
00ED007C 16 PUSH SS
00ED007D 77 77 JA SHORT BmJapane.00ED00F6
00ED007F 77 2E JA SHORT BmJapane.00ED00AF
00ED0081 77 65 JA SHORT BmJapane.00ED00E8
00ED0083 62746F 6F BOUND ESI,QWORD PTR DS:[EDI+EBP*2+6F]
00ED0087 6C INS BYTE PTR ES:[EDI],DX ; I/O command
00ED0088 6D INS DWORD PTR ES:[EDI],DX ; I/O command
00ED0089 61 POPAD
00ED008A 73 74 JNB SHORT BmJapane.00ED0100
00ED008C 65:72 2E JB SHORT BmJapane.00ED00BD ; Superfluous prefix
00ED008F 636F 6D ARPL DWORD PTR DS:[EDI+6D],EBP
00ED0092 0060 90 ADD BYTE PTR DS:[EAX-70],AH
00ED0095 E8 00000000 CALL BmJapane.00ED009A
F9之后:
00ED0766 CD 68 INT 68
shift+f9:
00ED07F2 0000 ADD BYTE PTR DS:[EAX],AL
在7f2处shift+f9之后软件就运行了!
restart,在ed07f2停下来后,堆栈中有SEH结构,之前玩
一个unpackme就有对SEH的跟踪,现在刚好来复习一下。堆栈
内容:
0012FFBC 0012FFE0 Pointer to next SEH record
0012FFC0 00ED0795 SE handler
0012FFC4 77E5EB69 RETURN to kernel32.77E5EB69
去ed0795处下断,shift+f9去到ed0795处。去掉断点,由于
试过tc eip<00ed0000不行,所以要f7一步步跟了:
00ED0795 55 PUSH EBP
00ED0796 8BEC MOV EBP,ESP
00ED0798 57 PUSH EDI
00ED0799 8B45 10 MOV EAX,DWORD PTR SS:[EBP+10]
00ED079C 8BB8 C4000000 MOV EDI,DWORD PTR DS:[EAX+C4]
00ED07A2 FF37 PUSH DWORD PTR DS:[EDI]
00ED07A4 33FF XOR EDI,EDI
00ED07A6 64:8F07 POP DWORD PTR FS:[EDI]
00ED07A9 8380 C4000000 08 ADD DWORD PTR DS:[EAX+C4],8
00ED07B0 8BB8 A4000000 MOV EDI,DWORD PTR DS:[EAX+A4]
00ED07B6 C1C7 07 ROL EDI,7 ==edi=00ecd001
00ED07B9 89B8 B8000000 MOV DWORD PTR DS:[EAX+B8],EDI
00ED07BF B8 00000000 MOV EAX,0
00ED07C4 5F POP EDI
00ED07C5 C9 LEAVE
00ED07C6 C3 RETN
RETN要返回到ntdll中:
0012FBF0 77F833A0 RETURN to ntdll.77F833A0
想想fly的文章‘模拟跟踪 之 PELock 1.06脱壳——fly杀手unpackme ’
里面的内容好相似!对SEH的跟踪及RETN到ntdll的方式,都一一对位了。
而lzqgj的回复:
========
实际只要小心F7走十几步,就到了这里
0037478A ADD DWORD PTR DS:[EAX+B8],2 //B8!!!明显是修改ConText结构,程序将从这里继续执行。
原来值为374986,加2 后为374988。
========
上面ed07a9的代码也对位了。上面0ed07f2+8=0ed07fa,不过,
从ed07f2开始的一直到尾都是00! 跟到ed07b6时edi=00ecd001,不
管3721,去下个断,F9。
运气不错,断下了:(到第二层壳了,ASPack壳)
00ECD001 60 PUSHAD
00ECD002 E8 03000000 CALL 00ECD00A
00ECD007 -E9 EB045D45 JMP 4649D4F7
00ECD00C 55 PUSH EBP
00ECD00D C3 RETN
跟着fly的文章‘ExeStealth 常用脱壳方法 + ExeStealth V2.72主程
序脱壳’,下断BP GetModuleHandleA(这可是宝贵的经验,不是我的,是
fly的,可能fly并不觉得宝贵,但我就觉得宝贵了,因为这对于快速脱壳很
重要,对于特别的壳用特别的断:))
77E59F93 > 837C24 04 00 CMP DWORD PTR SS:[ESP+4],0 ==fly的原文://断在这!取消断点 Ctrl+F9执行到返回
77E59F98 0F84 23060000 JE kernel32.77E5A5C1 ==ctrl+f9和shift+f9可大不相同,我刚看到这句时就眼花了
77E59F9E FF7424 04 PUSH DWORD PTR SS:[ESP+4] ==看成shift+f9了 :(
77E59FA2 E8 55080000 CALL kernel32.77E5A7FC
77E59FA7 85C0 TEST EAX,EAX
77E59FA9 74 08 JE SHORT kernel32.77E59FB3
77E59FAB FF70 04 PUSH DWORD PTR DS:[EAX+4]
77E59FAE E8 B0060000 CALL kernel32.GetModuleHandleW
77E59FB3 C2 0400 RETN 4 ==返回到ecd042
看看地址,和ecd001非常近!
但和文章里说的不同,指令并不是一个test eax,eax。只好
F7下去了...
00ECD042 8985 26040000 MOV DWORD PTR SS:[EBP+426],EAX ; kernel32.77E40000
00ECD048 8BF8 MOV EDI,EAX
00ECD04A 8D5D 5E LEA EBX,DWORD PTR SS:[EBP+5E] =='VirtualAlloc',要分配内存
00ECD04D 53 PUSH EBX
00ECD04E 50 PUSH EAX
00ECD04F FF95 490F0000 CALL DWORD PTR SS:[EBP+F49] ==取VirtualAlloc地址到EAX
00ECD055 8985 4D050000 MOV DWORD PTR SS:[EBP+54D],EAX
00ECD05B 8D5D 6B LEA EBX,DWORD PTR SS:[EBP+6B] =='VirtualFree'
00ECD05E 53 PUSH EBX
00ECD05F 57 PUSH EDI
00ECD060 FF95 490F0000 CALL DWORD PTR SS:[EBP+F49]
00ECD066 8985 51050000 MOV DWORD PTR SS:[EBP+551],EAX
00ECD06C 8D45 77 LEA EAX,DWORD PTR SS:[EBP+77] ==00ecd08a
00ECD06F FFE0 JMP EAX
跳过来:
00ECD08A 8B9D 31050000 MOV EBX,DWORD PTR SS:[EBP+531]
00ECD090 0BDB OR EBX,EBX
00ECD092 74 0A JE SHORT 00ECD09E ==跳了
00ECD094 8B03 MOV EAX,DWORD PTR DS:[EBX]
00ECD096 8785 35050000 XCHG DWORD PTR SS:[EBP+535],EAX
00ECD09C 8903 MOV DWORD PTR DS:[EBX],EAX
00ECD09E 8DB5 69050000 LEA ESI,DWORD PTR SS:[EBP+569]
00ECD0A4 833E 00 CMP DWORD PTR DS:[ESI],0
00ECD0A7 0F84 21010000 JE 00ECD1CE
00ECD0AD 6A 04 PUSH 4
00ECD0AF 68 00100000 PUSH 1000
00ECD0B4 68 00180000 PUSH 1800
00ECD0B9 6A 00 PUSH 0
00ECD0BB FF95 4D050000 CALL DWORD PTR SS:[EBP+54D] ==VirtualAlloc
00ECD0C1 8985 56010000 MOV DWORD PTR SS:[EBP+156],EAX
00ECD0C7 8B46 04 MOV EAX,DWORD PTR DS:[ESI+4] ==0040a000!
00ECD0CA 05 0E010000 ADD EAX,10E
00ECD0CF 6A 04 PUSH 4
00ECD0D1 68 00100000 PUSH 1000
00ECD0D6 50 PUSH EAX
00ECD0D7 6A 00 PUSH 0
00ECD0D9 FF95 4D050000 CALL DWORD PTR SS:[EBP+54D] ==VirtualAlloc
00ECD0DF 8985 52010000 MOV DWORD PTR SS:[EBP+152],EAX
00ECD0E5 56 PUSH ESI
00ECD0E6 8B1E MOV EBX,DWORD PTR DS:[ESI]
00ECD0E8 039D 22040000 ADD EBX,DWORD PTR SS:[EBP+422]
00ECD0EE FFB5 56010000 PUSH DWORD PTR SS:[EBP+156]
00ECD0F4 FF76 04 PUSH DWORD PTR DS:[ESI+4] ==0040a000
00ECD0F7 50 PUSH EAX
00ECD0F8 53 PUSH EBX
00ECD0F9 E8 6E050000 CALL 00ECD66C ==F8
00ECD0FE B3 00 MOV BL,0
00ECD100 80FB 00 CMP BL,0
00ECD103 75 5E JNZ SHORT 00ECD163
00ECD105 FE85 EC000000 INC BYTE PTR SS:[EBP+EC]
00ECD10B 8B3E MOV EDI,DWORD PTR DS:[ESI]
00ECD10D 03BD 22040000 ADD EDI,DWORD PTR SS:[EBP+422]
00ECD113 FF37 PUSH DWORD PTR DS:[EDI]
00ECD115 C607 C3 MOV BYTE PTR DS:[EDI],0C3
00ECD118 FFD7 CALL EDI ==call 007e1000 ,f8
00ECD11A 8F07 POP DWORD PTR DS:[EDI]
00ECD11C 50 PUSH EAX
00ECD11D 51 PUSH ECX
00ECD11E 56 PUSH ESI
00ECD11F 53 PUSH EBX
00ECD120 8BC8 MOV ECX,EAX
00ECD122 83E9 06 SUB ECX,6
00ECD125 8BB5 52010000 MOV ESI,DWORD PTR SS:[EBP+152]
00ECD12B 33DB XOR EBX,EBX
00ECD12D 0BC9 OR ECX,ECX
00ECD12F 74 2E JE SHORT 00ECD15F
00ECD131 78 2C JS SHORT 00ECD15F
00ECD133 AC LODS BYTE PTR DS:[ESI]
00ECD134 3C E8 CMP AL,0E8
00ECD136 74 0A JE SHORT 00ECD142
00ECD138 EB 00 JMP SHORT 00ECD13A
00ECD13A 3C E9 CMP AL,0E9
00ECD13C 74 04 JE SHORT 00ECD142
00ECD13E 43 INC EBX
00ECD13F 49 DEC ECX
00ECD140 ^EB EB JMP SHORT 00ECD12D ==循环
00ECD142 8B06 MOV EAX,DWORD PTR DS:[ESI] ==来这里F4跳出循环
00ECD144 EB 0A JMP SHORT 00ECD150
00ECD146 803E 00 CMP BYTE PTR DS:[ESI],0
00ECD149 ^75 F3 JNZ SHORT 00ECD13E
00ECD14B 24 00 AND AL,0
00ECD14D C1C0 18 ROL EAX,18
00ECD150 2BC3 SUB EAX,EBX
00ECD152 8906 MOV DWORD PTR DS:[ESI],EAX
00ECD154 83C3 05 ADD EBX,5
00ECD157 83C6 04 ADD ESI,4
00ECD15A 83E9 05 SUB ECX,5
00ECD15D ^EB CE JMP SHORT 00ECD12D ==又来循环
00ECD15F 5B POP EBX ==F4 007e1000
00ECD160 5E POP ESI
00ECD161 59 POP ECX
00ECD162 58 POP EAX ==0040a000
00ECD163 EB 08 JMP SHORT 00ECD16D
跳过来:
00ECD16D 8BC8 MOV ECX,EAX
00ECD16F 8B3E MOV EDI,DWORD PTR DS:[ESI]
00ECD171 03BD 22040000 ADD EDI,DWORD PTR SS:[EBP+422]
00ECD177 8BB5 52010000 MOV ESI,DWORD PTR SS:[EBP+152]
00ECD17D C1F9 02 SAR ECX,2
00ECD180 F3:A5 REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS>
00ECD182 8BC8 MOV ECX,EAX
00ECD184 83E1 03 AND ECX,3
00ECD187 F3:A4 REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[>
00ECD189 5E POP ESI
00ECD18A 68 00800000 PUSH 8000
00ECD18F 6A 00 PUSH 0
00ECD191 FFB5 52010000 PUSH DWORD PTR SS:[EBP+152]
00ECD197 FF95 51050000 CALL DWORD PTR SS:[EBP+551] ==VirtualFree
00ECD19D 83C6 08 ADD ESI,8
00ECD1A0 833E 00 CMP DWORD PTR DS:[ESI],0
00ECD1A3 ^0F85 1EFFFFFF JNZ 00ECD0C7 ==循环回去了
00ECD1A9 68 00800000 PUSH 8000 ==这里f4
00ECD1AE 6A 00 PUSH 0
00ECD1B0 FFB5 56010000 PUSH DWORD PTR SS:[EBP+156]
00ECD1B6 FF95 51050000 CALL DWORD PTR SS:[EBP+551] ==VirtualFree 解压完毕
00ECD1BC 8B9D 31050000 MOV EBX,DWORD PTR SS:[EBP+531]
00ECD1C2 0BDB OR EBX,EBX
00ECD1C4 74 08 JE SHORT 00ECD1CE ==跳了
00ECD1C6 8B03 MOV EAX,DWORD PTR DS:[EBX]
00ECD1C8 8785 35050000 XCHG DWORD PTR SS:[EBP+535],EAX
00ECD1CE 8B95 22040000 MOV EDX,DWORD PTR SS:[EBP+422] ==00400000
00ECD1D4 8B85 2D050000 MOV EAX,DWORD PTR SS:[EBP+52D] ==00400000
00ECD1DA 2BD0 SUB EDX,EAX
00ECD1DC 74 79 JE SHORT 00ECD257 ==解压OK?跳了
00ECD257 8B95 22040000 MOV EDX,DWORD PTR SS:[EBP+422] ; BmJapane.00400000
00ECD25D 8BB5 41050000 MOV ESI,DWORD PTR SS:[EBP+541] ==00400000
00ECD263 0BF6 OR ESI,ESI
00ECD265 74 11 JE SHORT 00ECD278 ==跳
00ECD278 BE 28EF7E00 MOV ESI,7EEF28
00ECD27D 8B95 22040000 MOV EDX,DWORD PTR SS:[EBP+422]
00ECD283 03F2 ADD ESI,EDX
00ECD285 8B46 0C MOV EAX,DWORD PTR DS:[ESI+C]
00ECD288 85C0 TEST EAX,EAX
00ECD28A 0F84 0A010000 JE 00ECD39A
00ECD290 03C2 ADD EAX,EDX
00ECD292 8BD8 MOV EBX,EAX
00ECD294 50 PUSH EAX
00ECD295 FF95 4D0F0000 CALL DWORD PTR SS:[EBP+F4D]
00ECD29B 85C0 TEST EAX,EAX
00ECD29D 75 07 JNZ SHORT 00ECD2A6 ==跳了(上面一段功能是得到kernel32.dll的地址)
00ECD2A6 8985 45050000 MOV DWORD PTR SS:[EBP+545],EAX ; kernel32.77E40000
00ECD2AC C785 49050000 00>MOV DWORD PTR SS:[EBP+549],0
00ECD2B6 8B95 22040000 MOV EDX,DWORD PTR SS:[EBP+422]
00ECD2BC 8B06 MOV EAX,DWORD PTR DS:[ESI]
00ECD2BE 85C0 TEST EAX,EAX
00ECD2C0 75 03 JNZ SHORT 00ECD2C5
00ECD2C2 8B46 10 MOV EAX,DWORD PTR DS:[ESI+10]
00ECD2C5 03C2 ADD EAX,EDX
00ECD2C7 0385 49050000 ADD EAX,DWORD PTR SS:[EBP+549]
00ECD2CD 8B18 MOV EBX,DWORD PTR DS:[EAX]
00ECD2CF 8B7E 10 MOV EDI,DWORD PTR DS:[ESI+10]
00ECD2D2 03FA ADD EDI,EDX
00ECD2D4 03BD 49050000 ADD EDI,DWORD PTR SS:[EBP+549]
00ECD2DA 85DB TEST EBX,EBX
00ECD2DC 0F84 A2000000 JE 00ECD384
00ECD2E2 F7C3 00000080 TEST EBX,80000000
00ECD2E8 75 04 JNZ SHORT 00ECD2EE
00ECD2EA 03DA ADD EBX,EDX
00ECD2EC 43 INC EBX
00ECD2ED 43 INC EBX
00ECD2EE 53 PUSH EBX =='LoadLibraryA'
00ECD2EF 81E3 FFFFFF7F AND EBX,7FFFFFFF
00ECD2F5 53 PUSH EBX
00ECD2F6 FFB5 45050000 PUSH DWORD PTR SS:[EBP+545]
00ECD2FC FF95 490F0000 CALL DWORD PTR SS:[EBP+F49] ==取LoadLibraryA地址
00ECD302 85C0 TEST EAX,EAX ; kernel32.LoadLibraryA
00ECD304 5B POP EBX
00ECD305 75 6F JNZ SHORT 00ECD376 ==跳了
00ECD376 8907 MOV DWORD PTR DS:[EDI],EAX ; kernel32.LoadLibraryA
00ECD378 8385 49050000 04 ADD DWORD PTR SS:[EBP+549],4
00ECD37F ^E9 32FFFFFF JMP 00ECD2B6 ==又要往回跳,去下一行F4
00ECD384 8906 MOV DWORD PTR DS:[ESI],EAX
00ECD386 8946 0C MOV DWORD PTR DS:[ESI+C],EAX
00ECD389 8946 10 MOV DWORD PTR DS:[ESI+10],EAX
00ECD38C 83C6 14 ADD ESI,14
00ECD38F 8B95 22040000 MOV EDX,DWORD PTR SS:[EBP+422]
00ECD395 ^E9 EBFEFFFF JMP 00ECD285 ==下一行F4
00ECD39A B8 90AE7E00 MOV EAX,7EAE90
00ECD39F 50 PUSH EAX
00ECD3A0 0385 22040000 ADD EAX,DWORD PTR SS:[EBP+422] ==00beae90
00ECD3A6 59 POP ECX
00ECD3A7 0BC9 OR ECX,ECX
00ECD3A9 8985 A8030000 MOV DWORD PTR SS:[EBP+3A8],EAX ==ebp=ecd013+3a8=ecd3bb,动态改代码!
00ECD3AF 61 POPAD ==这个指令可是等了好久的:)
00ECD3B0 75 08 JNZ SHORT 00ECD3BA ==跳了
00ECD3B2 B8 01000000 MOV EAX,1
00ECD3B7 C2 0C00 RETN 0C
00ECD3BA 68 00000000 PUSH 0
==改后:
00ECD3BA 68 90AEBE00 PUSH 0BEAE90
00ECD3BF C3 RETN
去到beae90:(又一个壳?昏倒,典型UPX壳)
00BEAE90 60 PUSHAD
00BEAE91 BE 00107E00 MOV ESI,7E1000
00BEAE96 8DBE 0000C2FF LEA EDI,DWORD PTR DS:[ESI+FFC20000] ==4010000
00BEAE9C 57 PUSH EDI
00BEAE9D 83CD FF OR EBP,FFFFFFFF
00BEAEA0 EB 10 JMP SHORT 00BEAEB2
对于UPX壳,可以直接去PUSHAD+11c(此处是beae90+11c=
beafac)的地方找POPAD,然后用F4来到POPAD行。
00BEAFAC 7E 00 JLE SHORT 00BEAFAE
00BEAFAE 09C0 OR EAX,EAX
00BEAFB0 74 07 JE SHORT 00BEAFB9
00BEAFB2 8903 MOV DWORD PTR DS:[EBX],EAX
00BEAFB4 83C3 04 ADD EBX,4
00BEAFB7 ^EB E1 JMP SHORT 00BEAF9A
00BEAFB9 FF96 5CE07E00 CALL DWORD PTR DS:[ESI+7EE05C]
00BEAFBF 61 POPAD
00BEAFC0 ^E9 3CE0D1FF JMP 00909001 ==跟
去909001,又是壳?口吐泡沫ing...
00909001 60 PUSHAD
00909002 E8 03000000 CALL 0090900A
00909007 -E9 EB045D45 JMP 45ED94F7
0090900C 55 PUSH EBP
0090900D C3 RETN
由于太烦了,直接了当,去后面找POPAD,找到下面的
地方,是不是和刚才第二层壳的尾部非常相似?!
对啦,连PUSHAD和POPAD的地址都一样:前面的是ecd001
-ecd3af,这里是909001-9093af,所以,和UPX的壳一样,非
常好找啊:) 到了PUSHAD之后直接加上偏移量就行了。(UPX是
11c附近,ASPack是3ae)
009093AF 61 POPAD
009093B0 75 08 JNZ SHORT 009093BA
009093B2 B8 01000000 MOV EAX,1
009093B7 C2 0C00 RETN 0C
009093BA 68 C4B25F00 PUSH 5FB2C4
009093BF C3 RETN
在9093af F4。F7到RETN后来到5fb2c4:
005FB2C4 55 PUSH EBP
005FB2C5 8BEC MOV EBP,ESP
005FB2C7 83C4 F0 ADD ESP,-10
005FB2CA 53 PUSH EBX
005FB2CB B8 B4AE5F00 MOV EAX,5FAEB4
005FB2D0 E8 8FBCE0FF CALL 00406F64
005FB2D5 8B1D 3C696000 MOV EBX,DWORD PTR DS:[60693C]
005FB2DB 8B0B MOV ECX,DWORD PTR DS:[EBX]
005FB2DD B2 01 MOV DL,1
005FB2DF A1 F4A05500 MOV EAX,DWORD PTR DS:[55A0F4]
005FB2E4 E8 CB4FE8FF CALL 004802B4
......
看样子应该是OEP吧...试下dump出来...
直接用OllyDump(Dump了好几分钟,以为死机了:(,看看网页先:) ),
再来ImportREC。oep->1fb2c4,get imports,fix dump. 10M多.运行
正常。
作者也算用心良苦了,EXEStealth 2.72-2.73 / ASPack / UPX / ASPack
加了4次壳。
=====================================================================