ToT 发表于 2007-2-17 22:15:47

飘云老大的Keygenme2007_B简单分析

因为比较简单,我这样的菜鸟来献个丑,算法很简单,高手略过

PEiD侦壳,NsPack,用ESP定律轻松搞定,不说。

跟注册码算法有关一共有三个地方,先找到402490这里:
004024A5   .8378 F8 2C    cmp   dword ptr , 2C
004024A9   .0F85 FF000000 jnz   004025AE

这里比较注册码位数是44位,不是就死。往下来到这里:
004024B7   > \8B8E 2C010000 mov   ecx,                    ;注册码
004024BD   .8A41 06       mov   al,                       ;第7位
004024C0   .8A51 05       mov   dl,                       ;第6位
004024C3   .33C2          xor   eax, edx
004024C5   .0FBE51 07   movsx   edx, byte ptr             ;第8位
004024C9   .83E0 7F       and   eax, 7F
004024CC   .0FBE49 04   movsx   ecx, byte ptr             ;第5位
004024D0   .0FAFC2      imul    eax, edx
004024D3   .03C1          add   eax, ecx
004024D5   .B9 6B000000   mov   ecx, 6B
004024DA   .99            cdq
004024DB   .F7F9          idiv    ecx
004024DD   .85D2          test    edx, edx
004024DF   .0F85 C9000000 jnz   004025AE
这里就是(第7位 xor 第6位)*第8位+第5位=107的整数倍,自己随便凑个数就过了这里。

后面的同类的计算还有3处,算法都很简单,不详细说了,这段里面不少花指令,不过都比较简单,不影响阅读。
4处注册码计算都过了之后来到这里:
00402586   > \817E 60 A4DB6>cmp   dword ptr , 260DBA4
0040258D   .74 18         je      short 004025A7
0040258F   .74 03         je      short 00402594
00402591   .75 01         jnz   short 00402594
这里的比较如果没过的话不是真正注册成功,因此要观察的值,下硬件访问断点。当输入用户名的时候断在这里:
00402790   .56            push    esi
00402791   .8BF1          mov   esi, ecx
00402793   .6A 01         push    1
00402795   .E8 385A0000   call    <jmp.&mfc42.#6334_CWnd::UpdateDa>
0040279A   .8B86 30010000 mov   eax,
004027A0   .8378 F8 05    cmp   dword ptr , 5             ;用户名要大于5位
004027A4   .7C 1E         jl      short 004027C4
004027A6   .8B8E 2C010000 mov   ecx,
004027AC   .8379 F8 2C    cmp   dword ptr , 2C            ;注册码一共44位
004027B0   .75 12         jnz   short 004027C4
004027B2   .8B56 20       mov   edx,
004027B5   .6A 00         push    0                              ; /Timerproc = NULL
004027B7   .6A 0A         push    0A                               ; |Timeout = 10. ms
004027B9   .6A 01         push    1                              ; |TimerID = 1
004027BB   .52            push    edx                              ; |hWnd
004027BC   .FF15 30934000 call    [<&user32.SetTimer>]             ; \SetTimer
004027C2   .5E            pop   esi
004027C3   .C3            retn
004027C4   >C746 60 40E20>mov   dword ptr , 1E240      ;到这里就死
004027CB   .5E            pop   esi
004027CC   .C3            retn
当两步比较都过了之后,会SetTimer,每隔10ms触发一次,触发之后在这里:
004025D0   .64:A1 0000000>mov   eax, fs:
004025D6   .6A FF         push    -1
004025D8   .68 E0864000   push    004086E0
004025DD   .50            push    eax
往下找,先到这里:
004025F3   .8B83 2C010000 mov   eax,                    ;注册码
004025F9   .8DBB 2C010000 lea   edi,
004025FF   .8A08          mov   cl,
00402601   .80F9 50       cmp   cl, 50                           ;P
00402604   .75 1B         jnz   short 00402621
00402606   .8078 01 59    cmp   byte ptr , 59             ;Y
0040260A   .75 15         jnz   short 00402621
0040260C   .8078 02 47    cmp   byte ptr , 47             ;G
00402610   .75 0F         jnz   short 00402621
00402612   .8078 03 2D    cmp   byte ptr , 2D             ;-
00402616   .75 09         jnz   short 00402621
00402618   .C743 60 B30D2>mov   dword ptr , 12F0DB3
0040261F   .EB 07         jmp   short 00402628
00402621   >C743 60 F1CD3>mov   dword ptr , 131CDF1      ;跳到这里就死
这里,注册码前四位必须是“PYG-”,然后会把赋值为12F0DB3,也就是前面的。
继续往下看
00402628   > \55            push    ebp
00402629   .56            push    esi
0040262A   .8DB3 30010000 lea   esi,
00402630   .6A 01         push    1
00402632   .8D4424 30   lea   eax,
00402636   .6A 00         push    0
00402638   .50            push    eax
00402639   .8BCE          mov   ecx, esi
0040263B   .E8 985B0000   call    <jmp.&mfc42.#4278_CString::Mid>;用户名第一位
00402640   .8BE8          mov   ebp, eax
00402642   .6A 01         push    1
00402644   .8D4C24 2C   lea   ecx,
00402648   .6A 14         push    14
0040264A   .51            push    ecx
0040264B   .8BCF          mov   ecx, edi
0040264D   .C74424 44 000>mov   dword ptr , 0
00402655   .E8 7E5B0000   call    <jmp.&mfc42.#4278_CString::Mid>;注册码第21位
0040265A   .8B6D 00       mov   ebp,
0040265D   .8B00          mov   eax,
0040265F   .55            push    ebp                              ; /s2
00402660   .8B2D D8924000 mov   ebp, [<&msvcrt._mbscmp>]         ; |msvcrt._mbscmp
00402666   .50            push    eax                              ; |s1
00402667   .C64424 40 01mov   byte ptr , 1             ; |
0040266C   .FFD5          call    ebp                              ; \_mbscmp
0040266E   .83C4 08       add   esp, 8
00402671   .85C0          test    eax, eax
00402673   .0F85 BB000000 jnz   00402734                         ;不等则死
这里,用户名第一位要等于注册码第21位,后面还有同样的比较,方法都一样,就不写了,还有2个地方的比较,分别是用户名第3位等于注册码第26位,用户名第5位等于注册码第37位,都过了之后来到这里:
0040275D   .84C0          test    al, al
0040275F   .5D            pop   ebp
00402760   .74 07         je      short 00402769
00402762   .8143 60 F1CD3>add   dword ptr , 131CDF1
这里=12F0DB3+131CDF1=260DBA4,就是前面最后一个判断的地方,这里也过了就通过注册
呵呵,算法很简单吧。

btw 飘云老大的程序有一个bug,当先输入用户名,然后输入注册码,这时按OK没有显示注册通过,原因是在输入用户名的时候判断注册码的位数,不等于0x2C就不会进入SetTimer,而输入注册码的时候不会触发402790程序段的判断,这是这个CrackMe的一个小bug,呵呵。

ToT 发表于 2007-2-17 22:16:35

给一组我用的用户名和注册码:
用户名:ToTToT
注册码:PYG-2679 012\45\c890T2345T7890c23456o8901234

飘云 发表于 2007-2-17 22:53:06

原帖由 ToT 于 2007-2-17 22:15 发表
因为比较简单,我这样的菜鸟来献个丑,算法很简单,高手略过

PEiD侦壳,NsPack,用ESP定律轻松搞定,不说。

跟注册码算法有关一共有三个地方,先找到402490这里:
004024A5   .8378 F8 2C    cmp      ...

不是BUG,是打破常规次序~~    嘘!;P


呵呵,不错!

KeyGenMe哦~~ 完成之后 加入精华!

ToT 发表于 2007-2-17 23:11:54

呵呵,其实只要把4027B0那句nop掉就不会有bug了....
注册机有点懒得写了,呵呵....这个精华留给别人吧

不懂算法 发表于 2007-3-1 17:52:32

飘过,丢个注册机
;
;不懂算法的keygen模版,欢迎随便修改
;
.386
.model flat,stdcall
option casemap:none

include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
include \masm32\include\comctl32.inc

includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\comctl32.lib

dlgproc proto :DWORD,:DWORD,:DWORD,:DWORD

.const

.data
szName        db        020h dup (0)
szSerial db        "PYG-k888h888?888w888888888888888888888888888",0
szErr        db        "错误",0
szErr1        db        "名字长度必须大于5",0

.data?
hInstance dd ?

.code
start:
invoke GetModuleHandle,NULL
mov hInstance,eax
invoke DialogBoxParam,eax,101,NULL,offset dlgproc,0
invoke ExitProcess,NULL

dlgproc proc hWnd:DWORD,wMsg:DWORD,wParam:DWORD,lParam:DWORD
moveax,wMsg
.ifeax == WM_CLOSE
        invokeEndDialog,hWnd,NULL
.elseifeax == WM_INITDIALOG
        invoke LoadIcon,hInstance,1
        invoke SendMessage,hWnd,WM_SETICON,0,eax
.elseifeax == WM_COMMAND
        moveax,wParam
        .ifeax == 1002
                invokeGetDlgItemText,hWnd,1000,addr szName,11h
                .if eax<6
                        invoke MessageBox,NULL,addr szErr1,addr szErr,MB_OK
                        mov eax,FALSE
                        ret
                .endif

                mov al,byte ptr ds:
                mov byte ptr ds:,al
                mov al,byte ptr ds:
                mov byte ptr ds:,al
                mov al,byte ptr ds:
                mov byte ptr ds:,al

                invoke SetDlgItemText,hWnd,1001,addr szSerial

        .endif
.else
        moveax,FALSE
        ret
.endif      
moveax,TRUE
ret
dlgproc endp

end start

Nisy 发表于 2007-3-26 20:27:27

原帖由 ToT 于 2007-2-17 23:11 发表 https://www.chinapyg.com/images/common/back.gif
呵呵,其实只要把4027B0那句nop掉就不会有bug了....
注册机有点懒得写了,呵呵....这个精华留给别人吧


这个就是PY所说的陷阱 /:017 不是BUG~~

jrstar 发表于 2007-3-30 13:15:47

可惜我不会算法学习中
页: [1]
查看完整版本: 飘云老大的Keygenme2007_B简单分析