# 前言
本文并不能带你解决这道题目,它是用来记录一些经典的解题思路和重点的
# 经典 - 爆破
iscc 原题,变表 base64,爆破思想
int __cdecl main_0(int argc, const char **argv, const char **envp)
{
size_t v4; // [esp+DCh] [ebp-E98h]
size_t v5; // [esp+E8h] [ebp-E8Ch]
char Str2[73]; // [esp+F4h] [ebp-E80h] BYREF
char v7[520]; // [esp+13Dh] [ebp-E37h] BYREF
char v8[511]; // [esp+345h] [ebp-C2Fh] BYREF
char Str1; // [esp+54Ch] [ebp-A28h] BYREF
char v10[511]; // [esp+54Dh] [ebp-A27h] BYREF
char v11; // [esp+754h] [ebp-820h] BYREF
char v12[511]; // [esp+755h] [ebp-81Fh] BYREF
char v13; // [esp+95Ch] [ebp-618h] BYREF
char v14[511]; // [esp+95Dh] [ebp-617h] BYREF
char v15; // [esp+B64h] [ebp-410h] BYREF
char v16[511]; // [esp+B65h] [ebp-40Fh] BYREF
char Str; // [esp+D6Ch] [ebp-208h] BYREF
char v18[511]; // [esp+D6Dh] [ebp-207h] BYREF
Str = 0;
j__memset(v18, 0, sizeof(v18));
v15 = 0;
j__memset(v16, 0, sizeof(v16));
v13 = 0;
j__memset(v14, 0, sizeof(v14));
v11 = 0;
j__memset(v12, 0, sizeof(v12));
Str1 = 0;
j__memset(v10, 0, sizeof(v10));
v7[519] = 0;
j__memset(v8, 0, sizeof(v8));
Str2[72] = 0;
j__memset(v7, 0, 0x1FFu);
j__printf(aFlag);
sub_411721((va_list)"%s", (char)&Str);
strcpy(Str2, ".W1BqthGbfGBqoXBmVZRQd.W5VoXNJcMR6XNBxoM5FoFDucMWyWNfBpXNAoF0.");
v5 = j__strlen(&Str);
sub_4116C7(&Str, v5, &v15, 0);//表为:‘ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/’的base64转码
v4 = j__strlen(&v15);
sub_411389(&v15, v4, &v13, 1);//表为:‘ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_’的base64转码
sub_411023(&v13, &v11, 46, 0);
sub_411023(&v11, &Str1, 46, 22);
//在0和22的位置插入“.”
sub_4116E0(&Str1, 2);
//学长教我们用爆破解开,这个函数实质的每个字符位移“2”位
if ( !j__strcmp(&Str1, Str2) )
j__printf("flag is Correct!\n");
else
j__printf("flag is wrong!\n");
j__system("pause");
return 0;
}
解析就在上面代码里
下面写一下爆破脚本
#include <iostream>
int main()
{
char x[100];//接收正确的字符
int Str[100];//作为爆破用的中间量
char a1[] = ".W1BqthGbfGBqoXBmVZRQd.W5VoXNJcMR6XNBxoM5FoFDucMWyWNfBpXNAoF0.";
int a2 = 2;//题中给的
int len = strlen(a1);
for (int i = 0;i<len; ++i)
{
for (int j = 0; j < 128; j++)
{
Str[i] = j;
if (Str[i] < 65 || Str[i] > 90)
{
if (Str[i] >= 97 && Str[i] <= 122)
Str[i] = (Str[i] + a2 - 97) % 26 + 97;
}
else
{
Str[i] = (Str[i] + a2 - 65) % 26 + 65;
}
if ((char)Str[i] == a1[i])
{
x[i] = j;
}
}
}
for (int i = 0; i < len; i++)
{
printf("%c", x[i]);
}
}
重点是学会使用爆破来解答一些复杂难逆的函数。
# 经典 base - 解码
看上图,对 base 敏感的很容易看出来是 base58,找个网站解一下就 OK 了。
ISCC
# cheems - 壳
打开啥都没有
查壳能查到
脱壳报错,回看上面 upx 壳关键字段却是 cpx
010 修改 CPX 后尝试脱壳
脱壳成功
ida 打开 shift+f12
# 经典 re1 - 寄存器
没有关键代码,关键字查不到 ——— 一般 flag 存在寄存器中,x64 运行后直接搜索字符串
# 经典 re2 - 关键字符为空
在分析代码时这一部分是空的,学长讲是藏在寄存器里
跟过去找到函数打开伪代码
再次进入那个地址就能找到藏起来的字符。
# squid-python 打包
ida 打开看不到解题信息,大量 py 文件
使用工具解包,但 pyz 提取失败
装上 3.6 再次提取,成功了
文件头修改一下
反编译并进行逆向
写出脚本得出 flag