题目虽然常规,但是学到了一些关于手动脱壳的知识。

脱壳过程

查看文件,发现是奇奇怪怪的壳,于是我们用OD手动脱壳.

将文件拖入OD

这里利用ESP脱壳大法,下面说一说ESP脱壳的具体步骤。

ESP定理脱壳(ESP在OD的寄存器中,我们只要在命令行下ESP的硬件访问断点,就会一下来到程序的OEP了!)

(1)开始就点F8,注意观察OD右上角的寄存器中ESP有没突现(变成红色)(这只是一 般情况下,更确切的说我们选择的ESP值是关键句之后的第一个ESP值)

(2)在命令行下:dd XXXXXXXX(指在当前代码中的ESP地址,或者是hr XXXXXXXX), 按回车

(3)选中下断的地址,断点—>硬件访问—>WORD断点

(4)按一下F9运行程序,直接来到了跳转处,按下F8,到达程序OEP

按下F8单步步过,发现ESP此时是红色,记下此时ESP寄存器中的值0019FF54(载入程序处的下一个ESP是红色,当然每个人机器上运行这个值有可能不同)

在命令行下输入dd 0019FF54,然后按下回车键

选中要下断点的0019FF54那行,依次选择断点 -> 硬件访问 -> Word

在菜单栏调试(D)下的硬件断点(H)下选项下可以看到我们设置的硬件断点

按F9运行,然后我们F8单步走,到了有大跳转时不要再按F8了(这是向上跳转的),我们必须跳过去,因为接下来就有可能是程序的OEP领空

这里有更多关于ESP定律的资料

https://blog.csdn.net/qiurisuixiang/article/details/7649799

https://beikeit.com/post-614.html

静态分析

把已经脱壳的exe文件拖入ida中

先分析重要函数

v1 = sub_40108C((int)&unk_435DC0, 56);
v2 = (char *)sub_401041((int)&unk_435DC0, (int)&dword_435DF8, 0x38u);
v3 = malloc(0x64u);
v4 = strlen(v2);
memcpy(v3, v2, v4);
v5 = sub_4010C3(&unk_435DC0, v2, &dword_435E30, 56);
sub_40101E(v1, v2, v5);

找到这些重要的函数先看传参,并找出其关联

访问&unk_435DC0

显然这是一个数组,不过在这之间,和我一样的小菜鸡们注意了,怎么找值
1.找类型,此处类型为db,及占4个字节,及是以四个字节为媒介进行分开
2.看地址,上图是一个地址一个地址进行分开
3.看端序,及所谓小端序(高到低)和大端序(低到高)
又上面3个要点可以得到

435DC0=[0x66,0x6d,0x63,0x64,0x7f,0x37,0x35,0x30,0x30,0x6b,0x3a,0x3c,0x3b,0x20]

访问&dword_435DF8

435DF8=[0x37,0x6f,0x38,0x62,0x36,0x7c,0x37,0x33,0x34,0x76,0x33,0x62,0x64,0x7a]

访问dword_435E30
得到

435E30=[0x1a,0,0,0x51,0x5,0x11,0x54,0x56,0x55,0x59,0x1d,0x9,0x5d,0x12,0,0]

提取完数据我们看逻辑

sub_40108C函数

化成代码:

a1 = unk_435DC0
char *v3
v3 = malloc(56>>2) // 56>>2 = 14
for(i = 0; i <14 ; ++i)
sprintf(&v3[i],"%c",i^*(a1 + 4*i))

a1 = [102, 109, 99, 100, 127, 55, 53, 48, 48, 107, 58, 60, 59, 32 ]

解这个函数

a1 = [102, 109, 99, 100, 127, 55, 53, 48, 48, 107, 58, 60, 59, 32 ]
flag = ''
for i in range(14):
flag += chr(a1[i]^i)

sub_401041((int)&unk_435DC0, (int)&dword_435DF8, 0x38u)函数

image-20201210173449644
image-20201210173449644

化成代码

char *v5;
v5 = malloc(56);
printf("%c",*a2[0])
for (i = 1;i<14;++i)
sprintf(&v5[i],"%c",*(a1 + 4* i)^*(a2 + 4*i)^*(a1+ 4*i -4))

解这个函数

a2 = [55, 111, 56, 98, 54, 124, 55, 51, 52, 118, 51, 98, 100, 122]
temp = []
flag += chr(a2[0])
temp.append(a2[0])
for i in range (1,14):
x = (a1[i]^a2[i]^a1[i-1])
flag += chr(x)
temp.append(x)

最后一个函数sub_4010C3((int)&unk_435DC0, (int)v3, (int)&dword_435E30, 56)

image-20201210173723720
image-20201210173723720

解函数

a3 = [26,0,0,81,5,17,84,86,85,89,29,9,93,18,0,0]

for i in range(13):
x += chr(a3[i+1]^temp[i]^i)

flag += chr(a3[i]^a2[i]) + x

完整的exp

a1 = [102, 109, 99, 100, 127, 55, 53, 48, 48, 107, 58, 60, 59, 32 ]
a2 = [55, 111, 56, 98, 54, 124, 55, 51, 52, 118, 51, 98, 100, 122]
a3 = [26,0,0,81,5,17,84,86,85,89,29,9,93,18,0,0]
temp=[]
flag=''
for i in range(14):
flag+=chr(a1[i]^i)

flag+=chr(a2[0])
temp.append(a2[0])
for i in range(1,14):
x=a1[i]^a2[i]^a1[i-1]
flag+=chr(x)
temp.append(x)

x=''
for i in range(13):
x+=chr(a3[i+1]^(temp[i])^i)
flag+= chr(a3[0] ^ a2[0]) + x
print(flag)

# flag{2378b077-7d6e-4564-bdca-7eec8eede9a2}

动态分析

其实也可以用动态调试的方法做,在三个函数的位置分别下断点

把得到的flag拼凑到一起即为答案。

刚刚发现自己脱壳出来的exe文件无法在od里动调,所以我试不了这种方法,图是偷的别人的。至于为什么动调不了等我回去问问大佬们吧。心态有一点小炸裂,无语凝噎!!!