迷蒙马背眠,月随残梦天边远,淡淡起茶烟。
——松尾芭蕉
目录
1.查壳
2.拖入64位IDA,找到主函数
3.静态分析主函数
4.wp
1.查壳
ELF文件,64bit
2.拖入64位IDA,找到主函数
没有标明main函数,我们打开string窗口跟踪一下存储的字符串常量
发现一个base64编码表,base64不懂的查看博文base64
点击这个编码表跟进
将光标放在上面按下快捷键X查看调用这个字符串的地方
点击进入
按下F5反汇编
while ( v2 < v4 - 2 )
{
*(_BYTE *)(v6 + v2) = aAbcdefghijklmn[*(_BYTE *)(v3 + a1) >> 2];
*(_BYTE *)(v6 + v2 + 1LL) = aAbcdefghijklmn[(16 * (*(_BYTE *)(v3 + a1) & 3)) | (*(_BYTE *)(v3 + 1LL + a1) >> 4)];
*(_BYTE *)(v6 + v2 + 2LL) = aAbcdefghijklmn[(4 * (*(_BYTE *)(v3 + 1LL + a1) & 0xF)) | (*(_BYTE *)(v3 + 2LL + a1) >> 6)];
*(_BYTE *)(v6 + v2 + 3LL) = aAbcdefghijklmn[*(_BYTE *)(v3 + 2LL + a1) & 0x3F];
v3 += 3;
v2 += 4;
}
这是base64编码的代码,需要知道base64编码算法的特征
这个函数有传入的参数,应该不是主函数
将光标放在函数名出,按下快捷键N重命名为base64encode
我们继续回到string窗口,查看别的可疑字符串
我们用同样的方法找到You find me字符串被使用的函数
这个函数应该是主函数
可以重命名一下函数名,光标放在函数名上,按下快捷键N
int __cdecl main(int argc, const char **argv, const char **envp)
{
__int64 v3; // rax
int result; // eax
unsigned __int64 v5; // rax
__int64 v6; // rax
int i; // [rsp+Ch] [rbp-114h]
__int64 v8; // [rsp+10h] [rbp-110h]
__int64 v9; // [rsp+18h] [rbp-108h]
__int64 v10; // [rsp+20h] [rbp-100h]
__int64 v11; // [rsp+28h] [rbp-F8h]
__int64 v12; // [rsp+30h] [rbp-F0h]
__int64 v13; // [rsp+38h] [rbp-E8h]
__int64 v14; // [rsp+40h] [rbp-E0h]
__int64 v15; // [rsp+48h] [rbp-D8h]
__int64 v16; // [rsp+50h] [rbp-D0h]
__int64 v17; // [rsp+58h] [rbp-C8h]
char v18; // [rsp+60h] [rbp-C0h]
char v19; // [rsp+61h] [rbp-BFh]
char v20; // [rsp+62h] [rbp-BEh]
char v21; // [rsp+63h] [rbp-BDh]
char v22; // [rsp+64h] [rbp-BCh]
char v23; // [rsp+65h] [rbp-BBh]
char v24; // [rsp+66h] [rbp-BAh]
char v25; // [rsp+67h] [rbp-B9h]
char v26; // [rsp+68h] [rbp-B8h]
char v27; // [rsp+69h] [rbp-B7h]
char v28; // [rsp+6Ah] [rbp-B6h]
char v29; // [rsp+6Bh] [rbp-B5h]
char v30; // [rsp+6Ch] [rbp-B4h]
char v31; // [rsp+6Dh] [rbp-B3h]
char v32; // [rsp+6Eh] [rbp-B2h]
char v33; // [rsp+6Fh] [rbp-B1h]
char v34; // [rsp+70h] [rbp-B0h]
char v35; // [rsp+71h] [rbp-AFh]
char v36; // [rsp+72h] [rbp-AEh]
char v37; // [rsp+73h] [rbp-ADh]
char v38; // [rsp+74h] [rbp-ACh]
char v39; // [rsp+75h] [rbp-ABh]
char v40; // [rsp+76h] [rbp-AAh]
char v41; // [rsp+77h] [rbp-A9h]
char v42; // [rsp+78h] [rbp-A8h]
char v43; // [rsp+79h] [rbp-A7h]
char v44; // [rsp+7Ah] [rbp-A6h]
char v45; // [rsp+7Bh] [rbp-A5h]
char v46; // [rsp+7Ch] [rbp-A4h]
char v47; // [rsp+7Dh] [rbp-A3h]
char v48; // [rsp+7Eh] [rbp-A2h]
char v49; // [rsp+7Fh] [rbp-A1h]
char v50; // [rsp+80h] [rbp-A0h]
char v51; // [rsp+81h] [rbp-9Fh]
char v52; // [rsp+82h] [rbp-9Eh]
char v53; // [rsp+83h] [rbp-9Dh]
char v54[32]; // [rsp+90h] [rbp-90h]
int v55; // [rsp+B0h] [rbp-70h]
char v56; // [rsp+B4h] [rbp-6Ch]
char v57; // [rsp+C0h] [rbp-60h]
char v58; // [rsp+E7h] [rbp-39h]
char v59; // [rsp+100h] [rbp-20h]
unsigned __int64 v60; // [rsp+108h] [rbp-18h]
v60 = __readfsqword(0x28u);
v18 = 73;
v19 = 111;
v20 = 100;
v21 = 108;
v22 = 62;
v23 = 81;
v24 = 110;
v25 = 98;
v26 = 40;
v27 = 111;
v28 = 99;
v29 = 121;
v30 = 127;
v31 = 121;
v32 = 46;
v33 = 105;
v34 = 127;
v35 = 100;
v36 = 96;
v37 = 51;
v38 = 119;
v39 = 125;
v40 = 119;
v41 = 101;
v42 = 107;
v43 = 57;
v44 = 123;
v45 = 105;
v46 = 121;
v47 = 61;
v48 = 126;
v49 = 121;
v50 = 76;
v51 = 64;
v52 = 69;
v53 = 67;
memset(v54, 0, sizeof(v54));
v55 = 0;
v56 = 0;
sub_4406E0(0LL, v54, 37LL);
v56 = 0;
LODWORD(v3) = sub_424BA0((const __m128i *)v54);
if ( v3 == 36 )
{
for ( i = 0; ; ++i )
{
LODWORD(v5) = sub_424BA0((const __m128i *)v54);
if ( i >= v5 )
break;
if ( (unsigned __int8)(v54[i] ^ i) != *(&v18 + i) )
{
result = -2;
goto LABEL_13;
}
}
sub_410CC0("continue!");
memset(&v57, 0, 0x40uLL);
v59 = 0;
sub_4406E0(0LL, &v57, 64LL);
v58 = 0;
LODWORD(v6) = sub_424BA0((const __m128i *)&v57);
if ( v6 == 39 )
{
v8 = base64encode((__int64)&v57);
v9 = base64encode(v8);
v10 = base64encode(v9);
v11 = base64encode(v10);
v12 = base64encode(v11);
v13 = base64encode(v12);
v14 = base64encode(v13);
v15 = base64encode(v14);
v16 = base64encode(v15);
v17 = base64encode(v16);
if ( !(unsigned int)sub_400360(v17, off_6CC090) )
{
sub_410CC0("You found me!!!");
sub_410CC0("bye bye~");
}
result = 0;
}
else
{
result = -3;
}
}
else
{
result = -1;
}
LABEL_13:
if ( __readfsqword(0x28u) != v60 )
sub_444020();
return result;
}
3.静态分析主函数
if ( v3 == 36 )
{
for ( i = 0; ; ++i )
{
LODWORD(v5) = sub_424BA0((const __m128i *)v54);
if ( i >= v5 )
break;
if ( (unsigned __int8)(v54[i] ^ i) != *(&v18 + i) )
{
result = -2;
goto LABEL_13;
}
}
关注这部分
if ( i >= v5 )
break;
这是循环结束的条件
照着这个循环用脚本模拟一下,看看会输出什么
string=[73,111,100,108,62,81,110,98,40,111,99,121,127,121,46,105,127,100,96,51,119,125,119,101,107,57,123,105,121,61,126,121,76,64,69,67]
flag=""
for i in range(0,35):
flag+=chr(string[i]^i)
print(flag)
输出:
Info:The first four chars are `flag`
前四个字符是flag
继续往下分析
是一组base64加密
黄色部分是一个strcmp函数
跟进off_6CC090
继续跟进aVm0wd2vhuxhtwg
这是一个base64编码将这个base64编码多次解码
解密网站
不断解密
进入这个网址
没什么用,纯属干扰解题的坑
下面有一个数据,使用快捷键X交叉引用查看一下
到这个函数中分析一下
unsigned __int64 sub_400D35()
{
unsigned __int64 result; // rax
unsigned int v1; // [rsp+Ch] [rbp-24h]
int i; // [rsp+10h] [rbp-20h]
int j; // [rsp+14h] [rbp-1Ch]
unsigned int v4; // [rsp+24h] [rbp-Ch]
unsigned __int64 v5; // [rsp+28h] [rbp-8h]
v5 = __readfsqword(0x28u);
v1 = sub_43FD20(0LL) - qword_6CEE38;
for ( i = 0; i <= 1233; ++i )
{
sub_40F790(v1);
sub_40FE60();
sub_40FE60();
v1 = (unsigned __int64)sub_40FE60() ^ 0x98765432;
}
v4 = v1;
if ( ((unsigned __int8)v1 ^ byte_6CC0A0[0]) == 102 && (HIBYTE(v4) ^ (unsigned __int8)byte_6CC0A3) == 103 )
{
for ( j = 0; j <= 24; ++j )
sub_410E90((unsigned __int8)(byte_6CC0A0[j] ^ *((_BYTE *)&v4 + j % 4)));
}
result = __readfsqword(0x28u) ^ v5;
if ( result )
sub_444020();
return result;
}
if ( ((unsigned __int8)v1 ^ byte_6CC0A0[0]) == 'f' && (HIBYTE(v4) ^ (unsigned __int8)byte_6CC0A3) == 'g' )
{
for ( j = 0; j <= 24; ++j )
sub_410E90((unsigned __int8)(byte_6CC0A0[j] ^ *((_BYTE *)&v4 + j % 4)));
}
v1是unsigned int 四个字节,高字节与低字节抑或分别是f和g,中间还有两个字节,那么很可能按位与其抑或就是flag
然后循环取出这四个字节与数据段异或就是flag
4.wp
data=[0x40, 0x35, 0x20, 0x56, 0x5D, 0x18, 0x22, 0x45, 0x17, 0x2F, 0x24, 0x6E, 0x62, 0x3C, 0x27, 0x54, 0x48, 0x6C, 0x24, 0x6E, 0x72, 0x3C, 0x32, 0x45, 0x5B]
four=['f','l','a','g']
data2=[]
flag=""
for i in range(4):
data2.append(data[i]^ord(four[i])) #两次异或等于没有异或
for i in range(len(data)):
flag+=chr(data[i]^data2[i%4])
print(flag)
flag{Act1ve_Defen5e_Test}
其他题解请关注我的专栏reverse