【Reverse】每日必逆0x00
阅读原文时间:2023年07月09日阅读:1

附件:https://files.buuoj.cn/files/aa4f6c7e8d5171d520b95420ee570e79/a9d22a0e-928d-4bb4-8525-e38c9481469e.rar

  • 拿到程序先进行查壳,避免做过多无用功

  • 确认是无壳,32位可执行文件,直接将其拖入到IDAPro中

  • 直接f5大法,分析伪代码

    int __cdecl main_0(int argc, const char **argv, const char **envp)
    {
    size_t v3; // eax
    const char *v4; // eax
    size_t v5; // eax
    char v7; // [esp+0h] [ebp-188h]
    char v8; // [esp+0h] [ebp-188h]
    signed int j; // [esp+DCh] [ebp-ACh]
    int i; // [esp+E8h] [ebp-A0h]
    signed int v11; // [esp+E8h] [ebp-A0h]
    char Destination[108]; // [esp+F4h] [ebp-94h] BYREF
    char Str[28]; // [esp+160h] [ebp-28h] BYREF
    char v14[8]; // [esp+17Ch] [ebp-Ch] BYREF

    for ( i = 0; i < 100; ++i ) //貌似是初始化空间 { if ( (unsigned int)i >= 0x64 )
    j____report_rangecheckfailure();
    Destination[i] = 0;
    }
    sub_41132F("please enter the flag:", v7);
    sub_411375("%20s", (char)Str);
    v3 = j_strlen(Str); //v3->Str的长度
    v4 = (const char *)sub_4110BE(Str, v3, v14);
    strncpy(Destination, v4, 0x28u); //将v4的前0x28个字符复制到Destination
    v11 = j_strlen(Destination); //v11-》des的长度
    for ( j = 0; j < v11; ++j ) //des每个字符+i
    Destination[j] += j;
    v5 = j_strlen(Destination); //v5-》des的长度
    if ( !strncmp(Destination, Str2, v5) ) //就是将des和Str2进行比较
    sub_41132F("rigth flag!\n", v8);
    else
    sub_41132F("wrong flag!\n", v8);
    return 0;
    }

  • 分析文件执行流向

    读取字符串-》进行sub_4110BE()加密处理=》再将加密后的字符串的每个字符按顺序加所在顺序索引=》最后再将该字符串和Str2进行比较就可以了

  • sub_4110BE()是一个处理函数,跟进去看

    void *__cdecl sub_411AB0(char *a1, unsigned int a2, int *a3)
    {
    int v4; // [esp+D4h] [ebp-38h]
    int v5; // [esp+D4h] [ebp-38h]
    int v6; // [esp+D4h] [ebp-38h]
    int v7; // [esp+D4h] [ebp-38h]
    int i; // [esp+E0h] [ebp-2Ch]
    unsigned int v9; // [esp+ECh] [ebp-20h]
    int v10; // [esp+ECh] [ebp-20h]
    int v11; // [esp+ECh] [ebp-20h]
    void *v12; // [esp+F8h] [ebp-14h]
    char *v13; // [esp+104h] [ebp-8h]

    if ( !a1 || !a2 )
    return 0;
    v9 = a2 / 3;
    if ( (int)(a2 / 3) % 3 )
    ++v9;
    v10 = 4 * v9;
    *a3 = v10;
    v12 = malloc(v10 + 1);
    if ( !v12 )
    return 0;
    j_memset(v12, 0, v10 + 1);
    v13 = a1;
    v11 = a2;
    v4 = 0;
    while ( v11 > 0 )
    {
    byte_41A144[2] = 0;
    byte_41A144[1] = 0;
    byte_41A144[0] = 0;
    for ( i = 0; i < 3 && v11 >= 1; ++i )
    {
    byte_41A144[i] = *v13;
    --v11;
    ++v13;
    }
    if ( !i )
    break;
    switch ( i )
    {
    case 1:
    *((_BYTE *)v12 + v4) = aAbcdefghijklmn[(int)(unsigned __int8)byte_41A144[0] >> 2];
    v5 = v4 + 1;
    *((_BYTE *)v12 + v5) = aAbcdefghijklmn[((byte_41A144[1] & 0xF0) >> 4) | (16 * (byte_41A144[0] & 3))];
    *((_BYTE *)v12 + ++v5) = aAbcdefghijklmn[64];
    *((_BYTE *)v12 + ++v5) = aAbcdefghijklmn[64];
    v4 = v5 + 1;
    break;
    case 2:
    *((_BYTE *)v12 + v4) = aAbcdefghijklmn[(int)(unsigned __int8)byte_41A144[0] >> 2];
    v6 = v4 + 1;
    *((_BYTE *)v12 + v6) = aAbcdefghijklmn[((byte_41A144[1] & 0xF0) >> 4) | (16 * (byte_41A144[0] & 3))];
    *((_BYTE *)v12 + ++v6) = aAbcdefghijklmn[((byte_41A144[2] & 0xC0) >> 6) | (4 * (byte_41A144[1] & 0xF))];
    *((_BYTE *)v12 + ++v6) = aAbcdefghijklmn[64];
    v4 = v6 + 1;
    break;
    case 3:
    *((_BYTE *)v12 + v4) = aAbcdefghijklmn[(int)(unsigned __int8)byte_41A144[0] >> 2];
    v7 = v4 + 1;
    *((_BYTE *)v12 + v7) = aAbcdefghijklmn[((byte_41A144[1] & 0xF0) >> 4) | (16 * (byte_41A144[0] & 3))];
    *((_BYTE *)v12 + ++v7) = aAbcdefghijklmn[((byte_41A144[2] & 0xC0) >> 6) | (4 * (byte_41A144[1] & 0xF))];
    *((_BYTE *)v12 + ++v7) = aAbcdefghijklmn[byte_41A144[2] & 0x3F];
    v4 = v7 + 1;
    break;
    }
    }
    *((_BYTE *)v12 + v4) = 0;
    return v12;
    }

这里我也是看wp的,才知道是个base64加密,还得积累

-点击Str2,进行查看,得到一个字符串

  • 逆向分析

    将字符串按顺序减掉数组索引,再进行base64解密,即可得到flag

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器

你可能感兴趣的文章