[MRCTF2020]Shit

main函数

int __cdecl main(int argc, const char **argv, const char **envp)
{
  int v3; // eax
  int v4; // eax
  char v5; // al
  int v6; // eax
  int v7; // eax
  int v8; // eax
  char v10[52]; // [esp+4h] [ebp-38h] BYREF

  v3 = sub_401890();
  std::ostream::operator<<(v3, sub_401AD0);
  sub_401BD0((int)v10);
  if ( IsDebuggerPresent() || strlen(v10) != 24 )
  {
    v4 = sub_401890();
    std::ostream::operator<<(v4, sub_401AD0);
    Sleep(0x7D0u);
    goto LABEL_3;
  }
  sub_401460();
  v5 = sub_4012F0(v10);
  *(_DWORD *)v10 = sub_401AD0;
  if ( v5 )
  {
    v6 = sub_401890();
    std::ostream::operator<<(v6, sub_401AD0);
    v7 = sub_401890();
    std::ostream::operator<<(v7, *(_DWORD *)v10);
    system("pause");
LABEL_3:
    exit(0);
  }
  v8 = sub_401890();
  std::ostream::operator<<(v8, *(_DWORD *)v10);
  Sleep(0x7D0u);
  return 0;
}

首先读入字符串到v10中,然后要求v10的长度为24
之后关键函数sub_401460和sub_4012F0存在花指令,IDA无法分析。
去除如下图所示花指令
在这里插入图片描述
得到函数sub_401460

int sub_401460()
{
  unsigned int v0; // eax
  int result; // eax
  int v2; // [esp+Ch] [ebp-30h]
  int v3; // [esp+18h] [ebp-24h]
  int v4; // [esp+1Ch] [ebp-20h]
  int v5; // [esp+28h] [ebp-14h]
  int v6; // [esp+2Ch] [ebp-10h]
  int k; // [esp+30h] [ebp-Ch]
  int j; // [esp+34h] [ebp-8h]
  int i; // [esp+38h] [ebp-4h]

  v6 = 0;
  v0 = time(0);
  srand(v0);
  for ( i = 1; i <= 20; ++i )
  {
    dword_405460[i] = dword_40545C[i] + rand() % 5;
    if ( v6 <= dword_405460[i] )
      v5 = dword_405460[i];
    else
      v5 = v6;
    v6 = v5;
  }
  v3 = time(0);
  for ( j = 0; ; ++j )
  {
    result = j;
    if ( j >= 6 )
      break;
    v4 = 0;
    v2 = time(0);
    result = v3;
    if ( v2 - v3 > v6 )
      break;
    for ( k = 0; k <= 20; ++k )
    {
      if ( v2 - v3 <= dword_405460[k] )
      {
        v4 = dword_405460[k];
        break;
      }
    }
    *((_DWORD *)&xmmword_405034 + j) = (3 * j + v4 + dword_405030 * *((_DWORD *)&xmmword_405034 + j)) % 32;
    v3 = v2;
  }
  return result;
}

函数sub_4012F0

char __cdecl sub_4012F0(const char *a1)
{
  int v1; // esi
  int v3; // [esp+14h] [ebp-14h]
  int i; // [esp+1Ch] [ebp-Ch]
  int v5; // [esp+20h] [ebp-8h]

  v3 = 0;
  for ( i = 0; i < strlen(a1); i += 4 )
  {
    v1 = __ROR4__(
           a1[i + 3] | (a1[i + 2] << 8) | (a1[i + 1] << 16) | (a1[i] << 24),
           *((_DWORD *)&xmmword_405034 + i / 4));
    v5 = ((v1 << 16) | (unsigned __int16)~HIWORD(v1)) ^ (1 << *((_DWORD *)&xmmword_405034 + i / 4));
    if ( i > 0 )
      v5 ^= v3;
    v3 = v5;
    if ( v5 != dword_405018[i / 4] )
      return 0;
  }
  return 1;
}

通过搜索提示字符串可知,sub_4012F0返回值为1表示输入正确。
要想根据sub_4012F0推知正确字符串需要获取sub_401460得到的xmmword_405034。
利用ollydbg动调发现结果受到每次循环的时间差v2 - v3的影响,而程序正常运行是时间差可以看做为0,因此对程序做一下修改使得时间差为0。
在这里插入图片描述
在这里插入图片描述
然后动调求xmmword_405034的值
在这里插入图片描述
得到结果为

0x03, 0x10, 0x0d, 0x04, 0x13, 0x0b

根据sub_4012F0写出对应的解密程序

#include<bits/stdc++.h>

using namespace std;
unsigned int dword_405018[6] = {2351698746u, 4148999158u, 4276070130u, 2871606843u, 651135530u, 2292314745u};
const unsigned int xmmword_405034[6] = {0x03, 0x10, 0x0d, 0x04, 0x13, 0x0b};

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    vector<char> ans(24);
    for (int i = 5; i >= 1; i--)dword_405018[i] ^= dword_405018[i - 1];
    for (int i = 0; i < 24; i += 4) {
        unsigned int tmp = dword_405018[i >> 2] ^ (1 << xmmword_405034[i >> 2]);
        tmp = (~tmp << 16) | (tmp >> 16);
        tmp = (tmp << xmmword_405034[i >> 2]) | (tmp >> (32 - xmmword_405034[i >> 2]));
        ans[i] = char(tmp >> 24 & 0xFF);
        ans[i + 1] = char(tmp >> 16 & 0xFF);
        ans[i + 2] = char(tmp >> 8 & 0xFF);
        ans[i + 3] = char(tmp & 0xFF);
    }
    for (char c: ans)cout << c;
    return 0;
}

运行得到flag

flag{a_3a2y_re_for_test}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_sky123_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值