攻防世界 流浪者

ida打开

没有发现main函数,可以从字符串入手,找到对应的函数。

点进一个字符串,两个都一样

ctrl+x找到所属函数

发现如下

找到调用此函数的函数

点进去

关于代码的解释

  v4 = (CWnd *)((char *)this + 100);
  v1 = CWnd::GetDlgItem(this, 1002);		//这些系统函数一开始吓到我了,虽然系统函数一直不是什么考点,但还是认为这里会有和输入相关的东西,后来下载了API的chm文档查了一下作用,的确,后面的GetBuffer应该就是获取用户输入了,但只是获取而已,相当于scanf,知道即可,还是没什么考点
  CWnd::GetWindowTextA(v1, v4);
  v2 = sub_401A30((char *)v8 + 100);
  Str = CString::GetBuffer((CWnd *)((char *)v8 + 100), v2);
  if ( !strlen(Str) )
    return CWnd::MessageBoxA(v8, &byte_4035DC, 0, 0);	//弹框函数,这里犯下第一个错误,IDA双击进去的数据都是db类型的,而我们一开始看到的弹框显示的是中文,所以我们要改类型为dd类型才可以,不然就显示不了中文,所以&byte_4035DC跟踪进去后要用热键D改为dd类型再转字符。
  for ( i = 0; Str[i]; ++i )	//把输入的字符串逐个判断条件并根据不同条件修改,
  {
    if ( Str[i] > 57 || Str[i] < 48 )  
    {
      if ( Str[i] > 122 || Str[i] < 97 )
      {
        if ( Str[i] > 90 || Str[i] < 65 )
          sub_4017B0();	//有一个不是弹框范围内就返回失败
        else
          v5[i] = Str[i] - 29;	//范围在65~90中,输出结果在36~61中
      }
      else
      {
        v5[i] = Str[i] - 87; //范围在97~122中,输出结果在10~35中
      }
    }
    else
    {
      v5[i] = Str[i] - 48;	//范围在48~57中,输出结果在0~9中
    }
  }
  return sub_4017F0((int)v5);		//把修改后的数组结果作为参数赋给后面密文对照函数。

int __cdecl sub_4017F0(int a1)
{
  int result; // eax
  char Str1[28]; // [esp+D8h] [ebp-24h] BYREF
  int v3; // [esp+F4h] [ebp-8h]
  int v4; // [esp+F8h] [ebp-4h]

  v4 = 0;
  v3 = 0;
  while ( *(int *)(a1 + 4 * v4) < 62 && *(int *)(a1 + 4 * v4) >= 0 )
  {
    Str1[v4] = aAbcdefghiabcde[*(_DWORD *)(a1 + 4 * v4)];    //aAbcdefghiabcde双击跟踪是abcdefghiABCDEFGHIJKLMNjklmn0123456789opqrstuvwxyzOPQRSTUVWXYZ'的62位长度字符串,也就不难解释while判断条件的<62了,这里还犯下第二,第三个错误,第二个错误是一开始没看出来这是个数组,*(_DWORD *)(a1 + 4 * v4)是取索引而已,a1是数组头地址,现在要知道带方括号的[]基本都是数组取字符!  第三个错误是这里*(_DWORD *)(a1 + 4 * v4)型我是真的搞不懂,明明a1是int型,还是数组头地址,它前面的(_DWORD *)把它又变成了uint32型地址,先不说这多此一举,关键是int型地址+1就是加4个字节啊!这里直接+4*v4,那不是一下就跳过4个a1数组元素了吗!关键是我调试IDA既然没有问题!!!好吧,只能认为是IDA分析出错了,
    ++v4;//可以看为 Str1[v4] = aAbcdefghiabcde【a1【v4】】
  }
  Str1[v4] = 0;
  if ( !strcmp(Str1, "KanXueCTF2019JustForhappy") )  //从字典中获取的字符与明文对比,符合就是flag
    result = sub_401770();
  else
    result = sub_4017B0();
  return result;
}

首先逆推出v5也就是a1这个数组

key1 = 'abcdefghiABCDEFGHIJKLMNjklmn0123456789opqrstuvwxyzOPQRSTUVWXYZ'
key2 = 'KanXueCTF2019JustForhappy'
s = []
for i in range(len(key2)):
    for j in range(len(key1)):
        if key2[i] == key1[j]:
            s.append(j)
print(s)

然后根据第一个解释逆推写出第二个脚本

flag = ''
v5 = s
for i in v5:
    if 0 <= i <= 9:
        v5 = i + 48
    elif 10 <= i <= 35:
        v5 = i + 87
    elif i >= 36:
        v5 = i + 29
    flag += chr(v5)
print(flag)

最终得到flag:flag{j0rXI4bTeustBiIGHeCF70DDM}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值