easyRE

本文介绍了如何使用逆向工程工具IDA分析64位文件,涉及字符串比较、异或操作及Base64解密过程。通过解密两次输入的字符串,揭示了潜在的flag和关键数据。第一次输入需匹配预设的字符异或数组,第二次输入经过多次Base64编码后的字符串需与特定常量匹配。文章还展示了涉及异或和解密的函数sub_400D35的细节,提供了解密flag的关键步骤。
摘要由CSDN通过智能技术生成

查看文件,获取信息为 64位文件。

IDA打开:

signed __int64 sub_4009C6()
{
  char *v0; // rsi
  char *v1; // rdi
  signed __int64 result; // rax
  __int64 v3; // ST10_8
  __int64 v4; // ST18_8
  __int64 v5; // ST20_8
  __int64 v6; // ST28_8
  __int64 v7; // ST30_8
  __int64 v8; // ST38_8
  __int64 v9; // ST40_8
  __int64 v10; // ST48_8
  __int64 v11; // ST50_8
  __int64 v12; // ST58_8
  int i; // [rsp+Ch] [rbp-114h]
  char arraym[36]; // [rsp+60h] [rbp-C0h]
  char v15[32]; // [rsp+90h] [rbp-90h]
  int v16; // [rsp+B0h] [rbp-70h]
  char v17; // [rsp+B4h] [rbp-6Ch]
  char v18; // [rsp+C0h] [rbp-60h]
  char v19; // [rsp+E7h] [rbp-39h]
  char v20; // [rsp+100h] [rbp-20h]
  unsigned __int64 v21; // [rsp+108h] [rbp-18h]

  v21 = __readfsqword(0x28u);
  arraym[0] = 73;
  arraym[1] = 111;
  arraym[2] = 100;
  arraym[3] = 108;
  arraym[4] = 62;
  arraym[5] = 81;
  arraym[6] = 110;
  arraym[7] = 98;
  arraym[8] = 40;
  arraym[9] = 111;
  arraym[10] = 99;
  arraym[11] = 121;
  arraym[12] = 127;
  arraym[13] = 121;
  arraym[14] = 46;
  arraym[15] = 105;
  arraym[16] = 127;
  arraym[17] = 100;
  arraym[18] = 96;
  arraym[19] = 51;
  arraym[20] = 119;
  arraym[21] = 125;
  arraym[22] = 119;
  arraym[23] = 101;
  arraym[24] = 107;
  arraym[25] = 57;
  arraym[26] = 123;
  arraym[27] = 105;
  arraym[28] = 121;
  arraym[29] = 61;
  arraym[30] = 126;
  arraym[31] = 121;
  arraym[32] = 76;
  arraym[33] = 64;
  arraym[34] = 69;
  arraym[35] = 67;
  memset(v15, 0, sizeof(v15));
  v16 = 0;
  v17 = 0;
  v0 = v15;
  sub_4406E0(0LL, (__int64)v15);
  v17 = 0;
  v1 = v15;
  if ( sub_424BA0(v15) == 36 )
  {
    for ( i = 0; ; ++i )
    {
      v1 = v15;
      if ( i >= (unsigned __int64)sub_424BA0(v15) )
        break;
      if ( (unsigned __int8)(v15[i] ^ i) != arraym[i] )
      {
        result = 4294967294LL;
        goto LABEL_13;
      }
    }
    sub_410CC0("continue!");
    memset(&v18, 0, 0x40uLL);
    v20 = 0;
    v0 = &v18;
    sub_4406E0(0LL, (__int64)&v18);
    v19 = 0;
    v1 = &v18;
    if ( sub_424BA0(&v18) == 39 )
    {
      v3 = sub_400E44(&v18);
      v4 = sub_400E44(v3);
      v5 = sub_400E44(v4);
      v6 = sub_400E44(v5);
      v7 = sub_400E44(v6);
      v8 = sub_400E44(v7);
      v9 = sub_400E44(v8);
      v10 = sub_400E44(v9);
      v11 = sub_400E44(v10);
      v12 = sub_400E44(v11);
      v0 = off_6CC090;
      v1 = (char *)v12;
      if ( !(unsigned int)sub_400360(v12, off_6CC090) )
      {
        sub_410CC0("You found me!!!");
        v1 = "bye bye~";
        sub_410CC0("bye bye~");
      }
      result = 0LL;
    }
    else
    {
      result = 4294967293LL;
    }
  }
  else
  {
    result = 0xFFFFFFFFLL;
  }
LABEL_13:
  if ( __readfsqword(0x28u) != v21 )
    sub_444020(v1, v0);
  return result;
}

代码分析:

首先有两次输入,第一次输入32位字符串,将每位字符异或后与已存在的marray数组比较,因此可以写出脚本,正确输入

arr = [73,111,100,108,62,81,110,98,40,111,99,121,127,121,46,105,127,100,96,51,119,125,
       119,101,107,57,123,105,121,61,126,121,76,64,69,67]

dec = ''
for i in range(36):
    dec += chr(arr[i]^i)

print(dec)

第二次输入,将输入的字符串进行10次base64加密后,与已知的字符串比较,反向解密:

enc = "Vm0wd2VHUXhTWGhpUm1SWVYwZDRWVll3Wkc5WFJsbDNXa1pPVlUxV2NIcFhhMk0xVmpKS1NHVkdXbFpOYmtKVVZtcEtTMUl5VGtsaVJtUk9ZV3hhZVZadGVHdFRNVTVYVW01T2FGSnRVbGhhVjNoaFZWWmtWMXBFVWxSTmJFcElWbTAxVDJGV1NuTlhia0pXWWxob1dGUnJXbXRXTVZaeVdrWm9hVlpyV1hwV1IzaGhXVmRHVjFOdVVsWmlhMHBZV1ZSR1lWZEdVbFZTYlhSWFRWWndNRlZ0TVc5VWJGcFZWbXR3VjJKSFVYZFdha1pXWlZaT2NtRkhhRk5pVjJoWVYxZDBhMVV3TlhOalJscFlZbGhTY1ZsclduZGxiR1J5VmxSR1ZXSlZjRWhaTUZKaFZqSktWVkZZYUZkV1JWcFlWV3BHYTFkWFRrZFRiV3hvVFVoQ1dsWXhaRFJpTWtsM1RVaG9hbEpYYUhOVmJUVkRZekZhY1ZKcmRGTk5Wa3A2VjJ0U1ExWlhTbFpqUldoYVRVWndkbFpxUmtwbGJVWklZVVprYUdFeGNHOVhXSEJIWkRGS2RGSnJhR2hTYXpWdlZGVm9RMlJzV25STldHUlZUVlpXTlZadE5VOVdiVXBJVld4c1dtSllUWGhXTUZwell6RmFkRkpzVWxOaVNFSktWa1phVTFFeFduUlRhMlJxVWxad1YxWnRlRXRXTVZaSFVsUnNVVlZVTURrPQ=="

for i in range(10):
    enc = enc.decode('base64')
print (enc)

在第二次输入加密后对比的常量下面,还发现了一个常量,在sub_400D35函数中调用

__int64 __fastcall sub_400D35(__int64 a1, __int64 a2)
{
  __int64 v2; // rdi
  __int64 result; // rax
  unsigned __int64 v4; // rt1
  unsigned int v5; // [rsp+Ch] [rbp-24h]
  signed int i; // [rsp+10h] [rbp-20h]
  signed int j; // [rsp+14h] [rbp-1Ch]
  unsigned int v8; // [rsp+24h] [rbp-Ch]
  unsigned __int64 v9; // [rsp+28h] [rbp-8h]

  v9 = __readfsqword(0x28u);
  v2 = 0LL;
  v5 = sub_43FD20(0LL) - qword_6CEE38;
  for ( i = 0; i <= 1233; ++i )
  {
    v2 = v5;
    sub_40F790(v5);
    sub_40FE60();
    sub_40FE60();
    v5 = (unsigned __int64)sub_40FE60() ^ 0x98765432;
  }
  v8 = v5;
  if ( ((unsigned __int8)v5 ^ byte_6CC0A0[0]) == 'f' && (HIBYTE(v8) ^ (unsigned __int8)byte_6CC0A3) == 'g' )
  {
    for ( j = 0; j <= 24; ++j )
    {
      v2 = (unsigned __int8)(byte_6CC0A0[j] ^ *((_BYTE *)&v8 + j % 4));
      sub_410E90(v2);
    }
  }
  v4 = __readfsqword(0x28u);
  result = v4 ^ v9;
  if ( v4 != v9 )
    sub_444020(v2, a2);
  return result;
}

两段异或,第一段异或,能够通过’flag’和已知数组反向解出v5

第二段异或。通过已知数组和v5解出flag:

key = ''
enc1 = 'flag'
dec = ''
enc = [0x40,0x35,0x20,0x56,0x5D,0x18,0x22,0x45,0x17,0x2F,0x24,0x6E,0x62,0x3C,0x27,0x54,0x48,0x6C,0x24,0x6E,0x72,0x3C,0x32,0x45,0x5B]
for i in range(4):
    key += chr(enc[i] ^ ord(enc1[i]))
print (key)

for i in range(len(enc)):
    dec += chr(enc[i] ^ ord(key[i%4]))
print(dec)

得到flag

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值