吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 674|回复: 5
上一主题 下一主题
收起左侧

[CrackMe] .Net CrackMe V4!

  [复制链接]
跳转到指定楼层
楼主
gsyifan 发表于 2026-8-14 10:27 回帖奖励
CM是什么?Crackme是什么?这是什么东西?楼主发的什么?
他们都是一些公开给别人尝试破解的小程序,制作 Crackme 的人可能是程序员,想测试一下自己的软件保护技术,也可能是一位 Cracker,想挑战一下其它 Cracker 的破解实力,也可能是一些正在学习破解的人,自己编一些小程序给自己破解,KeyGenMe是要求别人做出它的 keygen (序号产生器), ReverseMe 要求别人把它的算法做出逆向分析, UnpackMe 是要求别人把它成功脱壳,本版块禁止回复非技术无关水贴。

本帖最后由 gsyifan 于 2026-8-14 10:30 编辑

期望目标

  • 解出密码
  • 还原完整算法源码

程序环境

  • .Net 4.8

保护说明

  • 保护选项:混淆+VM虚拟化+反调试
  • V4版本使用了C++虚拟化,难度增加
  • 目前并非最强保护,欢迎持续挑战!

原程序(密码确定可解)

成功截图

可使用AI分析,希望能贴出分析的AI和环境(如Codex+Deepseek Pro)
期望和大家一起探讨对抗AI分析的手段和方法。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册[Register]

x

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

推荐
又是馒头 发表于 2026-8-14 12:24

Reasonix+deepseek_flash
花了我2.94元,楼主给不给报销?一行代码没敲,完全AI,跑了44分钟,用了1亿tokens

crackme_solution.py(算法源码+密码推导+走查)
[Python] 纯文本查看 复制代码
# -*- coding: utf-8 -*-
"""
CrackMe.exe 完整逆向
====================
保护: TWProtector (.NET 4.8) — 混淆 + VM虚拟化 + 反调试
虚拟化方法: 5 个 (token 0x06000001/2/5/6/B), 核心为 Verify(0x06000005)

VMBC 解密链:
  global.bin (VMBC v3) -> HMAC-SHA256 校验 + ChaCha20 解密 (master key 由
  "TWProtector_MK_v3.0.0_salt_xyz_9" + nonce + LCG 派生)
  方法体: ChaCha20(per-method key) + per-method S-box(逆)

Verify 算法 (还原自 VM 字节码, 控制流平坦化 + 常量混淆):
  静态数据 (来自 <PrivateImplementationDetails> RVA 字段):
    pattern = A5 5A A5 5A 0F F0 0F F0 33 CC 33 CC 55 AA 55 AA   (0x04000004)
    perm    = [3,11,7,14,1,9,4,12,0,6,10,2,15,5,13,8]           (0x04000003, int[16])
    seq     = 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF 00   (0x04000005)
    key     = 41 F7 25 EE 25 81 9C 93 47 21 E3 5B 88 12 59 28   (0x04000002)

  Verify(input[16]):
    1. input[i] ^= pattern[i]
    2. input[i] = ROL(input[i], 3)   # 循环左移 3 位
    3. out[i] = input[perm[i]]       # 按排列表重排
    4. out[i] ^= seq[i]
    5. 全部相等返回 true
"""

KEY   = bytes.fromhex('41f725ee25819c934721e35b88125928')
SEQ   = bytes.fromhex('112233445566778899aabbccddeeff00')
PAT   = bytes.fromhex('a55aa55a0ff00ff033cc33cc55aa55aa')
PERM  = [3,11,7,14,1,9,4,12,0,6,10,2,15,5,13,8]

def rol3(x):
    return ((x << 3) | (x >> 5)) & 0xFF

def ror3(x):
    return ((x >> 3) | (x << 5)) & 0xFF

def verify(byte_input):
    assert len(byte_input) == 16
    b = bytearray(byte_input)
    for i in range(16):
        b[i] ^= PAT[i]
    for i in range(16):
        b[i] = rol3(b[i])
    out = bytearray(16)
    for i in range(16):
        out[i] = b[PERM[i]]
    for i in range(16):
        out[i] ^= SEQ[i]
    return bytes(out) == KEY

def derive_password():
    # 逆推: 目标 out == KEY
    # 逆阶段4: out[i] = KEY[i] ^ SEQ[i]
    stage4 = bytes(k ^ s for k, s in zip(KEY, SEQ))
    # 逆阶段3: out[i] = b[PERM[i]]  =>  b[j] = stage4[PERM^-1[j]]
    inv = [0]*16
    for i, p in enumerate(PERM):
        inv[p] = i
    b = bytes(stage4[inv[j]] for j in range(16))
    # 逆阶段2: b = ROL3(x) => x = ROR3(b)
    xored = bytes(ror3(x) for x in b)
    # 逆阶段1: xored = input ^ PAT
    pwd = bytes(x ^ p for x, p in zip(xored, PAT))
    return pwd

if __name__ == '__main__':
    pwd16 = derive_password()
    print('16字节密码: ', pwd16.hex(' '))
    printable = pwd16.rstrip(b'\x00')
    print('可打印部分: ', repr(printable.decode('ascii')))
    # 程序 pad 到 16: 14 字符 + 2 NUL
    padded = printable + b'\x00' * (16 - len(printable))
    print('pad 验证:   ', padded == pwd16)

    # 验证算法
    print()
    print('verify(padded 16B) =', verify(pwd16))
    print('verify("test" pad) =', verify(b'test' + b'\x00'*12))

    # 走查一次: 输入正确密码
    demo = bytearray(padded)
    for i in range(16):
        demo[i] ^= PAT[i]
    print()
    print('演示阶段1 XOR pattern:', bytes(demo).hex(' '))
    for i in range(16):
        demo[i] = rol3(demo[i])
    print('演示阶段2 ROL3       :', bytes(demo).hex(' '))
    out = bytearray(16)
    for i in range(16):
        out[i] = demo[PERM[i]]
    print('演示阶段3 perm 重排  :', bytes(out).hex(' '))
    for i in range(16):
        out[i] ^= SEQ[i]
    print('演示阶段4 XOR seq    :', bytes(out).hex(' '))
    print('目标 key             :', KEY.hex(' '))

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册[Register]

x

免费评分

参与人数 1吾爱币 +1 热心值 +1 收起 理由
gsyifan + 1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!

查看全部评分

推荐
ma15803216102 发表于 2026-8-14 20:17
我的笨蛋AI脱壳脱了半个小时   脱完壳10分钟干完了   

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册[Register]

x
3#
sfl4800 发表于 2026-8-14 14:48
也差不多30~40分钟,5千万TOKEN...现在AI是真强大。直接扔给他就完事 了
[backcolor=oklab(0.999994 0.0000455678 0.0000200868 / 0.5)]完整还原算法 C# 源码


// ==============================================================================

// CrackMe.exe — Program.Verify(byte[]) 完整算法还原

//

// 原始方法受 TWProtector VM 保护,IL 字节码经 ChaCha20 + S-box 加密,

// 运行时由 native VM 引擎解密解释执行。以下为从 VM 执行跟踪逆向还原的

// 等效 C# 源码。

//

// 密码:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

// ==============================================================================



using System;

using System.Runtime.CompilerServices;



class Program

{

    // ====== 静态字段(来自 PE .sdata 段,RVA 0x2050-0x20BF)======



    /// <summary>RID2 (0x04000002) @ RVA 0x2050 — 比较目标值(16 字节)</summary>

    static byte[] s_key = new byte[16] {

        0x41, 0xF7, 0x25, 0xEE, 0x25, 0x81, 0x9C, 0x93,

        0x47, 0x21, 0xE3, 0x5B, 0x88, 0x12, 0x59, 0x28

    };



    /// <summary>RID3 (0x04000003) @ RVA 0x2060 — 置换表(int32[16])</summary>

    static int[] s_perm = new int[16] {

        3, 11,  7, 14,  1,  9,  4, 12,

        0,  6, 10,  2, 15,  5, 13,  8

    };



    /// <summary>RID4 (0x04000004) @ RVA 0x20A0 — XOR 掩码 1(16 字节)</summary>

    static byte[] s_mask1 = new byte[16] {

        0xA5, 0x5A, 0xA5, 0x5A, 0x0F, 0xF0, 0x0F, 0xF0,

        0x33, 0xCC, 0x33, 0xCC, 0x55, 0xAA, 0x55, 0xAA

    };



    /// <summary>RID5 (0x04000005) @ RVA 0x20B0 — XOR 掩码 2(16 字节)</summary>

    static byte[] s_mask2 = new byte[16] {

        0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,

        0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x00

    };



    // ====== Verify 方法 ======

    // 原始签名: private static bool Verify(byte[] input)

    // IL token: 0x06000005

    // IL 长度: 1525 字节(经 VM 解密后为标准 CIL)

    // 局部变量: 11 个(loc0-loc10)

    //   loc0  = mask2 (byte[])

    //   loc1  = perm  (int[])

    //   loc2  = mask1 (byte[])

    //   loc3  = output (byte[])

    //   loc4  = key   (byte[])

    //   loc5  = 循环索引 i(NOT/XOR 变换阶段)

    //   loc6  = 循环索引 j(比较阶段)

    //   loc7  = 循环索引 k(XOR mask1 阶段)

    //   loc8  = 循环索引 l(ROL 阶段)

    //   loc9  = 循环索引 m(置换阶段)

    //   loc10 = 状态机状态值



    private static bool Verify(byte[] input)

    {

        // ====== 阶段 1: 初始化静态字段 ======

        // IL_0000-IL_001F: 加载 RID4 (mask1) → loc2

        // IL_0428-IL_0443: 加载 RID3 (perm)  → loc1

        // IL_01F1-IL_020C: 加载 RID5 (mask2) → loc0

        // IL_0498-IL_04B3: 加载 RID2 (key)   → loc4

        // IL_04B5:         调用 u.g() 反调试检查



        byte[] mask1  = s_mask1;   // loc2

        int[]  perm   = s_perm;    // loc1

        byte[] mask2  = s_mask2;   // loc0

        byte[] key    = s_key;     // loc4



        // ====== 阶段 2: XOR mask1(16 轮)======

        // 状态机 case: IL_045B(XOR)、IL_031B(递增 loc7)、IL_03D8(检查 loc7 < 16)

        // IL_045B: input ^= mask1

        // IL_02F7: loc7 = 0  (初始化计数器)

        // 循环 16 次 (i = 0..15)

        for (int i = 0; i < 16; i++)

        {

            input ^= mask1;

        }



        // ====== 阶段 3: 循环左移 3 位(16 轮)======

        // 状态机 case: IL_04FE(ROL3)、IL_01A1(递增 loc8)、IL_055E(检查 loc8 < 16)

        // IL_04FE: input = (input << 3) | (input >> 5)

        // IL_0280: loc8 = 0  (初始化计数器)

        // 循环 16 次 (i = 0..15)

        for (int i = 0; i < 16; i++)

        {

            input = (byte)((input << 3) | (input >> 5));

        }



        // ====== 阶段 4: 置换(16 轮)======

        // 状态机 case: IL_0407(置换)、IL_058D(递增 loc9)、IL_0239(检查 loc9 < 16)

        // IL_02C2: new byte[16] → loc3 (output)

        // IL_0407: output = input[perm]

        // 循环 16 次 (i = 0..15)

        byte[] output = new byte[16];

        for (int i = 0; i < 16; i++)

        {

            output = input[perm];

        }



        // ====== 阶段 5: XOR mask2 变换(16 轮)======

        // 状态机 case: IL_053A(NOT/XOR)、IL_05B3(递减 loc5)、IL_0380(检查 loc5 >= 0)

        // IL_00BD: loc5 = 15 (初始化计数器,从 15 递减到 0)

        // IL_053A: output = ~(output ^ ~mask2) = output ^ mask2

        //   (因为 ~(a ^ ~b) = a ^ b)

        // 循环 16 次 (i = 15..0,递减)

        for (int i = 15; i >= 0; i--)

        {

            output = (byte)(~(output ^ (byte)~mask2));

            // 等效于: output ^= mask2;

        }



        // ====== 阶段 6: 逐字节比较(16 轮)======

        // 状态机 case: IL_0352(比较)、IL_0103(递增 loc6 + 检查 loc6 < 16)

        // IL_014B: loc6 = 0  (初始化计数器)

        // IL_0352: if (output[j] != key[j]) return false

        // 循环 16 次 (j = 0..15)

        for (int j = 0; j < 16; j++)

        {

            if (output[j] != key[j])

                return false;

        }



        return true;

    }



    // ====== 逆向求解 ======

    static byte[] Solve()

    {

        // 逆阶段 6: output = key

        byte[] output = (byte[])s_key.Clone();



        // 逆阶段 5: output ^= mask2 (XOR 自反)

        for (int i = 0; i < 16; i++)

            output ^= s_mask2;



        // 逆阶段 4: 逆置换 input[perm] = output

        byte[] input = new byte[16];

        for (int i = 0; i < 16; i++)

            input[s_perm] = output;



        // 逆阶段 3: ROR3 (逆 ROL3)

        for (int i = 0; i < 16; i++)

            input = (byte)((input >> 3) | (input << 5));



        // 逆阶段 2: XOR mask1 (XOR 自反)

        for (int i = 0; i < 16; i++)

            input ^= s_mask1;



        return input;

    }



    static void Main()

    {

        byte[] password = Solve();

        Console.WriteLine("Password (hex): " + BitConverter.ToString(password));

        Console.WriteLine("Password (ASCII): " + (password[14] == 0 && password[15] == 0

            ? System.Text.Encoding.ASCII.GetString(password, 0, 14)

            : System.Text.Encoding.ASCII.GetString(password)));

        Console.WriteLine("Verify result: " + Verify(password));

    }

}

--------------------------------

密码计算+VM 验证脚本


using System;
using System.Reflection;
using System.Runtime.CompilerServices;


class Solver
{
    // Constants from static fields (RID2-RID5)
    static byte[] key   = { 0x41, 0xF7, 0x25, 0xEE, 0x25, 0x81, 0x9C, 0x93, 0x47, 0x21, 0xE3, 0x5B, 0x88, 0x12, 0x59, 0x28 };
    static int[]  perm  = { 3, 11, 7, 14, 1, 9, 4, 12, 0, 6, 10, 2, 15, 5, 13, 8 };
    static byte[] mask1 = { 0xA5, 0x5A, 0xA5, 0x5A, 0x0F, 0xF0, 0x0F, 0xF0, 0x33, 0xCC, 0x33, 0xCC, 0x55, 0xAA, 0x55, 0xAA };
    static byte[] mask2 = { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x00 };


    static byte ROL(byte b, int n) { return (byte)((b << n) | (b >> (8 - n))); }
    static byte ROR(byte b, int n) { return (byte)((b >> n) | (b << (8 - n))); }


    static void Main()
    {
        // ===== FORWARD ALGORITHM (verify understanding) =====
        // Test with all-zero input
        byte[] test = new byte[16];
        byte[] fwd = (byte[])test.Clone();


        // Step 1: XOR with mask1
        for (int i = 0; i < 16; i++) fwd ^= mask1;
        // Step 2: ROL 3
        for (int i = 0; i < 16; i++) fwd = ROL(fwd, 3);
        // Step 3: Permute
        byte[] out1 = new byte[16];
        for (int i = 0; i < 16; i++) out1 = fwd[perm];
        // Step 4: XOR with mask2
        for (int i = 0; i < 16; i++) out1 ^= mask2;
        // Step 5: Compare with key
        bool allMatch = true;
        for (int i = 0; i < 16; i++)
        {
            if (out1 != key) { allMatch = false; }
        }
        Console.WriteLine("[Forward] all-zero input -> output: " + BitConverter.ToString(out1));
        Console.WriteLine("[Forward] matches key? " + allMatch);


        // ===== REVERSE ALGORITHM (compute password) =====
        // Step R5: output = key
        byte[] output = (byte[])key.Clone();
        // Step R4: XOR with mask2 (XOR is its own inverse)
        for (int i = 0; i < 16; i++) output ^= mask2;
        Console.WriteLine("[Reverse] after un-XOR mask2: " + BitConverter.ToString(output));


        // Step R3: Inverse permutation: output = input[perm] => input[perm] = output
        byte[] input = new byte[16];
        for (int i = 0; i < 16; i++) input[perm] = output;
        Console.WriteLine("[Reverse] after un-permute: " + BitConverter.ToString(input));


        // Step R2: ROR 3 (reverse of ROL 3)
        for (int i = 0; i < 16; i++) input = ROR(input, 3);
        Console.WriteLine("[Reverse] after un-ROL: " + BitConverter.ToString(input));


        // Step R1: XOR with mask1 (XOR is its own inverse)
        for (int i = 0; i < 16; i++) input ^= mask1;
        Console.WriteLine("[Reverse] after un-XOR mask1: " + BitConverter.ToString(input));


        // Print as ASCII if possible
        Console.Write("[Password] ASCII: ");
        foreach (byte b in input)
        {
            if (b >= 0x20 && b <= 0x7E) Console.Write((char)b);
            else Console.Write("\\x" + b.ToString("X2"));
        }
        Console.WriteLine();


        // ===== VERIFY BY CALLING Verify() =====
        Console.WriteLine("\n===== VM Verification =====");
        try
        {
            Assembly asm = Assembly.LoadFrom(@"D:\CrackMe\CrackMe.exe");
            Type progType = asm.GetType("Program");
            if (progType == null)
            {
                // Try to find the type containing Verify
                foreach (var t in asm.GetTypes())
                {
                    var m = t.GetMethod("Verify", BindingFlags.NonPublic | BindingFlags.Static);
                    if (m != null) { progType = t; break; }
                }
            }


            if (progType != null)
            {
                MethodInfo verify = progType.GetMethod("Verify", BindingFlags.NonPublic | BindingFlags.Static);
                if (verify != null)
                {
                    object result = verify.Invoke(null, new object[] { input });
                    Console.WriteLine("Verify(password) = " + result);
                    Console.WriteLine("Password bytes: " + BitConverter.ToString(input));
                }
                else
                {
                    Console.WriteLine("Verify method not found!");
                }
            }
            else
            {
                Console.WriteLine("Program type not found!");
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine("Error: " + ex.Message);
            if (ex.InnerException != null)
                Console.WriteLine("Inner: " + ex.InnerException.Message);
        }
    }
}

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册[Register]

x
4#
又是馒头 发表于 2026-8-14 17:01
sfl4800 发表于 2026-8-14 14:48
也差不多30~40分钟,5千万TOKEN...现在AI是真强大。直接扔给他就完事 了
完整还原算法 C# 源码

你用的什么AI环境
6#
xiaolia 发表于 2026-8-15 10:24
感谢老哥

免费评分

参与人数 1吾爱币 -15 违规 +1 收起 理由
L_Monkey -15 + 1 CM区等技术版块禁止回复与主题无关的非技术内容,违者重罚!

查看全部评分

您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - 52pojie.cn ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2026-8-17 07:19

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表