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、注意运算的顺序,尤其是看清括号在哪