ESP定律 手脱壳
手脱壳
为什么说是自写壳呢 关键是这一行
(Heur) Packer: Generic [Pushal at EP + Last section EP]
意思是
入口点 EP 附近有 PUSHAD/PUSHAL
入口点可能在最后一个 section
哎呀 其实是你die查壳之后打开IDA发现怎么没法反编译啊 又没有SMC 又没有花指令 但是有函数没法反编译 这时候就想到自写壳了 哈哈哈哈
ESP定律 这个里面有介绍 这里只实操
由于是32位程序 我使用的是ollydbg 吾爱破解的
能看到开头就是pushad 运行一下让他压栈
然后右击ESP 在数据内存转到
然后
然后F9运行
然后右击
直接脱壳保存 有一个方式一方式二 方式一脱完壳不能运行但可以静态分析 方式二都可以 脱完壳的
- 静态分析
main函数 由于能看到前面输出了一句话 所以前面两个函数是输出字符串 到下面有一个if else
int __cdecl main_0(int argc, const char **argv, const char **envp)
{
size_t v3; // eax
int v5; // [esp+50h] [ebp-1Ch]
void *v6; // [esp+54h] [ebp-18h]
const char *Src; // [esp+58h] [ebp-14h]
int v8; // [esp+5Ch] [ebp-10h]
sub_4010B4((int)&unk_4395F0, (char *)&byte_432020);
sub_40107D(sub_40102D);
if ( --File._cnt < 0 )
_filbuf(&File);
else
++File._ptr;
v8 = sub_40108C(&unk_435DC0, 56);
Src = (const char *)sub_401041((int)&unk_435DC0, (int)&dword_435DF8, 0x38u);
v6 = malloc(0x64u);
v3 = strlen(Src);
memcpy(v6, Src, v3);
v5 = sub_4010C3(&unk_435DC0, Src, &dword_435E30, 56);
sub_40101E(v8, Src, v5);
return 0;
}
这段代码实现的是 getc() 函数
if ( --File._cnt < 0 )
_filbuf(&File);
else
++File._ptr;
加密代码 三个都是简单异或和位移
char *__cdecl sub_401190(int a1, unsigned int a2)
{
char *v3; // [esp+4Ch] [ebp-Ch]
signed int i; // [esp+54h] [ebp-4h]
v3 = (char *)malloc(a2 >> 2);
for ( i = 0; i < (int)(a2 >> 2); ++i )
sprintf(&v3[i], "%c", i ^ *(_DWORD *)(a1 + 4 * i));
return v3;
}
char *__cdecl sub_401240(int a1, _DWORD *a2, size_t Size)
{
signed int i; // [esp+4Ch] [ebp-Ch]
char *Buffer; // [esp+50h] [ebp-8h]
Buffer = (char *)malloc(Size);
sprintf(Buffer, "%c", *a2);
for ( i = 1; i < (int)(Size >> 2); ++i )
sprintf(&Buffer[i], "%c", *(_DWORD *)(a1 + 4 * i) ^ a2[i] ^ *(_DWORD *)(a1 + 4 * i - 4));
return Buffer;
}
char *__cdecl sub_401320(int a1, int a2, int a3, unsigned int a4)
{
signed int i; // [esp+4Ch] [ebp-10h]
char *v6; // [esp+50h] [ebp-Ch]
char *Source; // [esp+54h] [ebp-8h]
Source = (char *)malloc(a4 - 1);
v6 = (char *)malloc(4 * a4 - 1);
for ( i = 0; i < (int)((a4 >> 2) - 1); ++i )
{
sprintf(&v6[i], "%c", *(_DWORD *)(a3 + 4 * i + 4) ^ *(char *)(i + a2));
sprintf(&Source[i], "%c", i ^ v6[i]);
}
sprintf(&Destination, "%c", dword_435E30 ^ dword_435DF8);
strcat(&Destination, Source);
return &Destination;
}
数据
unk_435DC0 = [0x66, 0x00, 0x00, 0x00, 0x6D, 0x00, 0x00, 0x00, 0x63, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x6B, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00]
dword_435DF8 = [0x37, 0x00, 0x00, 0x00, 0x6F, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x62, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x76, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x62, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x7A, 0x00, 0x00, 0x00]
dword_435E30 = [0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x5D, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00]
exp 懒得写 从网上p一个 嘿嘿
unk_435DC0 = [0x66, 0x6D, 0x63, 0x64, 0x7F, 0x37, 0x35, 0x30, 0x30, 0x6B, 0x3A, 0x3C, 0x3B, 0x20]
dword_435DF8 = [0x37, 0x6F, 0x38, 0x62, 0x36, 0x7C, 0x37, 0x33, 0x34, 0x76, 0x33, 0x62, 0x64, 0x7A]
dword_435E30 = [0x1A, 0x00, 0x00, 0x51, 0x05, 0x11, 0x54, 0x56, 0x55, 0x59, 0x1D, 0x09, 0x5D, 0x12]
v8 = ""
for i in range(0, 14):
v8 += chr(i ^ unk_435DC0[i])
print(v8)
Src = ""
Src += chr(dword_435DF8[0])
for j in range(1, 14):
Src += chr(unk_435DC0[j] ^ dword_435DF8[j] ^ unk_435DC0[j - 1])
print(Src)
Source = ""
for k in range(0, 13):
Source += chr(k ^ dword_435E30[k + 1] ^ ord(Src[k]))
Destination = ""
Destination = chr(dword_435DF8[0] ^ dword_435E30[0])
v5 = Destination + Source
print(v5)
flag = v8 + Src + v5
print(flag)
- 动态解密
由于我们能看到都是异或 然后通过查看最后一个main里面的最后一个函数能看到是一个拼接函数 那拼接肯定会有显示呀 所以我们直接在这里下断点
sub_40101E(v8, Src, v5);
flag
flag{2378b077-7d6e-4564-bdca-7eec8eede9a2}
一把梭
评论