[网鼎杯 2020 青龙组]singal-复现

43 篇文章 1 订阅
10 篇文章 0 订阅

[网鼎杯 2020 青龙组]singal

找到主函数

提取v4->&byte_403040数组

进入vm_operad函数

进入read函数

发现flag的长度为15

exp:

#include<stdio.h>


int __cdecl vm_operad(int* a1, int len_114);
int __cdecl vm_decode(int* a1, int len_114);
int main()
{
    char ida_chars[] =
    {
       10,   0,   0,   0,   4,   0,   0,   0,  16,   0,
        0,   0,   8,   0,   0,   0,   3,   0,   0,   0,
        5,   0,   0,   0,   1,   0,   0,   0,   4,   0,
        0,   0,  32,   0,   0,   0,   8,   0,   0,   0,
        5,   0,   0,   0,   3,   0,   0,   0,   1,   0,
        0,   0,   3,   0,   0,   0,   2,   0,   0,   0,
        8,   0,   0,   0,  11,   0,   0,   0,   1,   0,
        0,   0,  12,   0,   0,   0,   8,   0,   0,   0,
        4,   0,   0,   0,   4,   0,   0,   0,   1,   0,
        0,   0,   5,   0,   0,   0,   3,   0,   0,   0,
        8,   0,   0,   0,   3,   0,   0,   0,  33,   0,
        0,   0,   1,   0,   0,   0,  11,   0,   0,   0,
        8,   0,   0,   0,  11,   0,   0,   0,   1,   0,
        0,   0,   4,   0,   0,   0,   9,   0,   0,   0,
        8,   0,   0,   0,   3,   0,   0,   0,  32,   0,
        0,   0,   1,   0,   0,   0,   2,   0,   0,   0,
       81,   0,   0,   0,   8,   0,   0,   0,   4,   0,
        0,   0,  36,   0,   0,   0,   1,   0,   0,   0,
       12,   0,   0,   0,   8,   0,   0,   0,  11,   0,
        0,   0,   1,   0,   0,   0,   5,   0,   0,   0,
        2,   0,   0,   0,   8,   0,   0,   0,   2,   0,
        0,   0,  37,   0,   0,   0,   1,   0,   0,   0,
        2,   0,   0,   0,  54,   0,   0,   0,   8,   0,
        0,   0,   4,   0,   0,   0,  65,   0,   0,   0,
        1,   0,   0,   0,   2,   0,   0,   0,  32,   0,
        0,   0,   8,   0,   0,   0,   5,   0,   0,   0,
        1,   0,   0,   0,   1,   0,   0,   0,   5,   0,
        0,   0,   3,   0,   0,   0,   8,   0,   0,   0,
        2,   0,   0,   0,  37,   0,   0,   0,   1,   0,
        0,   0,   4,   0,   0,   0,   9,   0,   0,   0,
        8,   0,   0,   0,   3,   0,   0,   0,  32,   0,
        0,   0,   1,   0,   0,   0,   2,   0,   0,   0,
       65,   0,   0,   0,   8,   0,   0,   0,  12,   0,
        0,   0,   1,   0,   0,   0,   7,   0,   0,   0,
       34,   0,   0,   0,   7,   0,   0,   0,  63,   0,
        0,   0,   7,   0,   0,   0,  52,   0,   0,   0,
        7,   0,   0,   0,  50,   0,   0,   0,   7,   0,
        0,   0, 114,   0,   0,   0,   7,   0,   0,   0,
       51,   0,   0,   0,   7,   0,   0,   0,  24,   0,
        0,   0,   7,   0,   0,   0, 167, 255, 255, 255,
        7,   0,   0,   0,  49,   0,   0,   0,   7,   0,
        0,   0, 241, 255, 255, 255,   7,   0,   0,   0,
       40,   0,   0,   0,   7,   0,   0,   0, 132, 255,
      255, 255,   7,   0,   0,   0, 193, 255, 255, 255,
        7,   0,   0,   0,  30,   0,   0,   0,   7,   0,
        0,   0, 122,   0,   0,   0
    };
    vm_operad(ida_chars, 114);//从“char*”到“int* ”的类型不兼容,编译器强制转为int*类型
    vm_decode(ida_chars, 114);
    return 0;
}
int __cdecl vm_operad(int* a1, int len_114)
{
    int result; // eax
    char flag[200] = "111111111111111"; //flag长度为15
    char v4; // [esp+DBh] [ebp-1Dh]
    int v5; // [esp+DCh] [ebp-1Ch]
    int v6; // [esp+E0h] [ebp-18h]
    int v7; // [esp+E4h] [ebp-14h]
    int v8; // [esp+E8h] [ebp-10h]
    int i; // [esp+ECh] [ebp-Ch]
    i = 0;
    v8 = 0;
    v7 = 0;
    v6 = 0;
    v5 = 0;
    while (1)
    {
        result = i;
        if (i >= len_114)
            return result;
        switch (a1[i])
        {
        case 1:
            flag[v6 + 100] = v4;
            ++i;
            ++v6;
            ++v8;
            break;
        case 2:
            v4 = a1[i + 1] + flag[v8];
            i += 2;
            break;
        case 3:
            v4 = flag[v8] - a1[i + 1];
            i += 2;
            break;
        case 4:
            v4 = a1[i + 1] ^ flag[v8];
            i += 2;
            break;
        case 5:
            v4 = a1[i + 1] * flag[v8];
            i += 2;
            break;
        case 6:
            ++i;
            break;
        case 7:
            printf("%d,", a1[i + 1]);//输出符合条件的code
            ++v7;
            i += 2;
            break;
        case 8:
            flag[v5] = v4;
            ++i;
            ++v5;
            break;
        case 10:
            //read(flag);
            ++i;
            break;
        case 11:
            v4 = flag[v8] - 1;
            ++i;
            break;
        case 12:
            v4 = flag[v8] + 1;
            ++i;
            break;
        default:
            continue;
        }
        //printf("%d,", i);//输出下表
    }
}
//逆向过程为从后面向前面走
int __cdecl vm_decode(int* a1, int len_114)
{
    unsigned char flag[100] = { '\0'}; // [esp+13h] [ebp-E5h] BYREF
    int v4; // [esp+DBh] [ebp-1Dh]
    int v5; // [esp+DCh] [ebp-1Ch]
    int v6; // [esp+E0h] [ebp-18h]
    int v7; // [esp+E4h] [ebp-14h]
    int v8; // [esp+E8h] [ebp-10h]
    int i; // [esp+ECh] [ebp-Ch]
    v8 = 15;
    v7 = 15;
    v6 = 15;
    v5 = 15;
    unsigned int code[] = { 34,63,52,50,114,51,24,-89,49,-15,40,-124,-63,30,122, };
    char index[] = { 1,3,4,6,7,9,10,12,13,15,16,17,18,19,20,22,23,25,26,28,29,30,31,32,33,35,36,38,39,41,42,44,45,46,47,48,49,51,52,54,55,57,58,60,61,63,64,66,67,69,70,72,73,75,76,78,79,81,82,83,84,86,88,90,92,94,96,98,100,102,104,106,108,110,112,114, };
    for(int k=75;k>=0;k--)
    {
        i = index[k];
        switch (a1[i])
        {
        case 1:
            --v8;
            --v6;
            v4 = code[v6];
            break;
        case 2:
            flag[v8] = v4 - a1[i + 1];
            break;
        case 3:
            flag[v8] = v4 + a1[i + 1];
            break;
        case 4:
            flag[v8] = v4 ^ a1[i + 1];
            break;
        case 5:
            flag[v8] = v4 / a1[i + 1];
            break;
        case 6://可删除
            break;
        case 7://可删除
            --v7;
            break;
        case 8:
            v4 = flag[--v5];
            break;
        case 10://可删除
            break;
        case 11:
            flag[v8] = v4 + 1;
            break;
        case 12:
            flag[v8] = v4 - 1;
            break;
        default:
            continue;
        }
    }
    printf("\n%s", flag);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值