【破文标题】 豪杰屏幕录像机注册算法分析
【破文作者】 snake
【软件名称】 豪杰屏幕录像机 V2.0 Build 0801
【下载地址】 http://www4.skycn.com/soft/12856.html
【软件简介】 “课件制作”的全新突破,跟踪录制屏幕上所有区域的动作和键盘、鼠标的声音,可保存为
EXE,AVI,GIF和HSR格式,编码速度快,高保真,也常被应用进行计算机监控管理。
【调试环境】 Windows XP SP2
【作者声明】 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
【破解过程】
程序安装好后,目录下有一个AuthReg.exe文件,运行后是程序的注册模块,就直接调试它吧。
用PEiD查壳为Microsoft Visual C++ 6.0 [Debug],无壳。
OD载入程序,F9运行输入注册信息
用户名:snake
注册码:1234-5678-9876-5432
确定后弹出注册失败窗口
Ctrl+F2重新载入程序,搜索ASCII串,在此处下断点
Ultra String Reference Plugin, 条目 13
Address=00401663
Disassembly=push 0040A088
Text String=AuthReg.ini
F9运行,程序断下,F8单步跟踪
00401660 |. 83C4 08 add esp, 8 ; 下面部分是读取文件中的内容(略)
00401663 |. 68 88A04000 push 0040A088 ; /AuthReg.ini
00401668 |. 68 60CC4000 push 0040CC60 ; |D:\Program Files\hero\AuthReg.ini
0040166D |. FF15 10914000 call [<&KERNEL32.llstrcatA>] ; \llstrcatA
00401673 |. 33DB xor ebx, ebx
00401675 |. 8BAC24 A80000>mov ebp, [esp+A8]
0040167C |. 897424 14 mov [esp+14], esi
00401680 |. 55 push ebp ; /String
00401681 |. FF15 F4904000 call [<&KERNEL32.lstrlenA>] ; \lstrlenA
00401687 |. 8BF8 mov edi, eax
......
004017C8 |> \C605 80CD4000>mov byte ptr [40CD80], 0
004017CF |. E8 1C090000 call 004020F0 ; ***跟进***
004017D4 |. A3 40F84000 mov [40F840], eax
004017D9 |. 8B4424 00 mov eax, [esp]
004017DD |. 85C0 test eax, eax
004017DF |. 75 0A jnz short 004017EB
004017E1 |. FF15 B4914000 call [<&USER32.GetForegroundWindow>] ; [GetForegroundWindow
004017E7 |. 894424 00 mov [esp], eax
......
================= 004017CF |. E8 1C090000 call 004020F0 ====================
004020F0 /$ 81EC 44020000 sub esp, 244
004020F6 |. 33C0 xor eax, eax
004020F8 |. A0 53C74000 mov al, [40C753]
004020FD |. 33C9 xor ecx, ecx
004020FF |. 8A0D 52C74000 mov cl, [40C752]
00402105 |. 56 push esi
00402106 |. 50 push eax ; /<%02X>
00402107 |. A1 50C74000 mov eax, [40C750] ; |
......
; 这部分代码的功能是:生成打开注册表键值的字符串
; CLSID\{C0483E67-A363-40C8-BC4C-22EC7419CD21}\Implemented Categories
; 读取该键值下的内容,并还原为输入的注册信息,供程序后面逆计算验证用。
; 此部分代码与算法无关,略。
00402240 |. 8D5424 08 lea edx, [esp+8]
00402244 |. 85C0 test eax, eax
00402246 |. 52 push edx ; 假码入栈"1234-5678-9876-5432"
00402247 |. 74 0F je short 00402258
00402249 |. 8D4C24 4C lea ecx, [esp+4C]
0040224D |. 51 push ecx ; 用户名入栈"snake"
0040224E |. FFD0 call eax ; ***算法call,跟进***
00402250 |. 5E pop esi
00402251 |. 81C4 44020000 add esp, 244
00402257 |. C3 retn
================ 0040224E |. FFD0 call eax ====================
100010A0 83EC 20 sub esp, 20
100010A3 56 push esi
100010A4 57 push edi
100010A5 B9 08000000 mov ecx, 8
100010AA 33C0 xor eax, eax
100010AC 8D7C24 08 lea edi, [esp+8]
100010B0 F3:AB rep stos dword ptr es:[edi]
100010B2 8B4424 2C mov eax, [esp+2C]
100010B6 50 push eax ; 用户名"snake"运算
100010B7 E8 A4010000 call 10001260 ; ***跟进***
100010BC 83C4 04 add esp, 4
100010BF 894424 08 mov [esp+8], eax ; 运算结果为 0012FC34 2F 1C 8C 96
100010C3 33F6 xor esi, esi
100010C5 0FBE4434 08 movsx eax, byte ptr [esp+esi+8] ; 读取字符进行计算
100010CA 83F8 41 cmp eax, 41
100010CD 7C 08 jl short 100010D7
100010CF 83F8 5A cmp eax, 5A
100010D2 7F 03 jg short 100010D7
100010D4 83C0 20 add eax, 20
100010D7 50 push eax
100010D8 E8 33020000 call 10001310
100010DD 83C4 04 add esp, 4
100010E0 884434 08 mov [esp+esi+8], al
100010E4 46 inc esi
100010E5 83FE 04 cmp esi, 4
100010E8 ^ 7C DB jl short 100010C5
100010EA 8B7C24 30 mov edi, [esp+30] ; 计算结果为
100010EE 8D4C24 08 lea ecx, [esp+8] ; 0012FC34 31 33 33 39 串"1339"
100010F2 8BF7 mov esi, edi
100010F4 33D2 xor edx, edx
100010F6 2BF1 sub esi, ecx
100010F8 8D4C14 08 lea ecx, [esp+edx+8]
100010FC 0FBE040E movsx eax, byte ptr [esi+ecx] ; 生成的串"1339"与假码第一部分"1234"比较
10001100 83F8 41 cmp eax, 41
10001103 7C 08 jl short 1000110D
10001105 83F8 5A cmp eax, 5A
10001108 7F 03 jg short 1000110D
1000110A 83C0 20 add eax, 20
1000110D 0FBE09 movsx ecx, byte ptr [ecx]
10001110 3BC1 cmp eax, ecx
10001112 0F85 32010000 jnz 1000124A ; 关键跳转 nop
10001118 42 inc edx
10001119 83FA 04 cmp edx, 4
1000111C ^ 7C DA jl short 100010F8
1000111E 8B4424 08 mov eax, [esp+8] ; eax=39333331
10001122 8D1440 lea edx, [eax+eax*2]
10001125 8D0C95 09000000 lea ecx, [edx*4+9]
1000112C 0FAFC8 imul ecx, eax ; ecx=17EB8545
1000112F 894C24 0C mov [esp+C], ecx ; 0012FC38 45 85 EB 17
10001133 33F6 xor esi, esi
10001135 8A5434 0C mov dl, [esp+esi+C] ; 读取字符进行计算
10001139 52 push edx
1000113A 56 push esi
1000113B E8 80030000 call 100014C0
10001140 25 FF000000 and eax, 0FF
10001145 50 push eax
10001146 E8 C5010000 call 10001310
1000114B 83C4 0C add esp, 0C ; 计算结果为
1000114E 884434 0C mov [esp+esi+C], al ; 0012FC38 33 62 35 33 串"3b53"
10001152 46 inc esi
10001153 83FE 04 cmp esi, 4
10001156 ^ 7C DD jl short 10001135
10001158 33C9 xor ecx, ecx
1000115A 0FBE440F 05 movsx eax, byte ptr [edi+ecx+5] ; 生成的串"3b53"与假码第二部分"5678"比较
1000115F 83F8 41 cmp eax, 41
10001162 7C 08 jl short 1000116C
10001164 83F8 5A cmp eax, 5A
10001167 7F 03 jg short 1000116C
10001169 83C0 20 add eax, 20
1000116C 0FBE540C 0C movsx edx, byte ptr [esp+ecx+C]
10001171 3BC2 cmp eax, edx
10001173 0F85 D1000000 jnz 1000124A ; 关键跳转 nop
10001179 41 inc ecx
1000117A 83F9 04 cmp ecx, 4
1000117D ^ 7C DB jl short 1000115A
1000117F 8B4424 0C mov eax, [esp+C] ; eax=33356233
10001183 8B4C24 08 mov ecx, [esp+8] ; ecx=39333331
10001187 8BD0 mov edx, eax
10001189 33D1 xor edx, ecx
1000118B 42 inc edx
1000118C 0FAFD1 imul edx, ecx
1000118F 8D0C80 lea ecx, [eax+eax*4]
10001192 8D04C8 lea eax, [eax+ecx*8]
10001195 8D0440 lea eax, [eax+eax*2]
10001198 03D0 add edx, eax ; edx=96984914
1000119A 33F6 xor esi, esi
1000119C 895424 10 mov [esp+10], edx ; 0012FC3C 14 49 98 96
100011A0 0FBE4C34 10 movsx ecx, byte ptr [esp+esi+10] ; 读取字符进行计算
100011A5 51 push ecx
100011A6 E8 65010000 call 10001310
100011AB 83C4 04 add esp, 4 ; 计算结果为
100011AE 884434 10 mov [esp+esi+10], al ; 0012FC3C 35 69 37 39 串"5i79"
100011B2 46 inc esi
100011B3 83FE 04 cmp esi, 4
100011B6 ^ 7C E8 jl short 100011A0
100011B8 33C9 xor ecx, ecx
100011BA 0FBE440F 0A movsx eax, byte ptr [edi+ecx+A] ; 生成的串"5i79"与假码第三部分"9876"比较
100011BF 83F8 41 cmp eax, 41
100011C2 7C 08 jl short 100011CC
100011C4 83F8 5A cmp eax, 5A
100011C7 7F 03 jg short 100011CC
100011C9 83C0 20 add eax, 20
100011CC 0FBE540C 10 movsx edx, byte ptr [esp+ecx+10]
100011D1 3BC2 cmp eax, edx
100011D3 75 75 jnz short 1000124A ; 关键跳转 nop
100011D5 41 inc ecx
100011D6 83F9 04 cmp ecx, 4
100011D9 ^ 7C DF jl short 100011BA
100011DB 8B4424 0C mov eax, [esp+C] ; eax=33356233
100011DF 8B4C24 08 mov ecx, [esp+8] ; ecx=39333331
100011E3 0FAFC1 imul eax, ecx
100011E6 8D14C5 00000000 lea edx, [eax*8]
100011ED 2BD0 sub edx, eax
100011EF 8D0489 lea eax, [ecx+ecx*4]
100011F2 83C2 05 add edx, 5
100011F5 0FAF5424 10 imul edx, [esp+10] ; [esp+10]的值为39376935
100011FA 03D0 add edx, eax ; edx=DC46A197
100011FC 33F6 xor esi, esi
100011FE 895424 14 mov [esp+14], edx ; 0012FC40 97 A1 46 DC
10001202 0FBE4C34 14 movsx ecx, byte ptr [esp+esi+14] ; 读取字符进行计算
10001207 51 push ecx
10001208 E8 03010000 call 10001310
1000120D 83C4 04 add esp, 4 ; 计算结果为
10001210 884434 14 mov [esp+esi+14], al ; 0012FC40 39 31 66 73 串"91fs"
10001214 46 inc esi
10001215 83FE 04 cmp esi, 4
10001218 ^ 7C E8 jl short 10001202
1000121A 33C9 xor ecx, ecx
1000121C 0FBE440F 0F movsx eax, byte ptr [edi+ecx+F] ; 生成的串"91fs"与假码第四部分"5432"比较
10001221 83F8 41 cmp eax, 41
10001224 7C 08 jl short 1000122E
10001226 83F8 5A cmp eax, 5A
10001229 7F 03 jg short 1000122E
1000122B 83C0 20 add eax, 20
1000122E 0FBE540C 14 movsx edx, byte ptr [esp+ecx+14]
10001233 3BC2 cmp eax, edx
10001235 75 13 jnz short 1000124A ; 关键跳转 nop
10001237 41 inc ecx
10001238 83F9 04 cmp ecx, 4
1000123B ^ 7C DF jl short 1000121C
1000123D 5F pop edi
1000123E B8 01000000 mov eax, 1 ; 验证通过返回值eax=1
10001243 5E pop esi
10001244 83C4 20 add esp, 20
10001247 C2 0800 retn 8
1000124A 5F pop edi ; ntdll.7C930738
1000124B 33C0 xor eax, eax
1000124D 5E pop esi
1000124E 83C4 20 add esp, 20
10001251 C2 0800 retn 8
================ 100010B7 E8 A4010000 call 10001260 =================
10001260 81EC 00020000 sub esp, 200
10001266 B9 80000000 mov ecx, 80
1000126B 33C0 xor eax, eax
1000126D 53 push ebx
1000126E 55 push ebp
1000126F 56 push esi
10001270 8BB424 10020000 mov esi, [esp+210]
10001277 57 push edi
10001278 8D7C24 10 lea edi, [esp+10]
1000127C F3:AB rep stos dword ptr es:[edi]
1000127E 56 push esi ; 用户名"snake"
1000127F 33ED xor ebp, ebp
10001281 FF15 04600010 call [<&KERNEL32.lstrlenA>] ; kernel32.lstrlenA
10001287 8BD8 mov ebx, eax ; 长度 5
10001289 81FB 00020000 cmp ebx, 200
1000128F 76 12 jbe short 100012A3 ; 判断长度有效性
10001291 B9 80000000 mov ecx, 80
10001296 8D7C24 10 lea edi, [esp+10]
1000129A BB 00020000 mov ebx, 200
1000129F F3:A5 rep movs dword ptr es:[edi], dword p>
100012A1 EB 0C jmp short 100012AF
100012A3 8D4424 10 lea eax, [esp+10]
100012A7 56 push esi
100012A8 50 push eax
100012A9 FF15 84600010 call [<&KERNEL32.lstrcpyA>] ; kernel32.lstrcpyA
100012AF 8BC3 mov eax, ebx ; eax=ebx=5 用户名长度
100012B1 99 cdq
100012B2 83E2 03 and edx, 3
100012B5 03C2 add eax, edx
100012B7 8BF8 mov edi, eax
100012B9 C1FF 02 sar edi, 2
100012BC F6C3 03 test bl, 3
100012BF 74 01 je short 100012C2
100012C1 47 inc edi ; edi=2
100012C2 33C9 xor ecx, ecx
100012C4 85DB test ebx, ebx
100012C6 7E 17 jle short 100012DF
100012C8 8A540C 10 mov dl, [esp+ecx+10] ; 依次读取用户名字符并运算
100012CC 52 push edx
100012CD 51 push ecx
100012CE E8 ED010000 call 100014C0
100012D3 83C4 08 add esp, 8
100012D6 88440C 10 mov [esp+ecx+10], al
100012DA 41 inc ecx
100012DB 3BCB cmp ecx, ebx
100012DD ^ 7C E9 jl short 100012C8
; 该循环过后的运算结果
; 0012FCA8 73 6E 61 6B 65 00 snake.
; ----->转换为
; 0012FA24 B9 37 18 2D A6 00 00 00 ?-?....
100012DF 33F6 xor esi, esi
100012E1 85FF test edi, edi
100012E3 7E 1C jle short 10001301
100012E5 8B5CB4 10 mov ebx, [esp+esi*4+10] ; ebx=2D1837B9,000000A6
100012E9 8BC6 mov eax, esi
100012EB 83E0 1F and eax, 1F
100012EE 03EB add ebp, ebx
100012F0 50 push eax
100012F1 55 push ebp
100012F2 E8 99020000 call 10001590
100012F7 83C4 08 add esp, 8 ; eax=2D1837B9,968C1C2F
100012FA 46 inc esi
100012FB 3BF7 cmp esi, edi ; edi=2
100012FD 8BE8 mov ebp, eax
100012FF ^ 7C E4 jl short 100012E5
10001301 5F pop edi ; 0012FC54
10001302 8BC5 mov eax, ebp ; eax=968C1C2F
10001304 5E pop esi
10001305 5D pop ebp
10001306 5B pop ebx
10001307 81C4 00020000 add esp, 200
1000130D C3 retn
【汇编注册机算法部分源码】
.data?
szName db 64 dup (?)
szSerial db 32 dup (?)
.code
calculat proc
xor eax,eax
xor ecx,ecx
@@:
mov al,[esi+ecx]
push ecx
@2:
test al,0C3h
jpe @1
stc
@1:
rcr al,1
dec cl
jnz @2
pop ecx
mov [esi+ecx],al
inc ecx
cmp ecx,ebx
jl @b
ret
calculat endp
convert proc nNum:DWORD
mov eax,nNum
L000:
and eax,7Fh
cmp eax,41h
jl L006
cmp eax,5Ah
jg L006
or al,20h
L006:
cmp eax,6Fh
jnz L012
mov eax,90h
xor eax,0Eh
or al,31h
jmp L000
L012:
cmp eax,30h
jnz L018
mov eax,0CFh
xor eax,0Eh
or al,31h
jmp L000
L018:
cmp eax,61h
jl L022
cmp eax,7Ah
jle L030
L022:
cmp eax,31h
jl L026
cmp eax,39h
jle L030
L026:
xor eax,0Eh
or al,31h
jmp L000
L030:
ret
convert endp
GetRegKey proc hDlg
pushad
invoke RtlZeroMemory,addr szName,sizeof szName
invoke GetDlgItemText,hDlg,IDC_NAME,addr szName,sizeof szName
.if eax
lea esi,szName
mov ebx,eax
sar eax,2
inc eax
push eax
call calculat
pop ebx
xor eax,eax
xor ecx,ecx
@@:
mov edx,[esi+ecx*4]
add edx,eax
ror edx,cl
mov eax,edx
inc ecx
cmp ecx,ebx
jl @b
mov [esi],eax
xor eax,eax
xor ecx,ecx
@@:
mov al,[esi+ecx]
cmp al,41h
jl @3
cmp al,5Ah
jg @3
add al,20h
@3:
invoke convert,eax
mov [esi+ecx],al
inc ecx
cmp ecx,4
jl @b
mov WORD ptr [esi+ecx],2Dh
lea edi,szSerial
invoke lstrcpy,edi,esi
mov eax,[esi]
push eax
push eax
lea edx,[eax+eax*2]
lea ecx,[edx*4+9]
imul ecx,eax
mov [esi],ecx
mov ebx,4
call calculat
xor eax,eax
xor ecx,ecx
@@:
mov al,[esi+ecx]
invoke convert,eax
mov [esi+ecx],al
inc ecx
cmp ecx,4
jl @b
mov WORD ptr [esi+ecx],2Dh
invoke lstrcat,edi,esi
pop ecx
mov eax,[esi]
push eax
mov edx,eax
xor edx,ecx
inc edx
imul edx,ecx
lea ecx,[eax+eax*4]
lea eax,[eax+ecx*8]
lea eax,[eax+eax*2]
add edx,eax
mov [esi],edx
xor eax,eax
xor ecx,ecx
@@:
mov al,[esi+ecx]
invoke convert,eax
mov [esi+ecx],al
inc ecx
cmp ecx,4
jl @b
mov WORD ptr [esi+ecx],2Dh
invoke lstrcat,edi,esi
pop eax
pop ecx
mov ebx,[esi]
imul eax,ecx
lea edx,[eax*8]
sub edx,eax
lea eax,[ecx+ecx*4]
add edx,5
imul edx,ebx
add edx,eax
mov [esi],edx
xor eax,eax
xor ecx,ecx
@@:
mov al,[esi+ecx]
invoke convert,eax
mov [esi+ecx],al
inc ecx
cmp ecx,4
jl @b
mov WORD ptr [esi+ecx],0
invoke lstrcat,edi,esi
invoke SetDlgItemText,hDlg,IDC_REG,edi
.else
invoke SetDlgItemText,hDlg,IDC_REG,CTXT("请输入用户名!")
.endif
popad
ret
GetRegKey endp
【版权声明】 本文纯属技术交流, 转载请注明作者并保持文章的完整, 谢谢!
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)