本章对使用 UPX 加壳的 CRACKME.exe 程序进行脱壳。
加壳是指通过一种压缩或者加密的手段将程序的可执行代码隐藏起来,避免被轻易的逆向。加壳会在程序中加入额外的区段(STUB,存根),在程序开始运行后,将加密的文件进行解密并保存到内存中其他区段,或者创建原程序中的区段,然后跳转到解密后的代码执行。
现在有很多种类的加壳方式,大部分通过破坏 IAT(import table)也就是导入函数表,以及文件头(HEADER)来保护文件。它们会加入反调试代码来避免被脱壳出原始文件。
最简单的例子就是 UPX 壳,没有任何的反调试或者其他麻烦的手段,所以作为读者学习脱壳的开始。
UPX (Ultimate Packer for Executables) 是一种流行的可执行文件压缩工具,同时也可以被视为一种简单的加壳工具。它被广泛用于减少可执行文件的大小,同时提供一定程度的代码保护。
打开 IDA,勾选 MANUAL LOAD,取消 CREATE IMPORTS SEGMENT,加载所有的区段。IDA 推荐在加载加壳文件时取消这个选项。
如果按默认方式打开壳文件,就会发现 segment 里面只有2个:
UPX0 00401000 00409000 R W X . L para 0001 public CODE 32 0000 0000 0001 FFFFFFFF FFFFFFFF
UPX1 00409000 0040A000 R W X . L para 0002 public CODE 32 0000 0000 0001 FFFFFFFF FFFFFFFF
使用上述方式打开结果:
HEADER 00400000 00401000 ? ? ? . L page 0004 public DATA 32 FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF
UPX0 00401000 00409000 R W X . L para 0001 public CODE 32 0000 0000 0001 FFFFFFFF FFFFFFFF
UPX1 00409000 0040A000 R W X . L para 0002 public CODE 32 0000 0000 0001 FFFFFFFF FFFFFFFF
.rsrc 0040A000 0040B000 R W . . L para 0003 public DATA 32 0000 0000 0001 FFFFFFFF FFFFFFFF
OVERLAY 0040B000 0040B200 R W . . L byte 0000 private DATA 32 FFFFFFFF FFFFFFFF 0001 FFFFFFFF FFFFFFFF
未加壳的原始文件段如下:
HEADER 00400000 00401000 ? ? ? . L page 0007 public DATA 32 FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF
CODE 00401000 00402000 R . X . L para 0001 public CODE 32 0000 0000 0001 FFFFFFFF FFFFFFFF
DATA 00402000 00403000 R W . . L para 0002 public DATA 32 0000 0000 0001 FFFFFFFF FFFFFFFF
.idata 00403000 00404000 R W . . L para 0003 public DATA 32 0000 0000 0001 FFFFFFFF FFFFFFFF
.edata 00404000 00405000 R . . . L para 0004 public DATA 32 0000 0000 0001 FFFFFFFF FFFFFFFF
.reloc 00405000 00406000 R . . . L para 0005 public DATA 32 0000 0000 0001 FFFFFFFF FFFFFFFF
.rsrc 00406000 00408000 R . . . L para 0006 public DATA 32 0000 0000 0001 FFFFFFFF FFFFFFFF
OVERLAY 00408000 00408200 R W . . L byte 0000 private DATA 32 FFFFFFFF FFFFFFFF 0001 FFFFFFFF FFFFFFFF
加壳之后的程序入口,地址是 0x409be0,而原始文件的地址是 0x401000。
加壳之后,函数列表里面只有一个 start 函数了,其他的都看不见:
