莱鸟破解入门之算法分析
 
                  日期:2005年8月23日   破解人:林海雪原
———————————————————————————————————————————
 
【软件名称】:Pascal Analyzer 3.0   
【软件大小】:3M
【下载地址】:http://www.peganza.com/download.htm    pal 3.0.2 下载
【软件简介】:近日到上面网站看了下,东东升了,3.2了.
【软件限制】:
【破解声明】:初学Crack,只是感兴趣,没有其它目的。失误之处敬请诸位大侠赐教!
【破解工具】:windows2003,flyodbg,peid

———————————————————————————————————————————
 
【破解过程】:
   
    为不负各位大虾的厚爱,近日恶补汇编,以期看明让我晕头转向的算法,几位同事大呼--不错不错,小子学E文了。学的心痒,从硬盘的角

落找到一个东东,装起一看,是PAL语言分析器(是前些时日想学DELPHI时下的),用peid查了一下,嘿嘿,竟然无壳----你不下地狱谁下地

狱?拿起利器OD,向它猛攻一气,结果,几小时下来,我又不知东西南北了。只好再次恶补汇编----我不下地狱谁下地狱?~~~~~.......当再

次操刀时,只觉OD锋利了不少......感谢OD的作者,感谢前辈们对OD的改造........感谢上帝给我好运....感谢各位观赏与支持!

    闲话多了,现贴出详细过程,与莱鸟们共同研究,一起进步:

   试注册(名:scxtb;公司:www.pediy.com请看雪大哥原谅,莱鸟无门无派,借个名号;key:7878),有出错提示:wrong key(7878).于是,方法有二

:1,找wrong key;2,下断 messagebox;

1,找wrong key:失败!
2,下断:bp messageboxA,中断后ctrl+F9返回:

004B63A3   |.  50        push eax                              ; |Text
004B63A4   |.  53        push ebx                              ; |hOwner
004B63A5   |.  E8 5E37F5>call <jmp.&user32.MessageBoxA>        ; \MessageBoxA
004B63AA   |.  5F        pop edi                               ;  0006E83C     <<<-----返回到这!
004B63AB   |.  5E        pop esi

   <<<<<<<<<<<<<<<<<<<我在上一破文中说到的东东这里从简.>>>>>>>>>>>>>>>>>>>>>>
向上一看,没有cmp,也没了jmp,要返回到上一层才行.点这个call的第一句(004B6384处),提示有7处调用,看堆栈我们从哪来?

004B6384   /$  55        push ebp      <<<-----多处call
004B6385   |.  8BEC      mov ebp,esp
004B6387   |.  53        push ebx

7处调用:
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
Local Calls from 004B893B, 004B898F, 004B8A36, 0061F114, 0063267A, 00637D53, 00637D94
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
                                         
看堆栈中有:                              
\\\\\\\\\\\\\\\\\\堆栈中有\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
......
0006E674   004B8A3B   返回到 PAL.004B8A3B 来自 PAL.004B6384
......
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

调用与返回最近的是004B8A36,所以ctrl+G,输入004B8A36,到这:

004B8A06   |.  8B55 D0       mov edx,dword ptr ss:[ebp-30]            ; |
004B8A09   |.  8D83 1C030000 lea eax,dword ptr ds:[ebx+31C]           ; |
004B8A0F   |.  59            pop ecx                                  ; |
004B8A10   |.  E8 A3F8FFFF   call PAL.004B82B8                        ; \PAL.004B82B8  <<<----关键1!
004B8A15   |.  84C0          test al,al
004B8A17   |.  74 09         je short PAL.004B8A22                    ;1.这里跳楼!要是这不跳就好了
004B8A19   |.  C683 2C030000>mov byte ptr ds:[ebx+32C],1
004B8A20   |.  EB 21         jmp short PAL.004B8A43                   ;2.这里不会跳楼的
004B8A22   |>  68 10200100   push 12010
004B8A27   |.  8BC3          mov eax,ebx
004B8A29   |.  E8 9EB8FBFF   call PAL.004742CC
004B8A2E   |.  B9 E48A4B00   mov ecx,PAL.004B8AE4                     ; |ASCII "Error"
004B8A33   |.  8B55 FC       mov edx,dword ptr ss:[ebp-4]             ; |
004B8A36   |.  E8 49D9FFFF   call PAL.004B6384                        ; \PAL.004B6384
004B8A3B   |.  33C0          xor eax,eax                              ;它要回这,所以必跳过上面的call才行!
004B8A3D   |.  8983 4C020000 mov dword ptr ds:[ebx+24C],eax
004B8A43   |>  33C0          xor eax,eax
004B8A45   |.  5A            pop edx
004B8A46   |.  59            pop ecx
004B8A47   |.  59            pop ecx

显然,004B8A10处是关键的call,它的返回值AL决定是否跳楼,我们进去看看:

004B82B8   /$  55             push ebp
004B82B9   |.  8BEC           mov ebp,esp
004B82BB   |.  83C4 F8        add esp,-8
004B82BE   |.  53             push ebx
004B82BF   |.  56             push esi
004B82C0   |.  57             push edi
004B82C1   |.  8BF1           mov esi,ecx
004B82C3   |.  8BDA           mov ebx,edx
004B82C5   |.  8945 FC        mov [local.1],eax
004B82C8   |.  8B7D 14        mov edi,[arg.4]
004B82CB   |.  C645 FB 00     mov byte ptr ss:[ebp-5],0             ;<<-----1
004B82CF   |.  B8 80616400    mov eax,PAL.00646180
004B82D4   |.  8BD3           mov edx,ebx
004B82D6   |.  E8 1DD2F4FF    call PAL.004054F8
004B82DB   |.  B8 84616400    mov eax,PAL.00646184
004B82E0   |.  8BD6           mov edx,esi
004B82E2   |.  E8 11D2F4FF    call PAL.004054F8
004B82E7   |.  B8 88616400    mov eax,PAL.00646188
004B82EC   |.  8BD7           mov edx,edi
004B82EE   |.  E8 05D2F4FF    call PAL.004054F8
004B82F3   |.  8B45 0C        mov eax,[arg.2]
004B82F6   |.  50             push eax
004B82F7   |.  8B45 08        mov eax,[arg.1]
004B82FA   |.  50             push eax
004B82FB   |.  8B45 FC        mov eax,[local.1]
004B82FE   |.  8B4D 10        mov ecx,[arg.3]
004B8301   |.  33D2           xor edx,edx
004B8303   |.  E8 C0F9FFFF    call PAL.004B7CC8                    ;<<-----关键2!
004B8308   |.  84C0           test al,al
004B830A   |.  74 17          je short PAL.004B8323
004B830C   |.  C645 FB 01     mov byte ptr ss:[ebp-5],1            ;<<-----2
004B8310   |.  8B45 10        mov eax,[arg.3]
004B8313   |.  50             push eax
004B8314   |.  8B45 0C        mov eax,[arg.2]
004B8317   |.  50             push eax
004B8318   |.  8BCF           mov ecx,edi
004B831A   |.  8BD6           mov edx,esi
004B831C   |.  8BC3           mov eax,ebx
004B831E   |.  E8 E5FDFFFF    call PAL.004B8108
004B8323   |>  8A45 FB        mov al,byte ptr ss:[ebp-5]          ;<<-----3
004B8326   |.  5F             pop edi
004B8327   |.  5E             pop esi
004B8328   |.  5B             pop ebx
004B8329   |.  59             pop ecx
004B832A   |.  59             pop ecx
004B832B   |.  5D             pop ebp
004B832C   \.  C2 1000        retn 10

纵观这个call(1),我找到另一个关键call(关键2),因为它的值决定了(关键1)的返回结果,还得进入.我看不出什么苗头,只好一路F8,逢崖跳崖,

摸黑到这时眼前一亮,真是柳暗花明又一村:

004B7EF4    .  E8 8FD0FEFF    call PAL.004A4F88               ;  关键3!
004B7EF9    .  85C0           test eax,eax
004B7EFB    .  74 33          je short PAL.004B7F30
004B7EFD    .  8D55 90        lea edx,dword ptr ss:[ebp-70]
004B7F00    .  B8 F07F4B00    mov eax,PAL.004B7FF0
004B7F05    .  E8 0A010000    call PAL.004B8014
004B7F0A    .  FF75 90        push dword ptr ss:[ebp-70]      ;  停在这!
004B7F0D    .  68 04804B00    push PAL.004B8004               ;  ASCII " ("

\\\\\\\\\\\\\004B7F0A处\\\\\\\\\\\\\\\\\\\\\\\\\\\
堆栈 ss:[0006E5D0]=01EEE5D8, (ASCII "Wrong key")
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

我操刀就找wrong key却失败!这里自己跑了出来!停住分析一下,就知004B7EF4是关键call,进入有如下代码:

004A4F88   /$  57                push edi
004A4F89   |.  56                push esi
004A4F8A   |.  89C6              mov esi,eax
004A4F8C   |.  89D7              mov edi,edx
004A4F8E   |.  31C0              xor eax,eax
004A4F90   |.  09C9              or ecx,ecx
004A4F92   |.  74 0A             je short PAL.004A4F9E
004A4F94   |.  F3:A6             repe cmps byte ptr es:[edi],byte ptr ds:[esi] <<<---------明码比较(跟了n 次后知道的)!
004A4F96   |.  74 06             je short PAL.004A4F9E
004A4F98   |.  40                inc eax
004A4F99   |.  77 03             ja short PAL.004A4F9E
004A4F9B   |.  83C8 FF           or eax,FFFFFFFF
004A4F9E   |>  5E                pop esi
004A4F9F   |.  5F                pop edi
004A4FA0   \.  C3                retn

   这里面没有call,也跳不出去,仔细看看,仅有004A4F94处可疑(我在这上当不小,不知跟了多少次,竟然.....总之,莱!),看看这时的内存:

\\\\\\\\\\\\\**004A4F94处**\\\\\\\\\\\\\\\\\\
ecx=00000008 (十进制 8.)
ds:[esi]=stack [0006E62B]=00
es:[edi]=stack [0006E633]=AC
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

   显然是以ecx作计数器共8次循环,这是第一次cmp,"00"与"AC"是什么与什么在比?加密后的注册码与假码比较是最大嫌疑犯!在数据段内

ctrl+G,到 0006E62B, 请看下面数据区:

\\\\\\\\\\\\\\\\\\\ 004A4F94处数据区 \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
0006E62B  00 00 00 00 00 00 00 00 AC 88 89 D3 9A D9 71 48  ........瑘売氋qH
0006E63B  01 7C 86 20 01 64 E6 06 00 08 83 4B 00 BC E6 06  |?d?.僈.兼
0006E64B  00 48 1D 06 01 3C E8 06 00 F0 44 46 00 60 83 20  .H<?.餌F.`?
0006E65B  01 F0 44 46 00 7C 86 20 01 C0 E6 06 00 15 8A 4B  餌F.|?梨.奒
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

   我之所以上当,是这里没有数据.就算是非明码比较,我的假码也应被变个样放在这吧?够狠的!忘了是哪位大虾说过,做crack是要好运的,n次

后,上帝给了我好运(所以要感谢上帝),我想这样子不正是"AC8889D39AD97148"与"0000000000000000"比较么?把key换成"AC8889D39AD97148"一

试,把我高兴的那样了......同一段数据区比较下:

把key换成"AC8889D39AD97148"之后:  同上面的比较下.
\\\\\\\\\\\\\\\\\ 004A4F94处数据区  \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
0006E62B  AC 88 89 D3 9A D9 71 48 AC 88 89 D3 9A D9 71 48  瑘売氋qH瑘売氋qH
0006E63B  01 7C 86 20 01 64 E6 06 00 08 83 4B 00 BC E6 06  |?d?.僈.兼
0006E64B  00 48 1D 06 01 3C E8 06 00 F0 44 46 00 60 83 20  .H<?.餌F.`?
0006E65B  01 F0 44 46 00 7C 86 20 01 C0 E6 06 00 15 8A 4B  餌F.|?梨.奒
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

注册成功之后,我失去了继续分析算法的机会,只好卸下重来.如果作者把真码加密后再比较,我可能现在也没有结果!

我的注册信息:
name:scxtb
C.O.:www.pediy.com
key :AC8889D39AD97148


【算法分析】:

  
  由写0006E62B至0006E63C两处内存代码(用F8过call,看看哪写内存),跟到如下代码:
     

004B7EC9    .  8B55 9C           mov edx,dword ptr ss:[ebp-64]
004B7ECC    .  8D4D F3           lea ecx,dword ptr ss:[ebp-D]
004B7ECF    .  8D45 D4           lea eax,dword ptr ss:[ebp-2C]
004B7ED2    .  E8 71C5FDFF       call PAL.00494448                    <<<--------这里写0006e633!                    
004B7ED7    .  8D55 EB           lea edx,dword ptr ss:[ebp-15]
004B7EDA    .  B9 08000000       mov ecx,8
004B7EDF    .  A1 88616400       mov eax,dword ptr ds:[646188]
004B7EE4    .  E8 AF98FDFF       call PAL.00491798                    <<<--------这里写0006e62B!


call PAL.00494448:

0049437E   |.  8B4424 04         mov eax,dword ptr ss:[esp+4]
00494382   |.  8B5424 10         mov edx,dword ptr ss:[esp+10]
00494386   |.  8910              mov dword ptr ds:[eax],edx             <<<--------这里写0006e633!
00494388   |.  8B4424 04         mov eax,dword ptr ss:[esp+4]
0049438C   |.  8B5424 0C         mov edx,dword ptr ss:[esp+C]
00494390   |.  8950 04           mov dword ptr ds:[eax+4],edx           <<<--------这里写0006e637!
00494393   |.  83C4 18           add esp,18

...........
0049448C   |.  8BD8              mov ebx,eax
0049448E   |.  83FB 01           cmp ebx,1
00494491   |.  7C 1F             jl short PAL.004944B2
00494493   |>  8B45 FC           /mov eax,[local.1]                          ;EAX=SCXTB;WWW.PEDIY.COM
00494496   |.  8A4418 FF         |mov al,byte ptr ds:[eax+ebx-1]             ;从最后一位开始卓位传al;
0049449A   |.  3C 7F             |cmp al,7F                                  ;al>127?
0049449C   |.  76 0F             |jbe short PAL.004944AD
0049449E   |.  8D45 FC           |lea eax,[local.1]
004944A1   |.  B9 01000000       |mov ecx,1
004944A6   |.  8BD3              |mov edx,ebx
004944A8   |.  E8 5715F7FF       |call PAL.00405A04
004944AD   |>  4B                |dec ebx
004944AE   |.  85DB              |test ebx,ebx
004944B0   |.^ 75 E1             \jnz short PAL.00494493
004944B2   |>  8D55 F8           lea edx,[local.2]
004944B5   |.  8B45 FC           mov eax,[local.1]
004944B8   |.  E8 939EF7FF       call PAL.0040E350                           ;转为大写,用';'连接
004944BD   |.  8B45 F8           mov eax,[local.2]                           ;eax=SCXTB;WWW.PEDIY.COM
004944C0   |.  E8 0FFFFFFF       call PAL.004943D4                           ;关键,加密字串
004944C5   |.  8946 04           mov dword ptr ds:[esi+4],eax                ;转换后(加密)的串送[0006e65f]
004944C8   |.  8BD6              mov edx,esi                                 ;edx=d9f6 这个值不变?    
004944CA   |.  8BC7              mov eax,edi                                 ;eax=E11C1456这个值也不变?
004944CC   |.  B1 01             mov cl,1                                    ;
004944CE   |.  E8 D9FDFFFF       call PAL.004942AC                           ;关键,用加密的字串计算真码
004944D3   |.  33C0              xor eax,eax
004944D5   |.  5A                pop edx
............

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
\   注册码算法:
\  1.用";"连接用户名和公司名:a=用户名+;+公司名;
\  2.转换为大写             :A=f(a);
\  3.加密A                  :B=f(A);
\  4.由B计算注册码C         :C=f(B,d9f6,E11C1456,1);
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

call PAL.00491798:

0049185E   |.  8D55 F0       |lea edx,dword ptr ss:[ebp-10]
00491861   |.  E8 EE24F7FF   |call PAL.00403D54
00491866   |.  8807          |mov byte ptr ds:[edi],al                  <<<---------写0006e62B!
00491868   |.  837D F0 00    |cmp dword ptr ss:[ebp-10],0
0049186C   |.  75 09         |jnz short PAL.00491877


call PAL.00491798的入口参数:

...........
004B7ED7    .  8D55 EB           lea edx,dword ptr ss:[ebp-15]
004B7EDA    .  B9 08000000       mov ecx,8                                   ;假码要8个字,也就是注册码要16个字符
004B7EDF    .  A1 88616400       mov eax,dword ptr ds:[646188]               ;
004B7EE4    .  E8 AF98FDFF       call PAL.00491798                           ;检查假码
004B7EE9    .  8D55 F3           lea edx,dword ptr ss:[ebp-D]

********************************************************************
   在004B7EE4处的call中,可以看出假码要8个字,也就是注册码要16个字符,如果假码少于16位会出错(不写内存0006E62B处),但没有任何提示

,而且不与假码比较,只同0比较,如果假码有16位,内存中才会有真码与假码的比较.

004A4F94   |.  F3:A6             repe cmps byte ptr es:[edi],byte ptr ds:[esi] <<<---------明码比较!

   作者在其它处的保护还是较好的,但在这却使用明码比较,让我等莱鸟也能破了它,真是不幸!
********************************************************************


加密字串的算法(3.加密A 
 call PAL.0049439C:

0049439C   /$  53               push ebx
0049439D   |.  56               push esi
0049439E   |.  33C9             xor ecx,ecx                 ;ecx中将保存计算结果,清0
004943A0   |.  8BDA             mov ebx,edx
004943A2   |.  4B               dec ebx
004943A3   |.  85DB             test ebx,ebx
004943A5   |.  7C 25            jl short PAL.004943CC       ;如果未输入用户名和注册码,跳!
004943A7   |.  43               inc ebx                     ;计数器+1
004943A8   |>  C1E1 04          /shl ecx,4                  ;上次计算结果左移4位 (*2^4=16?)   
004943AB   |.  33D2             |xor edx,edx                ;edx清0 ,edx是每次计算的临时结果  
004943AD   |.  8A10             |mov dl,byte ptr ds:[eax]   ;字串按位(从第一位开始)传dl
004943AF   |.  03CA             |add ecx,edx                ;本次取的字符与ecx相加
004943B1   |.  8BD1             |mov edx,ecx                ;
004943B3   |.  81E2 000000F0    |and edx,F0000000           ;把计算结果的低7个字节置0
004943B9   |.  85D2             |test edx,edx               ;
004943BB   |.  74 07            |je short PAL.004943C4      ;如果edx=0则直截取反,否则计算后取反
004943BD   |.  8BF2             |mov esi,edx                ;计算方法是:
004943BF   |.  C1EE 18          |shr esi,18                 ;先把结果右移18位(除2^24=16777216?)
004943C2   |.  33CE             |xor ecx,esi                ;再把右移前后的值作xor
004943C4   |>  F7D2             |not edx                    ;edx取反
004943C6   |.  23CA             |and ecx,edx                ;取反结果与xor结果作and
004943C8   |.  40               |inc eax                    ;指向下一位字符
004943C9   |.  4B               |dec ebx                    ;计数器减1 
004943CA   |.^ 75 DC            \jnz short PAL.004943A8     ;计算未完则循环
004943CC   |>  8BC1              mov eax,ecx                ;把结果放入eax中反回
004943CE   |.  5E                pop esi
004943CF   |.  5B                pop ebx                     
004943D0   \.  C3                retn


注册码算法(4.由B计算注册码C):
   call PAL.004942AC:

004942AC   /$  53                push ebx
004942AD   |.  56                push esi
004942AE   |.  57                push edi
004942AF   |.  83C4 E8           add esp,-18
004942B2   |.  884C24 08         mov byte ptr ss:[esp+8],cl              ;[006e590]=01
004942B6   |.  895424 04         mov dword ptr ss:[esp+4],edx            ;ss:[0006E58C]=0006E65B
004942BA   |.  890424            mov dword ptr ss:[esp],eax              ;ss:[esp]=0006E63C
004942BD   |.  8B4424 04         mov eax,dword ptr ss:[esp+4]            ;eax=0006E65B
004942C1   |.  8B00              mov eax,dword ptr ds:[eax]              ;eax=0000D9F6
004942C3   |.  894424 0C         mov dword ptr ss:[esp+C],eax            ;ss:[0006E594]=0000D9F6
004942C7   |.  8B4424 04         mov eax,dword ptr ss:[esp+4]            ;eax=0006E65B
004942CB   |.  8B40 04           mov eax,dword ptr ds:[eax+4]            ;eax=03AF96FD
004942CE   |.  894424 10         mov dword ptr ss:[esp+10],eax           ;ss:[0006E598]=03AF96FD
004942D2   |.  C74424 14 0400000>mov dword ptr ss:[esp+14],4             ;计数器,循环4次
004942DA   |.  BE 14B46300       mov esi,PAL.0063B414                    ;
004942DF   |>  8B5424 0C         /mov edx,dword ptr ss:[esp+C]           ;上次结果A,第一次为d9f6
004942E3   |.  33C0              |xor eax,eax                            ;
004942E5   |.  8A4424 08         |mov al,byte ptr ss:[esp+8]             ;al=01
004942E9   |.  8BD8              |mov ebx,eax                            ;
004942EB   |.  03DB              |add ebx,ebx                            ;
004942ED   |.  8D1C5B            |lea ebx,dword ptr ds:[ebx+ebx*2]       ;
004942F0   |.  8B04DE            |mov eax,dword ptr ds:[esi+ebx*8]       ;
004942F3   |.  8B0C24            |mov ecx,dword ptr ss:[esp]             ;
004942F6   |.  8B0C81            |mov ecx,dword ptr ds:[ecx+eax*4]       ;ecx=04D3661E
004942F9   |.  8B44DE 04         |mov eax,dword ptr ds:[esi+ebx*8+>      ;
004942FD   |.  8B3C24            |mov edi,dword ptr ss:[esp]             ;
00494300   |.  8B0487            |mov eax,dword ptr ds:[edi+eax*4]       ;eax=D705870F
00494303   |.  8B5CDE 08         |mov ebx,dword ptr ds:[esi+ebx*8+>      ;
00494307   |.  8B3C24            |mov edi,dword ptr ss:[esp]             ;
0049430A   |.  8B1C9F            |mov ebx,dword ptr ds:[edi+ebx*4]       ;ebx=E11C1456
0049430D   |.  03D3              |add edx,ebx                            ;两常数相加:A+D=E11CEE4C
0049430F   |.  03DA              |add ebx,edx                            ;A+D*2
00494311   |.  8BFA              |mov edi,edx                            ;edi=E11CEE4C
00494313   |.  C1EF 07           |shr edi,7                              ;(A+D)/(2^7)
00494316   |.  33D7              |xor edx,edi                            ;xor (A+D)
00494318   |.  03CA              |add ecx,edx                            ;+B
0049431A   |.  03D1              |add edx,ecx                            ;+[(A+D)/(2^7)xor (A+D)]
0049431C   |.  8BF9              |mov edi,ecx                            ;
0049431E   |.  C1E7 0D           |shl edi,0D                             ;*2^14
00494321   |.  33CF              |xor ecx,edi                            ;
00494323   |.  03C1              |add eax,ecx                            ;
00494325   |.  03C8              |add ecx,eax                            ;
00494327   |.  8BF8              |mov edi,eax                            ;
00494329   |.  C1EF 11           |shr edi,11                             ;........
0049432C   |.  33C7              |xor eax,edi                            ;
0049432E   |.  03D8              |add ebx,eax                            ;
00494330   |.  03C3              |add eax,ebx                            ;  
00494332   |.  8BFB              |mov edi,ebx                            ;
00494334   |.  C1E7 09           |shl edi,9                              ; 
00494337   |.  33DF              |xor ebx,edi                            ;
00494339   |.  03D3              |add edx,ebx                            ;........
0049433B   |.  03DA              |add ebx,edx                            ;
0049433D   |.  8BFA              |mov edi,edx                            ;
0049433F   |.  C1EF 03           |shr edi,3                              ;
00494342   |.  33D7              |xor edx,edi                            ;
00494344   |.  03CA              |add ecx,edx                            ;
00494346   |.  8BD1              |mov edx,ecx                            ;.........
00494348   |.  C1E2 07           |shl edx,7                              ;
0049434B   |.  33CA              |xor ecx,edx                            ;
0049434D   |.  03C1              |add eax,ecx                            ;
0049434F   |.  8BD3              |mov edx,ebx                            ;
00494351   |.  C1EA 0F           |shr edx,0F                             ;
00494354   |.  33C2              |xor eax,edx                            ;........
00494356   |.  03D8              |add ebx,eax                            ;
00494358   |.  8BC3              |mov eax,ebx                            ;
0049435A   |.  C1E0 0B           |shl eax,0B                             ;
0049435D   |.  33D8              |xor ebx,eax                            ;
0049435F   |.  8B4424 10         |mov eax,dword ptr ss:[esp+10]          ;
00494363   |.  33C3              |xor eax,ebx                            ;A={Q xor ...}
00494365   |.  8B5424 0C         |mov edx,dword ptr ss:[esp+C]           ;
00494369   |.  895424 10         |mov dword ptr ss:[esp+10],edx          ;
0049436D   |.  894424 0C         |mov dword ptr ss:[esp+C],eax           ;
00494371   |.  83C6 0C           |add esi,0C                             ;
00494374   |.  FF4C24 14         |dec dword ptr ss:[esp+14]              ;
00494378   |.^ 0F85 61FFFFFF     \jnz PAL.004942DF                       ;
0049437E   |.  8B4424 04         mov eax,dword ptr ss:[esp+4]
00494382   |.  8B5424 10         mov edx,dword ptr ss:[esp+10]
00494386   |.  8910              mov dword ptr ds:[eax],edx
00494388   |.  8B4424 04         mov eax,dword ptr ss:[esp+4]
0049438C   |.  8B5424 0C         mov edx,dword ptr ss:[esp+C]
00494390   |.  8950 04           mov dword ptr ds:[eax+4],edx
00494393   |.  83C4 18           add esp,18
00494396   |.  5F                pop edi
00494397   |.  5E                pop esi
00494398   |.  5B                pop ebx
00494399   \.  C3                retn

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

设:四个参加运算的常数和加密后字串如下:
   A=D6F9;(第二轮时A是第一轮的结果)
   B=04D36614;
   C=D705870F;
   D=E11C1456;
   Q=加密后字串;这就是第一轮计算的5个数.
得公式:
  A={Q xor............+A+D*2)))}}
原公式太复杂给个简单的:
0049430D   |.  03D3              |add edx,ebx                            ;两常数相加:A+D=E11CEE4C
0049430F   |.  03DA              |add ebx,edx                            ;A+D*2
00494311   |.  8BFA              |mov edi,edx                            ;edi=E11CEE4C
00494313   |.  C1EF 07           |shr edi,7                              ;
00494316   |.  33D7              |xor edx,edi                            ;f1(x)=((A+D)/2^7 xor (A+D))=E;
00494318   |.  03CA              |add ecx,edx                            ;E+B
0049431A   |.  03D1              |add edx,ecx                            ;B*2+E
0049431C   |.  8BF9              |mov edi,ecx                            ;
0049431E   |.  C1E7 0D           |shl edi,0D                             ;*2^13
00494321   |.  33CF              |xor ecx,edi                            ;f2(x)=((E+B)*2^13 xor (E+B))=F;
00494323   |.  03C1              |add eax,ecx                            ;F+C;
00494325   |.  03C8              |add ecx,eax                            ;F*2+C
00494327   |.  8BF8              |mov edi,eax                            ;
00494329   |.  C1EF 11           |shr edi,11                             ;
0049432C   |.  33C7              |xor eax,edi                            ;f3(x)=((F+C)/2^17 xor (F+C))=G;
0049432E   |.  03D8              |add ebx,eax                            ;(A+D*2)+G
00494330   |.  03C3              |add eax,ebx                            ;(A+D*2)+G*2  
00494332   |.  8BFB              |mov edi,ebx                            ;
00494334   |.  C1E7 09           |shl edi,9                              ; 
00494337   |.  33DF              |xor ebx,edi                            ;f4(x)=(((A+D*2)+G)*2^9 xor (A+D*2)+G))=H;
00494339   |.  03D3              |add edx,ebx                            ;(B*2+E)+H
0049433B   |.  03DA              |add ebx,edx                            ;(B*2+E)+H*2
0049433D   |.  8BFA              |mov edi,edx                            ;
0049433F   |.  C1EF 03           |shr edi,3                              ;
00494342   |.  33D7              |xor edx,edi                            ;f5(x)=.....
00494344   |.  03CA              |add ecx,edx                            ;
00494346   |.  8BD1              |mov edx,ecx                            ;.........
........

f1(x)=((A+D)/2^7 xor (A+D))=E;
f2(x)=((E+B)*2^13 xor (E+B))=F;
其实就是f1,f2的结果不停叠代而成.当然参数要变的.
 
第一轮计算的结果A=B6739DD0;


第二轮计算的5个数:
   A=B6739DD0;
   B=9C60408B;
   C=E11C1456;
   D=D705870F;
   Q=D9F6;
第二轮计算的结果A=AAB54D56;


第三轮计算的5个数:
   A=AAB54D56;
   B=D705870F;
   C=9C60408B;
   D=04D36614;
   Q=第一轮计算的结果;
第三轮计算的结果A=D38988AC;


第四轮计算的5个数:
   A=D38988AC;
   B=E11C1456;
   C=04D36614;
   D=9C60408B;
   Q=第二轮计算的结果;
第四轮计算的结果A=4871D99A;


第三、四轮计算的结果就是注册码。

scxtb
www.pediy.com
AC8889D39AD97148

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ 

  • 标 题: 答复
  • 作 者:yunchengch
  • 时 间:2005-08-23 23:04

看得我头晕...

   公式:
A={Q xor {(((((e/2^17 xor e)+A+D*2)+(((e/2^17 xor e)+A+D*2)*2^9 xor ((e/2^17 xor e)+A+D*2)))/2^15 xor ((((((((e/2^17 xor e)+A+D*2)*2^9 xor ((e/2^17 xor e)+A+D*2))/2^3 xor (((e/2^17 xor e)+A+D*2)*2^9 xor ((e/2^17 xor e)+A+D*2)))+(e*2+C))*2^7) xor (((((e/2^17 xor e)+A+D*2)*2^9 xor ((e/2^17 xor e)+A+D*2))/2^3 xor (((e/2^17 xor e)+A+D*2)*2^9 xor ((e/2^17 xor e)+A+D*2)))+(e*2+C)))+((e/2^17 xor e)+A+D*2)))+((e/2^17 xor e)+A+D*2)+(((e/2^17 xor e)+A+D*2)*2^9 xor ((e/2^17 xor e)+A+D*2)))*2^11 xor (((((e/2^17 xor e)+A+D*2)+(((e/2^17 xor e)+A+D*2)*2^9 xor ((e/2^17 xor e)+A+D*2)))/2^15 xor ((((((((e/2^17 xor e)+A+D*2)*2^9 xor ((e/2^17 xor e)+A+D*2))/2^3 xor (((e/2^17 xor e)+A+D*2)*2^9 xor ((e/2^17 xor e)+A+D*2)))+(e*2+C))*2^7) xor (((((e/2^17 xor e)+A+D*2)*2^9 xor ((e/2^17 xor e)+A+D*2))/2^3 xor (((e/2^17 xor e)+A+D*2)*2^9 xor ((e/2^17 xor e)+A+D*2)))+(e*2+C)))+((e/2^17 xor e)+A+D*2)))+((e/2^17 xor e)+A+D*2)+(((e/2^17 xor e)+A+D*2)*2^9 xor ((e/2^17 xor e)+A+D*2)))}}

其中:
e={(((((A+D)/2^7) xor (A+D))+B)*2^14) xor ((((A+D)/2^7) xor (A+D))+B)}

第一轮计算的结果A=B6739DD0;


第二轮计算的5个数:
A=B6739DD0;
B=9C60408B;
C=E11C1456;
D=D705870F;
第二轮计算的结果A=AAB54D56;


第三轮计算的5个数:
A=AAB54D56;
B=D705870F;
C=9C60408B;
D=04D36614;
第三轮计算的结果A=D38988AC;


第四轮计算的5个数:
A=D38988AC;
B=E11C1456;
C=04D36614;
D=9C60408B;
第四轮计算的结果A=4871D99A;


第三、四轮计算的结果就是注册码。

scxtb
www.pediy.com
AC8889D39AD97148

佩服楼主!!还得再学习!

  • 标 题: 答复
  • 作 者:林海雪原
  • 时 间:2005-08-24 09:04

我在写注册机有如下困难,请大侠们指点:

1.用keymark写内存注册机,只能取出8位注册码.应如何才能取出8个字(16位码)?

2.用delphi写的代码如下:

function Strjm(tr: string): int64;<<<------1
var
  i,h,g,j,k:integer;
begin
  h:=0;
  if Length(tr) = 1 then  Result := 0
   else
   begin
    for i := 1 to Length(tr) do
     begin
      h:=h shl 4;
      h:=h+ord(tr[i]);
      g:=h;
      k:=g and 4026531840;
        if k <> 0 then
         begin
           j:=k shr 24;  <<<-----2
           h:=h xor j;
         end;
       K:= not k;
       h:=h and k;
   end;
    Result:=h;
  end;
end;


在大侠的指导下完成上面的函数,谢baby2008大侠.
代码已修改,delphi7+win2003通过.

  • 标 题: 答复
  • 作 者:baby2008
  • 时 间:2005-08-24 14:08

字符转化成十六进制函数写的不怎样,有Ord()求ASCII函数啊.

  • 标 题: 答复
  • 作 者:baby2008
  • 时 间:2005-08-24 15:01

看了一下,估计你错在这里:
0049439C   /$  53               push ebx
0049439D   |.  56               push esi
0049439E   |.  33C9             xor ecx,ecx                 ;ecx中将保存计算结果,清0
004943A0   |.  8BDA             mov ebx,edx
004943A2   |.  4B               dec ebx
004943A3   |.  85DB             test ebx,ebx
004943A5   |.  7C 25            jl short PAL.004943CC       ;如果未输入用户名和注册码,跳!
004943A7   |.  43               inc ebx                     ;计数器+1
004943A8   |>  C1E1 04          /shl ecx,4                  ;上次计算结果左移4位 (*2^4=16?)   
004943AB   |.  33D2             |xor edx,edx                ;edx清0 ,edx是每次计算的临时结果  
004943AD   |.  8A10             |mov dl,byte ptr ds:[eax]   ;字串按位(从第一位开始)传dl
004943AF   |.  03CA             |add ecx,edx                ;本次取的字符与ecx相加
004943B1   |.  8BD1             |mov edx,ecx                ;
004943B3   |.  81E2 000000F0    |and edx,F0000000           ;把计算结果的低7个字节置0
004943B9   |.  85D2             |test edx,edx               ;
004943BB   |.  74 07            |je short PAL.004943C4      ;如果edx=0则直截取反,否则计算后取反
004943BD   |.  8BF2             |mov esi,edx                ;计算方法是:
004943BF   |.  C1EE 18          |shr esi,18                 ;先把结果右移18位(除2^24=16777216?)
004943C2   |.  33CE             |xor ecx,esi                ;再把右移前后的值作xor
004943C4   |>  F7D2             |not edx                    ;edx取反
004943C6   |.  23CA             |and ecx,edx                ;取反结果与xor结果作and
004943C8   |.  40               |inc eax                    ;指向下一位字符
004943C9   |.  4B               |dec ebx                    ;计数器减1 
004943CA   |.^ 75 DC            \jnz short PAL.004943A8     ;计算未完则循环
004943CC   |>  8BC1              mov eax,ecx                ;把结果放入eax中反回
004943CE   |.  5E                pop esi
004943CF   |.  5B                pop ebx                     
004943D0   \.  C3                retn


不要想的太复杂,就是一个64位算法,Delphi中定义Int64就行了.

我的注册信息:

Name:Baby2008
Company:www.pediy.com
Key:48A008F2690CE5B1

  • 标 题: 答复
  • 作 者:林海雪原
  • 时 间:2005-09-02 10:55

给出dephli写的key:

unit Unit2;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls, jpeg;

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Edit2: TEdit;
    Button1: TButton;
    Button2: TButton;
    Edit4: TEdit;
    Timer1: TTimer;
    Image1: TImage;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure ClearMemory;
begin
if Win32Platform = VER_PLATFORM_WIN32_NT then
begin
SetProcessWorkingSetSize(GetCurrentProcess, $FFFFFFFF, $FFFFFFFF);
application.ProcessMessages;
end;
end;

function Strjm(tr:string): int64;
var
  i:integer;
  h,g,k:int64;
begin
   h:=0;
  if Length(tr) = 1 then  Result :=59
   else
   begin
   for i := 1 to Length(tr) do
     begin
     h := h shl 4;
     h := h+ord(tr[i]);
     g := h;
     k := g and 4026531840;
     if k > 0 then
     h := h xor (k shr 24);
     k:= not k;
     h:=h and k;
     end;
    Result:=h;
   end;
end;


function zcml(a,b:int64;c:byte): int64;
var
 d,e:integer;
begin
  d:= a+b;
  e:=d shl c ;
  Result:= e xor d ;
end;

function zcmr(a,b:int64;c:byte): int64;
var
 d,e:integer;
begin
  d:= a+b;
  e:=d shr c ;
  Result:= e xor d ;
end;

function zcmjs(a,b,c,d,st:int64): integer;
var
 f,g,h,j,k,l,t:integer;
begin
  f:=zcmr(a,b,7);
  h:=f;
  g:=zcml(d,f,13);
  j:=g;
  f:=zcmr(c,g,17);
  k:=f;
  g:=zcml(a+b*2,f,9);
  l:=g+h;
  f:=zcmr(h*2+d,g,3);
  g:=zcml(j*2+c,f,7);
  f:=g+(k+b)*2+a;
  g:=l*2+d;
  t:=g;
  g:=g shr 15;
  f:=f xor g;
  t:=f+t;
  g:=t shl 11;
  f:=g xor t;
  Result:=f xor st;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
   close;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
   A,B,C,D,e:integer;
   mytr:string;
begin
   mytr:=AnsiUpperCase(Edit1.Text+';'+Edit2.Text);
   e:=Strjm(mytr);
   A:=zcmjs(55798,3776713814,3607463695,80963102,e);
   B:=zcmjs(A,3607463695,3776713814,2623553675,55798);
   C:=zcmjs(B,80963102,2623553675,3607463695,A);
   D:=zcmjs(C,2623553675,80963102,3776713814,B);
   mytr:=inttohex(C,8)+inttohex(D,8);
   Edit4.Text:=mytr[7]+mytr[8]+mytr[5]+mytr[6]+mytr[3]+mytr[4]+mytr[1]+mytr[2]+mytr[15]+mytr[16]+mytr[13]+mytr[14]+mytr[11]+mytr[12]+mytr[9]+mytr[10];
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  ClearMemory;
end;



end.