ELF文件手脱upx变形壳

题目-hgame2022-week2-upx magic1

发现命令行脱壳没用,只能手脱,elf文件没办法使用esp定律,ida手脱

进入ida

在第一个call下断点,进行动态调试

F7单步进入

到了第二个call再次F7进入

一路f8

retn后到

F7进入

有三个向上的跳转

在第三个跳转之后F4

一直F8到达程序真正的入口点

此时需要dumpfile

ALT+F7运行脚本,脚本需要修改后缀为idc

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#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("D:\\dumpfile2","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);
}
}

得到dumpfile2,拖进ida得到正常的代码

爆破脚本

这里要按位与上0xffff,因为这里最后只赋值了最后十六位,所以需要使用&0xffff来限制位数,保证取到最后的十六位

有时候还存在左移溢出的问题:

https://blog.csdn.net/u013658041/article/details/78116449

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include<stdio.h> 
#include <string.h>
#include <stdlib.h>
int main()
{
int s[]={0x8d68,0x9d49,0x2a12,0xab1a,0xcbdc,0xb92b,0x2e32,0x9f59,0xddcd,0x9d49,0xa90a,0xe70,0xf5cf,0x5ed5,0x3c03,0x7c87,0x2672,0xab1a,0xa50,0x5af5,0xff9f,0x9f59,0xbd0b,0x58e5,0x3823,0xbf1b,0x78a7,0xab1a,0x48c4,0xa90a,0x2c22,0x9f59,0x5cc5,0x5ed5,0x78a7,0x2672,0x5695};
for(int i=0;i<40;++i)
{
for(int j=32;j<=127;++j)
{
int temp=(j<<8)&0xffff;
for(int k=0;k<8;++k)
{
if((temp&0x8000)!=0)
{
temp=((2*temp)^0x1021)&0xffff;
}
else
temp=(2*temp)&0xffff;
}
if(temp==s[i])
{
printf("%c",j);
}
}
}

return 0;
}