2024年5月7日发(作者:)

《加密与解密(第二版)》样章

看雪学院

看雪软件安全论坛

11.8.3 UPX的壳

UPX壳即破坏了输入表也破坏了重定位表,尽量使用其自身命令脱壳(upx -d),实在

没办法了再尝试手动脱壳。用UPX v 1.24将文件加壳,用ProDump查看其PE

信息,如图11.66。

图11.66 查看PE信息

1.寻找OEP

先在SoftICE里下个“Bpint 3”命令,然后在文件上点击鼠标右键,执行

LordPE的“Break 'n'Enter”命令。将被装载运行中断在外壳代码第一行,下指令

“ Eb eip 80”恢复原机器码。代码如下:

:009D8100 807C240801 CMP BYTE PTR [ESP+08],01

:009D8105 0F857D010000 JNZ 009D8288 ; 暗道,第二次经过入口点时将跳转

:009D810B 60 PUSHAD

:009D810C BE00609D00 MOV ESI,009D6000

对入口点下断点,DLL卸载时将会再次中断,此时9D8105处的转移指令将跳转。跳转

到如下代码处:

:009D8288 E93C8FFFFF JMP 009D11C9 ; 再进一步跳向OEP处

·2·

2.基址重定位表

加密与解密

UPX壳己将原基址重定位表清零,重定位操作时,使用其自己的重定位表。处理代码

如下:

:009D825E MOV AL,[EDI] ; EDI=009D7318指向UPX加密处理的重定位表

:009D8260 INC EDI ; 指针移向下一位

:009D8261 OR EAX,EAX ; EAX=0?结束标志

:009D8263 JZ 009D8287

:009D8265 CMP AL,EF ; AL=EF?

:009D8267 JA 009D827A

:009D8269 ADD EBX,EAX ; EBX的初值为(0xFFC+基址)

:009D826B MOV EAX,[EBX] ; EBX指向需要修改的数据,取出放到EAX

:009D826D XCHG AL,AH

:009D826F ROL EAX,10

:009D8272 XCHG AL,AH

:009D8274 ADD EAX,ESI

:009D8276 MOV [EBX],EAX ; 纠正过的数据放回去

:009D8278 JMP 009D825C ; 循环

:009D827A AND AL,0F ; 处理al=0F情况

:009D827C SHL EAX,10

:009D827F MOV AX,[EDI]

:009D8282 ADD EDI,02

:009D8285 JMP 009D8269

:009D8287 POPAD

:009D8288 JMP 009D11C9 ; 跳到OEP

9D825E代码处的EDI指向UPX生成的重定位表,重定位表的地址RVA=0x9D7318-基址

=0x7318。记下当前的基地址0x9D0000,然后在OEP处,将当前内存映像抓取出来。下命令:

PAGEIN D 9D0000 A000 ??C:

用PE工具PEditor里Sections的dumpfixer (RS=VS & RO=VO)功能修正区

块,使其块中Raw Size=Virtual Size,Raw Offset=Virtual Offset。

用十六进制工具HexWorkshop打开文件,跳到0x7318处,从此一直到0x74EA

(重定位表以00结束,此处有个PE字符标志)处为UPX生成的重定位数据。其重定位表

格式转换关系与PECompact类似,作者写了一个小工具UpxAngela来完成这种转换工作。

用HexWorkShop打开,选取0x7318~0x74EA这段重定位数据(多选也没关

系,程序根据0x00来判断是否结束),将这块数据复制到新建的一空白文件里,另存为

dump_。运行UpxAngela,打开dump_,将生成一个文件。打开

文件,选中所有数据,HexWorkShop状态栏将显示这块数据大小为0x3b0。然后在

里找一块空白代码处(一般在UPX1或UPX2区块里找),在这选择0x6000处,点击菜单

“Edit/Select Block”,输入0x3B0,将选中一块数据,将刚才的选中的文件数据

第10章 加壳与脱壳

·3·

复制粘贴覆盖原数据。这样就完成了重定位表的恢复工作,新的重定位表RVA为0x6000,

大小为0x3B0。

3.输入表

用ImportREC重建输入表,由于ImportREC不能自动识别DLL的IAT的位置和大小,

因此必须手动识别。用LoadLibraryA 函数设断可找到处理IAT的代码:

:009D822A FF963C800000 CALL [ESI+0000803C]; LoadLibraryA装入链接库

:009D8230 95 XCHG EAX,EBP

……

:009D8247 7407 JZ 009D8250

:009D8249 8903 MOV [EBX],EAX ; EBX=9D4014,指向IAT

9D8249处的EBX指向IAT中的某一项,其RVA值为0x4014。在里来到0x4014

处,根据IAT的特征就可判断IAT的范围0x4000~0x40CC。

用LordPE装载或运行EXE主文件装载该DLL文件。然后运行ImportREC,

在Options里将“Use PE Header From Disk”默认的选项去除。

1) 在ImportREC下拉列表框中选择DLL装载器的进程,此处为LordPE的

2) 点击“Pick DLL”按钮,在DLL进程列表中选择进程(图11.67)。

图11.67 选择进程

3) 填入IAT偏移(RVA域)0x4000和大小(Size域)0xCC。

4) 点击“Get Import”按钮,让其分析IAT结构重建输入表。

5) 点击“Fix Dump”按钮,并选择刚抓取的映像文件,它将创建一个dump_.dll

文件。

4.PE文件修正

1)OEP与基址修正

用PE编辑工具LordPE(或ProDump)打程序。将11C9填进EntryPoint域

中,在ImageBase域填入9D0000,点击“Save”按钮保存。

2)基址重定位表修正

用LordPE打开,点击“Directories”按钮打开目录表,在Relocation的RVA

域中填6000,Size域中填3B0,点击“Save”按钮保存修改。

·4·

加密与解密