注:此文章仅供学习使用,造成的一切后果与作者无关!!!

样本概况

Mr.Hu-Image

程序信息

它是需要注册的一个状态

一般这种情况都会有两种思路

​ 1, 暴力破解(脚本小子)

​ 2, 序列号解密(需要屏蔽网络验证)

分析环境

系统:Win 7 32为专业版

使用工具:IDA,OD,(PE/010Editor),VS2019

分析过程

暴力破解

提取关键字符串

一般在没有序列号的情况下随机输入是这样的

Mr.Hu-Image

这个时候复制它的报错信息

1
2
3
4
5
6
7
8
---------------------------
010 Editor
---------------------------
Invalid name or password. Please enter your name and password exactly as given when you purchased 010 Editor (make sure no quotes are included).
---------------------------
&OK
---------------------------

使用OD打开010Editor

Mr.Hu-Image

让他运行起来(由于之前折腾过的原因我这里,点击运行后会直接弹出注册窗口,这个无所谓,只要你能找到这个窗口随机输入一个序列号,复制他的报错信息就可以了)

注:注册窗口在(Help–>About…)

Mr.Hu-Image

右击反汇编界面–>查找–>所有参考文本字串

Mr.Hu-Image

在弹出的(文本字串参考位于)窗口右击–>查找文本,,,输入之前提取的字符串(只需要关键字符串即可,如图)

Mr.Hu-Image

找到之后双击进入代码区域

Mr.Hu-Image

双击后会看到自己搜索的字符串

Mr.Hu-Image

找到关键函数

要知道,搜索的字符串是是序列号错误的情况下输出的信息,所以需要找到什么地方判断序列号是错的从而跳转到该错误的信息处

当鼠标左键点击到push的字符串的那句代码上时下面的提示框显示了该语句来自于那个地址的跳转,这时可以右击该地址–>单机(转到jnz来自)

Mr.Hu-Image

跳转到的地方

Mr.Hu-Image

可以看到这一块都是比较后跳转,不用关系这些是往哪跳的,主要找到是哪跳过来的

接下来继续找到跳转到这里的的地方

Mr.Hu-Image

同样的方法继续,右击该地址–>单机(转到jnz来自)

Mr.Hu-Image

这里有个关键信息 CMP edi,0xDB,要注意到跳转后的地方有赋值个EDI的指令

继续

Mr.Hu-Image

在这块地方可以得知EDI是call 00409C9B 这个函数的返回值,(说明这个函数是关键)

更改指令

先不用关注这个函数到底干了啥,现在掌握的基本只要确认DB的等于或者不等会得到什么样的结果(我这里已经试过了不等于DB代表的就是错误)

本来一开始是想改cmp esi,0xBD这条指令后面的跳转给Nop掉,但是前面有几个网络验证(俩三个call),所以我准备在函数返回值出来就写上跳转到cmp esi,0xBD这条指令的的跳转后面,地址是0x00DD592C(就是你要跳转的地方的最前面那串16进制)

Mr.Hu-Image

然后运行之后你会看到,“成功了”

Mr.Hu-Image

当然OD关了之后就会失效了,要把更改保存下来

保存更改

Mr.Hu-Image Mr.Hu-Image Mr.Hu-Image

这样不能算完全破解,因为每次启动都会弹出注册框(虽然随便输入也能用,但是就是不爽)

所以继续分析

完美破解

回到刚刚地方分析那个关键函数

Mr.Hu-Image

打上断点,运行之后步入看一下,主要关注的是DB是怎么返回的

一进来就看到的是网络验证,这层验证可以使用jmp直接跳过

Mr.Hu-Image

由于不知名的bug 导致我换了一个OD,分析是一样的

更改jmp

Mr.Hu-Image

继续往下分析

Mr.Hu-Image

把每个比较的跳转都看一下跳到那

运气比较好,第一个比较0x2D就直接跳到了需要的返回值DB

Mr.Hu-Image

进入关键函数,一般里面还有一层,直接回车即可(这个函数要记住,等下解密序列号的时候要详细分析这个函数)

Mr.Hu-Image

接下只要把这个关键函数的返回值改成一直返回0x2D即可

进入函数之后更改如下

Mr.Hu-Image

更改完成后继续将程序运行起来,发现又走到一个网络验证

Mr.Hu-Image

这个网络验证的返回值为-1,直接把返回值强行修改为1,(尝试一下,看看结果如何)

同样进入这个函数,进入之后更改如下

Mr.Hu-Image

再次将程序运行起来

这个时候发现成功了

Mr.Hu-Image

再次保存,不过这次保存要整个保存,因为修改的地方太多(不然每修改一个地方就保存一次)

Mr.Hu-Image

一路确定之后,在下图窗口右击保存,(取一个名字,确定保存即可)

Mr.Hu-Image

之后就能直接打开了

Mr.Hu-Image

当然还有重要的一点,如果其中涉及重定位操作,最好把重定位标志去除

解密序列号

解密序列号的话就不能像暴力破解哪有直接修改源代码,那是脚本小子干的事(当然网络验证还是得这么改)

接下来打卡原版的(未更改的010Editor),

回到如下界面

Mr.Hu-Image

进入之后长这样

Mr.Hu-Image

由于这个函数稍微有那麽一丢丢长,同时我也写上了注释,直接将他复制出来,以便查看

函数的解析

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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
013BDBC0      55            PUSH EBP                                 ;  \
013BDBC1 8BEC MOV EBP,ESP
013BDBC3 6A FF PUSH -0x1
013BDBC5 68 595E8801 PUSH 010Edito.01885E59 ; 开辟栈帧
013BDBCA . 64:A1 0000000>MOV EAX,DWORD PTR FS:[0]
013BDBD0 . 50 PUSH EAX
013BDBD1 . 83EC 18 SUB ESP,0x18 ; /
013BDBD4 . 53 PUSH EBX ; 保存易失性寄存器
013BDBD5 . 56 PUSH ESI
013BDBD6 . 57 PUSH EDI
013BDBD7 . A1 F0CFE602 MOV EAX,DWORD PTR DS:[0x2E6CFF0]
013BDBDC . 33C5 XOR EAX,EBP ; 加密安全COOkie
013BDBDE . 50 PUSH EAX
013BDBDF . 8D45 F4 LEA EAX,DWORD PTR SS:[EBP-0xC]
013BDBE2 . 64:A3 0000000>MOV DWORD PTR FS:[0],EAX
013BDBE8 . 8BF9 MOV EDI,ECX ; 把this给edi
013BDBEA . 8D5F 04 LEA EBX,DWORD PTR DS:[EDI+0x4] ; 把user赋值个ebx
013BDBED . C745 F0 00000>MOV DWORD PTR SS:[EBP-0x10],0x0
013BDBF4 . 8BCB MOV ECX,EBX ; 把user赋值给ecx
013BDBF6 . C747 30 00000>MOV DWORD PTR DS:[EDI+0x30],0x0
013BDBFD . C747 18 00000>MOV DWORD PTR DS:[EDI+0x18],0x0
013BDC04 . C747 34 00000>MOV DWORD PTR DS:[EDI+0x34],0x0
013BDC0B . FF15 B424E702 CALL DWORD PTR DS:[<&Qt5Core.?isEmpty@QS>; this指针的第一个四字节(2)与0比较,al==0
013BDC11 . 84C0 TEST AL,AL ; 0与上0 zf标志位赋值为1(表示相等)
013BDC13 . 0F85 75020000 JNZ 010Edito.013BDE8E ; 不等则跳(跳到结束位置:等于报错)
013BDC19 . 8D4F 08 LEA ECX,DWORD PTR DS:[EDI+0x8] ; 把序列号给ecx
013BDC1C . FF15 B424E702 CALL DWORD PTR DS:[<&Qt5Core.?isEmpty@QS>; this指针的第一个四字节(2)与0比较,al==0
013BDC22 . 84C0 TEST AL,AL ; 0与上0 zf标志位赋值为1(表示相等)
013BDC24 . 0F85 64020000 JNZ 010Edito.013BDE8E ; 不等则跳(跳到结束位置:等于报错)
013BDC2A . 8D45 DC LEA EAX,DWORD PTR SS:[EBP-0x24] ; 把地址002ACC44给eax
013BDC2D . 8BCF MOV ECX,EDI ; 把this指针给ecx
013BDC2F . 50 PUSH EAX ; 把this指针push到栈中(作为参数传给下面的call)
013BDC30 . E8 3ABF04FF CALL 010Edito.00409B6F ; 不知道干了什么(里面代码很乱先忽略)
013BDC35 . BE 1446E602 MOV ESI,010Edito.02E64614 ; 把字符串999给esi
013BDC3A . 8D9B 00000000 LEA EBX,DWORD PTR DS:[EBX] ; 解一层引用,相当于把里面的地址(this指针)赋值给自己
013BDC40 > FF36 PUSH DWORD PTR DS:[ESI] ; 把999放到栈中
013BDC42 . 8BCB MOV ECX,EBX ; 把this指针个ecx
013BDC44 . FF15 E82CE702 CALL DWORD PTR DS:[<&Qt5Core.??8QString@>; eax==0(不知到怎么操作的)
013BDC4A . 84C0 TEST AL,AL ; 0与上0 zf==1
013BDC4C . 0F85 23020000 JNZ 010Edito.013BDE75 ; zf为0时跳转
013BDC52 . 83C6 04 ADD ESI,0x4 ; 01234566789ABCDEF
013BDC55 . 81FE 1846E602 CMP ESI,010Edito.02E64618 ; 01234566789ABCDEF 比 999
013BDC5B .^ 7C E3 JL SHORT 010Edito.013BDC40 ; 小于时短跳转(往回跳)
013BDC5D . 8A5D DF MOV BL,BYTE PTR SS:[EBP-0x21] ; BL = K[3]
013BDC60 . 8A7D E1 MOV BH,BYTE PTR SS:[EBP-0x1F] ; BH = K[5]
013BDC63 . 80FB 9C CMP BL,0x9C ; 比较K[3],0x9C; Switch (cases 9C..FC)
013BDC66 . 75 70 JNZ SHORT 010Edito.013BDCD8 ; 不等于就跳
013BDC68 . 8A45 DC MOV AL,BYTE PTR SS:[EBP-0x24] ; AL = K[0]; Case 9C of switch 013BDC63
013BDC6B . 3245 E2 XOR AL,BYTE PTR SS:[EBP-0x1E] ; AL = K[0]^K[6]
013BDC6E . 8845 E8 MOV BYTE PTR SS:[EBP-0x18],AL ; [EBP - 0x18] = K[0]^K[6]
013BDC71 . 8A45 DD MOV AL,BYTE PTR SS:[EBP-0x23] ; AL = K[1]
013BDC74 . 3245 E3 XOR AL,BYTE PTR SS:[EBP-0x1D] ; AL = K[1]^K[7]
013BDC77 . FF75 E8 PUSH DWORD PTR SS:[EBP-0x18] ; push K[0]^K[6]
013BDC7A . 0FB6C8 MOVZX ECX,AL ; ECX = (K[1]^K[6]) & 0xFF
013BDC7D . B8 00010000 MOV EAX,0x100 ; EAX = 0x100
013BDC82 . 66:0FAFC8 IMUL CX,AX ; CX = ((K[1]^K[6]) & 0xFF) * 0x100
013BDC86 . 8A45 DE MOV AL,BYTE PTR SS:[EBP-0x22] ; AL = K[2]
013BDC89 . 32C7 XOR AL,BH ; AL = K[2]^k[5]
013BDC8B . 0FB6C0 MOVZX EAX,AL ; EAX = K[2]^K[5] & 0xFF
013BDC8E . 66:03C8 ADD CX,AX ; CX = ((K[1]^K[6]) & 0xFF) * 0x100) + (K[2]^K[5] & 0xFF)
013BDC91 . 0FB7F1 MOVZX ESI,CX ; ESi = (CX) & 0xFFFF
013BDC94 . E8 AB9904FF CALL 010Edito.00407644
013BDC99 . 0FB6C0 MOVZX EAX,AL ; AL = (K[0]^K[6]^0x18+0x3D)^0xA7
013BDC9C . 56 PUSH ESI
013BDC9D . 8947 1C MOV DWORD PTR DS:[EDI+0x1C],EAX
013BDCA0 . E8 23A704FF CALL 010Edito.004083C8 ; 判断余数,余数为0返回商否则返回0
013BDCA5 . 8B4F 1C MOV ECX,DWORD PTR DS:[EDI+0x1C]
013BDCA8 . 83C4 08 ADD ESP,0x8
013BDCAB . 0FB7C0 MOVZX EAX,AX
013BDCAE . 8947 20 MOV DWORD PTR DS:[EDI+0x20],EAX
013BDCB1 . 85C9 TEST ECX,ECX
013BDCB3 . 0F84 BC010000 JE 010Edito.013BDE75 ; ECX != 0
013BDCB9 . 85C0 TEST EAX,EAX
013BDCBB . 0F84 B4010000 JE 010Edito.013BDE75 ; EAX != 0
013BDCC1 . 3D E8030000 CMP EAX,0x3E8
013BDCC6 . 0F87 A9010000 JA 010Edito.013BDE75 ; EAX <= 0x3E8
013BDCCC . 83F9 02 CMP ECX,0x2 ; -----------------------------<<<<<
013BDCCF . 1BF6 SBB ESI,ESI
013BDCD1 . 23F1 AND ESI,ECX
013BDCD3 . E9 B3000000 JMP 010Edito.013BDD8B ; 这里直接往下跳到地址(013BDD8B)的位置
013BDCD8 > 80FB FC CMP BL,0xFC
013BDCDB . 75 1F JNZ SHORT 010Edito.013BDCFC
013BDCDD . C747 1C FF000>MOV DWORD PTR DS:[EDI+0x1C],0xFF ; Case FC of switch 013BDC63
013BDCE4 . BE FF000000 MOV ESI,0xFF
013BDCE9 . C747 20 01000>MOV DWORD PTR DS:[EDI+0x20],0x1
013BDCF0 . C747 30 01000>MOV DWORD PTR DS:[EDI+0x30],0x1
013BDCF7 . E9 8F000000 JMP 010Edito.013BDD8B
013BDCFC > 80FB AC CMP BL,0xAC
013BDCFF . 0F85 70010000 JNZ 010Edito.013BDE75
013BDD05 . 8A45 DD MOV AL,BYTE PTR SS:[EBP-0x23] ; Case AC of switch 013BDC63
013BDD08 . 3245 E3 XOR AL,BYTE PTR SS:[EBP-0x1D]
013BDD0B . 0FB6C8 MOVZX ECX,AL
013BDD0E . B8 00010000 MOV EAX,0x100
013BDD13 . 66:0FAFC8 IMUL CX,AX
013BDD17 . 8A45 DE MOV AL,BYTE PTR SS:[EBP-0x22]
013BDD1A . 32C7 XOR AL,BH
013BDD1C . C747 1C 02000>MOV DWORD PTR DS:[EDI+0x1C],0x2
013BDD23 . 0FB6C0 MOVZX EAX,AL
013BDD26 . 66:03C8 ADD CX,AX
013BDD29 . 0FB7C1 MOVZX EAX,CX
013BDD2C . 50 PUSH EAX
013BDD2D . E8 96A604FF CALL 010Edito.004083C8
013BDD32 . 0FB7C0 MOVZX EAX,AX
013BDD35 . 83C4 04 ADD ESP,0x4
013BDD38 . 8947 20 MOV DWORD PTR DS:[EDI+0x20],EAX
013BDD3B . 85C0 TEST EAX,EAX
013BDD3D . 0F84 32010000 JE 010Edito.013BDE75
013BDD43 . 3D E8030000 CMP EAX,0x3E8
013BDD48 . 0F87 27010000 JA 010Edito.013BDE75
013BDD4E . 0FB655 E5 MOVZX EDX,BYTE PTR SS:[EBP-0x1B]
013BDD52 . 0FB64D E0 MOVZX ECX,BYTE PTR SS:[EBP-0x20]
013BDD56 . 0FB6C7 MOVZX EAX,BH
013BDD59 . 33D0 XOR EDX,EAX
013BDD5B . 0FB645 E4 MOVZX EAX,BYTE PTR SS:[EBP-0x1C]
013BDD5F . 33C8 XOR ECX,EAX
013BDD61 . C1E2 08 SHL EDX,0x8
013BDD64 . 0FB645 E2 MOVZX EAX,BYTE PTR SS:[EBP-0x1E]
013BDD68 . 03D1 ADD EDX,ECX
013BDD6A . 0FB64D DC MOVZX ECX,BYTE PTR SS:[EBP-0x24]
013BDD6E . C1E2 08 SHL EDX,0x8
013BDD71 . 33C8 XOR ECX,EAX
013BDD73 . 03D1 ADD EDX,ECX
013BDD75 . 68 278C5B00 PUSH 010Edito.005B8C27
013BDD7A . 52 PUSH EDX
013BDD7B . E8 0BCA04FF CALL 010Edito.0040A78B
013BDD80 . 83C4 08 ADD ESP,0x8
013BDD83 . 8945 F0 MOV DWORD PTR SS:[EBP-0x10],EAX
013BDD86 . 8947 34 MOV DWORD PTR DS:[EDI+0x34],EAX
013BDD89 . 8BF0 MOV ESI,EAX
013BDD8B > 8D45 EC LEA EAX,DWORD PTR SS:[EBP-0x14]
013BDD8E . 50 PUSH EAX ; push 一个局部变量的地址
013BDD8F . 8D4F 04 LEA ECX,DWORD PTR DS:[EDI+0x4] ; EDI+4是unicode编码的用户名
013BDD92 . FF15 782BE702 CALL DWORD PTR DS:[<&Qt5Core.?toUtf8@QSt>; eax返回的是ascii编码的用户名
013BDD98 . FF77 20 PUSH DWORD PTR DS:[EDI+0x20] ; push 的是一个0空间
013BDD9B . 33C0 XOR EAX,EAX
013BDD9D . C745 FC 00000>MOV DWORD PTR SS:[EBP-0x4],0x0
013BDDA4 . 80FB FC CMP BL,0xFC
013BDDA7 . 8D4D EC LEA ECX,DWORD PTR SS:[EBP-0x14] ; ascii编码的用户名的对象
013BDDAA . 56 PUSH ESI ; 0
013BDDAB . 0F95C0 SETNE AL ; zf = 0时设置al
013BDDAE . 50 PUSH EAX ; 1
013BDDAF . FF15 8C24E702 CALL DWORD PTR DS:[<&Qt5Core.?data@QByte>; Qt5Core.?data@QByteArray@@QAEPADXZ
013BDDB5 . 50 PUSH EAX ; eax是call返回的ascii编码的用户名
013BDDB6 . E8 955004FF CALL 010Edito.00402E50
013BDDBB . 8BD0 MOV EDX,EAX ; 返回值
013BDDBD . 83C4 10 ADD ESP,0x10
013BDDC0 . 3855 E0 CMP BYTE PTR SS:[EBP-0x20],DL ; cmp K[4],返回值&0xFF
013BDDC3 . 0F85 81000000 JNZ 010Edito.013BDE4A ; 字符串处理
013BDDC9 . 8BCA MOV ECX,EDX ; ecx = 返回值
013BDDCB . C1E9 08 SHR ECX,0x8 ; 右移8位
013BDDCE . 3AF9 CMP BH,CL ; cmp K[4],返回值>>8&0xff
013BDDD0 . 75 78 JNZ SHORT 010Edito.013BDE4A
013BDDD2 . 8BCA MOV ECX,EDX ; ecx = 返回值
013BDDD4 . C1E9 10 SHR ECX,0x10 ; 右移16位
013BDDD7 . 384D E2 CMP BYTE PTR SS:[EBP-0x1E],CL ; cmp K[6],返回值>>16&0xff
013BDDDA . 75 6E JNZ SHORT 010Edito.013BDE4A
013BDDDC . C1E8 18 SHR EAX,0x18 ; 右移24位
013BDDDF . 3845 E3 CMP BYTE PTR SS:[EBP-0x1D],AL ; cmp K[7],返回值>>24&0xff
013BDDE2 . 75 66 JNZ SHORT 010Edito.013BDE4A
013BDDE4 . 80FB 9C CMP BL,0x9C ; cmp K[3],9C
013BDDE7 . 75 0F JNZ SHORT 010Edito.013BDDF8
013BDDE9 . 8B45 08 MOV EAX,DWORD PTR SS:[EBP+0x8] ; Case 9C of switch 013BDDE4
013BDDEC . 3B47 1C CMP EAX,DWORD PTR DS:[EDI+0x1C] ; 比较的具体条件看当时的EBP+0x8,EDI+0x1C
013BDDEF . 76 52 JBE SHORT 010Edito.013BDE43 ;这个跳转成功,返回的就是是2D,可以看到跳转地址
013BDDF1 . BE 4E000000 MOV ESI,0x4E
013BDDF6 . EB 57 JMP SHORT 010Edito.013BDE4F
013BDDF8 > 80FB FC CMP BL,0xFC
013BDDFB . 75 2E JNZ SHORT 010Edito.013BDE2B
013BDDFD . 0FB64D DE MOVZX ECX,BYTE PTR SS:[EBP-0x22] ; Case FC of switch 013BDDE4
013BDE01 . 0FB645 DD MOVZX EAX,BYTE PTR SS:[EBP-0x23]
013BDE05 . C1E1 08 SHL ECX,0x8
013BDE08 . 03C8 ADD ECX,EAX
013BDE0A . 0FB645 DC MOVZX EAX,BYTE PTR SS:[EBP-0x24]
013BDE0E . C1E1 08 SHL ECX,0x8
013BDE11 . 52 PUSH EDX
013BDE12 . 03C8 ADD ECX,EAX
013BDE14 . 51 PUSH ECX
013BDE15 . E8 71C904FF CALL 010Edito.0040A78B
013BDE1A . 83C4 08 ADD ESP,0x8
013BDE1D . 85C0 TEST EAX,EAX
013BDE1F . 74 29 JE SHORT 010Edito.013BDE4A
013BDE21 . 8947 18 MOV DWORD PTR DS:[EDI+0x18],EAX
013BDE24 . BE 93000000 MOV ESI,0x93
013BDE29 . EB 24 JMP SHORT 010Edito.013BDE4F
013BDE2B > 80FB AC CMP BL,0xAC
013BDE2E . 75 1A JNZ SHORT 010Edito.013BDE4A
013BDE30 . 8B45 F0 MOV EAX,DWORD PTR SS:[EBP-0x10] ; Case AC of switch 013BDDE4
013BDE33 . 85C0 TEST EAX,EAX
013BDE35 . 74 13 JE SHORT 010Edito.013BDE4A
013BDE37 . 3945 0C CMP DWORD PTR SS:[EBP+0xC],EAX
013BDE3A . 76 07 JBE SHORT 010Edito.013BDE43
013BDE3C . BE 4E000000 MOV ESI,0x4E
013BDE41 . EB 0C JMP SHORT 010Edito.013BDE4F
013BDE43 > BE 2D000000 MOV ESI,0x2D
013BDE48 . EB 05 JMP SHORT 010Edito.013BDE4F
013BDE4A > BE E7000000 MOV ESI,0xE7 ; Default case of switch 013BDDE4
013BDE4F > 8D4D EC LEA ECX,DWORD PTR SS:[EBP-0x14]
013BDE52 . C745 FC FFFFF>MOV DWORD PTR SS:[EBP-0x4],-0x1
013BDE59 . FF15 7C24E702 CALL DWORD PTR DS:[<&Qt5Core.??1QByteArr>; Qt5Core.??1QByteArray@@QAE@XZ
013BDE5F . 8BC6 MOV EAX,ESI
013BDE61 . 8B4D F4 MOV ECX,DWORD PTR SS:[EBP-0xC]
013BDE64 . 64:890D 00000>MOV DWORD PTR FS:[0],ECX
013BDE6B . 59 POP ECX
013BDE6C . 5F POP EDI
013BDE6D . 5E POP ESI
013BDE6E . 5B POP EBX
013BDE6F . 8BE5 MOV ESP,EBP
013BDE71 . 5D POP EBP
013BDE72 . C2 0800 RETN 0x8
013BDE75 > B8 E7000000 MOV EAX,0xE7 ; Default case of switch 013BDC63
013BDE7A . 8B4D F4 MOV ECX,DWORD PTR SS:[EBP-0xC]
013BDE7D . 64:890D 00000>MOV DWORD PTR FS:[0],ECX
013BDE84 . 59 POP ECX
013BDE85 . 5F POP EDI
013BDE86 . 5E POP ESI
013BDE87 . 5B POP EBX
013BDE88 . 8BE5 MOV ESP,EBP
013BDE8A . 5D POP EBP
013BDE8B . C2 0800 RETN 0x8
013BDE8E > B8 93000000 MOV EAX,0x93
013BDE93 . 8B4D F4 MOV ECX,DWORD PTR SS:[EBP-0xC]
013BDE96 . 64:890D 00000>MOV DWORD PTR FS:[0],ECX
013BDE9D . 59 POP ECX
013BDE9E . 5F POP EDI
013BDE9F . 5E POP ESI
013BDEA0 . 5B POP EBX
013BDEA1 . 8BE5 MOV ESP,EBP
013BDEA3 . 5D POP EBP
013BDEA4 . C2 0800 RETN 0x8

关键部分

序列号(字节)之间的关系

Mr.Hu-Image

把这两个函数带入参数分别解析(K是输入的(密码/序列号)K[0]代表第一个字节,例如:112233445566778899AA,K[0]就等于 11)

函数1 (00407644)参数(K[0],^K[6])

1
2
3
4
5
6
7
8
013BD0B0  /> \55            PUSH EBP
013BD0B1 |. 8BEC MOV EBP,ESP
013BD0B3 |. 8B45 08 MOV EAX,[ARG.1] ; EAX = K[0]^K[6]
013BD0B6 |. 34 18 XOR AL,0x18 ; AL = (K[0]^K[6])^0x18
013BD0B8 |. 04 3D ADD AL,0x3D ; AL = ((K[0]^K[6])^0x18)+0x3D
013BD0BA |. 34 A7 XOR AL,0xA7 ; AL = (((K[0]^K[6])^0x18)+0x3D)^0xA7
013BD0BC |. 5D POP EBP
013BD0BD \. C3 RETN

函数2 (004083C8)参数 ( ((K[1]^K[6]) & 0xFF) * 0x100) + (K[2]^K[5] & 0xFF)&0xFFFF)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
013BD020  /> \55            PUSH EBP
013BD021 |. 8BEC MOV EBP,ESP
013BD023 |. 8B45 08 MOV EAX,[ARG.1] ; EAX = (0x100*(K[1]^K[7]&0xFF)+K[2]^K[5]&0xFF)&0xFFFF
013BD026 |. B9 0B000000 MOV ECX,0xB ; ECX = 0xB
013BD02B |. 35 92780000 XOR EAX,0x7892 ; EAX = (EAX)^0x7892
013BD030 |. 05 304D0000 ADD EAX,0x4D30 ; EAX = (EAX)^0x7892 + 0x4D30
013BD035 |. 35 21340000 XOR EAX,0x3421 ; EAX = ((EAX)^0x7892 + 0x4D30) ^ 0x3421
013BD03A |. 0FB7C0 MOVZX EAX,AX ; EAX = (((EAX)^0x7892 + 0x4D30) ^ 0x3421) & 0xFFFF
013BD03D |. 99 CDQ ; 清除EDX
013BD03E |. F7F9 IDIV ECX ; EAX / ECX (商放eax,余数放edx)
013BD040 |. 85D2 TEST EDX,EDX
013BD042 |. 74 02 JE SHORT 010Edito.013BD046 ; 余数等于0 直接退出并返回商 ,余数不为0则返回0
013BD044 |. 33C0 XOR EAX,EAX
013BD046 |> 5D POP EBP
013BD047 \. C3 RETN
代码转换

根据以上信息,可以通过c++代码运算得到序列号

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
int main()
{
//013BDDE4 . 80FB 9C CMP BL,0x9C ; cmp K[3],9C
byte K[] = { 11,22,33,0x9C,55,66,77,88,99,0xAA };
while (true)
{
//AL = (K[0]^K[6]^0x18+0x3D)^0xA7
byte K0 = rand() % 0xFF;
byte K6 = rand() % 0xFF;
byte AL = (K0 ^ K6 ^ 0x18 + 0x3D) ^ 0xA7;
if (AL > 0 )
{
K[0] = K0;
K[6] = K6;
break;
}
}
while (true)
{
byte K1 = rand() % 0xFF;
byte K2 = rand() % 0xFF;
byte K5 = rand() % 0xFF;
byte K7 = rand() % 0xFF;
//DWORD ESI = (((K1 ^ K7) & 0xFF) * 0x100) + ((K2 ^ K5 & 0xFF) & 0xFFFF);
DWORD ESI = ((K1 ^ K7 & 0xFF) * 0x100) + ((K2 ^ K5) & 0xFF) & 0xFFFF;
//DWORD EAX = (((ESI ^ 0x7892) + 0x4D30) ^ 0x3421) & 0xFFFF;
DWORD EAX = (((ESI ^ 0x7892) + 0x4D30) ^ 0x3421) & 0xFFFF;
//余数等于0 直接退出并返回商 ,余数不为0则返回0
//EAX <= 0x3E8
if (EAX % 0xB == 0 && EAX / 0xB <= 0x3E8)
{
K[1] = K1;
K[2] = K2;
K[5] = K5;
K[7] = K7;
break;
}
}
for (int index = 0; index < sizeof(K); index++)
{
printf("%02X",K[index]);
if (index % 2 != 0 && index != sizeof(K)-1)
printf("-");
}
getchar();
return 0;
}

根据以上代码算出来的序列号(序列号字节之间的对应关系)没有问题,但是下面还要分析与账户之间的对应关系

账户与序列号之间的关系

Mr.Hu-Image
1
2
3
4
5
6
7
8
9
10
11
013BDD98   .  FF77 20       PUSH DWORD PTR DS:[EDI+0x20]             ;  返回值(商),第四个参数
013BDD9B . 33C0 XOR EAX,EAX
013BDD9D . C745 FC 00000>MOV DWORD PTR SS:[EBP-0x4],0x0
013BDDA4 . 80FB FC CMP BL,0xFC
013BDDA7 . 8D4D EC LEA ECX,DWORD PTR SS:[EBP-0x14] ; ascii编码的用户名的对象
013BDDAA . 56 PUSH ESI ; 0 ,第三个参数
013BDDAB . 0F95C0 SETNE AL ; zf = 0时设置al
013BDDAE . 50 PUSH EAX ; 1 ,第二个参数
013BDDAF . FF15 8C24E702 CALL DWORD PTR DS:[<&Qt5Core.?data@QByte>; Qt5Core.?data@QByteArray@@QAEPADXZ
013BDDB5 . 50 PUSH EAX ; eax是call返回的ascii编码的用户名,第一个参数
013BDDB6 . E8 955004FF CALL 010Edito.00402E50 ; 这个是用户名的加密,看多了会掉头发
使用加密代码

这里地方要转换成c++代码稍微有点麻烦,因为有一个加密,这里我直接用IDA打开,用IDA分析这个加密函数,然后直接拿过来用

注:如果要通过IDA找到该函数的地址需要经过地址转换,随意这里最好使用默认基址(把重定位标志去掉),而且使用IDA打开010Editor,需要几分钟时间,需要耐心等待

完全打开的状态:左下角那串字符不在动了

IDA打开
Mr.Hu-Image

或者是这个样子

Mr.Hu-Image

也可能是这个样子

Mr.Hu-Image

这种状态可通过空格键(Space)切换

013BDDB6 . E8 955004FF CALL 010Edito.00402E50 ; 这个是用户名的加密,看多了会掉头发

函数调用地址 013BDDB6 在IDA界面按G搜索

Mr.Hu-Image

点击OK后

Mr.Hu-Image

双击进入后

Mr.Hu-Image

再次双击后,会看到如下界面

Mr.Hu-Image

然后直接按F5,会看到它被解析成C++代码

Mr.Hu-Image

这个是后看一下,这个函数的代码是不是可以直接拿过来用

当往下看的时候,发现有一个四字节的数组操作

找数组元素
Mr.Hu-Image

这个时候需要找到这个数组的,双击数组地址进入

Mr.Hu-Image

可以看到这个数组在data段,地址是02E6418,这个时候可以通过OD找到这个数组的定义(元素)

Mr.Hu-Image

找到的数组元素

Mr.Hu-Image

把它复制出来(这里用到一个插件”数据转换“)

Mr.Hu-Image

复制出来的元素

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
0x39cb44b8, 0x23754f67, 0x5f017211, 0x3ebb24da, 0x351707c6, 0x63f9774b, 0x17827288, 0x0fe74821, 0x5b5f670f, 0x48315ae8, 0x785b7769, 0x2b7a1547, 0x38d11292, 0x42a11b32, 0x35332244, 0x77437b60,
0x1eab3b10, 0x53810000, 0x1d0212ae, 0x6f0377a8, 0x43c03092, 0x2d3c0a8e, 0x62950cbf, 0x30f06ffa, 0x34f710e0, 0x28f417fb, 0x350d2f95, 0x5a361d5a, 0x15cc060b, 0x0afd13cc, 0x28603bcf, 0x3371066b,
0x30cd14e4, 0x175d3a67, 0x6dd66a13, 0x2d3409f9, 0x581e7b82, 0x76526b99, 0x5c8d5188, 0x2c857971, 0x15f51fc0, 0x68cc0d11, 0x49f55e5c, 0x275e4364, 0x2d1e0dbc, 0x4cee7ce3, 0x32555840, 0x112e2e08,
0x6978065a, 0x72921406, 0x314578e7, 0x175621b7, 0x40771dbf, 0x3fc238d6, 0x4a31128a, 0x2dad036e, 0x41a069d6, 0x25400192, 0x00dd4667, 0x6afc1f4f, 0x571040ce, 0x62fe66df, 0x41db4b3e, 0x3582231f,
0x55f6079a, 0x1ca70644, 0x1b1643d2, 0x3f7228c9, 0x5f141070, 0x3e1474ab, 0x444b256e, 0x537050d9, 0x0f42094b, 0x2fd820e6, 0x778b2e5e, 0x71176d02, 0x7fea7a69, 0x5bb54628, 0x19ba6c71, 0x39763a99,
0x178d54cd, 0x01246e88, 0x3313537e, 0x2b8e2d17, 0x2a3d10be, 0x59d10582, 0x37a163db, 0x30d6489a, 0x6a215c46, 0x0e1c7a76, 0x1fc760e7, 0x79b80c65, 0x27f459b4, 0x799a7326, 0x50ba1782, 0x2a116d5c,
0x63866e1b, 0x3f920e3c, 0x55023490, 0x55b56089, 0x2c391fd1, 0x2f8035c2, 0x64fd2b7a, 0x4ce8759a, 0x518504f0, 0x799501a8, 0x3f5b2cad, 0x38e60160, 0x637641d8, 0x33352a42, 0x51a22c19, 0x085c5851,
0x032917ab, 0x2b770ac7, 0x30ac77b3, 0x2bec1907, 0x035202d0, 0x0fa933d3, 0x61255df3, 0x22ad06bf, 0x58b86971, 0x5fca0de5, 0x700d6456, 0x56a973db, 0x5ab759fd, 0x330e0be2, 0x5b3c0ddd, 0x495d3c60,
0x53bd59a6, 0x4c5e6d91, 0x49d9318d, 0x103d5079, 0x61ce42e3, 0x7ed5121d, 0x14e160ed, 0x212d4ef2, 0x270133f0, 0x62435a96, 0x1fa75e8b, 0x6f092fbe, 0x4a000d49, 0x57ae1c70, 0x004e2477, 0x561e7e72,
0x468c0033, 0x5dcc2402, 0x78507ac6, 0x58af24c7, 0x0df62d34, 0x358a4708, 0x3cfb1e11, 0x2b71451c, 0x77a75295, 0x56890721, 0x0fef75f3, 0x120f24f1, 0x01990ae7, 0x339c4452, 0x27a15b8e, 0x0ba7276d,
0x60dc1b7b, 0x4f4b7f82, 0x67db7007, 0x4f4a57d9, 0x621252e8, 0x20532cfc, 0x6a390306, 0x18800423, 0x19f3778a, 0x462316f0, 0x56ae0937, 0x43c2675c, 0x65ca45fd, 0x0d604ff2, 0x0bfd22cb, 0x3afe643b,
0x3bf67fa6, 0x44623579, 0x184031f8, 0x32174f97, 0x4c6a092a, 0x5fb50261, 0x01650174, 0x33634af1, 0x712d18f4, 0x6e997169, 0x5dab7afe, 0x7c2b2ee8, 0x6edb75b4, 0x5f836fb6, 0x3c2a6dd6, 0x292d05c2,
0x052244db, 0x149a5f4f, 0x5d486540, 0x331d15ea, 0x4f456920, 0x483a699f, 0x3b450f05, 0x3b207c6c, 0x749d70fe, 0x417461f6, 0x62b031f1, 0x2750577b, 0x29131533, 0x588c3808, 0x1aef3456, 0x0f3c00ec,
0x7da74742, 0x4b797a6c, 0x5ebb3287, 0x786558b8, 0x00ed4ff2, 0x6269691e, 0x24a2255f, 0x62c11f7e, 0x2f8a7dcd, 0x643b17fe, 0x778318b8, 0x253b60fe, 0x34bb63a3, 0x5b03214f, 0x5f1571f4, 0x1a316e9f,
0x7acf2704, 0x28896838, 0x18614677, 0x1bf569eb, 0x0ba85ec9, 0x6aca6b46, 0x1e43422a, 0x514d5f0e, 0x413e018c, 0x307626e9, 0x01ed1dfa, 0x49f46f5a, 0x461b642b, 0x7d7007f2, 0x13652657, 0x6b160bc5,
0x65e04849, 0x1f526e1c, 0x5a0251b6, 0x2bd73f69, 0x2dbf7acd, 0x51e63e80, 0x5cf2670f, 0x21cd0a03, 0x5cff0261, 0x33ae061e, 0x3bb6345f, 0x5d814a75, 0x257b5df4, 0x0a5c2c5b, 0x16a45527, 0x16f23945};
复制加密代码

回到IDA,之前还记得加密函数的第四个参数是四字节整数(013BDD98 . FF77 20 PUSH DWORD PTR DS:[EDI+0x20] ; 返回值(商),第四个参数),但是IDA分析的是char类型,需要给他改过来

Mr.Hu-Image

改完之后全选后复制

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
int __cdecl sub_13BD120(const char *a1, int a2, char a3, DWORD a4)
{
const char *v4; // edx@1
signed int v5; // esi@1
signed int v6; // edi@1
unsigned __int8 v7; // bl@2
int v8; // eax@3
int v9; // ecx@3
int v10; // ecx@4
int result; // eax@4
int v12; // ecx@5
unsigned __int8 v13; // [sp+8h] [bp-10h]@2
unsigned __int8 v14; // [sp+Ch] [bp-Ch]@2
unsigned __int8 v15; // [sp+10h] [bp-8h]@2
int v16; // [sp+14h] [bp-4h]@1

v4 = a1;
v16 = 0;
v5 = strlen(a1);
v6 = 0;
if ( v5 <= 0 )
{
result = 0;
}
else
{
v13 = 0;
v14 = 0;
v7 = 15 * a4;
v15 = 17 * a3;
do
{
v8 = toupper(v4[v6]);
v9 = v16 + dword_2E64148[v8];
if ( a2 )
{
v10 = dword_2E64148[v7]
+ dword_2E64148[v15]
+ dword_2E64148[(unsigned __int8)(v8 + 47)] * (dword_2E64148[(unsigned __int8)(v8 + 13)] ^ v9);
result = dword_2E64148[v14] + v10;
v16 = dword_2E64148[v14] + v10;
}
else
{
v12 = dword_2E64148[v7]
+ dword_2E64148[v15]
+ dword_2E64148[(unsigned __int8)(v8 + 23)] * (dword_2E64148[(unsigned __int8)(v8 + 63)] ^ v9);
result = dword_2E64148[v13] + v12;
v16 = dword_2E64148[v13] + v12;
}
v14 += 19;
++v6;
v15 += 9;
v7 += 13;
v13 += 7;
v4 = a1;
}
while ( v6 < v5 );
}
return result;
}

注册机编写

现在开始写成自己的代码

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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#include <Windows.h>
#include <time.h>
#include <stdio.h>

DWORD g_KeyArr[]{
0x39cb44b8, 0x23754f67, 0x5f017211, 0x3ebb24da, 0x351707c6, 0x63f9774b, 0x17827288, 0x0fe74821, 0x5b5f670f, 0x48315ae8, 0x785b7769, 0x2b7a1547, 0x38d11292, 0x42a11b32, 0x35332244, 0x77437b60,
0x1eab3b10, 0x53810000, 0x1d0212ae, 0x6f0377a8, 0x43c03092, 0x2d3c0a8e, 0x62950cbf, 0x30f06ffa, 0x34f710e0, 0x28f417fb, 0x350d2f95, 0x5a361d5a, 0x15cc060b, 0x0afd13cc, 0x28603bcf, 0x3371066b,
0x30cd14e4, 0x175d3a67, 0x6dd66a13, 0x2d3409f9, 0x581e7b82, 0x76526b99, 0x5c8d5188, 0x2c857971, 0x15f51fc0, 0x68cc0d11, 0x49f55e5c, 0x275e4364, 0x2d1e0dbc, 0x4cee7ce3, 0x32555840, 0x112e2e08,
0x6978065a, 0x72921406, 0x314578e7, 0x175621b7, 0x40771dbf, 0x3fc238d6, 0x4a31128a, 0x2dad036e, 0x41a069d6, 0x25400192, 0x00dd4667, 0x6afc1f4f, 0x571040ce, 0x62fe66df, 0x41db4b3e, 0x3582231f,
0x55f6079a, 0x1ca70644, 0x1b1643d2, 0x3f7228c9, 0x5f141070, 0x3e1474ab, 0x444b256e, 0x537050d9, 0x0f42094b, 0x2fd820e6, 0x778b2e5e, 0x71176d02, 0x7fea7a69, 0x5bb54628, 0x19ba6c71, 0x39763a99,
0x178d54cd, 0x01246e88, 0x3313537e, 0x2b8e2d17, 0x2a3d10be, 0x59d10582, 0x37a163db, 0x30d6489a, 0x6a215c46, 0x0e1c7a76, 0x1fc760e7, 0x79b80c65, 0x27f459b4, 0x799a7326, 0x50ba1782, 0x2a116d5c,
0x63866e1b, 0x3f920e3c, 0x55023490, 0x55b56089, 0x2c391fd1, 0x2f8035c2, 0x64fd2b7a, 0x4ce8759a, 0x518504f0, 0x799501a8, 0x3f5b2cad, 0x38e60160, 0x637641d8, 0x33352a42, 0x51a22c19, 0x085c5851,
0x032917ab, 0x2b770ac7, 0x30ac77b3, 0x2bec1907, 0x035202d0, 0x0fa933d3, 0x61255df3, 0x22ad06bf, 0x58b86971, 0x5fca0de5, 0x700d6456, 0x56a973db, 0x5ab759fd, 0x330e0be2, 0x5b3c0ddd, 0x495d3c60,
0x53bd59a6, 0x4c5e6d91, 0x49d9318d, 0x103d5079, 0x61ce42e3, 0x7ed5121d, 0x14e160ed, 0x212d4ef2, 0x270133f0, 0x62435a96, 0x1fa75e8b, 0x6f092fbe, 0x4a000d49, 0x57ae1c70, 0x004e2477, 0x561e7e72,
0x468c0033, 0x5dcc2402, 0x78507ac6, 0x58af24c7, 0x0df62d34, 0x358a4708, 0x3cfb1e11, 0x2b71451c, 0x77a75295, 0x56890721, 0x0fef75f3, 0x120f24f1, 0x01990ae7, 0x339c4452, 0x27a15b8e, 0x0ba7276d,
0x60dc1b7b, 0x4f4b7f82, 0x67db7007, 0x4f4a57d9, 0x621252e8, 0x20532cfc, 0x6a390306, 0x18800423, 0x19f3778a, 0x462316f0, 0x56ae0937, 0x43c2675c, 0x65ca45fd, 0x0d604ff2, 0x0bfd22cb, 0x3afe643b,
0x3bf67fa6, 0x44623579, 0x184031f8, 0x32174f97, 0x4c6a092a, 0x5fb50261, 0x01650174, 0x33634af1, 0x712d18f4, 0x6e997169, 0x5dab7afe, 0x7c2b2ee8, 0x6edb75b4, 0x5f836fb6, 0x3c2a6dd6, 0x292d05c2,
0x052244db, 0x149a5f4f, 0x5d486540, 0x331d15ea, 0x4f456920, 0x483a699f, 0x3b450f05, 0x3b207c6c, 0x749d70fe, 0x417461f6, 0x62b031f1, 0x2750577b, 0x29131533, 0x588c3808, 0x1aef3456, 0x0f3c00ec,
0x7da74742, 0x4b797a6c, 0x5ebb3287, 0x786558b8, 0x00ed4ff2, 0x6269691e, 0x24a2255f, 0x62c11f7e, 0x2f8a7dcd, 0x643b17fe, 0x778318b8, 0x253b60fe, 0x34bb63a3, 0x5b03214f, 0x5f1571f4, 0x1a316e9f,
0x7acf2704, 0x28896838, 0x18614677, 0x1bf569eb, 0x0ba85ec9, 0x6aca6b46, 0x1e43422a, 0x514d5f0e, 0x413e018c, 0x307626e9, 0x01ed1dfa, 0x49f46f5a, 0x461b642b, 0x7d7007f2, 0x13652657, 0x6b160bc5,
0x65e04849, 0x1f526e1c, 0x5a0251b6, 0x2bd73f69, 0x2dbf7acd, 0x51e63e80, 0x5cf2670f, 0x21cd0a03, 0x5cff0261, 0x33ae061e, 0x3bb6345f, 0x5d814a75, 0x257b5df4, 0x0a5c2c5b, 0x16a45527, 0x16f23945};


int __cdecl sub_13BD120(const char* a1, int a2, char a3, unsigned short a4)
{
const char* v4; // edx@1
signed int v5; // esi@1
signed int v6; // edi@1
unsigned __int8 v7; // bl@2
int v8; // eax@3
int v9; // ecx@3
int v10; // ecx@4
int result; // eax@4
int v12; // ecx@5
unsigned __int8 v13; // [sp+8h] [bp-10h]@2
unsigned __int8 v14; // [sp+Ch] [bp-Ch]@2
unsigned __int8 v15; // [sp+10h] [bp-8h]@2
int v16; // [sp+14h] [bp-4h]@1

v4 = a1;
v16 = 0;
v5 = strlen(a1);
v6 = 0;
if (v5 <= 0)
{
result = 0;
}
else
{
v13 = 0;
v14 = 0;
v7 = 15 * a4;
v15 = 17 * a3;
do
{
v8 = toupper(v4[v6]);
v9 = v16 + g_KeyArr[v8];
if (a2)
{
v10 = g_KeyArr[v7]
+ g_KeyArr[v15]
+ g_KeyArr[(unsigned __int8)(v8 + 47)] * (g_KeyArr[(unsigned __int8)(v8 + 13)] ^ v9);
result = g_KeyArr[v14] + v10;
v16 = g_KeyArr[v14] + v10;
}
else
{
v12 = g_KeyArr[v7]
+ g_KeyArr[v15]
+ g_KeyArr[(unsigned __int8)(v8 + 23)] * (g_KeyArr[(unsigned __int8)(v8 + 63)] ^ v9);
result = g_KeyArr[v13] + v12;
v16 = g_KeyArr[v13] + v12;
}
v14 += 19;
++v6;
v15 += 9;
v7 += 13;
v13 += 7;
v4 = a1;
} while (v6 < v5);
}
return result;
}

int main()
{
byte K[] = { 11,22,33,0x9C,55,66,77,88,99,0xAA };
srand(time(NULL));
DWORD Reslt = 0x3E8;
DWORD dwKey = sub_13BD120("hugang_first.github.io",1,0, Reslt);//这里的用户名可以输入自己的,也可以改成用户动态输入
K[4] = dwKey & 0xFF;
K[5] = dwKey >> 8 & 0xFF;
K[6] = dwKey >> 16 & 0xFF;
K[7] = dwKey >> 24 & 0xFF;

while (true)
{
//AL = (K[0]^K[6]^0x18+0x3D)^0xA7
byte K0 = rand() % 0xFF;
byte K6 = K[6];
byte AL = (K0 ^ K6 ^ 0x18 + 0x3D) ^ 0xA7;
if (AL > 0 && AL <= 4)
{
K[0] = K0;
break;
}
}
while (true)
{
byte K1 = rand() % 0xFF;
byte K2 = rand() % 0xFF;
byte K5 = K[5];
byte K7 = K[7];
//DWORD ESI = (((K1 ^ K7) & 0xFF) * 0x100) + ((K2 ^ K5 & 0xFF) & 0xFFFF);
DWORD ESI = ((K1 ^ K7 & 0xFF) * 0x100) + ((K2 ^ K5) & 0xFF) & 0xFFFF;
//DWORD EAX = (((ESI ^ 0x7892) + 0x4D30) ^ 0x3421) & 0xFFFF;
DWORD EAX = (((ESI ^ 0x7892) + 0x4D30) ^ 0x3421) & 0xFFFF;
//余数等于0 直接退出并返回商 ,余数不为0则返回0
//EAX <= 0x3E8
if (EAX % 0xB == 0 && EAX / 0xB == Reslt)
{
K[1] = K1;
K[2] = K2;

break;
}
}
for (int index = 0; index < sizeof(K); index++)
{
printf("%02X",K[index]);
if (index % 2 != 0 && index != sizeof(K)-1)
printf("-");
}
getchar();
return 0;
}

运行测试

运行结果

Mr.Hu-Image

把这串序列号和用户米输入试一下

Mr.Hu-Image

然后发现网络验证失败,这个时候需要把网络验证给屏蔽掉,具体方法在暴力破解时已经简述

成功破解

屏蔽网络后发现就成功了,

Mr.Hu-Image