【破文标题】 ScreenFlash V1.7 注册算法分析
【破文作者】 snake
【软件名称】 ScreenFlash
【下载地址】 http://unflash.com/
【调试环境】 Windows XP + SP2
【作者声明】 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
【破解过程】
用PEiD查壳为Microsoft Visual C++ 7.0 [Debug],无壳。
运行程序输入注册信息
Name: snake
Activation: 123456789ABC
点“Activate”按钮后提示错误信息,并把注册信息写入到注册表中
OD载入程序,下断bp RegQueryValueExA,F9运行,断下,连续按N次F9,直到堆栈显示内容为
0012D8F4 005E0E2C /CALL 到 RegQueryValueExA 来自 SFlash.005E0E2A
0012D8F8 000000A8 |hKey = A8
0012D8FC 00DD6EB0 |ValueName = "sn"
0012D900 00000000 |Reserved = NULL
0012D904 0012D920 |pValueType = 0012D920
0012D908 00DD5E58 |Buffer = 00DD5E58
0012D90C 0012D91C \pBufSize = 0012D91C
F2取消断点,Alt+F9返回程序领空,N次F8到004C6B2C处,算法验证处
004C6B2C > \8B4C24 14 mov ecx, [esp+14] ; 用户名
004C6B30 . 8B41 F4 mov eax, [ecx-C]
004C6B33 . 85C0 test eax, eax
004C6B35 . 0F8E EC010000 jle 004C6D27 ; 不能为空
004C6B3B . 8B5424 20 mov edx, [esp+20] ; 注册码
004C6B3F . 837A F4 0C cmp dword ptr [edx-C], 0C ; 为12位字符串
004C6B43 . 0F85 DE010000 jnz 004C6D27
004C6B49 . 6A 04 push 4
004C6B4B . 8D4424 2C lea eax, [esp+2C]
004C6B4F . 50 push eax
004C6B50 . 8D4C24 28 lea ecx, [esp+28]
004C6B54 . E8 27E1F4FF call 00414C80
004C6B59 . C64424 74 0D mov byte ptr [esp+74], 0D
004C6B5E . 8D4C24 20 lea ecx, [esp+20]
004C6B62 . 51 push ecx
004C6B63 . 8D4C24 14 lea ecx, [esp+14]
004C6B67 . E8 64B9F3FF call 004024D0
004C6B6C . C64424 74 0E mov byte ptr [esp+74], 0E
004C6B71 . 8B5424 10 mov edx, [esp+10]
004C6B75 . 8B4C24 14 mov ecx, [esp+14]
004C6B79 . 8B42 F4 mov eax, [edx-C]
004C6B7C . 8B71 F4 mov esi, [ecx-C]
004C6B7F . 50 push eax
004C6B80 . 8D4C24 14 lea ecx, [esp+14]
004C6B84 . E8 97B9F3FF call 00402520
004C6B89 . 50 push eax
004C6B8A . 56 push esi
004C6B8B . 8D4C24 1C lea ecx, [esp+1C]
004C6B8F . E8 8CB9F3FF call 00402520
004C6B94 . 8BF8 mov edi, eax
004C6B96 . E8 85DFFFFF call 004C4B20 ; 算法验证call
;根据前4位注册码生成最后4位注册码,并与假码的最后4位相比较,al=1继续验证
{{{
004C4B20 /$ 81EC 18010000 sub esp, 118
004C4B26 |. A1 00156900 mov eax, [691500]
004C4B2B |. 53 push ebx
004C4B2C |. 55 push ebp
004C4B2D |. 8BAC24 240100>mov ebp, [esp+124]
004C4B34 |. 56 push esi
004C4B35 |. 8D7424 20 lea esi, [esp+20]
004C4B39 |. 898424 200100>mov [esp+120], eax
004C4B40 |. E8 5BFFFFFF call 004C4AA0 ; 生成长字符串
"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCD"
004C4B45 |. 803F 00 cmp byte ptr [edi], 0
004C4B48 |. 74 0E je short 004C4B58
004C4B4A |. 8BC7 mov eax, edi
004C4B4C |. 8D6424 00 lea esp, [esp]
004C4B50 |> 8A48 01 /mov cl, [eax+1]
004C4B53 |. 40 |inc eax
004C4B54 |. 84C9 |test cl, cl
004C4B56 |.^ 75 F8 \jnz short 004C4B50
004C4B58 |> 8BC5 mov eax, ebp
004C4B5A |. 8B08 mov ecx, [eax]
004C4B5C |. 8B50 04 mov edx, [eax+4]
004C4B5F |. 8B40 08 mov eax, [eax+8]
004C4B62 |. 894C24 10 mov [esp+10], ecx
004C4B66 |. 895424 14 mov [esp+14], edx
004C4B6A |. 894424 18 mov [esp+18], eax
004C4B6E |. 33C9 xor ecx, ecx
004C4B70 |> 8A540C 20 /mov dl, [esp+ecx+20] ; 取前4位注册码分别在长字符串中的索引值
004C4B74 |. 33C0 |xor eax, eax
004C4B76 |> 385404 10 |/cmp [esp+eax+10], dl
004C4B7A |. 75 04 ||jnz short 004C4B80
004C4B7C |. 884C04 0C ||mov [esp+eax+C], cl ; 保存索引值
004C4B80 |> 40 ||inc eax
004C4B81 |. 83F8 04 ||cmp eax, 4
004C4B84 |.^ 7C F0 |\jl short 004C4B76
004C4B86 |. 41 |inc ecx
004C4B87 |. 83F9 24 |cmp ecx, 24
004C4B8A |.^ 7C E4 \jl short 004C4B70
004C4B8C |. 8A4424 0F mov al, [esp+F]
004C4B90 |. 8A5424 0E mov dl, [esp+E]
004C4B94 |. 8B4C24 0C mov ecx, [esp+C]
004C4B98 |. 8AD8 mov bl, al
004C4B9A |. 02DA add bl, dl
004C4B9C |. 02DD add bl, ch
004C4B9E |. 02D9 add bl, cl
004C4BA0 |. 0FB6F3 movzx esi, bl ; 4个索引值相运算
004C4BA3 |. 8A5D 08 mov bl, [ebp+8] ; 取注册码第9位
004C4BA6 |. 3A5C34 20 cmp bl, [esp+esi+20] ; 与长串中的值比较
004C4BAA |. 74 18 je short 004C4BC4 ; 关键跳转 jmp
004C4BAC |> 5E pop esi
004C4BAD |. 5D pop ebp
004C4BAE |. 32C0 xor al, al
004C4BB0 |. 5B pop ebx
004C4BB1 |. 8B8C24 140100>mov ecx, [esp+114]
004C4BB8 |. E8 51270A00 call 0056730E
004C4BBD |. 81C4 18010000 add esp, 118
004C4BC3 |. C3 retn
004C4BC4 |> 8ADA mov bl, dl
004C4BC6 |. 2AD8 sub bl, al
004C4BC8 |. 02DD add bl, ch
004C4BCA |. 02D9 add bl, cl
004C4BCC |. 80C3 24 add bl, 24
004C4BCF |. 0FB6F3 movzx esi, bl ; 4个索引值相运算
004C4BD2 |. 8A5D 09 mov bl, [ebp+9] ; 取注册码第10位
004C4BD5 |. 3A5C34 20 cmp bl, [esp+esi+20] ; 与长串中的值比较
004C4BD9 |.^ 75 D1 jnz short 004C4BAC ; 关键跳转 nop
004C4BDB |. 8ADD mov bl, ch
004C4BDD |. 2AD8 sub bl, al
004C4BDF |. 2ADA sub bl, dl
004C4BE1 |. 02D9 add bl, cl
004C4BE3 |. 80C3 48 add bl, 48
004C4BE6 |. 0FB6F3 movzx esi, bl ; 4个索引值相运算
004C4BE9 |. 8A5D 0A mov bl, [ebp+A] ; 取注册码第11位
004C4BEC |. 3A5C34 20 cmp bl, [esp+esi+20] ; 与长串中的值比较
004C4BF0 |.^ 75 BA jnz short 004C4BAC ; 关键跳转 nop
004C4BF2 |. 2AC5 sub al, ch
004C4BF4 |. 02C2 add al, dl
004C4BF6 |. 8A55 0B mov dl, [ebp+B] ; 取注册码第12位
004C4BF9 |. 02C1 add al, cl
004C4BFB |. 04 24 add al, 24
004C4BFD |. 0FB6C8 movzx ecx, al ; 4个索引值相运算
004C4C00 |. 8A440C 20 mov al, [esp+ecx+20]
004C4C04 |. 8B8C24 200100>mov ecx, [esp+120]
004C4C0B |. 5E pop esi
004C4C0C |. 3AD0 cmp dl, al ; 与长串中的值比较
004C4C0E |. 5D pop ebp
004C4C0F |. 0F94C0 sete al ; al=1
004C4C12 |. 5B pop ebx
004C4C13 |. E8 F6260A00 call 0056730E
004C4C18 |. 81C4 18010000 add esp, 118
004C4C1E \. C3 retn
}}}
004C6B9B . 83C4 04 add esp, 4
004C6B9E . 84C0 test al, al
004C6BA0 . 0F84 66010000 je 004C6D0C ; 关键跳转 nop
004C6BA6 . 8B5424 14 mov edx, [esp+14]
004C6BAA . 8B42 F4 mov eax, [edx-C]
004C6BAD . 50 push eax
004C6BAE . 8D4C24 18 lea ecx, [esp+18]
004C6BB2 . E8 69B9F3FF call 00402520
004C6BB7 . 8D5C24 60 lea ebx, [esp+60]
004C6BBB . 8BF8 mov edi, eax ; 用户名"snake"
004C6BBD . E8 5EE0FFFF call 004C4C20 ; 算法call,由用户名生成4位的字符串
{{{
004C4C20 /$ 81EC 04010000 sub esp, 104
004C4C26 |. A1 00156900 mov eax, [691500]
004C4C2B |. 56 push esi
004C4C2C |. 8D7424 04 lea esi, [esp+4]
004C4C30 |. 898424 040100>mov [esp+104], eax
004C4C37 |. E8 64FEFFFF call 004C4AA0 ; 生成长字符串
004C4C3C |. 8A07 mov al, [edi]
004C4C3E |. 33C9 xor ecx, ecx
004C4C40 |. 84C0 test al, al
004C4C42 |. B2 20 mov dl, 20
004C4C44 |. 74 09 je short 004C4C4F
004C4C46 |> 8A4439 01 /mov al, [ecx+edi+1] ; 计算用户名长度
004C4C4A |. 41 |inc ecx
004C4C4B |. 84C0 |test al, al
004C4C4D |.^ 75 F7 \jnz short 004C4C46
004C4C4F |> 33C0 xor eax, eax
004C4C51 |. 85C9 test ecx, ecx
004C4C53 |. 7E 08 jle short 004C4C5D
004C4C55 |> 021438 /add dl, [eax+edi] ; 分别取用户名的ASCII值进行运算
004C4C58 |. 40 |inc eax
004C4C59 |. 3BC1 |cmp eax, ecx
004C4C5B |.^ 7C F8 \jl short 004C4C55
004C4C5D |> 0FB6C2 movzx eax, dl ; 运算结果
004C4C60 |. 8A4404 04 mov al, [esp+eax+4] ; al='O'
004C4C64 |. 33F6 xor esi, esi
004C4C66 |. 85C9 test ecx, ecx
004C4C68 |. 8803 mov [ebx], al
004C4C6A |. A2 1C466D00 mov [6D461C], al
004C4C6F |. B2 40 mov dl, 40
004C4C71 |. 7E 0C jle short 004C4C7F
004C4C73 |> 8A043E /mov al, [esi+edi] ; 分别取用户名的ASCII值进行运算
004C4C76 |. F6EA |imul dl
004C4C78 |. 46 |inc esi
004C4C79 |. 3BF1 |cmp esi, ecx
004C4C7B |. 8AD0 |mov dl, al
004C4C7D |.^ 7C F4 \jl short 004C4C73
004C4C7F |> 0FB6D2 movzx edx, dl ; 运算结果
004C4C82 |. 8A4414 04 mov al, [esp+edx+4] ; al='U'
004C4C86 |. 8843 01 mov [ebx+1], al
004C4C89 |. A2 1D466D00 mov [6D461D], al
004C4C8E |. 33C0 xor eax, eax
004C4C90 |. 85C9 test ecx, ecx
004C4C92 |. B2 80 mov dl, 80
004C4C94 |. 5E pop esi
004C4C95 |. 7E 08 jle short 004C4C9F
004C4C97 |> 2A1438 /sub dl, [eax+edi] ; 分别取用户名的ASCII值进行运算
004C4C9A |. 40 |inc eax
004C4C9B |. 3BC1 |cmp eax, ecx
004C4C9D |.^ 7C F8 \jl short 004C4C97
004C4C9F |> 8A0C0C mov cl, [esp+ecx] ; cl='F'
004C4CA2 |. 0FB6C2 movzx eax, dl
004C4CA5 |. 8A0404 mov al, [esp+eax] ; al='C'
004C4CA8 |. 8843 02 mov [ebx+2], al
004C4CAB |. A2 1E466D00 mov [6D461E], al
004C4CB0 |. 884B 03 mov [ebx+3], cl ; 最终结果为
004C4CB3 |. 880D 1F466D00 mov [6D461F], cl ; 006D461C 4F 55 43 46 串"OUCF"
004C4CB9 |. 8B8C24 000100>mov ecx, [esp+100]
004C4CC0 |. E8 49260A00 call 0056730E
004C4CC5 |. 81C4 04010000 add esp, 104
004C4CCB \. C3 retn
}}}
004C6BC2 . 6A 04 push 4
004C6BC4 . 8D4424 30 lea eax, [esp+30]
004C6BC8 . 50 push eax
004C6BC9 . 8D4C24 28 lea ecx, [esp+28]
004C6BCD . E8 1EBAF3FF call 004025F0
004C6BD2 . C64424 74 0F mov byte ptr [esp+74], 0F
004C6BD7 . 50 push eax
004C6BD8 . 8D4C24 14 lea ecx, [esp+14]
004C6BDC . E8 1FBBF3FF call 00402700
004C6BE1 . C64424 74 0E mov byte ptr [esp+74], 0E
004C6BE6 . 8D4C24 2C lea ecx, [esp+2C]
004C6BEA . E8 41B8F3FF call 00402430
004C6BEF . 8B4C24 10 mov ecx, [esp+10] ; 取注册码前4位
004C6BF3 . 8B41 F4 mov eax, [ecx-C]
004C6BF6 . 50 push eax
004C6BF7 . 8D4C24 14 lea ecx, [esp+14]
004C6BFB . C64424 68 00 mov byte ptr [esp+68], 0
004C6C00 . 8BF3 mov esi, ebx ; 取由用户名生成的字符串
004C6C02 . E8 19B9F3FF call 00402520
004C6C07 > 8A10 mov dl, [eax] ; 逐位比较相等则验证通过
004C6C09 . 8A1E mov bl, [esi]
004C6C0B . 8ACA mov cl, dl
004C6C0D . 3AD3 cmp dl, bl
004C6C0F . 75 1E jnz short 004C6C2F ; 关键跳转 nop
004C6C11 . 84C9 test cl, cl
004C6C13 . 74 16 je short 004C6C2B
004C6C15 . 8A50 01 mov dl, [eax+1]
004C6C18 . 8A5E 01 mov bl, [esi+1]
004C6C1B . 8ACA mov cl, dl
004C6C1D . 3AD3 cmp dl, bl
004C6C1F . 75 0E jnz short 004C6C2F ; 关键跳转 nop
004C6C21 . 83C0 02 add eax, 2
004C6C24 . 83C6 02 add esi, 2
004C6C27 . 84C9 test cl, cl
004C6C29 .^ 75 DC jnz short 004C6C07
004C6C2B > 33C0 xor eax, eax
004C6C2D . EB 04 jmp short 004C6C33 ; 中间4位注册码为任意值
004C6C2F > 1BC0 sbb eax, eax
004C6C31 . 1BC5 sbb eax, ebp
004C6C33 > 85C0 test eax, eax
004C6C35 . 0F85 CF000000 jnz 004C6D0A
......
【汇编注册机算法部分源码】
.data
szTable db "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ01"
db "23456789ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRST"
db "UVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKL"
db "MNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCD",0
.data?
szName dd 32 dup (?)
szSerial db 16 dup (?)
szTmp db 8 dup (?)
nCon dd ?
.code
GetRegKey proc hDlg
pushad
invoke GetDlgItemText,hDlg,IDC_NAME,addr szName,sizeof szName
.if eax
mov nCon,eax
lea esi,szTable
mov dl,[esi+eax]
mov [szSerial+3],dl
xor edx,edx
lea edi,szName
@@:
add dl,[edi+eax-1]
dec eax
jnz @b
cmp dl,80h
ja @1
mov ecx,80h
sub ecx,edx
jmp @2
@1:
mov ecx,180h
sub ecx,edx
@2:
mov dl,[esi+ecx]
mov [szSerial+2],dl
mov ecx,nCon
xor ebx,ebx
mov dl,40h
@@:
mov al,[edi+ebx]
imul dl
mov dl,al
inc ebx
dec ecx
jnz @b
mov al,[esi+edx]
mov [szSerial+1],al
xor edx,edx
mov ecx,nCon
@@:
sub dl,[edi+ecx-1]
dec ecx
jnz @b
cmp dl,20h
ja @3
mov ecx,20h
sub ecx,edx
jmp @4
@3:
mov ecx,120h
sub ecx,edx
@4:
mov dl,[esi+ecx]
mov [szSerial],dl
lea edi,szSerial
lea ebx,szTmp
xor ecx,ecx
@@:
mov dl,[esi+ecx]
xor eax,eax
@6:
cmp dl,[edi+eax]
jnz @5
mov [ebx+eax],cl
@5:
inc eax
cmp eax,4
jl @6
inc ecx
cmp ecx,24h
jl @b
xor edx,edx
mov ecx,4
@@:
add dl,[ebx+ecx-1]
dec ecx
jnz @b
mov dl,[esi+edx]
mov [szSerial+8],dl
mov dl,[ebx+2]
sub dl,[ebx+3]
add dl,[ebx+1]
add dl,[ebx]
add dl,24h
mov dl,[esi+edx]
mov [szSerial+9],dl
mov dl,[ebx+1]
sub dl,[ebx+3]
sub dl,[ebx+2]
add dl,[ebx]
add dl,48h
mov dl,[esi+edx]
mov [szSerial+0Ah],dl
mov dl,[ebx+3]
sub dl,[ebx+1]
add dl,[ebx+2]
add dl,[ebx]
add dl,24h
mov dl,[esi+edx]
mov [szSerial+0Bh],dl
invoke GetTickCount
and eax,3Fh
mov ecx,4
@@:
mov dl,[esi+eax]
mov [szSerial+3+ecx],dl
add eax,7
dec ecx
jnz @b
invoke SetDlgItemText,hDlg,IDC_REG,addr szSerial
.else
invoke SetDlgItemText,hDlg,IDC_REG,CTXT("Please Enter the Name!")
.endif
popad
ret
GetRegKey endp
【版权声明】 本文纯属技术交流, 转载请注明作者并保持文章的完整, 谢谢!