buu—Re(5)


[网鼎杯 2020 青龙组]singal


进入ida看主函数:v4被赋值unk_403040数组,然后有个操作函数vm_operad
在这里插入图片描述
进入操作函数:这是以v4数组里面的值为操作的函数,只需跟进v4数组的下标并进行相应的操作即可

switch ( a1[v10] )
    {
      case 1:
        v4[v7] = v5;
        ++v10;
        ++v7;
        ++v9;
        break;
      case 2:
        v5 = a1[v10 + 1] + flag[v9];
        v10 += 2;
        break;
      case 3:
        v5 = flag[v9] - LOBYTE(a1[v10 + 1]);
        v10 += 2;
        break;
      case 4:
        v5 = a1[v10 + 1] ^ flag[v9];
        v10 += 2;
        break;
      case 5:
        v5 = a1[v10 + 1] * flag[v9];
        v10 += 2;
        break;
      case 6:
        ++v10;
        break;
      case 7:
        if ( v4[v8] != a1[v10 + 1] )//a1[v10+1]也就是数组的下一位,而下一位不参与switch,且Str有15位,这就可以把Str给找出来
        {
          printf("what a shame...");
          exit(0);
        }
        ++v8;
        v10 += 2;
        break;
      case 8:
        flag[v6] = v5;
        ++v10;
        ++v6;
        break;
      case 10:
        read(flag);
        ++v10;
        break;
      case 11:
        v5 = flag[v9] - 1;
        ++v10;
        break;
      case 12:
        v5 = flag[v9] + 1;
        ++v10;
        break;
      default:
        continue;

v4数组:因为是小端存储,所以前面三个0x00去掉,留下后面的

10, 4, 16, 8, 3, 5, 1, 4, 32, 8, 5, 3, 1, 3, 2, 8, 11, 1, 12, 8, 4, 4, 1, 5, 3, 8, 3, 33, 1, 11, 8, 11, 1, 4, 9, 8, 3, 32, 1,2, 81, 8, 4, 36, 1, 12, 8, 11, 1, 5, 2, 8, 2, 37, 1, 2, 54, 8, 4, 65, 1, 2, 32, 8,5, 1, 1, 5, 3, 8, 2, 37, 1, 4, 9, 8, 3, 32,1, 2, 65, 8, 12, 1, 7, 34, 7, 63, 7, 52, 7, 50, 7, 114, 7, 51, 7, 24, 7, 167,255, 255, 255, 7, 49, 7, 241, 255, 255, 255, 7,40, 7, 132, 255, 255, 255, 7, 193, 255, 255, 255, 7, 30, 7, 122

我们从第一个数字7开始,得到Str数组的值:34, 63, 52, 50, 114, 51, 24, 167, 49, 241, 40, 132, 193, 30, 122(至于为什么在7这里就是下一位,因为我数了,在7之前的任何一个数字你都不能说:它会不会参与操作,因为有+1也有+2,但是在7这里确确实实是下一位,因为7是+2,当时我还有点迷惑,数过就不迷了)

case 1 :唯一一个给v4赋值的
case 2 , 3 , 4 ,5 :都是给v5赋值的
case 7 :相当于continue
case 10 :输入

分析case:
里面的case1,操作了15次,说明v4跟flag有关,且v5是给v4赋值的,在操作期间进行了许多的变化,猜测v5是个中间变量,相当于进行加密。而v4则是最终的加密结果。

我整理了一下操作的case:
4,8,3,1,4,8,5,1,3,8,11,1,12,8,4,1,5,8,3,1,11,8,11,1,4,8,3,1,2,8,4,1,12,8,11,1,5,8,2,1,2,8,4,1,2,8,5,1,5,8,2,1,4,8,3,1,2,12,1
想着去逆一下,不过还是失败了
参考了大佬博客
大佬博客
记录一下虚拟机逆向脚本吧:

a1=[]
v4=[10, 4, 16, 8, 3, 5, 1, 4, 32, 8, 5, 3, 1, 3, 2, 8, 11, 1, 12, 8, 4, 4, 1, 5, 3, 8, 3, 33, 1, 11, 8, 11, 1, 4, 9, 8, 3, 32, 1, 2, 81, 8, 4, 36, 1, 12, 8, 11, 1, 5, 2, 8, 2, 37, 1, 2, 54, 8, 4, 65, 1, 2, 32, 8, 5, 1, 1, 5, 3, 8, 2, 37, 1, 4, 9, 8, 3, 32, 1, 2, 65, 8, 12, 1, 7, 34, 7, 63, 7, 52, 7, 50, 7, 114, 7, 51, 7, 24, 7, 167, 255, 255, 255, 7, 49, 7, 241, 255, 255, 255, 7, 40, 7, 132, 255, 255, 255, 7, 193, 255, 255, 255, 7, 30, 7, 122]
for i in range(0,len(v4)):
          if v4[i]==7:
                    a1.append(v4[i+1])
a1 = [34, 63, 52, 50, 114, 51, 24, 167, 49, 241, 40, 132, 193, 30, 122]
a1.reverse()
v4.reverse()

v9 = 0
us = 0
v5 = 0
flag = []
for i in range(0, len(v4)):
    if i == len(v4) - 1:
        flag.append(us)
#这里因为是逆着来的,所以倒数第1个才是最开始输入的,所以到时候要赋值
    if v4[i] == 1 and v4[i - 1] != 1:
        v5 = a1[v9]
        v9 += 1
        flag.append(us)
#防止重复进行case1的操作
    if v4[i] == 2:
        if (v4[i + 1] != 3 and v4[i + 1] != 4 and v4[i + 1] != 5):
            us = v5 - v4[i - 1]
#2,3,4,5case都是会+2的,如果前一位是3、4、5,那么会导致跳过本case,产生矛盾,所以会判断一下
    if v4[i] == 3:
        if (v4[i + 1] != 2 and v4[i + 1] != 4 and v4[i + 1] != 5):
            us = v5 + v4[i - 1]

    if v4[i] == 4:
        if (v4[i + 1] != 3 and v4[i + 1] != 2 and v4[i + 1] != 5):
            us = v5 ^ v4[i - 1]

    if v4[i] == 5:
        if (v4[i + 1] != 3 and v4[i + 1] != 4 and v4[i + 1] != 2):
            us = int(v5 / v4[i - 1])
    if v4[i] == 8:
        v5 = us

    if v4[i] == 11:
        us = v5 + 1

    if v4[i] == 12:
        us = v5 - 1
flag.reverse()
out = ''
for j in flag:
    out += chr(j)
print("flag{" + out + "}")

reverse1

进入ida看主函数:
在这里插入图片描述
找到关键函数,如果Str里面有o,转化为0
在这里插入图片描述
找到Str2,所以flag就是hell0_w0rld
在这里插入图片描述

reverse2

进入ida看主函数
在这里插入图片描述
找到关键部分
在这里插入图片描述

在这里插入图片描述

内涵的软件

直接字符串查找得到flag
在这里插入图片描述

新年快乐

检查到upx
在这里插入图片描述
题目上说flag就是一串字符串,考察眼力,所以我查找字符串,猜一个:
flag还真猜对了
在这里插入图片描述

xor

进入ida看主函数,一个异或,然后对比
在这里插入图片描述
写脚本:

#include <stdio.h>
#include <stdlib.h>

int main(){
    char a[] =
{
  0x66, 0x0A, 0x6B, 0x0C, 0x77, 0x26, 0x4F, 0x2E, 0x40, 0x11,
  0x78, 0x0D, 0x5A, 0x3B, 0x55, 0x11, 0x70, 0x19, 0x46, 0x1F,
  0x76, 0x22, 0x4D, 0x23, 0x44, 0x0E, 0x67, 0x06, 0x68, 0x0F,
  0x47, 0x32, 0x4F,0x00
};
    for(int i=1;i<33;i++){
        a[i-1] = a[i]^a[i-1];
    }
    printf("%s",a);
    return 0;
}


helloword

进入jdax,没想到随手一翻找到了😓
在这里插入图片描述

reverse3

看主函数,从后往前逆:Str2就是Destination进行for循环后的,所以通过Str2可以得到Destination。
在这里插入图片描述
进入sub_4110BE函数,发现是个base64加密(其实通过查找字符串能看出有个base64表,从而猜出有个base64加密)
v4就是base64加密后跟Destination对比的,所以得到Destination进行解密即可
在这里插入图片描述
脚本:

#include <stdio.h>
#include <stdlib.h>

int main(){
    char a[] ="e3nifIH9b_C@n@dH";
    int b = 16;
    char c[]="e2lfbDB2ZV95b3V9";

    for(int i=1;i<b;i++){
        a[i] = a[i]-i;
    }
    printf("%s",a);
    return 0;
}


解密:
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值