好友
阅读权限35
听众
最后登录1970-1-1
|
也差不多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);
}
}
}
|
|