加密狗技术网 加密狗破解 AceFTP3 算法分析

AceFTP3 算法分析

用DeDe找到注册按钮的例程:0061D4B0 push ebp…0061D572 mov eax, [ebp…

用DeDe找到注册按钮的例程:
0061D4B0 push ebp

0061D572 mov eax, [ebp-4]
0061D575 call 005EA4C8 ; 计算注册码,进入
0061D57A lea edx, [ebp-38]
0061D57D mov eax, [ebp-8]
0061D580 call 00409798 ; 注册码转为大写
0061D585 mov edx, [ebp-38] ; 假注册码
0061D588 mov eax, [ebp-10] ; 真注册码
0061D58B call 00404898 ; ->System.@LStrCmp;这个就不用说了吧
0061D590 jnz short 0061D59C

说实话,这个软件的算法真有点烦。用peid查出三种算法:
BASE64 table :: 000A7830 :: 004A8430
CRC32 [poly] :: 000AB807 :: 004AC407
ZLIB deflate [long] :: 0028E508 :: 0068F908
好像都没有用在注册码方面,或许是有而偶不知道吧。~_~

来到005EA4C8:

一开始是写入注册表项(不过好像没执行到),这里就不贴出来了 ,来到:

005EA625 . lea edx, [ebp-18] ; 下面的这个是表
005EA628 . mov eax,005EA810 ; ASCII “WBNMH234598764SXZKPTREWQCVBN238”
005EA62D . call 00409798 ; SysUtils.UpperCase
005EA632 . lea edx, [ebp-10]
005EA635 . mov eax, [ebp-4]
005EA638 . call 00409798 ; SysUtils.UpperCase(AnsiString):AnsiString;
005EA63D . xor eax, eax ; 用户名转大写
005EA63F . mov [ebp-20], eax
005EA642 . lea eax, [ebp-14]
005EA645 . call 00404470 ; System.@LStrClr(void;void);
005EA64A . mov eax, [ebp-4]
005EA64D . call 0040474C ; System.@LStrLen(String):Integer;
005EA652 . mov edi, eax
005EA654 . test edi, edi
005EA656 . jle short 005EA699
005EA658 . mov esi, 1
005EA65D > lea eax, [ebp-34]
005EA660 . mov edx, [ebp-10] ; 用户名
005EA663 . mov dl, [edx+esi-1] ; 依次取用户名的ascii
005EA667 . call 00404658 ; System.@LStrFromChar(String;String;Char);
005EA66C . mov eax, [ebp-34]
005EA66F . mov edx, [ebp-18]
005EA672 . call 00404A90 ; System.@LStrPos;
005EA677 . test eax, eax
005EA679 . jle short 005EA695 ; 用户名的第n位不在表中
005EA67B . lea eax, [ebp-38]
005EA67E . mov edx, [ebp-10]
005EA681 . mov dl, [edx+esi-1]
005EA685 . call 00404658 ; System.@LStrFromChar(String;String;Char);
005EA68A . mov edx, [ebp-38]
005EA68D . lea eax, [ebp-14] ; 把在表中的用户名连成字符串1
005EA690 . call 00404754 ; System.@LStrCat;
005EA695 > inc esi
005EA696 . dec edi
005EA697 .^ jnz short 005EA65D
005EA699 > lea eax, [ebp-10]
005EA69C . mov edx, [ebp-14] ; 连成字符串1
005EA69F . call 00404508 ; System.@LStrLAsg(void;void;void;void);
005EA6A4 . mov eax, [ebp-10]
005EA6A7 . call 0040474C ; System.@LStrLen(String):Integer;
005EA6AC . cmp eax, 18
005EA6AF . jge short 005EA6DF ; 字符串1的长度>=18h时跳
005EA6B1 . mov edi, 18
005EA6B6 . sub edi, eax
005EA6B8 . test edi, edi
005EA6BA . jle short 005EA6DF ; <= 005EA6BC . mov esi, 1 005EA6C1 > lea eax, [ebp-3C]
005EA6C4 . mov edx, [ebp-18] ; 表
005EA6C7 . mov dl, [edx+esi-1] ; 表的第n位
005EA6CB . call 00404658 ; System.@LStrFromChar(String;String;Char);
005EA6D0 . mov edx, [ebp-3C]
005EA6D3 . lea eax, [ebp-10]
005EA6D6 . call 00404754 ; System.@LStrCat;
005EA6DB . inc esi ; 字符串1和表连成长度为18h的字符串2
005EA6DC . dec edi
005EA6DD .^ jnz short 005EA6C1
005EA6DF > mov eax, [ebp-10] ; 得出的字符串2
005EA6E2 . call 0040474C ; System.@LStrLen(String):Integer;
005EA6E7 . cmp eax, 18
005EA6EA . jle short 005EA702 ; <=18跳 005EA6EC . lea eax, [ebp-10] 005EA6EF . push eax 005EA6F0 . mov ecx, 18 005EA6F5 . mov edx, 1 005EA6FA . mov eax, [ebp-10] 005EA6FD . call 004049AC ; System.@LStrCopy; 005EA702 > lea eax, [ebp-14]
005EA705 . call 00404470 ; System.@LStrClr(void;void);
005EA70A . mov esi, 1
005EA70F > mov eax, [ebp-10] ; 连成的字符串2
005EA712 . mov bl, [eax+esi-1] ; 依次取字符串2的ascii
005EA716 . lea eax, [ebp-40]
005EA719 . mov edx, ebx
005EA71B . call 00404658 ; System.@LStrFromChar(String;String;Char);
005EA720 . mov eax, [ebp-40]
005EA723 . mov edx, [ebp-18] ; 表
005EA726 . call 00404A90 ; System.@LStrPos;
005EA72B . mov ebx, eax ; 该字符在表中的位置(以1开始,以0开始要加1)
005EA72D . mov eax, [ebp-18] ; 表
005EA730 . call 0040474C ; System.@LStrLen(String):Integer;
005EA735 . push eax ; 表的长度(1Fh)
005EA736 . mov eax, ebx
005EA738 . imul ebx ; 该字符在表中的位置*该字符在表中的位置
005EA73A . sub eax, ebx ; 值再减去该字符在表中的位置
005EA73C . add eax, [ebp-20] ; 上次运算出的余数+1,第一次为0
005EA73F . pop edx
005EA740 . mov ecx, edx
005EA742 . cdq
005EA743 . idiv ecx ; 除以表的长度
005EA745 . mov ebx, edx ; edx=余数
005EA747 . inc ebx ; ebx=edx=余数+1
005EA748 . mov [ebp-20], ebx ; 写入[ 0012f2e8]
005EA74B . mov eax, [ebp-18] ; 表
005EA74E . mov bl, [eax+ebx-1] ; 表的第ebx-1位
005EA752 . lea eax, [ebp-44]
005EA755 . mov edx, ebx ; edx=ebx=表的第ebx-1位的ascii码
005EA757 . call 00404658 ; System.@LStrFromChar(String;String;Char);
005EA75C . mov edx, [ebp-44]
005EA75F . lea eax, [ebp-14]
005EA762 . call 00404754 ; System.@LStrCat;
005EA767 . mov eax, esi ; eax=esi=循环次数
005EA769 . mov ecx, 6
005EA76E . cdq
005EA76F . idiv ecx ; 循环次数除以6
005EA771 . test edx, edx
005EA773 . jnz short 005EA787 ; 不能整除跳过
005EA775 . cmp esi, 18 ; 可以整除
005EA778 . jge short 005EA787 ; esi>=18跳
005EA77A . lea eax, [ebp-14]
005EA77D . mov edx,005EA838 ; 加上’-‘
005EA782 . call 00404754 ; System.@LStrCat;
005EA787 > inc esi ; 上面这段函数就是每6位加上’-‘
005EA788 . cmp esi, 19
005EA78B .^ jnz short 005EA70F
005EA78D . mov eax, [ebp-C]
005EA790 . mov edx, [ebp-14]

算法就出来了,简单说一下:


将用户名进行查表,把在表中的用户名连起来,再和表连成长度为18h的字符串。

依次取该字符串的ascii码,查表,得到该字符在表中的位置:X,进行运算:

(X*X-X)+(变量A)=Y

edx=Y mod (表的长度1F),变量A <- (余数+1)

用余数查表,连成字符串,每6位插入’-‘


是不是很烦呀。赶紧,写注册机。^_^
========================================================================
注册码保存在X:\Documents and Settings\你的用户名\Application Data\Visicom Media\
AceFTP,删掉Settings.cfg就可以了,但是你的配置也会被删除。


Suyana -> 用户名

WBNMH234598764SXZKPTREWQCVBN238 -> 表

SNWBNMH234598764SXZKPTRE -> 连成的字符串

CWBH7C-SSBEB8-KB2QK8-HBM682 -> 注册码

注册机源码:
.data
szFmt db ‘%s’,0
szFmtS db ‘%s%c’,0
table db ‘WBNMH234598764SXZKPTREWQCVBN238’,0

.code
;———–在字符串中查找指定字符,返回位置————
LStrPos proc uses edx ecx lpstring,char
xor ecx,ecx
mov edx,lpstring
.repeat
mov al,[edx]
.if al==byte ptr char
jmp brk
.endif
inc edx
inc ecx
.until al==0
push 0
pop eax
ret
brk:
inc ecx
push ecx
pop eax
ret
LStrPos endp
;—————-判断用户名是否有效——————-
isUserIsValid proc uses edx ecx _addr
mov edx,_addr
aa:
mov cl,[edx]
or cl,cl
je fa
invoke LStrPos,addr table,cl
.if eax
push 1
pop eax
ret
.endif
inc edx
jmp aa
fa:
push 0
pop eax
ret
isUserIsValid endp
;—————小写转大写—————————
UpperCase proc lpString
push eax
mov eax,lpString
aa:
mov cl, [eax]
cmp cl, 61h
jl loo
cmp cl, 7Ah
jg loo
sub cl, 20h
mov [eax], cl
loo:
inc eax
cmp byte ptr [eax], 0
jnz aa
pop eax
ret
UpperCase endp
;——————–计算长度———————-
GetStrLen proc uses edx ecx _addr
xor ecx,ecx
mov edx,_addr
.repeat
inc ecx
inc edx
mov al,[edx]
.until al==0
mov eax,ecx
ret
GetStrLen endp
;——————–计算注册码的函数——————————–
_GetSN proc uses ebx ecx edx edi esi hWnd
local szBufUser[128]:byte,szBuffer[256]:byte,szBuf1[128]:byte
local incYushu,szBuf2[128]:byte

    mov incYushu,0
    invoke RtlZeroMemory,addr szBufUser,sizeof szBufUser
    invoke GetDlgItemText,hWnd,1000,addr szBufUser,128
    .if !eax
            invoke SetDlgItemText,hWnd,1001,addr szTip
            ret
    .endif
    mov edi,eax
    invoke UpperCase,addr szBufUser                    ;小写转大写
    invoke isUserIsValid,addr szBufUser                ;判断用户名是否有效
    .if !eax
            invoke SetDlgItemText,hWnd,1001,addr szTip
            ret
    .endif
    invoke RtlZeroMemory,addr szBuf1,sizeof szBuf1
    invoke RtlZeroMemory,addr szBuf2,sizeof szBuf2
    invoke RtlZeroMemory,addr szBuffer,sizeof szBuffer
    mov    esi, 1
@@:
    lea     edx,szBufUser                 ; 用户名
    mov     dl, [edx+esi-1]               ; 用户名第一位
    invoke  LStrPos,addr table,dl
    test    eax, eax
    jle     xx
    invoke  wsprintf,addr szBuf1,addr szFmtS,addr szBuf1,dl
xx:
    inc     esi
    dec     edi
    jnz     @B

    lea     edi,table
    lea     edx,szBuf1
    invoke  GetStrLen,addr szBuf1
    mov     esi,eax
@@:
    mov     cl,byte ptr [edi]
    mov     [edx+esi],cl
    inc     edi
    inc     esi
    .if esi<18h
            jmp @B
    .endif

    mov     esi, 1
@aceftp3_  005EA70F:
    lea     eax, szBuf1
    mov     bl, [eax+esi-1]                ; 依次取字符串2的ascii
    invoke  LStrPos,addr table,bl

    mov     ebx, eax                       ; 该字符在表中的位置(以1开始,以0开始要加1)
    invoke  GetStrLen,addr table           ; 表的长度
    push    eax                
    mov     eax, ebx
    imul    ebx                            ; 该字符在表中的位置*该字符在表中的位置
    sub     eax, ebx                       ; 值再减去该字符在表中的位置
    add     eax, incYushu                  ; 0,1,2,(上次运行出的余数+1)
    pop     edx
    mov     ecx, edx
    cdq
    idiv    ecx                            ; 除以表的长度
    mov     ebx, edx                       ; edx=余数
    inc     ebx                            ; ebx=edx=余数+1
    mov     incYushu, ebx
    lea     eax,table                      ; 表
    mov     bl, [eax+ebx-1]                ; 表的第ebx-1位
    invoke  wsprintf,addr szBuf2,addr szFmtS,addr szBuf2,bl
    mov     eax, esi                       ; eax=esi=循环次数
    mov     ecx, 6
    cdq
    idiv    ecx                            ; 除以6
    test    edx, edx
    jnz     @aceftp3_  005EA787            ; 不能整除
    cmp     esi, 018h                      ; 可以整除
    jge     @aceftp3_  005EA787            ; esi>=18跳
    invoke  wsprintf,addr szBuf2,addr szFmtS,addr szBuf2,'-'
@aceftp3_  005EA787:
    inc     esi
    cmp     esi, 019h
    jnz     @aceftp3_  005EA70F

    ; 显示注册码---------------------                
    invoke wsprintf,addr szBuffer,addr szFmt,addr szBuf2
    invoke SetDlgItemText,hWnd,1001,addr szBuffer
    ret

_GetSN endp

本文来自网络,不代表加密狗技术网立场,转载请注明出处:http://www.crackgou.com/pojie/66.html

作者: admin

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注

联系我们

联系我们

000-00000000

在线咨询: QQ交谈

邮箱: wolfree@qq.com

工作时间:8:00-23:00

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

关注微博
返回顶部