XYCTF-----Reverse复现

1、baby unity:

 当时是根据网上的教程做出来的,现在记录一下学习一下

首先先打开运行一下文件,发现有提示显示unity,所以进行il2cpp逆向

1、查壳与脱壳:

有upx的壳,脱掉UPX的壳

2、分析baby unity_Data\il2cpp_data\Metadata\global-metadata.dat文件,观察是不是以AF 1B 1B FA 开头。然后才可以进行dump

接下来使用il2cppdump进行解包

命令格式:
 

Il2CppDumper.exe executable-file global-metadata output-directory

我使用了bat进行处理,方便下次使用

..\Il2CppDumper.exe GameAssembly.dll global-metadata.dat ..\output

说明一下上面的使用,首先用txt进行编写,后面进行bat修改后缀,在这里我将其放在了input的文件夹内,输出到output里面

所以我们就可以在output里面进行查看CSharp文件

我们使用dnspy打开这个文件

我们使用ida对GameAssmely.dll文件进行符号还原

使用script file 导入文件,依次选择ida py3和script.json

搜索这个函数,进行反编译进行查看代码

根据这个·我们可以看到他的加密部分

这个代码就是将其原文与0xF异或得到密文

我们找一下密文反着求回去

给一下解密代码:
 

import base64

data='XIcKYJU8Buh:UeV:BKN{U[JvUL??VuZ?CXJ;AX^{Ae]gA[]gUecb@K]ei^22'
flag=''
for i in range(len(data)):
  flag+=chr(ord(data[i])^0xf)
print(flag)
print(base64.b64decode(flag))

WFlDVEZ7Mzg5ZjY5MDAtZTEyZC00YzU0LWE4NWQtNjRhNTRhZjlmODRjfQ==
b'XYCTF{389f6900-e12d-4c54-a85d-64a54af9f84c}'

此题总结:

1、li2cpp逆向的步骤:

        (1):首先查看他的global-metada.dat是否被篡改(文件头是不是AF1BB1FA)

        (2):使用ill2cppdump进行解包,命令行
                Il2CppDumper.exe executable-file global-metadata output-directory

        (3):使用dnspy查看函数在哪加密;

        (4):使用ida进行符号还原:先把GameAssmely.dl拉入ida,然后把ida py3拉入ida 然后再把script.json拉入ida

        (5):根据在dnspy中看到的函数在ida中查找具体的函数

2、ez_rand:

1、查壳:

   64位程序

2、ida启动:

一定一定一定要注意类型以及位数,要不然根本爆不出来

int __fastcall main(int argc, const char **argv, const char **envp)
{
  unsigned __int64 v3; // rbx
  unsigned __int16 v4; // ax
  int v5; // edi
  __int64 v6; // rsi
  int v7; // eax
  int v9[7]; // [rsp+20h] [rbp-50h]
  char v10; // [rsp+3Ch] [rbp-34h]
  __int16 v11; // [rsp+3Dh] [rbp-33h]
  __int128 v12; // [rsp+40h] [rbp-30h]
  __int64 v13; // [rsp+50h] [rbp-20h]
  int v14; // [rsp+58h] [rbp-18h]
  __int16 v15; // [rsp+5Ch] [rbp-14h]
  char v16; // [rsp+5Eh] [rbp-12h]

  v13 = 0i64;
  v12 = 0i64;
  v14 = 0;
  v15 = 0;
  v16 = 0;
  sub_7FF7B62F1020("请输入flag:");
  sub_7FF7B62F1080("%s");
  v9[0] = -362017699;
  v11 = 0;
  v3 = -1i64;
  v9[1] = 888936774;
  v9[2] = 119759538;
  v9[3] = -76668318;
  v9[4] = -1443698508;
  v9[5] = -2044652911;
  v9[6] = 1139379931;
  v10 = 77;
  do
    ++v3;
  while ( *(&v12 + v3) );
  v4 = time64(0i64);
  srand(v4);
  v5 = 0;
  if ( v3 )
  {
    v6 = 0i64;
    do
    {
      v7 = rand();
      if ( (*(&v12 + v6) ^ (v7
                          + ((((2155905153i64 * v7) >> 32) & 0x80000000) != 0i64)
                          + (((2155905153i64 * v7) >> 32) >> 7))) != *(v9 + v6) )
      {
        sub_7FF7B62F1020("Error???\n");
        exit(0);
      }
      ++v5;
      ++v6;
    }
    while ( v5 < v3 );
  }
  sub_7FF7B62F1020("Right???\n");
  system("pause");
  return 0;
}

给一下解密代码:

#include <iostream>
using namespace std;

int main() {
   char data[29] = { 0x5D, 0x0C, 0x6C, 0xEA, 0x46, 0x19, 0xFC, 0x34,
0xB2, 0x62, 0x23, 0x07, 0x62, 0x22, 0x6E, 0xFB, 0xB4, 0xE8, 0xF2, 0xA9, 0x91,
0x12, 0x21, 0x86, 0xDB, 0x8E, 0xE9, 0x43, 0x4D };
    char flag[29] = {0};
     int v7;
    for ( int i = 0; i < 65535; i++) {
        srand(i);
        
        for ( int j = 0; j < 29; j++) {
            v7 = rand();
            int num = (int)((2155905153 * v7) >> 32);
            int data2 = (v7+ ((num & 0x80000000) != 0)+( num >> 7) );
            flag[j] = data2 ^ data[j];
        }
        if (flag[0] == 'X' and flag[1] == 'Y')
            cout << flag;
        
        
    }
}

此题总结:

1、注意变量的类型和位数

2、注意运算的顺序,尤其是看清括号在哪

 

  • 34
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值