# 前言

本文并不能带你解决这道题目,它是用来记录一些经典的解题思路和重点的

# 经典 - 爆破

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 - 解码

img
看上图,对 base 敏感的很容易看出来是 base58,找个网站解一下就 OK 了。
ISCC

# cheems - 壳

img
打开啥都没有
img
查壳能查到
img
脱壳报错,回看上面 upx 壳关键字段却是 cpx
010 修改 CPX 后尝试脱壳
img

img
脱壳成功
ida 打开 shift+f12
img

# 经典 re1 - 寄存器

没有关键代码,关键字查不到 ——— 一般 flag 存在寄存器中,x64 运行后直接搜索字符串
img

img

# 经典 re2 - 关键字符为空

img

在分析代码时这一部分是空的,学长讲是藏在寄存器里
img 跟过去找到函数打开伪代码
img

再次进入那个地址就能找到藏起来的字符。

# squid-python 打包

ida 打开看不到解题信息,大量 py 文件
img 使用工具解包,但 pyz 提取失败
img 装上 3.6 再次提取,成功了
img 文件头修改一下
img 反编译并进行逆向
img 写出脚本得出 flag

img

Edited on

Give me a cup of [coffee]~( ̄▽ ̄)~*

lxy WeChat Pay

WeChat Pay

lxy Alipay

Alipay

lxy PayPal

PayPal