CrackMe_注册码
Last updated on January 27, 2024 am
记录一道CrackMe
Crack
题目逻辑很简单,题目内置一个machine id
,然后需要输入user name
和key
,再进行验证
继续往下分析,会出现两个加密的函数sub_7FF7425F1000
和sub_7FF7425F10E0
,通过加密常量和调试分析可以确定这两个函数实际作用是进行MD5加密。
在经过MD5加密后,继续进行一个加密,这里用到大量的SIMD指令,粗略查看这里面涉及到打乱、乘法、相加等操作,可以先暂且跳过,不详细跟。
在对得到的MD5密文加密后,得到一个新的密文。
然后继续对user_id
作相同的处理
得到密文
再将两个密文作拼接操作
得到新的密文
然后再对新的密文作两次完全一样的加密,即先MD5然后SIMD指令加密,这样操作两次
最后对输入的key进行相同的加密
最终进行比较
回顾整个加密比较流程,用F
表示MD5和SIMD加密,那么machine_code
、user_id
和key
之间应该满足如下关系
F(key) = F(F(F(machine_code)+F(user_id)))
那么key
就应该等于
F(F(machine_code)+F(user_id))
而这一个可以通过调试手段在中间拿到
总结
文件没有直接存放密文,而是在程序运行中生成密文进行比较
SIMD指令总结
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110__m128i _mm_loadl_epi64 (__m128i const* mem_addr)
加载参数低64bit到低64dit,高64bit置0
__m128i _mm_unpacklo_epi8 (__m128i a, __m128i b)
a与b每按8bit交错排布到返回值,低bit对应低bit,先a再b
__m128i _mm_sub_epi16 (__m128i a, __m128i b)
每16bit相减
__m128i _mm_shuffle_epi32 (__m128i a, int imm8)
将__m128i 分为4 * 32 bit,a0 a1 a2 a3
这4个int有一个位置代号:0x11 0x10 0x01 0x00
如果imm = 0x00 0x00 0x00 0x00 ,则得到的__m128i则是(r0 = a3,r1=a3,r2=a3,r3=a3)
__m128i _mm_cmpgt_epi32 (__m128i a, __m128i b)
每32bit比较,若a>b则相应的32bit置全F,否则置0
__m128i _mm_xor_si128 (__m128i a, __m128i b)
每bit异或
int _mm_cvtsi128_si32 (__m128i a)
取低32位赋值
__m128i _mm_cvtsi32_si128 (int a)
将a赋值给0:31,32-127赋值0
__m128i _mm_srli_epi64 (__m128i a, int imm8)
每64位右移imm8,空出的位置补零
__m128i _mm_srli_epi32 (__m128i a, int imm8)
每32位右移imm8,空出的位置补零
__m128i _mm_unpackhi_epi32 (__m128i a, __m128i b)
取a,b的高64位,每32bit交错排列,如:
dst[31:0] := src1[95:64]
dst[63:32] := src2[95:64]
dst[95:64] := src1[127:96]
dst[127:96] := src2[127:96]
__m128i _mm_srli_si128 (__m128i a, int imm8)
右移8*imm8位
int _mm_extract_epi16 (__m128i a, int imm8)
a右移imm8*16bit后取低16bit赋值给目标int的低16位,高16位置零
dst[15:0] := (a[127:0] >> (imm8[2:0] * 16))[15:0]
dst[31:16] := 0
__m128i _mm_slli_epi32 (__m128i a, int imm8)
每个32左移imm8,空余补零
__m128 _mm_set_ps1 (float a)
将a重复拷贝到4个32中
__m128 _mm_set_ps (float e3, float e2, float e1, float e0)
dst[31:0] := e0
dst[63:32] := e1
dst[95:64] := e2
dst[127:96] := e3
__m128 _mm_max_ps (__m128 a, __m128 b)
每32bit取较大值
__m128 _mm_set_ss (float a)
将a赋给目标的0:31 bit
CrackMe_注册码
http://example.com/2024/01/19/Register_MD5/