UPX
upx大家应该都不陌生,在做题时算是比较容易遇到的一种壳,代码开源。
UPX(the Ultimate Packer for eXecutables)是一个免费且开源的可执行程序文件加壳器,支持许多不同操作系统下的可执行文件格式
upx使用
加壳:
upx file -o upx_file
注:如果因为程序过小而压缩失败可以通过添加如下代码进行解决:
int const dummy_to_make_this_compressible[10000] = {1,2,3};
脱壳:
upx -d upx_file
UPX魔改
- 对upx_file二进制文件进行魔术头修改,将UPX!改为其他数据;
- 对UPX源码进行魔改,隐藏upx加壳标志,防止一键脱壳。
- 更改overlay_offset(文件最后4个字节);这里overlay_offset值为p_info字段的文件偏移,通常为0xf4,视情况而定
upx手脱
运行程序后查看进程的内存信息
ps -ef |grep upx_file
pmap -d pid_of_file
脱壳的基本原理是程序在运行时会将代码释放到内存中,我们只需在运行时将内存中的可执行代码段dump出来即可。
如下命令:
sudo dd if=/proc/$(pidof mac-main-upx)/mem of=main_dump skip=0x400000 bs=1c count=786432
当然使用gdb附加,使用(gdb) dump memory /root/memory.dump 0x400000 0x40c000
也是一样的效果。
这时便可以动静结合来进行调试了。
当然如果你有能力修复的,那么把dump的程序修复下也是可以的。
脚本
idc dump镜像脚本:
#include <idc.idc>
#define PT_LOAD 1
#define PT_DYNAMIC 2
static main(void)
{
auto ImageBase,StartImg,EndImg;//基址 08048000
auto e_phoff;
auto e_phnum,p_offset;//paddr 0xc 地址,pmemsz ox14大小,p_offset 0x4
auto i,dumpfile;
ImageBase=0x08048000;
StartImg=0x08048000;
EndImg=0x0;
Message("%8x\n",Dword(ImageBase));
if (Dword(ImageBase)==0x7f454c46 || Dword(ImageBase)==0x464c457f )
{
if(dumpfile=fopen("./dumpfile","w+"))
{
e_phoff=ImageBase+Word(ImageBase+0x1c);
e_phnum=Word(ImageBase+0x2c);
for(i=0;i<e_phnum;i++)
{
if (Dword(e_phoff)==PT_LOAD || Dword(e_phoff)==PT_DYNAMIC)
{ p_offset=Dword(e_phoff+0x4);
StartImg=Dword(e_phoff+0xc);
EndImg=Dword(e_phoff+0xc)+Dword(e_phoff+0x14);
dump(dumpfile,StartImg,EndImg,p_offset);
Message("dump LOAD%d ok.\n",i);
}
e_phoff=e_phoff+0x20;
}
fseek(dumpfile,0x30,0);
fputc(0x00,dumpfile);
fputc(0x00,dumpfile);
fputc(0x00,dumpfile);
fputc(0x00,dumpfile);
fclose(dumpfile);
}else Message("dump err.");
}
}
static dump(dumpfile,startimg,endimg,offset)
{
auto i;
auto size;
size=endimg-startimg;
fseek(dumpfile,offset,0);
for ( i=0; i < size; i=i+1 )
{
fputc(Byte(startimg+i),dumpfile);
}
}