@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@ Armadillo 4.01a (Public Build) 手动脱壳 by KaGra @@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
工具: Olly v1.10,commandline插件,HideOlly插件,Ollydump插件,
LordPE(未使用IMPREC)
是的,如你所听到的,没有使用ImpRec或者别的工具来重建导入表.我们采用的手工修复的方法,
这很简单,而且可用于别的加壳程序脱壳。我使用一个下载的Armadillo演示版本版本加壳了一个Crackme,
但保护选项中的我使用的功能都能正常工作。我所选择的这些功能(下面我将详叙)与注册版本相比,仅仅
少了个被保护程序启动时的nag窗口.
你可以通过打开dillo的Protection->Edit Project菜单查看提供的程序保护选项。我是这样选择
的:
程序保护选项:Standard Protection only,Enable import elimination,
Enable strategic code splicing,enable memory patching protections.
(标准保护方式,使用擦除导入表,使用代码拼接,使用内存补丁保护)
其他选项未做改变。
在ZIP文件中,有一个加壳的和一个未加壳的EXE文件。打开olly载入加壳文件.确认你未设置任何类型的断点,
在olly的调试选项中只选上忽略kernel32.dll中的内存访问异常这一项。
(Ignore memory Access Violations in KERNEL32).
我在Dillo中设置的这些选项有两个反调试保护:
1,常用的IsDebuggerPresent API调用,但因为使用了hideolly插件,这个可以不用考虑。
2,对OutPutDebugString API的调用,如果olly正在运行,这个api调用将在调试器中打印一个字符串。
只是因为olly存在一个格式化堆栈缓冲区溢出的bug,当处理诸如%X这样的字符串的时候将会导致olly产生溢
出并崩溃.(详见 http://www.securiteam.com/windowsntfocus/5ZP0N00DFE.html)
我们这样来解决:
在olly代码窗口中,点右键"搜索->全部模块中的名称",找到OutPutDebugString并双击,来到这个api
代码在内存中的起始位置.不要在这里设置任何断点,因为这会被Dillo的内存补丁保护功能检测到(或者别的选项
也会检测到)。代码如下:
77E949B7 > 68 2C020000 PUSH 22C
77E949BC 68 8853E977 PUSH kernel32.77E95388
77E949C1 E8 1259FEFF CALL kernel32.77E7A2D8
77E949C6 8365 FC 00 AND DWORD PTR SS:[EBP-4],0
77E949CA 8B4D 08 MOV ECX,DWORD PTR SS:[EBP+8]
77E949CD 8BC1 MOV EAX,ECX
77E949CF 8D70 01 LEA ESI,DWORD PTR DS:[EAX+1]
77E949D2 8A10 MOV DL,BYTE PTR DS:[EAX]
77E949D4 40 INC EAX
77E949D5 84D2 TEST DL,DL
77E949D7 ^75 F9 JNZ SHORT kernel32.77E949D2
77E949D9 2BC6 SUB EAX,ESI
77E949DB 40 INC EAX
77E949DC 8945 E0 MOV DWORD PTR SS:[EBP-20],EAX
77E949DF 894D E4 MOV DWORD PTR SS:[EBP-1C],ECX
77E949E2 8D45 E0 LEA EAX,DWORD PTR SS:[EBP-20]
77E949E5 50 PUSH EAX
77E949E6 6A 02 PUSH 2
77E949E8 6A 00 PUSH 0
77E949EA 68 06000140 PUSH 40010006
77E949EF E8 43EEFDFF CALL kernel32.RaiseException
77E949F4 834D FC FF OR DWORD PTR SS:[EBP-4],FFFFFFFF
77E949F8 E8 A259FEFF CALL kernel32.77E7A39F
77E949FD C2 0400 RETN 4
如你所见,结尾是RETN 4.所以,在代码开始处:77E949B7(因为windows版本的不同,你看到的地址也许有所差别)输
入RETN 4的操作码
(把
77E949B7 > 68 2C020000 PUSH 22C
修改为:
77E949B7 > C2 0400 RET 4
),因为这是在操作系统内存处的内存补丁,Dillo不会检测到.
现在,开始按Shift+F9多次直到程序执行。并记下所按的次数,我这里是31次.重新运行olly并使用前面所说的跳过反
调试的方法,并按前面的次数减2次Shift+F9,我这是29次.如果其间出项nag窗口,点OK就行了.然后会停在这里:
00ADD266 8900 MOV DWORD PTR DS:[EAX],EAX <- Olly停在这里
00ADD268 90 NOP
00ADD269 E9 57010000 JMP 00ADD3C5
00ADD26E FF75 EC PUSH DWORD PTR SS:[EBP-14]
00ADD271 E8 34F5FFFF CALL 00ADC7AA
00ADD276 59 POP ECX
00ADD277 C3 RETN
00ADD278 8B65 E8 MOV ESP,DWORD PTR SS:[EBP-18]
00ADD27B 70 07 JO SHORT 00ADD284
00ADD27D 7C 03 JL SHORT 00ADD282
00ADD27F EB 05 JMP SHORT 00ADD286
00ADD281 E8 74FBEBF9 CALL FA99CDFA
00ADD286 A1 5C4DAF00 MOV EAX,DWORD PTR DS:[AF4D5C]
00ADD28B 85C0 TEST EAX,EAX
00ADD28D 0F84 0C010000 JE 00ADD39F
00ADD293 8B50 04 MOV EDX,DWORD PTR DS:[EAX+4]
00ADD296 8B0D B84DAF00 MOV ECX,DWORD PTR DS:[AF4DB8] ; packed.00400000
00ADD29C 3BD1 CMP EDX,ECX
00ADD29E 8B1D BC4DAF00 MOV EBX,DWORD PTR DS:[AF4DBC] ; packed.004A5000
现在,在olly中按"ALT+M",在程序的代码段设置一个内存访问断点.(在我这里,这个位置是401000,大小:1000)
继续按shift+F9,直到olly停在内存断点,我们就停在了OEP处.代码如下:
00401099 EB 27 JMP SHORT packed.004010C2 <--- Olly在OEP断下.所以 OEP=00401099
0040109B 33C0 XOR EAX,EAX
0040109D A3 F7204000 MOV DWORD PTR DS:[4020F7],EAX
004010A2 6A 29 PUSH 29
004010A4 68 0E204000 PUSH packed.0040200E
004010A9 6A 65 PUSH 65
004010AB FF75 08 PUSH DWORD PTR SS:[EBP+8]
004010AE E8 D9010000 CALL packed.0040128C ; JMP to USER32.GetDlgItemTextA
004010B3 A3 F7204000 MOV DWORD PTR DS:[4020F7],EAX
004010B8 B8 01000000 MOV EAX,1
004010BD E9 89000000 JMP packed.0040114B
004010C2 6A 00 PUSH 0
004010C4 E8 E1010000 CALL packed.004012AA
004010C9 A3 F3204000 MOV DWORD PTR DS:[4020F3],EAX
004010CE C705 C7204000 03>MOV DWORD PTR DS:[4020C7],4003
004010D8 C705 CB204000 89>MOV DWORD PTR DS:[4020CB],packed.0040118>
004010E2 C705 CF204000 00>MOV DWORD PTR DS:[4020CF],0
004010EC C705 D3204000 00>MOV DWORD PTR DS:[4020D3],0
004010F6 A1 F3204000 MOV EAX,DWORD PTR DS:[4020F3]
004010FB A3 D7204000 MOV DWORD PTR DS:[4020D7],EAX
删除内存断点并使用ollydump插件dump文件.用olly或者lordpe打开dump文件,发现它没有被识别为有效的pe文件,
这是因为作为一种反dump的方法,Dillo破坏了文件的PE首部.这很容易修复.olly停在程序OEP的时候,按"ALT+M"可以看到
程序的PE首部就位于程序代码段之前(在我这里是,起始地址:400000,大小:1000).另外打开一个olly进程载入加壳文件,
并查看它的PE首部.观察他们的区别,并把停于OEP的dump文件的PE首部修改成和加密文件的PE首部一样(注意别搞反了).
这很简单,因为只有不多的一些字节需要修改.完成之后再次dump这个停于OEP的dump文件,然后关闭刚才打开的第2个
olly进程.
用olly打开重新dump的文件,现在正常了.但一运行就崩溃了,呵呵,是重建IAT的时候了.在这个例子中,IAT中的很多节表
(thunks)IMPRec不能修复.这不光是因为API被重定向,IAT被檫除,还因为拼接代码被分成许多部分放在程序内存映象之外的
内存中(还记得我使用了拼接代码选项吗?).这是用过使用Virtualalloc和别的api分配内存空间来完成的.所以,这些部分代码
(其实是从原始文件的代码段分出来的)没有包含在使用ollydump插件dump下来的文件中.新的方法:
我将把保护程序分配的包含程序代码的这部分内存,和保护程序分配的包含IAT中api绝对地址的那部分内存分别dump下来.
(因为在我们dump文件的时候,程序使用的或者从原始IAT中重定向的api的绝对地址一定存放于内存某处).所以,我将用别的段来
填充位于程序最后一个段与dump下来的段之间的空间,(不是dump,是用LordPE来创建).这些填充的段没有别的用处,只是用来填充
程序运行时的内存地址.因此,最后会得到一个比加壳程序大的dump文件(因为这些填充的段占的空间),这将是内存的精确拷贝,因
此也应该能够完美运行.在我们这个例子中这两个段在什么地方呢?我们这样来找:
olly正停在OEP处:
00401099 EB 27 JMP SHORT packed.004010C2 <--- Olly Breakz HeRe at OEP.So OEP=00401099
0040109B 33C0 XOR EAX,EAX
0040109D A3 F7204000 MOV DWORD PTR DS:[4020F7],EAX
004010A2 6A 29 PUSH 29
004010A4 68 0E204000 PUSH packed.0040200E
004010A9 6A 65 PUSH 65
004010AB FF75 08 PUSH DWORD PTR SS:[EBP+8]
004010AE E8 D9010000 CALL packed.0040128C ; JMP to USER32.GetDlgItemTextA
004010B3 A3 F7204000 MOV DWORD PTR DS:[4020F7],EAX
004010B8 B8 01000000 MOV EAX,1
004010BD E9 89000000 JMP packed.0040114B
004010C2 6A 00 PUSH 0
004010C4 E8 E1010000 CALL packed.004012AA
用F7跟踪来到004010C4并进入这个Call:
004012AA -FF25 98304000 JMP DWORD PTR DS:[403098]
[403098]处应该是一个api地址.按F7进入后来到这里:
00AC8C70 55 PUSH EBP
00AC8C71 8BEC MOV EBP,ESP
00AC8C73 51 PUSH ECX
00AC8C74 53 PUSH EBX
00AC8C75 56 PUSH ESI
00AC8C76 57 PUSH EDI
00AC8C77 FF75 08 PUSH DWORD PTR SS:[EBP+8]
00AC8C7A E8 1ACBFFFF CALL 00AC5799
00AC8C7F 85C0 TEST EAX,EAX
00AC8C81 59 POP ECX
00AC8C82 8945 FC MOV DWORD PTR SS:[EBP-4],EAX
00AC8C85 75 2A JNZ SHORT 00AC8CB1
00AC8C87 60 PUSHAD
00AC8C88 8B15 184AAF00 MOV EDX,DWORD PTR DS:[AF4A18] ; kernel32.77E7A237
因为这个程序的基址是00400000,所以,这部分代码应该是来自Dillo的拼接代码.因此,储存来自Dillo的拼接代码
的段应该位于00ACXXXX,通过在olly中按"ALT+M"可以发现这个段的地址是:AB0000,大小:4E000.在olly内存映象的这个段处
按右键,"设置权限->全部权限"(set access->Full access).这样才能dump下来.打开LordPE选取这个进程,使用部分dump
方式(dump partical)把这个段dump下来.那么哪个段是存放API的有效地址的呢?继续按F7直到进入00AC8C7A处的CALL,来
到这里:
00AC5799 55 PUSH EBP
00AC579A 8BEC MOV EBP,ESP
00AC579C 6A FF PUSH -1
00AC579E 68 E826AE00 PUSH 0AE26E8
00AC57A3 68 4017AE00 PUSH 0AE1740 ; JMP to msvcrt._except_handler3
00AC57A8 64:A1 00000000 MOV EAX,DWORD PTR FS:[0]
00AC57AE 50 PUSH EAX
00AC57AF 64:8925 00000000 MOV DWORD PTR FS:[0],ESP
00AC57B6 83EC 0C SUB ESP,0C
00AC57B9 53 PUSH EBX
00AC57BA 56 PUSH ESI
00AC57BB 57 PUSH EDI
00AC57BC 8965 E8 MOV DWORD PTR SS:[EBP-18],ESP
00AC57BF 8365 FC 00 AND DWORD PTR SS:[EBP-4],0
00AC57C3 6A 3A PUSH 3A
00AC57C5 8B7D 08 MOV EDI,DWORD PTR SS:[EBP+8]
00AC57C8 57 PUSH EDI
00AC57C9 FF15 0423AE00 CALL DWORD PTR DS:[AE2304] ; msvcrt.strchr
继续按F7来到00AC57C9,查看内存[AE2304]处:
00AE2304 00 36 C4 77 00 3A C4 77 90 35 C4 77 60 2E C4 77 .6镊.:镊?镊`.镊
00AE2314 50 32 C4 77 25 89 C2 77 10 2F C4 77 33 89 C2 77 P2镊%?w/镊3?w
00AE2324 70 BD C1 77 44 3F C4 77 F8 C5 C1 77 66 CD C3 77 p搅wD?镊?流f兔w
00AE2334 75 D9 C3 77 34 E0 C3 77 C1 3F C4 77 F0 3D C4 77 u倜w4嗝w?镊?镊
00AE2344 C5 CB C1 77 42 89 C2 77 DC 7A C3 77 40 31 C3 77 潘流B?w茭明@1明
00AE2354 F6 30 C3 77 6B AA C2 77 DB 79 C3 77 46 AC C2 77 ?明k?w垸明F?w
00AE2364 88 D3 C5 77 82 E3 C3 77 BF E1 C3 77 85 BF C3 77 ?坯?明酷明?明
00AE2374 20 26 C4 77 A2 22 C4 77 B8 27 C4 77 F5 24 C4 77 &镊?镊?镊?镊
00AE2384 70 26 C4 77 62 23 C4 77 9A 2A C4 77 F5 19 C2 77 p&镊b#镊?镊?瞒
00AE2394 C0 36 C4 77 00 00 00 00 50 16 12 77 4B 17 12 77 ?镊....PwKw
00AE23A4 7E 36 12 77 EC 14 12 77 00 00 00 00 97 28 43 77 ~6w?w....?Cw
00AE23B4 00 00 00 00 E6 56 D4 77 69 8E D6 77 79 96 D4 77 ....嬷憎i?wy?w
00AE23C4 3C 97 D6 77 C4 C6 D4 77 CA 6B D4 77 CB 0B D6 77 <?w钠憎孰憎?主
00AE23D4 6F 68 D4 77 0C 86 D4 77 C0 5A D4 77 D9 55 D4 77 oh憎.?w磊憎僬憎
00AE23E4 E9 D9 D4 77 9D 56 D4 77 09 53 D4 77 27 8E D4 77 橘憎?憎.S憎'?w
这就是完成的IAT有效地址.如果再按F7,我们就会跳到77C43600的api处.这个段是我们刚才dump过了的,不用
dump了.
打开lordPE,还记得我们刚才dump的那个段的起始地址是:AB0000吗?通过从文件中导入段的方式(adding a section from
file)创建一个虚拟大小和物理大小和这个段一样的段(选取我们刚才dump的段),物理偏移(Raw Offset)和虚拟偏移(Virtual
Offset)都是6B0000[AB0000-00400000=6B0000].这样,当dump程序运行的时候,这个段的位置就是AB0000,程序会在这里找到
需要的拼接代码和IAT地址.olly停在OEP的时候,内存中的段如下:
Memory map
Address Size Owner Section Contains Type Access Initial Mapped as
00010000 00001000 Priv RW RW
00020000 00001000 Priv RW RW
000E4000 00001000 Priv RW Guar RW
000E5000 0004B000 stack of mai Priv RW Guar RW
00130000 00001000 Map R R
00140000 00016000 Priv RW RW
00240000 00006000 Priv RW RW
00250000 00001000 Map RW RW
00260000 00016000 Map R R \Device\HarddiskVolume1\WINDOWS\system32\unicode.nls
00280000 00034000 Map R R \Device\HarddiskVolume1\WINDOWS\system32\locale.nls
002C0000 00041000 Map R R \Device\HarddiskVolume1\WINDOWS\system32\sortkey.nls
00310000 00006000 Map R R \Device\HarddiskVolume1\WINDOWS\system32\sorttbls.nls
00320000 00006000 Map R E R E
003E0000 00002000 Map R E R E
003F0000 00001000 Priv RW RW
00400000 00001000 packed Imag R RWE
00401000 00001000 packed CODE Imag R RWE
00402000 00001000 packed DATA Imag R RWE
00403000 00001000 packed .idata Imag R RWE
00404000 00001000 packed .reloc Imag R RWE
00405000 00040000 packed .text code Imag R RWE
00445000 00010000 packed .adata Imag R RWE
00455000 00010000 packed .data data,imports Imag R RWE
00465000 00010000 packed .reloc1 relocations Imag R RWE
00475000 00030000 packed .pdata Imag R RWE
004A5000 00007000 packed .rsrc resources Imag R RWE
004B0000 00103000 Map R R
005C0000 000D4000 Map R E R E
008C0000 00001000 Priv RW RW
008D0000 0000E000 Priv RW RW
008E0000 00003000 Map R R \Device\HarddiskVolume1\WINDOWS\system32\ctype.nls
008F0000 0000E000 Priv RW RW
00900000 00051000 Map R R
00960000 00001000 Map RW RW
00970000 00010000 Map RW RW
009B0000 00001000 Priv RW RW
00AB0000 0004E000 Priv RW RW
00B00000 0000C000 Priv RW RW
00B10000 00002000 Map R R
00B20000 00018000 Priv RW RW
00B40000 000A4000 Priv RW RW
00BF4000 00001000 Priv RW RW
00C04000 00001000 Priv RW RW
00C20000 00006000 Priv RW RW
00C30000 00003000 Priv RW RW
00C70000 00001000 Map RW RW
00C80000 00001000 Map RW RW
00C90000 00001000 Priv RW RW
00CD1000 00002000 Priv RW RW
00E90000 00011000 Map R R \Device\HarddiskVolume1\WINDOWS\system32\c_1253.nls
00EB0000 00001000 Priv RW RW
00F30000 00001000 Priv RW RW
00F40000 00007000 Map RW RW
00FC0000 00004000 Priv RW RW
00FD0000 00003000 Priv RW RW
0110D000 00003000 Priv RW Guar RW
01300000 00002000 Map R R
01310000 00010000 Priv RW RW
5AD70000 00001000 uxtheme PE header Imag R RWE
5AD71000 0002C000 uxtheme .text code,imports Imag R RWE
5AD9D000 00001000 uxtheme .data data Imag R RWE
5AD9E000 00004000 uxtheme .rsrc resources Imag R RWE
5ADA2000 00002000 uxtheme .reloc relocations Imag R RWE
666F0000 00001000 inetmib1 PE header Imag R RWE
666F1000 00005000 inetmib1 .text code,imports Imag R RWE
666F6000 00003000 inetmib1 .data data Imag R RWE
666F9000 00001000 inetmib1 .rsrc resources Imag R RWE
666FA000 00001000 inetmib1 .reloc relocations Imag R RWE
70A70000 00001000 SHLWAPI PE header Imag R RWE
70A71000 0005B000 SHLWAPI .text code,imports Imag R RWE
70ACC000 00001000 SHLWAPI .data data Imag R RWE
70ACD000 00002000 SHLWAPI .rsrc resources Imag R RWE
70ACF000 00005000 SHLWAPI .reloc relocations Imag R RWE
71950000 00001000 comctl_1 PE header Imag R RWE
71951000 00088000 comctl_1 .text code,imports Imag R RWE
719D9000 00001000 comctl_1 .data data Imag R RWE
719DA000 00054000 comctl_1 .rsrc resources Imag R RWE
71A2E000 00006000 comctl_1 .reloc relocations Imag R RWE
71AA0000 00001000 WS2HELP PE header Imag R RWE
71AA1000 00004000 WS2HELP .text code,imports Imag R RWE
71AA5000 00001000 WS2HELP .data data Imag R RWE
71AA6000 00001000 WS2HELP .rsrc resources Imag R RWE
71AA7000 00001000 WS2HELP .reloc relocations Imag R RWE
71AB0000 00001000 WS2_32 PE header Imag R RWE
71AB1000 00011000 WS2_32 .text code,imports Imag R RWE
71AC2000 00001000 WS2_32 .data data Imag R RWE
71AC3000 00001000 WS2_32 .rsrc resources Imag R RWE
71AC4000 00001000 WS2_32 .reloc relocations Imag R RWE
71AD0000 00001000 WSOCK32 PE header Imag R RWE
71AD1000 00003000 WSOCK32 .text code,imports Imag R RWE
71AD4000 00003000 WSOCK32 .rsrc data,resourc Imag R RWE
71AD7000 00001000 WSOCK32 .reloc relocations Imag R RWE
71BF0000 00001000 SAMLIB PE header Imag R RWE
71BF1000 0000D000 SAMLIB .text code,imports Imag R RWE
71BFE000 00001000 SAMLIB .data data Imag R RWE
71BFF000 00001000 SAMLIB .rsrc resources Imag R RWE
71C00000 00001000 SAMLIB .reloc relocations Imag R RWE
71C20000 00001000 NETAPI32 PE header Imag R RWE
71C21000 00046000 NETAPI32 .text code,imports Imag R RWE
71C67000 00003000 NETAPI32 .data data Imag R RWE
71C6A000 00001000 NETAPI32 .rsrc resources Imag R RWE
71C6B000 00003000 NETAPI32 .reloc relocations Imag R RWE
71F60000 00001000 snmpapi PE header Imag R RWE
71F61000 00004000 snmpapi .text code,imports Imag R RWE
71F65000 00001000 snmpapi .data data Imag R RWE
71F66000 00001000 snmpapi .rsrc resources Imag R RWE
71F67000 00001000 snmpapi .reloc relocations Imag R RWE
73420000 00001000 MSVBVM60 PE header Imag R RWE
73421000 000FD000 MSVBVM60 .text code,imports Imag R RWE
7351E000 0000D000 MSVBVM60 ENGINE code Imag R RWE
7352B000 00007000 MSVBVM60 .data data Imag R RWE
73532000 00031000 MSVBVM60 .rsrc resources Imag R RWE
73563000 00010000 MSVBVM60 .reloc relocations Imag R RWE
74720000 00001000 MSCTF PE header Imag R RWE
74721000 0003A000 MSCTF .text code,imports Imag R RWE
7475B000 00002000 MSCTF .data data Imag R RWE
7475D000 00004000 MSCTF .rsrc resources Imag R RWE
74761000 00003000 MSCTF .reloc relocations Imag R RWE
763B0000 00001000 comdlg32 PE header Imag R RWE
763B1000 0002C000 comdlg32 .text code,imports Imag R RWE
763DD000 00004000 comdlg32 .data data Imag R RWE
763E1000 00011000 comdlg32 .rsrc resources Imag R RWE
763F2000 00003000 comdlg32 .reloc relocations Imag R RWE
76670000 00001000 SETUPAPI PE header Imag R RWE
76671000 00071000 SETUPAPI .text code,imports Imag R RWE
766E2000 00002000 SETUPAPI .data data Imag R RWE
766E4000 0006E000 SETUPAPI .rsrc resources Imag R RWE
76752000 00005000 SETUPAPI .reloc relocations Imag R RWE
76B20000 00001000 ATL PE header Imag R RWE
76B21000 0000A000 ATL .text code Imag R RWE
76B2B000 00003000 ATL .rdata imports,expo Imag R RWE
76B2E000 00002000 ATL .data data Imag R RWE
76B30000 00003000 ATL .rsrc resources Imag R RWE
76B33000 00002000 ATL .reloc relocations Imag R RWE
76D40000 00001000 MPRAPI PE header Imag R RWE
76D41000 00012000 MPRAPI .text code,imports Imag R RWE
76D53000 00001000 MPRAPI .data data Imag R RWE
76D54000 00001000 MPRAPI .rsrc resources Imag R RWE
76D55000 00001000 MPRAPI .reloc relocations Imag R RWE
76D60000 00001000 iphlpapi PE header Imag R RWE
76D61000 00011000 iphlpapi .text code,imports Imag R RWE
76D72000 00001000 iphlpapi .data data Imag R RWE
76D73000 00003000 iphlpapi .rsrc resources Imag R RWE
76D76000 00001000 iphlpapi .reloc relocations Imag R RWE
76E10000 00001000 adsldpc PE header Imag R RWE
76E11000 00021000 adsldpc .text code,imports Imag R RWE
76E32000 00001000 adsldpc .data data Imag R RWE
76E33000 00001000 adsldpc .rsrc resources Imag R RWE
76E34000 00001000 adsldpc .reloc relocations Imag R RWE
76E40000 00001000 ACTIVEDS PE header Imag R RWE
76E41000 00023000 ACTIVEDS .text code,imports Imag R RWE
76E64000 00008000 ACTIVEDS .data data Imag R RWE
76E6C000 00001000 ACTIVEDS .rsrc resources Imag R RWE
76E6D000 00002000 ACTIVEDS .reloc relocations Imag R RWE
76E80000 00001000 rtutils PE header Imag R RWE
76E81000 00009000 rtutils .text code,imports Imag R RWE
76E8A000 00001000 rtutils .data data Imag R RWE
76E8B000 00001000 rtutils .rsrc resources Imag R RWE
76E8C000 00001000 rtutils .reloc relocations Imag R RWE
76F60000 00001000 WLDAP32 PE header Imag R RWE
76F61000 00020000 WLDAP32 .text code,imports Imag R RWE
76F81000 00008000 WLDAP32 .data data Imag R RWE
76F89000 00001000 WLDAP32 .rsrc resources Imag R RWE
76F8A000 00002000 WLDAP32 .reloc relocations Imag R RWE
77120000 00001000 OLEAUT32 PE header Imag R RWE
77121000 00081000 OLEAUT32 .text code,imports Imag R RWE
771A2000 00002000 OLEAUT32 .data Imag R RWE
771A4000 00001000 OLEAUT32 .rsrc resources Imag R RWE
771A5000 00006000 OLEAUT32 .reloc relocations Imag R RWE
771B0000 00001000 OLE32 PE header Imag R RWE
771B1000 000F9000 OLE32 .text code,imports Imag R RWE
772AA000 00006000 OLE32 .orpc code Imag R RWE
772B0000 00007000 OLE32 .data data Imag R RWE
772B7000 00002000 OLE32 .rsrc resources Imag R RWE
772B9000 0000E000 OLE32 .reloc relocations Imag R RWE
77340000 00001000 COMCTL32 PE header Imag R RWE
77341000 00066000 COMCTL32 .text code,imports Imag R RWE
773A7000 00001000 COMCTL32 .data data Imag R RWE
773A8000 0001F000 COMCTL32 .rsrc resources Imag R RWE
773C7000 00004000 COMCTL32 .reloc relocations Imag R RWE
773D0000 00001000 SHELL32 PE header Imag R RWE
773D1000 001E0000 SHELL32 .text code,imports Imag R RWE
775B1000 0001C000 SHELL32 .data data Imag R RWE
775CD000 005E0000 SHELL32 .rsrc resources Imag R RWE
77BAD000 0001A000 SHELL32 .reloc relocations Imag R RWE
77C10000 00001000 msvcrt PE header Imag R RWE
77C11000 00047000 msvcrt .text code,imports Imag R RWE
77C58000 00007000 msvcrt .data data Imag R RWE
77C5F000 00001000 msvcrt .rsrc resources Imag R RWE
77C60000 00003000 msvcrt .reloc relocations Imag R RWE
77D40000 00001000 USER32 PE header Imag R RWE
77D41000 0005B000 USER32 .text code,imports Imag R RWE
77D9C000 00002000 USER32 .data data Imag R RWE
77D9E000 0002B000 USER32 .rsrc resources Imag R RWE
77DC9000 00003000 USER32 .reloc relocations Imag R RWE
77DD0000 00001000 ADVAPI32 PE header Imag R RWE
77DD1000 00067000 ADVAPI32 .text code,imports Imag R RWE
77E38000 00005000 ADVAPI32 .data data Imag R RWE
77E3D000 0001B000 ADVAPI32 .rsrc resources Imag R RWE
77E58000 00005000 ADVAPI32 .reloc relocations Imag R RWE
77E60000 00001000 kernel32 PE header Imag R RWE
77E61000 00076000 kernel32 .text code,imports Imag R RWE
77ED7000 00003000 kernel32 .data data Imag R RWE
77EDA000 00066000 kernel32 .rsrc resources Imag R RWE
77F40000 00006000 kernel32 .reloc relocations Imag R RWE
77F50000 00001000 ntdll PE header Imag R RWE
77F51000 0006E000 ntdll .text code,exports Imag R RWE
77FBF000 00004000 ntdll ECODE code Imag R RWE
77FC3000 00005000 ntdll .data data Imag R RWE
77FC8000 0002C000 ntdll .rsrc resources Imag R RWE
77FF4000 00003000 ntdll .reloc relocations Imag R RWE
78000000 00001000 RPCRT4 PE header Imag R RWE
78001000 00070000 RPCRT4 .text code,imports Imag R RWE
78071000 00006000 RPCRT4 .orpc code Imag R RWE
78077000 00001000 RPCRT4 .data data Imag R RWE
78078000 00001000 RPCRT4 .rsrc resources Imag R RWE
78079000 00005000 RPCRT4 .reloc relocations Imag R RWE
7E090000 00001000 GDI32 PE header Imag R RWE
7E091000 0003C000 GDI32 .text code,imports Imag R RWE
7E0CD000 00001000 GDI32 .data data Imag R RWE
7E0CE000 00001000 GDI32 .rsrc resources Imag R RWE
7E0CF000 00002000 GDI32 .reloc relocations Imag R RWE
7F6F0000 00007000 Map R E R E
7FFB0000 00024000 Map R R
7FFDD000 00001000 Priv RWE RWE
7FFDE000 00001000 data block o Priv RWE RWE
7FFDF000 00001000 Priv RWE RWE
7FFE0000 00001000 Priv R R
可以看到,在程序的最后一个节开始于004A5000(.rsrc)之后,一直分配内存到我们需要的段的地址AB0000.创建了2个新的段之后,
再次用olly载入程序,查看内存映象:
Memory map
Address Size Owner Section Contains Type Access Initial Mapped as
00010000 00001000 Priv RW RW
00020000 00001000 Priv RW RW
0012D000 00001000 Priv RW Guar RW
0012E000 00002000 stack of mai Priv RW Guar RW
00130000 00001000 Map R R
00140000 00004000 Priv RW RW
00240000 00006000 Priv RW RW
00250000 00001000 Map RW RW
00260000 00016000 Map R R \Device\HarddiskVolume1\WINDOWS\system32\unicode.nls
00280000 00034000 Map R R \Device\HarddiskVolume1\WINDOWS\system32\locale.nls
002C0000 00041000 Map R R \Device\HarddiskVolume1\WINDOWS\system32\sortkey.nls
00310000 00006000 Map R R \Device\HarddiskVolume1\WINDOWS\system32\sorttbls.nls
00320000 00006000 Map R E R E
003E0000 00002000 Map R E R E
003F0000 00001000 Priv RW RW
00400000 00001000 unpacked PE header Imag R RWE
00401000 00001000 unpacked CODE Imag R RWE
00402000 00001000 unpacked DATA Imag R RWE
00403000 00001000 unpacked .idata Imag R RWE
00404000 00001000 unpacked .reloc Imag R RWE
00405000 00040000 unpacked .text code Imag R RWE
00445000 00010000 unpacked .adata Imag R RWE
00455000 00010000 unpacked .data data,imports Imag R RWE
00465000 00010000 unpacked .reloc1 relocations Imag R RWE
00475000 00030000 unpacked .pdata Imag R RWE
004A5000 00007000 unpacked .rsrc resources Imag R RWE
004AC000 00604000 unpacked .NewSec Imag R RWE
00AB0000 0004E000 unpacked dumped1. Imag R RWE
00B00000 00103000 Map R R
00C10000 000D4000 Map R E R E
00F10000 00001000 Priv RW RW
77D40000 00001000 USER32 PE header Imag R RWE
77D41000 0005B000 USER32 .text code,imports Imag R RWE
77D9C000 00002000 USER32 .data data Imag R RWE
77D9E000 0002B000 USER32 .rsrc resources Imag R RWE
77DC9000 00003000 USER32 .reloc relocations Imag R RWE
77DD0000 00001000 ADVAPI32 PE header Imag R RWE
77DD1000 00067000 ADVAPI32 .text code,imports Imag R RWE
77E38000 00005000 ADVAPI32 .data data Imag R RWE
77E3D000 0001B000 ADVAPI32 .rsrc resources Imag R RWE
77E58000 00005000 ADVAPI32 .reloc relocations Imag R RWE
77E60000 00001000 kernel32 PE header Imag R RWE
77E61000 00076000 kernel32 .text code,imports Imag R RWE
77ED7000 00003000 kernel32 .data data Imag R RWE
77EDA000 00066000 kernel32 .rsrc resources Imag R RWE
77F40000 00006000 kernel32 .reloc relocations Imag R RWE
77F50000 00001000 ntdll PE header Imag R RWE
77F51000 0006E000 ntdll .text code,exports Imag R RWE
77FBF000 00004000 ntdll ECODE code Imag R RWE
77FC3000 00005000 ntdll .data data Imag R RWE
77FC8000 0002C000 ntdll .rsrc resources Imag R RWE
77FF4000 00003000 ntdll .reloc relocations Imag R RWE
78000000 00001000 RPCRT4 PE header Imag R RWE
78001000 00070000 RPCRT4 .text code,imports Imag R RWE
78071000 00006000 RPCRT4 .orpc code Imag R RWE
78077000 00001000 RPCRT4 .data data Imag R RWE
78078000 00001000 RPCRT4 .rsrc resources Imag R RWE
78079000 00005000 RPCRT4 .reloc relocations Imag R RWE
7E090000 00001000 GDI32 PE header Imag R RWE
7E091000 0003C000 GDI32 .text code,imports Imag R RWE
7E0CD000 00001000 GDI32 .data data Imag R RWE
7E0CE000 00001000 GDI32 .rsrc resources Imag R RWE
7E0CF000 00002000 GDI32 .reloc relocations Imag R RWE
7F6F0000 00007000 Map R E R E
7FFB0000 00024000 Map R R
7FFDE000 00001000 data block o Priv RWE RWE
7FFDF000 00001000 Priv RWE RWE
7FFE0000 00001000 Priv R R
我们强制载入程序分配足够的内存,在这段内存以我们创建的一个实质上对程序运行无用的段(.NewSec)开始,但其后却是
包含API绝对地址的调用和程序拼接代码的很有用的段(dumped1).
尝试运行dump文件却发现它仍然不能运行.Why?因为Dillo增加了一种新的保护方式.当olly停在OEP的时候你会发现程序载入的dll
比未加壳程序载入的dll多(按"ALT+M").因此,我们要注入一些代码到程序里面,通过LoadLibraryA载入缺少的dll然后再跳转到OEP.在
这个例子中需要载入的只有一个dll:msvcrt.dll.下面是我在跳转到OEP之前修改的代码:
004012C6 > 9C PUSHFD
004012C7 60 PUSHAD
004012C8 68 1C154000 PUSH unpacked.0040151C ; ASCII "C:\WINDOWS\system32\msvcrt.dll"
004012CD E8 8FC6A777 CALL kernel32.LoadLibraryA
004012D2 61 POPAD
004012D3 9D POPFD
004012D4 ^E9 C0FDFFFF JMP unpacked.00401099
为了保证地址正确增加.NewSec段,所以程序最后的大小是10MB.压缩为ZIP文件之后大小和加壳文件差不多,因为我们增加的.NewSec
段只是为了保证地址分配正确的无用段,是lordPE用00来填充的,所以zip压缩率很高(近97%).我们也可以使用VirtuallAlloc来copy
位于AB0000的.dumped1段,而不必填加到执行文件中.我尝试了,但我不能使用VirtuallAlloc来分配开始于特定位置的内存(这里是
AB0000).但你可以试试.
现在程序可以完美运行了,但需要注意,这样脱壳的文件不能在你脱壳之外的别的版本的windows上运行,因为新的存储程序使用的API
绝对地址的IAT是在这个特定的系统中的.这谁在乎呢?我们已经完美脱壳了......
结束:我想这是我曾经写过的最好的教程了;)你可能也这样认为 ;)
译者小注:
strategic code splicing这个词一下想不到什么准确的译法,看意思大概是代码分割,代码抽取之类,把原始程序部分代码
放到了壳里面,不知是不是?
参考了newsearch的译文,致谢.
translate by ikki[D.4s]
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)