吾爱破解论坛【2026春节】解题领红包活动解题思路

吾爱破解论坛【2026春节】解题领红包活动解题思路

【春节】解题领红包之一 {送分题} 关注论坛微信公众号:吾爱破解论坛,回复“52TDL”获得口令。 口令:论坛禁止留联系方式

【春节】解题领红包之一 {送分题}

关注论坛微信公众号:吾爱破解论坛,回复“52TDL”获得口令。

口令:论坛禁止留联系方式

【春节】解题领红包之二 {Windows 初级题}

首先分析主验证函数sub_4CD130

int __cdecl sub_4CD130(char a1)
{
  __time32_t Seed; // eax
  char v2; // al
  char v3; // al
  char n53; // dl
  char v5; // cl
  int v6; // eax
  unsigned __int8 v8; // al
  int v9; // edx
  int v10; // edx
  int v11; // eax
  __time32_t *Time; // [esp+0h] [ebp-78h] BYREF
  char **p_p_Str; // [esp+14h] [ebp-64h]
  char *Str; // [esp+18h] [ebp-60h]
  char v15[4]; // [esp+1Ch] [ebp-5Ch] BYREF
  int v16; // [esp+20h] [ebp-58h]
  int (__cdecl *p_sub_4CC800)(int, int, int, int, int, int); // [esp+34h] [ebp-44h]
  int *v18; // [esp+38h] [ebp-40h]
  int *v19; // [esp+3Ch] [ebp-3Ch]
  void (__noreturn *p_sub_4CD4EA)(); // [esp+40h] [ebp-38h]
  __time32_t **p_Time; // [esp+44h] [ebp-34h]
  char *p_Str; // [esp+58h] [ebp-20h] BYREF
  int v23; // [esp+5Ch] [ebp-1Ch]
  char v24; // [esp+60h] [ebp-18h] BYREF
  char *v25; // [esp+70h] [ebp-8h]
  int savedregs; // [esp+78h] [ebp+0h] BYREF

  v25 = &a1;
  p_sub_4CC800 = sub_4CC800;
  p_Time = &Time;
  v18 = dword_4CE3D4;
  v19 = &savedregs;
  p_sub_4CD4EA = sub_4CD4EA;
  sub_40C330(v15);
  sub_40A650();
  v16 = -1;
  Seed = time(0);
  srand(Seed);
  SetConsoleOutputCP(0xFDE9u);
  sub_4C7E50((int)&dword_4D27C0, "========================================");
  sub_4015B0(Time);
  sub_4C7E50((int)&dword_4D27C0, "   CrackMe Challenge v2.5 - 2026        ");
  sub_4015B0(Time);
  sub_4C7E50((int)&dword_4D27C0, "========================================");
  sub_4015B0(Time);
  sub_4C7E50((int)&dword_4D27C0, "Keywords: 52pojie, 2026, Happy new year");
  sub_4015B0(Time);
  sub_4C7E50((int)&dword_4D27C0, "Hint: Fake flag; length is key");
  sub_4015B0(Time);
  sub_4C7E50((int)&dword_4D27C0, "----------------------------------------");
  sub_4015B0(Time);
  p_Str = &v24;
  v23 = 0;
  v24 = 0;
  v16 = 1;
  p_p_Str = &p_Str;
  sub_4C7E50((int)&dword_4D27C0, "\n[?] Enter the password: ");
  p_p_Str = &p_Str;
  v2 = sub_401560();
  p_p_Str = &p_Str;
  sub_4C5840(&dword_4D25E0, &p_Str, v2);
  Str = p_Str;
  v3 = sub_401740(p_Str);
  n53 = 53;
  v5 = v3;
  v6 = 0;
  if ( !v5 )
  {
    while ( Str[v6] == n53 )
    {
      if ( ++v6 == 16 )
      {
        v16 = 1;
        sub_4C7E50((int)&dword_4D27C0, "\n[!] You're getting closer...");
        v16 = 1;
        goto LABEL_9;
      }
      n53 = byte_4D3032[v6];
    }
    if ( strlen(Str) != 31 )
    {
      v16 = 1;
      sub_4C7E50((int)&dword_4D27C0, "\n[!] Hint: The length is your first real challenge.");
      goto LABEL_9;
    }
    v16 = 1;
    if ( sub_4016D0(Str, 31) )
    {
      Str = 0;
      v8 = *p_Str;
      if ( !*p_Str )
        goto LABEL_16;
      v9 = 0;
      do
      {
        Str += ++v9 * v8;
        v8 = p_Str[v9];
      }
      while ( v8 );
      if ( Str != (char *)44709 )
      {
LABEL_16:
        v16 = 1;
        sub_4C7E50((int)&dword_4D27C0, "\n[!] Checksum failed! Something is wrong...");
        sub_4015B0(Time);
        sub_4C7E50((int)&dword_4D27C0, "[!] Expected: 44709, Got: ");
        sub_47DE70(Str);
        sub_4015B0(v10);
LABEL_17:
        v16 = 1;
        goto LABEL_10;
      }
      v16 = 1;
      sub_4C7E50((int)&dword_4D27C0, "\n========================================");
      sub_4015B0(Time);
      sub_4C7E50((int)&dword_4D27C0, "        *** SUCCESS! ***                ");
      sub_4015B0(Time);
      sub_4C7E50((int)&dword_4D27C0, "========================================");
      sub_4015B0(Time);
      sub_4C7E50((int)&dword_4D27C0, "[+] Congratulations! You cracked it!");
      sub_4015B0(Time);
      v11 = sub_4C7E50((int)&dword_4D27C0, "[+] Correct flag: ");
      sub_4C4330(v11, p_Str, v23);
    }
    else
    {
      v16 = 1;
      sub_4C7E50((int)&dword_4D27C0, "\n[X] Access Denied!");
      sub_4015B0(Time);
      sub_4C7E50((int)&dword_4D27C0, "[X] Wrong password. Keep trying!");
    }
    sub_4015B0(Time);
    goto LABEL_17;
  }
  sub_4C7E50((int)&dword_4D27C0, "\n[!] Nice try, but not quite right...");
LABEL_9:
  sub_4015B0(Time);
LABEL_10:
  sub_4017C0();
  sub_4B1AE0(p_p_Str);
  sub_40C600(v15);
  return 0;
}

程序接收用户输入后,进行了一次循环比对:

  • Fake Flag 陷阱:如果输入的前 16 个字符匹配内置数组byte_4D3032(首字符为ASCII53即“5”),程序会打印“You’re getting closer…”然后直接跳出结束。这是出题人设下的心理战干扰项。

  • 长度限制:紧接着程序执行了strlen(Str) != 31的判断,这为我们提供了第一个硬性约束条件:真正的Flag长度严格等于31位。

在程序的导出/入口表中观察到一个TlsCallback_0函数。TLS(Thread Local Storage)回调在执行时机上早于main函数,常被恶意软件或CTF用来埋设反调试(Anti-Debug)逻辑。但经仔细静态分析,该函数仅包含__mingw_TLScallback的标准编译器初始化代码,并无“藏毒”,可放心忽略。

main函数尾部,有一个复杂的校验和逻辑用来验证最终结果:

i=131(i×input[i1])=44709\sum_{i=1}^{31} (i \times \text{input}[i-1]) = 44709

但在此之前,程序必须先通过关键的一行判定:

if ( (unsigned __int8)sub_4016D0(Str, 31) )

跟进sub_4016D0

bool __cdecl sub_4016D0(char *Str, int n31)
{
  unsigned __int8 *Block; // ebp
  int n31_1; // eax
  int n31_2; // ebx
  bool v5; // dl

  Block = (unsigned __int8 *)sub_4CB710(0x64u);
  sub_401620(Block);
  if ( n31 <= 0 )
  {
    n31_2 = 0;
  }
  else
  {
    n31_1 = 0;
    n31_2 = 0;
    do
    {
      v5 = Str[n31_1] == Block[n31_1];
      ++n31_1;
      n31_2 += v5;
    }
    while ( n31 != n31_1 );
  }
  j_j_free(Block);
  return n31 == n31_2;
}

我们发现,它在堆上malloc了一段100字节的内存空间(变量Block),将其传给sub_401620函数处理,随后用自定义的do-while do-while循环将用户输入与这段Block内存逐字节比对。这说明真实的Flag是在运行时动态解密并写入内存的。

进入造旗工厂sub_401620,我们找到了纯粹的底层数据操作逻辑:

_BYTE *__cdecl sub_401620(int a1)
{
  _BYTE *result; // eax

  *(_DWORD *)a1 = 758280311;
  *(_DWORD *)(a1 + 4) = 1663511336;
  *(_DWORD *)(a1 + 8) = 1880974179;
  *(_DWORD *)(a1 + 12) = 494170226;
  *(_DWORD *)(a1 + 16) = 842146570;
  *(_DWORD *)(a1 + 20) = 657202491;
  *(_DWORD *)(a1 + 24) = 658185525;
  *(_BYTE *)(a1 + 30) = 99;
  *(_WORD *)(a1 + 28) = 12323;
  result = (_BYTE *)a1;
  do
    *result++ ^= 0x42u;
  while ( result != (_BYTE *)(a1 + 31) );
  *(_BYTE *)(a1 + 31) = 0;
  return result;
}
  1. 内存硬编码拼接:程序将7个DWORD(32位)、1个WORD(16位)和1个BYTE(8位)整型数据,硬生生地连续赋值给刚才分配的内存指针。

  2. 小端序存储:在x86/x64架构下,这些多字节整数在内存中是以小端序(Little-Endian)排列的(低位字节存放在低地址处)。

  3. 异或解密:最后,通过一个经典的单字节XOR循环*result++ ^= 0x42u; *result++ ^= 0x42u;,将这31个字节依次与0x42异或,还原出真正的Flag明文。

利用Python的struct模块可以完美模拟C语言底层的内存分配规则,精准还原原始字节流并进行异或:

import struct

def solve():
    data = bytearray(31)
    
    # '<I' 表示小端序无符号 32 位整数 (DWORD)
    data[0:4]   = struct.pack('<I', 758280311)
    data[4:8]   = struct.pack('<I', 1663511336)
    data[8:12]  = struct.pack('<I', 1880974179)
    data[12:16] = struct.pack('<I', 494170226)
    data[16:20] = struct.pack('<I', 842146570)
    data[20:24] = struct.pack('<I', 657202491)
    data[24:28] = struct.pack('<I', 658185525)
    
    # '<H' 表示小端序无符号 16 位整数 (WORD)
    data[28:30] = struct.pack('<H', 12323)
    
    # '<B' 表示无符号 8 位整数 (BYTE)
    data[30:31] = struct.pack('<B', 99)

    # 逐字节 XOR 0x42 解密
    flag = "".join([chr(b ^ 0x42) for b in data])
    return flag

if __name__ == '__main__':
    real_flag = solve()
    print(f"[+] 成功解密 Flag: {real_flag}")

    # 验证最外层的冗余校验和机制
    checksum = sum((i + 1) * ord(c) for i, c in enumerate(real_flag))
    if checksum == 44709:
        print("[+] 校验和匹配 (44709),答案完全正确!")

口令:52pojie!!!_2026_Happy_new_year!

【春节】解题领红包之三 {Android 初级题}

直接玩通关,新(第一行第一列)、年(第一行第二列)、别(第一行第三列)、感(第二行第三列)。

口令:flag{Wu41_P0j13_2026_Spr1ng_F3st1v4l}

【春节】解题领红包之四 {Windows 初级题}

双击运行【2026春节】解题领红包之四 {Windows 初级题} 出题老师:云在天.exe,得到提示:去反编译它。这是一个Python编写的CrackMe,我们需要使用PyInstaller Extractor,为了后续命令执行方便,我们将源文件重命名为4.exe,然后在终端运行python pyinstxtractor.py 4.exe。在4.exe_extracted文件夹下,我们发现了crackme_easy.pyc,使用https://pylingual.io反编译得到如下代码:

# Decompiled with PyLingual (https://pylingual.io)
# Internal filename: 'crackme_easy.py'
# Bytecode version: 3.14rc3 (3627)
# Source timestamp: 1970-01-01 00:00:00 UTC (0)

import hashlib
import base64
import sys
def xor_decrypt(data, key):
    """XOR解密"""
    result = bytearray()
    for i, byte in enumerate(data):
        result.append(byte ^ key ^ i & 255)
    return result.decode('utf-8', errors='ignore')
def get_encrypted_flag():
    """获取加密的flag"""
    enc_data = 'e3w+fiRvfW18fnx4ZAZ6Pj43YwB9OWMXfXo8Dg4O'
    return base64.b64decode(enc_data)
def generate_flag():
    """动态生成flag"""
    encrypted = get_encrypted_flag()
    key = 78
    result = bytearray()
    for i, byte in enumerate(encrypted):
        result.append(byte ^ key)
    return result.decode('utf-8')
def calculate_checksum(s):
    """计算校验和"""
    total = 0
    for i, c in enumerate(s):
        total += ord(c) * (i + 1)
    return total
def hash_string(s):
    """计算字符串哈希"""
    return hashlib.sha256(s.encode()).hexdigest()
def verify_flag(user_input):
    """验证flag"""
    correct_flag = generate_flag()
    if len(user_input)!= len(correct_flag):
        return False
    else:
        for i in range(len(correct_flag)):
            if user_input[i]!= correct_flag[i]:
                return False
        return True
def fake_check_1(user_input):
    """假检查1"""
    fake_hash = 'a1b2c3d4e5f67890abcdef1234567890abcdef1234567890abcdef1234567890'
    return hash_string(user_input) == fake_hash
def fake_check_2(user_input):
    """假检查2"""
    fake_hash = '1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef'
    return hash_string(user_input) == fake_hash
def main():
    """主函数"""
    print('==================================================')
    print('   CrackMe Challenge - Python Edition')
    print('==================================================')
    print('Keywords: 52pojie, 2026, Happy New Year')
    print('Hint: Decompile me if you can!')
    print('--------------------------------------------------')
    user_input = input('\n[?] Enter the password: ').strip()
    if fake_check_1(user_input):
        print('\n[!] Nice try, but not quite right...')
        input('\nPress Enter to exit...')
        return None
    else:
        if fake_check_2(user_input):
            print('\n[!] You\'re getting closer...')
            input('\nPress Enter to exit...')
        else:
            if verify_flag(user_input):
                checksum = calculate_checksum(user_input)
                expected_checksum = calculate_checksum(generate_flag())
                if checksum == expected_checksum:
                    print('\n==================================================')
                    print('        *** SUCCESS! ***')
                    print('==================================================')
                    print('[+] Congratulations! You cracked it!')
                    print(f'[+] Correct flag: {user_input}')
                else:
                    print('\n[!] Checksum failed!')
            else:
                print('\n[X] Access Denied!')
                print('[X] Wrong password. Keep trying!')
            input('\nPress Enter to exit...')
if __name__ == '__main__':
    try:
        main()
    except KeyboardInterrupt:
        print('\n\n[!] Interrupted by user')
        sys.exit(0)

写出解密脚本:

import base64

# 1. 提取硬编码的 Base64 密文
enc_data = 'e3w+fiRvfW18fnx4ZAZ6Pj43YwB9OWMXfXo8Dg4O'

# 2. Base64 解码
decoded_bytes = base64.b64decode(enc_data)

# 3. 异或解密 (Key = 78)
key = 78
flag = bytearray()
for byte in decoded_bytes:
    flag.append(byte ^ key)

# 4. 打印最终结果
print("The Flag is:", flag.decode('utf-8'))

口令:52p0j!3#2026*H4ppy-N3w-Y34r@@@

一言 2026-02-20
烤串命名法(kebab-case):让你的标题“串”起来 2026-02-20