wgf4242 发表于 2024-9-17 07:33

一个简单的ELF程序逆向题。

本帖最后由 wgf4242 于 2024-9-18 08:16 编辑

https://wwi.lanzoup.com/iD6hP2a53b5c

upx 解压

ptrace 反调试
call $+5 花指令去除。jz,jnz很多花指令全去掉。
字符串有加密 高低位互换再 ^0x17

流程:
1.先验证前16字节解密。 127408DDE2F8286DCE072D85A11CA71D , 可输入 flag{Junk_c0de_1s_1n 测试。
2.用前16作为key解一下加密的执行流程,
3.一些操作后,改变输入的后16字节,再验证后16字节是否等于 6D412F7034256C2D4D296D3027913F3F


最终代码如下
```c
void sub_402021()
{
deStr((unsigned __int8 *)&unk_4C70F0);
Output(aInputFlag, 0LL);
sread(0LL, byte_4C9420, 33LL);
xxtea_encrypt(byte_4C9420, 4LL, &unk_4C7150);
if ( (unsigned int)check(byte_4C9420, &unk_4C7120, 16LL) )
{
    deStr((unsigned __int8 *)&unk_4C7100);
    Output(&Wrong, &unk_4C7120);
}
else
{
    qword_4C9450 = (__int64)&loc_4021DD;
    sub_449240((unsigned __int64)&loc_4021DD & 0xFFFFFFFFFFFFF000LL, 0x2000LL, 7LL);
    xxtea_decrypt((unsigned int *)(qword_4C9450 + 224), 24, (__int64)byte_4C9420);
    sub_40B950(4919LL);
    sub_401DF5();
    if ( (unsigned int)check(&byte_4C9420, &unk_4C7130, 17LL) )
    {
      deStr((unsigned __int8 *)&unk_4C7100);
      Output(&Wrong, &unk_4C7130);
    }
    else
    {
      deStr((unsigned __int8 *)&unk_4C7108);
      Output(&Correct, &unk_4C7130);
    }
}
}
```

后面这个 401DF5 看不懂在干嘛。包括里面的 sub_401ED8 , sub_401C0F。后面弄不出来了。
求解释。
```c
__int64 __fastcall sub_401DF5(__int64 a1, __int64 a2, __int64 a3, __int64 a4, __int64 a5)
{
int v5; // eax
__int64 v7; //

++byte_4C9458;
v7 = (unsigned __int64)sub_401DF5 ^ 0xCAFECAFE;
v7 = (unsigned __int64)sub_401ED8 ^ 0xCAFECAFE;
v7 = (unsigned __int64)sub_401C0F ^ 0xCAFECAFE;
v7 = (unsigned __int64)sub_401D12 ^ 0xCAFECAFE;
v7 = (unsigned __int64)sub_401B2D ^ 0xCAFECAFE;
v5 = sub_40C010(a1, a2, sub_401B2D, a4, a5);
return ((__int64 (*)(void))(v7[(v5 % 5 + 5) % 5] ^ 0xCAFECAFELL))();
}
```

测试了一下,类似sub_401DF5 中取执行数组v5= sub_40C010 返回的 v5 每次都是固定的序列。输出序列操作逆回去就行了。

但是 sub_40C010 这个选取值没看懂。求分析。

爱飞的猫 发表于 2024-9-17 23:40

不是很熟悉 Linux 下的调试,但是 v11 (你代码里的 v7)其实就是拿地址 xor 固定值,完事后从这几个里面挑一个再 xor 固定值(得到设置的函数地址)来调用。

你的输入大概会传入进去,用来选择下一个执行的函数。

LOAD:0000000000401E11 lea   rdx, sub_401DF5               ; rdx = 0x401DF5
LOAD:0000000000401E18 mov   eax, 0CAFECAFEh
LOAD:0000000000401E1D xor   rax, rdx                        ; rax = rdx ^ 0xCAFECAFE
LOAD:0000000000401E20 mov   , rax

v11 = 0x401DF5 ^ 0xCAFECAFE; // 存入 5 个地址
v11 = 0x401ED8 ^ 0xCAFECAFE;
v11 = 0x401C0F ^ 0xCAFECAFE;
v11 = 0x401D12 ^ 0xCAFECAFE;
v11 = 0x401B2D ^ 0xCAFECAFE;

// ...

v8 = (__int64 (__fastcall *)(__int64, __int64, _QWORD, __int64, __int64))(v11 ^ 0xCAFECAFELL); // 挑选函数
return v8(a1, a2, v8, v7, v9); // 执行下一条

落尘大大和你呢 发表于 2024-9-19 18:17

可以给一下去除花指令后的.i64吗,我自己尝试取出花指令但总有的地方去不干净,不知道是不是哪里弄错了。
页: [1]
查看完整版本: 一个简单的ELF程序逆向题。