最近的新生赛里遇到了一堆UPX,基本都很简单 , But you know ,出题人总是该撅的,也是出了个我不会的然后就简单学习了下,记录一手
Ez UPX
这类UPX就纯白给,直接 upx -d filename就能解,或者用来隐藏程序是pyhon写的

然后就可以直接正常分析了
Baby UPX
UPX加了个段保护,将UPX加密后特有的UPX0 UPX1 段用010改成CTF、XXX啥的,直接-d 是解不出来的
可以通过010改回去,但是不能保证不会损坏原数据

需要扔到ida里面动调,利用UPX将加壳数据会放在PUSHAX/POPAX之间,就可以在函数入口处下硬件断点,放行到pop处(加密程序开始运行时需要还原环境),就可以进主函数了



然后就可以进主函数了,直接分析就可以,或者用OD带的工具Syll开头的那个工具把代码dump出来
阴间UPX
正常 -d 脱壳会报错 l_info corrupted 、p_info corrupted 、corrupt b_info

这个就跟UPX加壳之后的文件有关系了,通过UPX的Linux.h可以看到UPX对这几个信息的声明
struct b_info // 12-byte header before each compressed block
{
uint32_t sz_unc; // uncompressed_size
uint32_t sz_cpr; // compressed_size
unsigned char b_method; // compression algorithm
unsigned char b_ftid; // filter id
unsigned char b_cto8; // filter parameter
unsigned char b_unused; // unused
};
struct l_info // 12-byte trailer in header for loader (offset 116)
{
uint32_t l_checksum; // checksum
uint32_t l_magic; // UPX! magic [55 50 58 21]
uint16_t l_lsize; // loader size
uint8_t l_version; // version info
uint8_t l_format; // UPX format
};
struct p_info // 12-byte packed program header follows stub loader
{
uint32_t p_progid; // program header id [00 00 00 00]
uint32_t p_filesize; // filesize [same as blocksize]
uint32_t p_blocksize; // blocksize [same as filesize]
};
l_info和p_info作为脱壳时用的信息如果被修改,可以起到很好的反脱壳的作用,报错显示该信息被占用,所以需要先找到加壳之后的程序的 l_info 在什么位置
自己写了个Helloworld编译一下,然后加个壳,由于遇到的题是upx4.01就用的upx4.01加的壳

与题目一致后开始分析

扔入010之后就可以比较着看了

绿框里面的是l_info 、橙色框里面的是p_info
根据官方文档里面对相应信息的描述,l_info的前四个字节3C 38 5A 6F是跟版本有关系的,往后 UPX!是特征,再往后两个字节 54 09是lsize,后一个字节0E与版本有关,最后的16跟加密模式以及加密程度有关
p_info就是l_info的后面12个字节,前四个字节是p_progid 为00 00 00 00,后八个为p_filesize和p_blocksize,在普通加密模式下这两个应该是相同的,也就有了将这两个数都擦除,起到反脱壳的作用,可以通过文件尾来恢复这两个数据

标准加密下就可以直接 -d 将文件脱壳了
我遇到的题目为l_info 被占据,但是并未发现文件头处的异常(该一样的都一样),所以文件检查文件尾

发现不同,修改后就可以-d正常脱壳了
如果文件头的 l_info 中的 UPX!被修改也会报l_info被占用
如果将l_checksum擦除的话-d会直接报不是UPX打包的文件