基础
壳
作用:可以是开发者未来保护自己的代码不被借鉴、破解、逆向;也可用来病毒、木马、蠕虫隐藏恶意代码,不被杀毒如软件查杀!
壳的执行过程
加壳压缩,壳先执行,还原源程序,执行源程序
OEP
EP(Entry Point)
即程序的入口点。而OEP是程序的原始入口点,正常的程序只有一个EP,例如:C语言main函数
只有入口点被修改的程序(加壳等),才会拥有OEP。
OEP(Original Entry Point),
程序原始入口,软件加壳就是隐藏了EP, 只要我们找到程序的OEP,就可以立刻脱壳。
PUSHAD(压栈) 代表程序的入口点,POPAD(出栈) 代表程序的出口点,
一般找到PUSHAD这个地方基本上就是OEP
脱壳
执行程序是这个流程,错误没回显
发现是有UPX壳的
使用IDA打开也是很明显的UPX加壳特点,如(ABCD)段加壳->(12CD)段
在start处下断点,然后开启远程linux调试
一直F8步过,然后过程中像这种循环会有很多个
直接在尾部要退出的地方下断点然后F9直接跳过循环的地方
过程中有很多次,一直这样操作就行,直到遇到一个jmp 寄存器的
可以看到跳回了原来程序的地址
然后会执行一次syscall
然后跳回来的这个地方,可以发现和我最开始下断点的汇编很像,这里就是start处(OEP)
这个时候看他的file format头(\x7fELF)和入口点,都已经还原了
然后使用IDC脚本dump出来
#include <idc.idc>
#define PT_LOAD 1
#define PT_DYNAMIC 2
static main(void)
{
auto ImageBase, StartImg, EndImg;
auto e_phoff;
auto e_phnum, p_offset;
auto i, dumpfile;
ImageBase = 0x400000;
StartImg = 0x400000;
EndImg = 0x0;
if (Dword(ImageBase) == 0x7f454c46 || Dword(ImageBase) == 0x464c457f ) {
if (dumpfile = fopen("G:\\dumpfile", "wb"))
{
e_phoff = ImageBase + Qword(ImageBase + 0x20);
Message("e_phoff = 0x%x\n", e_phoff);
e_phnum = Word(ImageBase + 0x38);
Message("e_phnum = 0x%x\n", e_phnum);
for (i = 0; i < e_phnum; i++)
{
if (Dword(e_phoff) == PT_LOAD || Dword(e_phoff) == PT_DYNAMIC)
{
p_offset = Qword(e_phoff + 0x8);
StartImg = Qword(e_phoff + 0x10);
EndImg = StartImg + Qword(e_phoff + 0x28);
Message("start = 0x%x, end = 0x%x, offset = 0x%x\n", StartImg, EndImg, p_offset);
dump(dumpfile, StartImg, EndImg, p_offset);
Message("dump segment %d ok.\n", i);
}
e_phoff = e_phoff + 0x38;
}
fseek(dumpfile, 0x3c, 0);
fputc(0x00, dumpfile);
fputc(0x00, dumpfile);
fputc(0x00, dumpfile);
fputc(0x00, dumpfile);
fseek(dumpfile, 0x28, 0);
fputc(0x00, dumpfile);
fputc(0x00, dumpfile);
fputc(0x00, dumpfile);
fputc(0x00, dumpfile);
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);
}
}
dump出来的也可以正常运行
然后就是正常的逆向分析