• 标 题:3Dmark2003算法研究 (14千字)
  • 作 者:火翼[CCG]
  • 时 间:2003-2-13 2:45:42
  • 链 接:http://bbs.pediy.com

标题:3Dmark2003注册号的算法研究
软件:3Dmark 2003
版本:3.1.3.0
下载网站:www.mydrivers.com
破解者:  火翼[CCG]
组织 :    [CCG]  (China Cracking Group)
使用软件: OllyDbg+Ida430

昨天才出来的软件,官方下载地址没提供注册号(官方当然不会提供)。
用IDA反汇编,搜索"Incorrect registration code."在41D8CA找到对这个字符串的调用,向上可以在0041D81E找到关键判断
.text:0041D81E                call    sub_405190 //关键判断
.text:0041D823                add    esp, 4
.text:0041D826                test    al, al
.text:0041D828                lea    ecx, [ebp+var_6C]
.text:0041D82B                jz      loc_41D8CA
跟进去之后,代码如下
.text:00405190                push    0FFFFFFFFh
.text:00405192                push    offset loc_596D31
.text:00405197                mov    eax, large fs:0
.text:0040519D                push    eax
.text:0040519E                mov    large fs:0, esp
.text:004051A5                sub    esp, 40h
.text:004051A8                mov    eax, dword_611F00
.text:004051AD                xor    eax, [esp+4Ch]
.text:004051B1                push    ebx
.text:004051B2                push    ebp
.text:004051B3                push    esi
.text:004051B4                push    edi
.text:004051B5                mov    edi, [esp+5Ch+arg_0]
.text:004051B9                mov    ecx, edi
.text:004051BB                mov    [esp+5Ch+var_10], eax
.text:004051BF                call    ?size@?
              $basic_string@DU?$char_traits@D@std@@V?
              $allocator@D@2@@std@@QBEIXZ //MFC字符串类的方法
                                          //得到字符串长度
.text:004051C5                cmp    eax, 17h
                                          //看输入的是否是23
                                          //个字符
.text:004051C8                jnz    loc_40540C
.text:004051CE                push    5
.text:004051D0                mov    ecx, edi
.text:004051D2                call    ??A?$basic_string@DU?
                          $char_traits@D@std@@V?$allocator@D
                          @2@@std@@QBEABDI@Z //取字符串的第6
                                              //个字符
.text:004051D8                cmp    byte ptr [eax], 2Dh
                                              //和"-"比较

以下还有两处,判断第12位和第18位是不是"-"
.text:00405207                push    offset
            a5azuhNzcd6La83 ; "5AZUH-NZCD6-LA83C-RW5KS"
                                //黑名单
.text:0040520C                push    edi
.text:0040520D                call    ds:??8std@@YA_NABV?
                $basic_string@DU?$char_traits@D@std@@V?
                $allocator@D@2@@0@PBD@Z //字符串比较
.text:00405213                add    esp, 8
.text:00405216                test    al, al
.text:00405218                jnz    loc_40540C //相等就跳

现在开始时注册号的计算过程
一共分为3段
(1)把输入的字符串在字符表B2CD6FHJ1LN4RSTE3VWX8YZA0Q7MUK9P5
  中的位置写道内存中
  对应ZA5UH-NZCD6-LA83C-RW5KS
  在内存中的数字就是
  16 17 20 1C 06 - 
  0A 16 02 03 04 -
  09 17 14 10 02 -
  0C 12 20 1D 0D
每个数字占32位,“-“用ffffffff代表
代码如下
.text:0040521E                lea    ecx, [esp+30h]
.text:00405222                call    ds:??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@XZ ; std::basic_string<char,std::char_traits<char>,std::allocator<char>>::basic_string<char,std::char_traits<char>,std::allocator<char>>(void)
.text:00405228                lea    esi, [esp+30h]
.text:0040522C                mov    dword ptr [esp+58h], 0
.text:00405234                call    sub_404A20
.text:00405239                mov    ecx, edi
.text:0040523B                call    ds:?size@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBEIXZ ; std::basic_string<char,std::char_traits<char>,std::allocator<char>>::size(void)
.text:00405241                push    eax
.text:00405242                lea    ecx, [esp+5Ch+var_38]
.text:00405246                call    sub_405160
.text:0040524B                mov    ecx, edi
.text:0040524D                mov    byte ptr [esp+58h], 1
.text:00405252                xor    ebx, ebx
.text:00405254                call    ds:?size@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBEIXZ ; std::basic_string<char,std::char_traits<char>,std::allocator<char>>::size(void)
.text:0040525A                test    eax, eax
.text:0040525C                mov    esi, [esp+24h]
.text:00405260                jbe    short loc_405298
.text:00405262
.text:00405262 loc_405262:                            ; CODE XREF: sub_405190+106j
.text:00405262                push    ebx
.text:00405263                mov    ecx, edi
.text:00405265                call    ds:??A?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBEABDI@Z ; std::basic_string<char,std::char_traits<char>,std::allocator<char>>::operator[](uint)
.text:0040526B                movsx  eax, byte ptr [eax]
.text:0040526E                push    0
.text:00405270                push    eax
.text:00405271                lea    ecx, [esp+5Ch+var_24]
.text:00405275                call    ds:?find@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBEIDI@Z ; std::basic_string<char,std::char_traits<char>,std::allocator<char>>::find(char,uint)
.text:0040527B                mov    ecx, ds:?npos@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@2IB ; uint const std::basic_string<char,std::char_traits<char>,std::allocator<char>>::npos
.text:00405281                cmp    eax, [ecx]
.text:00405283                jnz    short loc_405288
.text:00405285                or      eax, 0FFFFFFFFh
.text:00405288
.text:00405288 loc_405288:                            ; CODE XREF: sub_405190+F3j
.text:00405288                mov    [esi+ebx*4], eax
.text:0040528B                mov    ecx, edi
.text:0040528D                inc    ebx
.text:0040528E                call    ds:?size@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBEIXZ ; std::basic_string<char,std::char_traits<char>,std::allocator<char>>::size(void)
.text:00405294                cmp    ebx, eax
.text:00405296                jb      short loc_405262
.text:00405298
.text:00405298 loc_405298:                            ;
(2)对内存中的编号进行运算得到正确的8个数
算法如下
前三个数是把前三段的头四个字符对应的编号相加再对21取余,
第4个数是把第5,11,17个字符的编号相加再对21取余,
第5个数是第11,17,19个字符的编号相加再对21取余,
第6个数是把第17,19,20个字符的编号相加再对21取余,
第7个数是把第19,20,21个字符的编号相加再对21取余,
第8个数是把第20,21,22个字符的编号相加再对21取余,

对应ZA5UH-NZCD6-LA83C-RW5KS
第一个
1  2  3  4       
16+17+20+1C=69 %21=06
第二个
9  8  10  7       
02+16+03+0A=25 %21=04
第三个
15 14 13 16         
14+17+09+10=44 %21=02
第四个
5  17 11       
06+02+04=0C %21=0C
第五个
17 11 19       
02+04+0C=12 %21=12
第六个
20 17 19       
12+02+0C=20 %21=20
第七个
19 20 21       
0C+12+20=3E %21=1D
第八个
22 20 21       
1D+12+20=4F %21=0D
CODE XREF: sub_405190+D0j
.text:00405298                lea    ecx, [esp+54h+var_24]
.text:0040529C                call    ds:?size@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBEIXZ ; std::basic_string<char,std::char_traits<char>,std::allocator<char>>::size(void)
.text:004052A2                mov    ebx, [esi+4]
.text:004052A5                mov    edi, [esi+0Ch]
.text:004052A8                mov    edx, [esi]
.text:004052AA                mov    ecx, eax
.text:004052AC                mov    eax, [esi+8]
.text:004052AF                add    eax, ebx
.text:004052B1                add    eax, edi
.text:004052B3                add    eax, edx
.text:004052B5                xor    edx, edx
.text:004052B7                div    ecx
.text:004052B9                lea    ecx, [esp+4Ch+var_1C]
.text:004052BD                mov    edi, edx
.text:004052BF                call    ds:?size@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBEIXZ ; std::basic_string<char,std::char_traits<char>,std::allocator<char>>::size(void)
.text:004052C5                mov    ebp, [esi+20h]
.text:004052C8                mov    ebx, [esi+1Ch]
.text:004052CB                mov    edx, [esi+24h]
.text:004052CE                mov    ecx, eax
.text:004052D0                mov    eax, [esi+18h]
.text:004052D3                add    eax, ebp
.text:004052D5                add    eax, ebx
.text:004052D7                add    eax, edx
.text:004052D9                xor    edx, edx
.text:004052DB                div    ecx
.text:004052DD                lea    ecx, [esp+30h]
.text:004052E1                mov    ebx, edx
.text:004052E3                call    ds:?size@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBEIXZ ; std::basic_string<char,std::char_traits<char>,std::allocator<char>>::size(void)
.text:004052E9                mov    ebp, [esi+38h]
.text:004052EC                mov    edx, [esi+34h]
.text:004052EF                mov    ecx, eax
.text:004052F1                mov    eax, [esi+30h]
.text:004052F4                add    eax, ebp
.text:004052F6                mov    ebp, [esi+3Ch]
.text:004052F9                add    eax, edx
.text:004052FB                add    eax, ebp
.text:004052FD                xor    edx, edx
.text:004052FF                div    ecx
.text:00405301                lea    ecx, [esp+30h]
.text:00405305                mov    ebp, edx
.text:00405307                call    ds:?size@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBEIXZ ; std::basic_string<char,std::char_traits<char>,std::allocator<char>>::size(void)
.text:0040530D                mov    edx, [esi+40h]
.text:00405310                mov    ecx, eax
.text:00405312                mov    eax, [esi+10h]
.text:00405315                add    eax, edx
.text:00405317                add    eax, [esi+28h]
.text:0040531A                xor    edx, edx
.text:0040531C                div    ecx
.text:0040531E                lea    ecx, [esp+30h]
.text:00405322                mov    [esp+34h+var_24], edx
.text:00405326                call    ds:?size@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBEIXZ ; std::basic_string<char,std::char_traits<char>,std::allocator<char>>::size(void)
.text:0040532C                mov    edx, [esi+28h]
.text:0040532F                mov    ecx, eax
.text:00405331                mov    eax, [esi+40h]
.text:00405334                add    eax, edx
.text:00405336                add    eax, [esi+48h]
.text:00405339                xor    edx, edx
.text:0040533B                div    ecx
.text:0040533D                lea    ecx, [esp+2Ch+arg_0]
.text:00405341                mov    [esp+2Ch+var_18], edx
.text:00405345                call    ds:?size@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBEIXZ ; std::basic_string<char,std::char_traits<char>,std::allocator<char>>::size(void)
.text:0040534B                mov    edx, [esi+4Ch]
.text:0040534E                mov    ecx, eax
.text:00405350                mov    eax, [esi+40h]
.text:00405353                add    eax, edx
.text:00405355                add    eax, [esi+48h]
.text:00405358                xor    edx, edx
.text:0040535A                div    ecx
.text:0040535C                lea    ecx, [esp+30h]
.text:00405360                mov    [esp+18h], edx
.text:00405364                call    ds:?size@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBEIXZ ; std::basic_string<char,std::char_traits<char>,std::allocator<char>>::size(void)
.text:0040536A                mov    edx, [esi+48h]
.text:0040536D                mov    ecx, eax
.text:0040536F                mov    eax, [esi+4Ch]
.text:00405372                add    eax, edx
.text:00405374                add    eax, [esi+50h]
.text:00405377                xor    edx, edx
.text:00405379                div    ecx
.text:0040537B                lea    ecx, [esp+30h]
.text:0040537F                mov    [esp+1Ch], edx
.text:00405383                call    ds:?size@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBEIXZ ; std::basic_string<char,std::char_traits<char>,std::allocator<char>>::size(void)
.text:00405389                mov    edx, [esi+54h]
.text:0040538C                mov    ecx, eax
.text:0040538E                mov    eax, [esi+4Ch]
.text:00405391                add    eax, edx
.text:00405393                add    eax, [esi+50h]
.text:00405396                xor    edx, edx
.text:00405398                div    ecx
(3)把这八个数和输入注册号的对应位编号比较
第一个 5位
第二个 11位
第三位 17位
第四个 19位
第五个 20位
第六个 21位
第七个 22位
第八个 23位
代码如下
.text:0040539A                cmp    [esi+10h], edi //1
.text:0040539D                jnz    short loc_4053F1
.text:0040539F                cmp    [esi+28h], ebx//2
.text:004053A2                jnz    short loc_4053F1
.text:004053A4                cmp    [esi+40h], ebp//3
.text:004053A7                jnz    short loc_4053F1
.text:004053A9                mov    eax, [esp+10h]
.text:004053AD                cmp    [esi+48h], eax//4
.text:004053B0                jnz    short loc_4053F1
.text:004053B2                mov    ecx, [esp+14h]
.text:004053B6                cmp    [esi+4Ch], ecx//5
.text:004053B9                jnz    short loc_4053F1
.text:004053BB                mov    eax, [esp+14h+arg_0]
.text:004053BF                cmp    [esi+50h], eax//6
.text:004053C2                jnz    short loc_4053F1
.text:004053C4                mov    ecx, [esp+1Ch]
.text:004053C8                cmp    [esi+54h], ecx//7
.text:004053CB                jnz    short loc_4053F1
.text:004053CD                cmp    [esi+58h], edx//8
.text:004053D0                jnz    short loc_4053F1
.text:004053D2                lea    ecx, [esp+20h]
总结
注册号生成算法如下
先在字符串B2CD6FHJ1LN4RSTE3VWX8YZA0Q7MUK9P5中任取12位
组成XXXXa-XXXXb-XXXXc-defgh形的字串,X为任取的字符,
a,b,c位对应的前面4个字符在字符串B2CD6FHJ1LN4RSTE3VWX8YZA0Q7MUK9P5中的位置编号(16进制)相加再对21(16进制)取余得到数字对应位置的字符,d为a,b,c位置编号相加再对21取余得到数字对应位置的字符,e为b,c,d位置编号相加再对21取余得到数字对应位置的字符,f为c,d,e位置编号相加再对21取余得到数字对应位置的字符,g为d,e,f位置编号相加再对21取余得到数字对应位置的字符,h为e,f,g位置编号相加再对21取余得到数字对应位置的字符。


标 题:3dmark2003注册机源码

  • 作 者:火翼[CCG]
  • 时 间:03-2-16 0:49:18
  • 链 接:http://bbs.pediy.com
  • 源码下载

    .386
    .model flat,stdcall
    option casemap:none
    include windows.inc
    include gdi32.inc
    includelib gdi32.lib
    include user32.inc
    includelib user32.lib
    include kernel32.inc
    includelib kernel32.lib
    include masm32.inc
    includelib masm32.lib
    .data
    szCoder db 'Code By Firewings[CCG] Org:China Crack Group',0
    a db 26 dup(0)
    b db 26 dup(0)
    count db 0
    num db 0
    num1 db 0
    szButton db 'button',0
    szButtonText db 'Generate',0
    szButtonText1 db 'Copy',0
    szButtonText2 db 'Exit',0
    sztext db 'Hello World!',0
    hInstance dd ?
    hWinMain dd ?
    hGA dd ?
    hIcon dd ?
    hDcBack dd ?
    base dd 33
    hBmp dd ?
    ORISTR db 'B2CD6FHJ1LN4RSTE3VWX8YZA0Q7MUK9P5',0
    .const
    szClassName db 'FWClass',0
    szCaptionMain db 'KeyGen of 3Dmark 2003 Build 3.1.3.0',0
    szText db 'Hello, I',39,'m Firewings!',0
    .code

    Paint_Proc proc hWin:DWORD, hDC:DWORD

    LOCAL hOld:DWORD
    LOCAL memDC :DWORD

    invoke CreateCompatibleDC,hDC
    mov memDC, eax

    invoke SelectObject,memDC,hBmp
    mov hOld, eax

    invoke BitBlt,hDC,120,10,150,56,memDC,0,0,SRCCOPY
    ;invoke BitBlt,hDc,90,71,150,56,hBmp,0,0,SRCCOPY

    invoke SelectObject,hDC,hOld
    invoke DeleteDC,memDC
    mov eax,0
    ret
    Paint_Proc endp

    _ProcWinMain proc uses ebx edi esi,hWnd,uMsg,wParam,lParam
    local @stPs:PAINTSTRUCT
    local @stRect:RECT
    local @hdc1
    local @hDc
    local @hBmpBack
    local @hDc2
    mov eax,uMsg

    .if eax==WM_PAINT
    invoke BeginPaint,hWnd,addr @stPs
    mov @hDc,eax
    invoke GetClientRect,hWnd,addr @stRect
    invoke FillRect,@hDc,addr @stRect,COLOR_BTNFACE+1
    invoke EndPaint,hWnd,addr @stPs
    invoke GetDC,hWnd
    mov @hDc,eax
    invoke Paint_Proc,hWnd,@hDc
    mov @stRect.left,90
    mov @stRect.top,71
    mov @stRect.right,310
    mov @stRect.bottom,91
    invoke FillRect,@hDc,addr @stRect,COLOR_BTNFACE+1
    invoke SetBkMode,@hDc,TRANSPARENT
    invoke DrawText,@hDc,addr a,-1,addr @stRect,DT_CENTER or DT_VCENTER or DT_SINGLELINE
    mov @stRect.left,3
    mov @stRect.top,92
    mov @stRect.right,380
    mov @stRect.bottom,112
    invoke SetBkMode,@hDc,TRANSPARENT
    invoke DrawText,@hDc,addr szCoder,-1,addr @stRect,DT_VCENTER or DT_SINGLELINE
    invoke ReleaseDC,hWnd,@hDc
    .elseif eax==WM_CLOSE
    invoke DestroyWindow,hWinMain
    invoke PostQuitMessage,NULL
    .elseif eax==WM_COMMAND
    mov eax,wParam
    movzx eax,ax
    .if eax==1
    call _KeyGen
    invoke SendMessage ,hWnd,WM_PAINT,NULL,NULL
    .elseif eax==2
    invoke GlobalAlloc,GMEM_MOVEABLE,30
    mov hGA,eax
    invoke GlobalLock,hGA
    .if eax==0
    .else
    mov edi,eax
    mov esi,offset a
    mov ecx,25
    rep movsb
    invoke GlobalUnlock,hGA
    call _CopyData
    .endif
    .elseif eax==3
    invoke DestroyWindow,hWinMain
    invoke PostQuitMessage,NULL
    .else
    jmp loc4
    .endif
    .else
    loc4: invoke DefWindowProc,hWnd,uMsg,wParam,lParam
    ret
    .endif
    ;********************************************************************
    xor eax,eax
    ret

    _ProcWinMain endp

    _WinMain proc
    local @stWndClass:WNDCLASSEX
    local @stMsg:MSG
    invoke GetModuleHandle,NULL
    mov hInstance,eax
    invoke RtlZeroMemory,addr @stWndClass,sizeof @stWndClass
    invoke LoadBitmap,hInstance,5678
    mov hBmp, eax
    invoke LoadIcon,hInstance,1234
    mov @stWndClass.hIcon,eax
    mov hIcon,eax
    invoke LoadCursor,0,IDC_ARROW
    mov @stWndClass.hCursor,eax
    push hInstance
    pop @stWndClass.hInstance
    mov @stWndClass.cbSize,sizeof WNDCLASSEX
    mov @stWndClass.style,CS_HREDRAW or CS_VREDRAW
    mov @stWndClass.lpfnWndProc,offset _ProcWinMain
    mov @stWndClass.hbrBackground,COLOR_BTNFACE+1
    mov @stWndClass.lpszClassName,offset szClassName
    invoke RegisterClassEx,addr @stWndClass
    invoke CreateWindowEx,WS_EX_CLIENTEDGE,offset szClassName,offset szCaptionMain,WS_OVERLAPPED or WS_SYSMENU,300,200,340,150,NULL,NULL,hInstance,NULL
    mov hWinMain,eax
    invoke CreateWindowEx,NULL,offset szButton,offset szButtonText,WS_CHILD or WS_VISIBLE,10,10,70,22,hWinMain,1,hInstance,NULL
    invoke CreateWindowEx,NULL,offset szButton,offset szButtonText1,WS_CHILD or WS_VISIBLE,10,40,70,22,hWinMain,2,hInstance,NULL
    invoke CreateWindowEx,NULL,offset szButton,offset szButtonText2,WS_CHILD or WS_VISIBLE,10,70,70,22,hWinMain,3,hInstance,NULL
    invoke ShowWindow,hWinMain,SW_SHOWNORMAL
    call _KeyGen
    invoke UpdateWindow,hWinMain
    .While TRUE
    invoke GetMessage,addr @stMsg,NULL,0,0
    .break .if eax==0
    invoke TranslateMessage,addr @stMsg
    invoke DispatchMessage,addr @stMsg
    .endw
    ret
    _WinMain endp

    _KeyGen proc uses ebx edi esi
    invoke GetTickCount
    invoke nseed,eax
    mov count,0
    lea ebx,a
    loc1:
    mov eax,1
    add al,count
    xor edx,edx
    mov ecx,6
    div ecx
    cmp edx,0
    jz loc2
    invoke nrandom,base
    lea edx,ORISTR
    mov num,al
    add edx,eax
    mov al,[edx]
    jmp loc3
    loc2: mov al,2dh
    mov num,-1
    loc3: xor ecx,ecx
    mov cl,count
    lea ebx,a
    mov [ebx+ecx],al
    mov al,num
    lea ebx,b
    mov [ebx+ecx],al
    add count,1
    cmp count,18
    jnz loc1
    lea esi,a
    lea edi,b
    xor eax,eax
    xor ecx,ecx
    xor ebx,ebx
    loc7: push ecx
    xor edx,edx
    mov count,0
    mov num,0
    mov al,6
    mul cl
    mov num1,al
    loc8: movzx bx,count
    xor ecx,ecx
    push eax
    add ax,bx
    mov al,[edi+eax]
    add num,al
    add count,1
    cmp count,4
    pop eax
    jnz loc8
    xor eax,eax
    xor edx,edx
    mov al,num
    mov ecx,33
    div ecx
    lea ebx,ORISTR
    add bx,dx
    mov bl,[ebx]
    xor ax,ax
    mov al,num1
    add al,4
    mov [esi+eax],bl
    mov [edi+eax],dl
    pop ecx
    inc ecx
    cmp ecx,3
    jnz loc7
    xor eax,eax
    xor edx,edx
    xor ebx,ebx
    mov ecx,33
    mov bl,[edi+4]
    add ax,bx
    mov bl,[edi+10]
    add ax,bx
    mov bl,[edi+16]
    add ax,bx
    div cx
    lea ebx,ORISTR
    add bx,dx
    mov bl,[ebx]
    mov [esi+18],bl
    mov [edi+18],dl
    xor eax,eax
    xor edx,edx
    mov ecx,33
    xor ebx,ebx
    mov bl,[edi+10]
    add ax,bx
    mov bl,[edi+16]
    add ax,bx
    mov bl,[edi+18]
    add ax,bx
    div cx
    lea ebx,ORISTR
    add bx,dx
    mov bl,[ebx]
    mov [esi+19],bl
    mov [edi+19],dl
    xor eax,eax
    xor edx,edx
    xor ebx,ebx
    mov ecx,33
    mov bl,[edi+16]
    add ax,bx
    mov bl,[edi+18]
    add ax,bx
    mov bl,[edi+19]
    add ax,bx
    div cx
    lea ebx,ORISTR
    add bx,dx
    mov bl,[ebx]
    mov [esi+20],bl
    mov [edi+20],dl
    xor eax,eax
    xor edx,edx
    xor ebx,ebx
    mov ecx,33
    mov bl,[edi+18]
    add ax,bx
    mov bl,[edi+19]
    add ax,bx
    mov bl,[edi+20]
    add ax,bx
    div cx
    lea ebx,ORISTR
    add bx,dx
    mov bl,[ebx]
    mov [esi+21],bl
    mov [edi+21],dl
    xor eax,eax
    xor edx,edx
    xor ebx,ebx
    mov ecx,33
    mov bl,[edi+19]
    add ax,bx
    mov bl,[edi+20]
    add ax,bx
    mov bl,[edi+21]
    add ax,bx
    div cx
    lea ebx,ORISTR
    add bx,dx
    mov bl,[ebx]
    mov [esi+22],bl
    mov [edi+22],dl
    invoke UpdateWindow,hWinMain
    ret
    _KeyGen endp

    _CopyData proc
    invoke OpenClipboard,hWinMain
    invoke EmptyClipboard
    invoke SetClipboardData,CF_TEXT,hGA
    invoke CloseClipboard
    ret
    _CopyData endp
    start:
    ;invoke MessageBox,NULL,offset a,offset szCap,MB_OK
    call _WinMain
    invoke ExitProcess,NULL
    end start