pcmedik V5.4.8.2003破解手記--演算法分析

看雪資料發表於2003-05-10

pcmedik V5.4.8.2003破解手記--演算法分析(我和浮點運算的第一次)
作者:newlaos[CCG][DFCG]


軟體名稱:pcmedik V5.4.8.2003(系統工具)
最新版本:V5.4.8.2003
檔案大小:854KB
軟體授權:共享軟體
使用平臺:Win9x/Me/NT/2000/XP
下載網址:華軍網--->搜尋一下
軟體簡介:中文譯名為個人電腦醫生,一個傻瓜式的系統最佳化軟體,功能不錯,介面也作得漂亮。


加密方式:註冊碼
功能限制:功能限制
PJ工具:TRW20001.23註冊版,W32Dasm8.93黃金版,FI2.5,HMILY[CCG][BCG]的“多功能運算器2.25”,unpecompact1.32
PJ日期:2003-05-08
作者newlaos申明:只是學習,請不用於商業用途或是將本文方法制作的序號產生器任意傳播,造成後果,本人一概不負。

1、先用FI2.5看一下主檔案“PCMedik.exe”,加了pecompact1.68-84的殼。用專用脫殼工具unpecompact1.32脫殼搞定

2、用W32Dasm8.93黃金版對PCMedik.exe進行靜態反彙編,再用串式資料參考,但找不到任何有用的字元,用eXeScope 6.30卻可以看見,不知道其它高手對於這種情況有沒有更好的解決方案。

3、再用TRW20001.23註冊版進行動態跟蹤,下萬能斷點BPX hmemcpy,
先輸入姓名:newlaos
假碼: 78787878
斷下,你很快就能來到這裡
.......
.......
:0047A7DC E813D1FDFF              call 004578F4
:0047A7E1 837DFC00                cmp dword ptr [ebp-04], 00000000
:0047A7E5 0F843C010000            je 0047A927
:0047A7EB 8D55F8                  lea edx, dword ptr [ebp-08]
:0047A7EE 8B8324030000            mov eax, dword ptr [ebx+00000324]
:0047A7F4 E8FBD0FDFF              call 004578F4   <===查註冊碼的長度
:0047A7F9 837DF800                cmp dword ptr [ebp-08], 00000000  <===如果長度為0,也就是沒有輸入註冊碼
:0047A7FD 0F8424010000            je 0047A927   <===沒輸入就跳向OVER了
:0047A803 8D55F0                  lea edx, dword ptr [ebp-10]
:0047A806 8B8324030000            mov eax, dword ptr [ebx+00000324]
:0047A80C E8E3D0FDFF              call 004578F4
:0047A811 8B45F0                  mov eax, dword ptr [ebp-10] <===EAX=78787878
:0047A814 8D55F4                  lea edx, dword ptr [ebp-0C]
:0047A817 E8ECD8F8FF              call 00408108
:0047A81C 8B45F4                  mov eax, dword ptr [ebp-0C]
:0047A81F 50                      push eax
:0047A820 8D55E8                  lea edx, dword ptr [ebp-18]
:0047A823 8B832C030000            mov eax, dword ptr [ebx+0000032C]
:0047A829 E8C6D0FDFF              call 004578F4
:0047A82E 8B45E8                  mov eax, dword ptr [ebp-18] <===EAX=newlaos
:0047A831 8D55EC                  lea edx, dword ptr [ebp-14]
:0047A834 E8CFD8F8FF              call 00408108
:0047A839 8B45EC                  mov eax, dword ptr [ebp-14] <===EAX=newlaos
:0047A83C 5A                      pop edx                     <===EDX=78787878
:0047A83D E8B63D0000              call 0047E5F8 <===這裡就是關鍵的CALL了,F8跟進
:0047A842 3C01                    cmp al, 01    <===要想正確註冊,則出來進AL必須為1
:0047A844 0F85A7000000            jne 0047A8F1  <===這裡不能跳,一跳就OVER了
:0047A84A A1E04C4800              mov eax, dword ptr [00484CE0]
:0047A84F 8B00                    mov eax, dword ptr [eax]
:0047A851 8B805C030000            mov eax, dword ptr [eax+0000035C]
:0047A857 33D2                    xor edx, edx
.......
.......

-----------:0047A83D call 0047E5F8 關鍵的CALL了,F8跟進-----------
:0047E5F8 55                      push ebp
:0047E5F9 8BEC                    mov ebp, esp
:0047E5FB B90C000000              mov ecx, 0000000C

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0047E605(C)
|
:0047E600 6A00                    push 00000000
:0047E602 6A00                    push 00000000
:0047E604 49                      dec ecx
:0047E605 75F9                    jne 0047E600
:0047E607 51                      push ecx
:0047E608 53                      push ebx
:0047E609 56                      push esi
:0047E60A 57                      push edi
:0047E60B 8955F8                  mov dword ptr [ebp-08], edx
:0047E60E 8945FC                  mov dword ptr [ebp-04], eax
:0047E611 8B45FC                  mov eax, dword ptr [ebp-04]
:0047E614 E8775FF8FF              call 00404590
:0047E619 8B45F8                  mov eax, dword ptr [ebp-08]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0047E5A3(C)
|
:0047E61C E86F5FF8FF              call 00404590
:0047E621 33C0                    xor eax, eax
:0047E623 55                      push ebp
:0047E624 68A5E94700              push 0047E9A5
:0047E629 64FF30                  push dword ptr fs:[eax]
:0047E62C 648920                  mov dword ptr fs:[eax], esp
:0047E62F 33C0                    xor eax, eax
:0047E631 55                      push ebp
:0047E632 6851E94700              push 0047E951
:0047E637 64FF30                  push dword ptr fs:[eax]
:0047E63A 648920                  mov dword ptr fs:[eax], esp
:0047E63D B201                    mov dl, 01
:0047E63F A1101A4200              mov eax, dword ptr [00421A10]
:0047E644 E8C734FAFF              call 00421B10
:0047E649 8945EC                  mov dword ptr [ebp-14], eax
:0047E64C BA02000080              mov edx, 80000002
:0047E651 8B45EC                  mov eax, dword ptr [ebp-14]
:0047E654 E85735FAFF              call 00421BB0
:0047E659 B101                    mov cl, 01
:0047E65B BAC0E94700              mov edx, 0047E9C0            ;  ASCII "\Software\PGWARE\PCMedik"
:0047E660 8B45EC                  mov eax, dword ptr [ebp-14]  
    <===註冊資訊儲存的位置,程式並不先驗證,而是先儲存註冊資訊
:0047E663 E8AC35FAFF              call 00421C14
:0047E668 837DFC00                cmp dword ptr [ebp-04], 00000000  <===[ebp-04]=newlaos
:0047E66C 7428                    je 0047E696  <===這兩個都沒有跳轉
:0047E66E 837DF800                cmp dword ptr [ebp-08], 00000000  <===[ebp-08]=78787878
:0047E672 7422                    je 0047E696  <===這兩個都沒有跳轉
:0047E674 8B4DFC                  mov ecx, dword ptr [ebp-04]
:0047E677 BAE4E94700              mov edx, 0047E9E4            ;  ASCII "Name"
:0047E67C 8B45EC                  mov eax, dword ptr [ebp-14]
:0047E67F E82C37FAFF              call 00421DB0  
:0047E684 8B4DF8                  mov ecx, dword ptr [ebp-08]
:0047E687 BAF4E94700              mov edx, 0047E9F4            ;  ASCII "Serial"  
:0047E68C 8B45EC                  mov eax, dword ptr [ebp-14]
:0047E68F E81C37FAFF              call 00421DB0
:0047E694 EB20                    jmp 0047E6B6  <===我跳

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0047E66C(C), :0047E672(C)
|
:0047E696 8D4DFC                  lea ecx, dword ptr [ebp-04]
:0047E699 BAE4E94700              mov edx, 0047E9E4
:0047E69E 8B45EC                  mov eax, dword ptr [ebp-14]
:0047E6A1 E83637FAFF              call 00421DDC
:0047E6A6 8D4DF8                  lea ecx, dword ptr [ebp-08]
:0047E6A9 BAF4E94700              mov edx, 0047E9F4
:0047E6AE 8B45EC                  mov eax, dword ptr [ebp-14]
:0047E6B1 E82637FAFF              call 00421DDC

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0047E694(U)
|
:0047E6B6 33C0                    xor eax, eax
:0047E6B8 55                      push ebp
:0047E6B9 6829E94700              push 0047E929
:0047E6BE 64FF30                  push dword ptr fs:[eax]
:0047E6C1 648920                  mov dword ptr fs:[eax], esp
:0047E6C4 837DFC00                cmp dword ptr [ebp-04], 00000000
:0047E6C8 0F8451020000            je 0047E91F  <===還是和上面一樣不會跳的
:0047E6CE 837DF800                cmp dword ptr [ebp-08], 00000000
:0047E6D2 0F8447020000            je 0047E91F  <===還是和上面一樣不會跳的
:0047E6D8 B85C5F4800              mov eax, 00485F5C
:0047E6DD 8B55FC                  mov edx, dword ptr [ebp-04]
:0047E6E0 E84F5AF8FF              call 00404134
:0047E6E5 68605F4800              push 00485F60
:0047E6EA 8D45E4                  lea eax, dword ptr [ebp-1C]
:0047E6ED 50                      push eax
:0047E6EE 8B55F8                  mov edx, dword ptr [ebp-08]
:0047E6F1 B804EA4700              mov eax, 0047EA04
:0047E6F6 E8E95FF8FF              call 004046E4
:0047E6FB 40                      inc eax
:0047E6FC 50                      push eax
:0047E6FD 8B45F8                  mov eax, dword ptr [ebp-08] <===EAX=78787878
:0047E700 E89B5CF8FF              call 004043A0    <===演算法註冊碼的長度
:0047E705 8BC8                    mov ecx, eax     <===EAX=ECX=8
:0047E707 8B45F8                  mov eax, dword ptr [ebp-08]
:0047E70A 5A                      pop edx
:0047E70B E8F05EF8FF              call 00404600
:0047E710 8B55E4                  mov edx, dword ptr [ebp-1C]
:0047E713 B804EA4700              mov eax, 0047EA04
:0047E718 E8C75FF8FF              call 004046E4
:0047E71D 48                      dec eax
:0047E71E 50                      push eax
:0047E71F 8D45E0                  lea eax, dword ptr [ebp-20]
:0047E722 50                      push eax
:0047E723 8B55F8                  mov edx, dword ptr [ebp-08]
:0047E726 B804EA4700              mov eax, 0047EA04
:0047E72B E8B45FF8FF              call 004046E4
:0047E730 40                      inc eax
:0047E731 50                      push eax
:0047E732 8B45F8                  mov eax, dword ptr [ebp-08]
:0047E735 E8665CF8FF              call 004043A0
:0047E73A 8BC8                    mov ecx, eax
:0047E73C 8B45F8                  mov eax, dword ptr [ebp-08]
:0047E73F 5A                      pop edx
:0047E740 E8BB5EF8FF              call 00404600
:0047E745 8B45E0                  mov eax, dword ptr [ebp-20]
:0047E748 BA01000000              mov edx, 00000001
:0047E74D 59                      pop ecx
:0047E74E E8AD5EF8FF              call 00404600
:0047E753 BB01000000              mov ebx, 00000001  <===EBX=1

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0047E7F3(C)
|                   ***************迴圈開始************************
:0047E758 8D45D8                  lea eax, dword ptr [ebp-28]
:0047E75B 50                      push eax
:0047E75C B901000000              mov ecx, 00000001  <===這裡為取值長度為1
:0047E761 8BD3                    mov edx, ebx       <===取值開始的位置,依次是1,2,3,4,5,6,7
:0047E763 8B45FC                  mov eax, dword ptr [ebp-04] <===EAX="newlaos'
:0047E766 E8955EF8FF              call 00404600      <===將上面給出的引數取值
:0047E76B 8B45D8                  mov eax, dword ptr [ebp-28] <===EAX為依次取出的字元,n,e,w,l,a,o,s
:0047E76E 0FB600                  movzx eax, byte ptr [eax]   <===取出字元的ASC值,6E,65,77,6C,61,6F,73
:0047E771 F7EB                    imul ebx <===這裡的作用是將EAX的值乘以EBX(依次增加),結果返回EAX,EAX的值依次為6E,CA,165,1B0,1E5,29A,325
:0047E773 8945D4                  mov dword ptr [ebp-2C], eax
:0047E776 DB45D4                  fild dword ptr [ebp-2C]
:0047E779 E85A43F8FF              call 00402AD8
:0047E77E 8945CC                  mov dword ptr [ebp-34], eax
:0047E781 8955D0                  mov dword ptr [ebp-30], edx
:0047E784 DF6DCC                  fild qword ptr [ebp-34]
:0047E787 83C4F4                  add esp, FFFFFFF4
:0047E78A DB3C24                  fstp tbyte ptr [esp]
:0047E78D 9B                      wait
:0047E78E 8D55DC                  lea edx, dword ptr [ebp-24]
:0047E791 B810EA4700              mov eax, 0047EA10
:0047E796 E895B5F8FF              call 00409D30  <===將前面得出的值轉為10進位制的表示
     --------------------
       6E   ----> 110
       CA   ----> 202
       165  ----> 357
       1B0  ----> 432
       1E5  ----> 485
       29A  ----> 666
       325  ----> 805
     --------------------
:0047E79B FF75DC                  push [ebp-24]
:0047E79E 8D55C8                  lea edx, dword ptr [ebp-38]
:0047E7A1 8BC3                    mov eax, ebx  
:0047E7A3 E8C89BF8FF              call 00408370
:0047E7A8 FF75C8                  push [ebp-38]
:0047E7AB FF35605F4800            push dword ptr [00485F60]
:0047E7B1 8D45E8                  lea eax, dword ptr [ebp-18]
:0047E7B4 BA03000000              mov edx, 00000003
:0047E7B9 E8A25CF8FF              call 00404460  <===將上面的值與EBX的值以字串的形式連起來
     --------------------
       "110" + "1" = "1101"
       "202" + "2" = "2022"
       "357" + "3" = "3573"
       "432" + "4" = "4324"
       "485" + "5" = "4855"
       "666" + "6" = "6666"
       "805" + "7" = "8057"
     --------------------
:0047E7BE 8B45E8                  mov eax, dword ptr [ebp-18] <===eax依次為上面的字串
:0047E7C1 E8E69CF8FF              call 004084AC  <===將字串轉為數值,EAX依次為44D,7E6,DF5,10E4,12F7,1A0A,1F79
:0047E7C6 8BF0                    mov esi, eax
:0047E7C8 8B45E8                  mov eax, dword ptr [ebp-18] <===eax依次為上面的字串
:0047E7CB E8DC9CF8FF              call 004084AC  <===將字串轉為數值,EAX依次為44D,7E6,DF5,10E4,12F7,1A0A,1F79
:0047E7D0 03F0                    add esi, eax   <===暈,這就等效於每個數值乘以2
:0047E7D2 8BC6                    mov eax, esi   <===EAX依次為89A,FCC,1DEA,21C8,25EE,3414,3EF2
:0047E7D4 8D55C4                  lea edx, dword ptr [ebp-3C]
:0047E7D7 E8949BF8FF              call 00408370  <===這個CALL又將數值轉為了字元
:0047E7DC 8B55C4                  mov edx, dword ptr [ebp-3C]
:0047E7DF 8D45E8                  lea eax, dword ptr [ebp-18]
:0047E7E2 E89159F8FF              call 00404178
:0047E7E7 43                      inc ebx
:0047E7E8 8B45FC                  mov eax, dword ptr [ebp-04]  <===eax=newlaos
:0047E7EB E8B05BF8FF              call 004043A0 <===求註冊名的長度
:0047E7F0 40                      inc eax    <===EAX=7+1=8
:0047E7F1 3BD8                    cmp ebx, eax  <===所以這裡就保證了,迴圈7次
:0047E7F3 0F855FFFFFFF            jne 0047E758  <===從這裡向上跳是一個迴圈結構
            ***************迴圈結束************************
:0047E7F9 6A17                    push 00000017
:0047E7FB 683652C70D              push 0DC75236
:0047E800 8B45E8                  mov eax, dword ptr [ebp-18]  <===EAX="16114"也就是最後一位的計算結果
:0047E803 E8A49CF8FF              call 004084AC  <===將字元轉為數值,EAX=3EF2
:0047E808 99                      cdq
:0047E809 E8CE67F8FF              call 00404FDC  <===這裡是一小段程式碼,F8跟進,出來後EAX=4C54CB0C,EDX=5AB21
:0047E80E 8945CC                  mov dword ptr [ebp-34], eax
:0047E811 8955D0                  mov dword ptr [ebp-30], edx
:0047E814 DF6DCC                  fild qword ptr [ebp-34]  <===呵呵,[ebp-34]的值為5AB214C54CB0C
:0047E817 83C4F4                  add esp, FFFFFFF4
:0047E81A DB3C24                  fstp tbyte ptr [esp]
:0047E81D 9B                      wait
:0047E81E 8D55C0                  lea edx, dword ptr [ebp-40]
:0047E821 B810EA4700              mov eax, 0047EA10
:0047E826 E805B5F8FF              call 00409D30   <===這個CALL計算出一串數字1595534386449164(好一個大數運算庫,我用了HMILY[CCG][BCG]的“多功能運算器2.25”才知道的這個結果,這真是個好軟體!)
:0047E82B 8B55C0                  mov edx, dword ptr [ebp-40]  <===EDX="1595534386449164"
:0047E82E 8D45E8                  lea eax, dword ptr [ebp-18]  <===EAX的地址指標指向"16114"
:0047E831 E84259F8FF              call 00404178   <===
:0047E836 8D45F0                  lea eax, dword ptr [ebp-10]
:0047E839 50                      push eax
:0047E83A 8B55F8                  mov edx, dword ptr [ebp-08]  <===EDX="78787878"
:0047E83D B804EA4700              mov eax, 0047EA04   <===這裡是“+”
:0047E842 E89D5EF8FF              call 004046E4  <===定位在輸入的註冊碼中“+”的位置,我們將註冊碼改為78787878+12345678,重新來
:0047E847 8BC8                    mov ecx, eax   <===EAX=9(說時“+”在輸入註冊碼的第9位)
:0047E849 49                      dec ecx  <===ECX=9-1=8 取字串的長度
:0047E84A BA01000000              mov edx, 00000001  <===從第一個的開始取
:0047E84F 8B45F8                  mov eax, dword ptr [ebp-08] <===EAX="78787878+12345678"
:0047E852 E8A95DF8FF              call 00404600  <===進行取字串的動作
:0047E857 8B45F0                  mov eax, dword ptr [ebp-10] <===EAX="78787878"
:0047E85A E829B5F8FF              call 00409D88  
:0047E85F DB7DB4                  fstp tbyte ptr [ebp-4C]
:0047E862 9B                      wait
:0047E863 8B45E8                  mov eax, dword ptr [ebp-18] <===EAX="1595534386449164"
:0047E866 E81DB5F8FF              call 00409D88
:0047E86B DB6DB4                  fld tbyte ptr [ebp-4C]
:0047E86E DEE1                    fsubrp st(1), st(0)
:0047E870 D81D14EA4700            fcomp dword ptr [0047EA14]
:0047E876 DFE0                    fstsw ax
:0047E878 9E                      sahf
:0047E879 0F879C000000            ja 0047E91B  <===從這裡跳走就OVER了,當這裡改為78787878+12345678後這裡不跳走
:0047E87F 8B45E8                  mov eax, dword ptr [ebp-18] <===EAX="1595534386449164"
:0047E882 E801B5F8FF              call 00409D88
:0047E887 DB7DA8                  fstp tbyte ptr [ebp-58]
:0047E88A 9B                      wait
:0047E88B 8B45F0                  mov eax, dword ptr [ebp-10] <===EAX="78787878"
:0047E88E E8F5B4F8FF              call 00409D88
:0047E893 DB6DA8                  fld tbyte ptr [ebp-58]
:0047E896 DEE1                    fsubrp st(1), st(0)
:0047E898 D81D14EA4700            fcomp dword ptr [0047EA14]  <===明白了,這裡真正的註冊碼在"+"號前面必須就是"1595534386449164",哈哈,註冊成功了!
:0047E89E DFE0                    fstsw ax
:0047E8A0 9E                      sahf
:0047E8A1 7778                    ja 0047E91B  <===從這裡跳走就OVER了
:0047E8A3 C605585F480001          mov byte ptr [00485F58], 01
:0047E8AA C645F701                mov [ebp-09], 01  <===哈哈,勝利的希望在這裡
:0047E8AE B201                    mov dl, 01
:0047E8B0 A1682B4100              mov eax, dword ptr [00412B68]
:0047E8B5 E8024AF8FF              call 004032BC
:0047E8BA 8BF0                    mov esi, eax
:0047E8BC BA20EA4700              mov edx, 0047EA20
:0047E8C1 8BC6                    mov eax, esi
:0047E8C3 8B08                    mov ecx, dword ptr [eax]
:0047E8C5 FF5138                  call [ecx+38]
:0047E8C8 33DB                    xor ebx, ebx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0047E910(C)
|         ***************迴圈開始************************
:0047E8CA 8D55A4                  lea edx, dword ptr [ebp-5C]
:0047E8CD 8B45FC                  mov eax, dword ptr [ebp-04]
:0047E8D0 E8E395F8FF              call 00407EB8
:0047E8D5 8B45A4                  mov eax, dword ptr [ebp-5C]
:0047E8D8 50                      push eax
:0047E8D9 8D4D9C                  lea ecx, dword ptr [ebp-64]
:0047E8DC 8BD3                    mov edx, ebx
:0047E8DE 8BC6                    mov eax, esi
:0047E8E0 8B38                    mov edi, dword ptr [eax]
:0047E8E2 FF570C                  call [edi+0C]
:0047E8E5 8B459C                  mov eax, dword ptr [ebp-64]
:0047E8E8 8D55A0                  lea edx, dword ptr [ebp-60]
:0047E8EB E8C895F8FF              call 00407EB8
:0047E8F0 8B55A0                  mov edx, dword ptr [ebp-60]
:0047E8F3 58                      pop eax
:0047E8F4 E8F35BF8FF              call 004044EC
:0047E8F9 750B                    jne 0047E906  <===在這裡就必須跳走了
:0047E8FB C605585F480000          mov byte ptr [00485F58], 00
:0047E902 C645F700                mov [ebp-09], 00  <===到這裡也是錯了

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0047E8F9(C)
|
:0047E906 43                      inc ebx
:0047E907 8BC6                    mov eax, esi
:0047E909 8B10                    mov edx, dword ptr [eax] <===
:0047E90B FF5214                  call [edx+14]
:0047E90E 3BD8                    cmp ebx, eax
:0047E910 75B8                    jne 0047E8CA  <===從這裡向上跳是一個迴圈結構
        ***************迴圈結束************************
:0047E912 8BC6                    mov eax, esi
:0047E914 E8D349F8FF              call 004032EC
:0047E919 EB04                    jmp 0047E91F

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0047E879(C), :0047E8A1(C)    <===向上看兩個錯誤跳轉
|
:0047E91B C645F700                mov [ebp-09], 00   <===這裡不能經過

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0047E6C8(C), :0047E6D2(C), :0047E919(U)
|
:0047E91F 33C0                    xor eax, eax
:0047E921 5A                      pop edx
:0047E922 59                      pop ecx
:0047E923 59                      pop ecx
:0047E924 648910                  mov dword ptr fs:[eax], edx
:0047E927 EB0E                    jmp 0047E937
:0047E929 E95E4EF8FF              jmp 0040378C
:0047E92E C645F700                mov [ebp-09], 00   <===這裡不能經過,當然也不會經過
:0047E932 E8BD51F8FF              call 00403AF4

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0047E927(U)
|
:0047E937 8B45EC                  mov eax, dword ptr [ebp-14]
:0047E93A E84132FAFF              call 00421B80
:0047E93F 8B45EC                  mov eax, dword ptr [ebp-14]
:0047E942 E8A549F8FF              call 004032EC
:0047E947 33C0                    xor eax, eax
:0047E949 5A                      pop edx
:0047E94A 59                      pop ecx
:0047E94B 59                      pop ecx
:0047E94C 648910                  mov dword ptr fs:[eax], edx
:0047E94F EB0A                    jmp 0047E95B
:0047E951 E9364EF8FF              jmp 0040378C
:0047E956 E89951F8FF              call 00403AF4

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0047E94F(U)
|
:0047E95B 33C0                    xor eax, eax
:0047E95D 5A                      pop edx
:0047E95E 59                      pop ecx
:0047E95F 59                      pop ecx
:0047E960 648910                  mov dword ptr fs:[eax], edx
:0047E963 68ACE94700              push 0047E9AC

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0047E9AA(U)
|
:0047E968 8D459C                  lea eax, dword ptr [ebp-64]
:0047E96B BA03000000              mov edx, 00000003
:0047E970 E88F57F8FF              call 00404104
:0047E975 8D45C0                  lea eax, dword ptr [ebp-40]
:0047E978 BA03000000              mov edx, 00000003
:0047E97D E88257F8FF              call 00404104
:0047E982 8D45D8                  lea eax, dword ptr [ebp-28]
:0047E985 BA05000000              mov edx, 00000005
:0047E98A E87557F8FF              call 00404104
:0047E98F 8D45F0                  lea eax, dword ptr [ebp-10]
:0047E992 E84957F8FF              call 004040E0
:0047E997 8D45F8                  lea eax, dword ptr [ebp-08]
:0047E99A BA02000000              mov edx, 00000002
:0047E99F E86057F8FF              call 00404104
:0047E9A4 C3                      ret


:0047E9A5 E99650F8FF              jmp 00403A40
:0047E9AA EBBC                    jmp 0047E968
:0047E9AC 8A45F7                  mov al, byte ptr [ebp-09] <===[ebp-09]為至關重要的數值,向上看
:0047E9AF 5F                      pop edi
:0047E9B0 5E                      pop esi
:0047E9B1 5B                      pop ebx
:0047E9B2 8BE5                    mov esp, ebp
:0047E9B4 5D                      pop ebp
:0047E9B5 C3                      ret

-------------------F8跟進來到這裡-------------------------------------------
:00404FDC 52                      push edx
:00404FDD 50                      push eax
:00404FDE 8B442410                mov eax, dword ptr [esp+10] <===EAX=17為作者內定值
:00404FE2 F72424                  mul dword ptr [esp]  <===[esp]為3EF2,EAX=17 * 3EF2=5A7BE
:00404FE5 89C1                    mov ecx, eax   <===ECX=5A7BE
:00404FE7 8B442404                mov eax, dword ptr [esp+04] <===EAX=0
:00404FEB F764240C                mul [esp+0C]   <===[esp+0C]=0DC75236為作者內定值,EAX=0 * DC75236=0
:00404FEF 01C1                    add ecx, eax   <===ECX=5A7BE+0=5A7BE
:00404FF1 8B0424                  mov eax, dword ptr [esp] <===[esp]為3EF2,EAX=3EF2
:00404FF4 F764240C                mul [esp+0C]   <===EAX=3EF2 * 0DC75236 =4C54CB0C   EDX=363(相乘大於FFFFFFFF,溢位的高位)
:00404FF8 01CA                    add edx, ecx   <===EDX=5A7BE+363=5AB21
:00404FFA 59                      pop ecx
:00404FFB 59                      pop ecx
:00404FFC C20800                  ret 0008

--------------------------------------------------------------------
4、演算法分析:---型別:f(註冊名)=註冊碼---
 a、取出註冊名的最後一個字元的ASC值,乘以它在註冊名的位置,結果轉為10進位制的字元表示,後面再接上它在註冊名的位置的字元形式
 b、將這個字串,轉回為數值形式,乘以2,得出新的結果firstsum。
 c、將firstsum乘以17(10進位制是25),得到highsum, 將firstsum乘以DC75236,結果高位進入EDX,低位進入EAX,將EDX的值加上highsum,再以字串的形式與低位EAX連成一個大於8位的16進位制形式的字串,將這個字串轉為10進位制,就是我們要的註冊碼前面部分了
 d、輸入的註冊碼中必須用一個"+",在這之前才作為實際校驗,之後的沒有用。

5、-----VB6.0編譯的序號產生器原始碼,WIN98的透過-------
Private Sub Command1_Click()
'每一個0代表4位數,第一個0代表1-4位,第2個0代表5-8位,第3個0代表9-12們,類推,第7個0代表25-28位(這是從最低位開始數喲)
namestr = Text1.Text    '取註冊名
nlen = Len(namestr) '得出長度
e = 1    '輸入正確標誌
For i = 1 To nlen  '檢查註冊名的合法性,不支援中文註冊名
 sumsum = Asc(Mid(namestr, i, 1))
 If sumsum <> Abs(sumsum) Then
   e = 2
 End If
Next i

If e = 1 And nlen <> 0 Then
  firstsum = CLng((CStr(sumsum * nlen) + CStr(nlen))) * 2 '因為已經是最後一位,所以直接拿來用,firstsum為由註冊碼產生的值

'--------------------開始firstsum與1700000000(16進位制)的相乘------------------------
'這裡等效於firstsum*&H17*4294967296
astr1 = CStr(firstsum * &H17)       '相乘數1
astr2 = CStr(4294967296#)       '相乘數2(16進位制的100000000等於10進位制的4294967296)
a = Array(0, 0, 0, 0, 0, 0, 0)
i = 0
k = 1
Do
alen = Len(astr1)
 If alen <= 4 Then
   k = 2
   a(i) = CLng(astr1)
 Else
   a(i) = CLng(Right(astr1, 4))              '每次從低位取4位
   astr1 = Mid(astr1, 1, alen - 4)
 End If
 i = i + 1
Loop While k = 1
'到這裡完成將10進位制數第4位放入陣列a
b = Array(0, 0, 0, 0, 0, 0, 0)
i = 0
k = 1
Do
alen = Len(astr2)
 If alen <= 4 Then
   k = 2
   b(i) = CLng(astr2)
 Else
   b(i) = CLng(Right(astr2, 4))              '每次取4位
   astr2 = Mid(astr2, 1, alen - 4)
 End If
i = i + 1
Loop While k = 1
'到這裡完成將10進位制數第4位放入陣列b
c = Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)  '定義最終結果陣列,每一個0代表8位數
For i = 0 To 6
 tmp2 = 0
 For j = 0 To 6
   sumtmp = a(j) * b(i) + tmp2 + c(i + j)
   c(i + j) = (sumtmp Mod 10000)
   tmp2 = Int(sumtmp / 10000)
 Next j
  c(i + j) = tmp2
Next i
k = 1
For i = 13 To 0 Step -1
 If c(i) <> 0 Or k <> 1 Then
    ttmp = CStr(c(i))
    If Len(ttmp) < 4 And k <> 1 Then  '當出現某個陣列中的數為0890的情況,如果不補0,就會出錯了。當然也要考第一個數防止出現數字最前面出現多餘的0的情況
      For j = 1 To 4 - Len(ttmp)
        ttmp = "0" + ttmp
      Next
    End If
    laststr1 = laststr1 + ttmp
    k = 2
 End If
Next i
sumstr1 = laststr1   '用於下次相加
'--------------------firstsum與1700000000(16進位制)的相乘結束------------------------
'--------------------開始firstsum與&HDC75236的相乘------------------------
astr1 = CStr(firstsum)         '相乘數1
astr2 = CStr(&HDC75236)        '相乘數2
For i = 0 To 6          '陣列初始化
 a(i) = 0
Next i
i = 0
k = 1
Do
alen = Len(astr1)
 If alen <= 4 Then
   k = 2
   a(i) = CLng(astr1)
 Else
   a(i) = CLng(Right(astr1, 4))              '每次從低位取4位
   astr1 = Mid(astr1, 1, alen - 4)
 End If
 i = i + 1
Loop While k = 1
'到這裡完成將10進位制數第4位放入陣列a
For i = 0 To 6          '陣列初始化
 b(i) = 0
Next i
i = 0
k = 1
Do
alen = Len(astr2)
 If alen <= 4 Then
   k = 2
   b(i) = CLng(astr2)
 Else
   b(i) = CLng(Right(astr2, 4))              '每次取4位
   astr2 = Mid(astr2, 1, alen - 4)
 End If
i = i + 1
Loop While k = 1
'到這裡完成將10進位制數第4位放入陣列b
For i = 0 To 13          '陣列初始化
 c(i) = 0
Next i
For i = 0 To 6
 tmp2 = 0
 For j = 0 To 6
   sumtmp = a(j) * b(i) + tmp2 + c(i + j)
   c(i + j) = (sumtmp Mod 10000)
   tmp2 = Int(sumtmp / 10000)
 Next j
  c(i + j) = tmp2
Next i
k = 1
For i = 13 To 0 Step -1
 If c(i) <> 0 Or k <> 1 Then
    ttmp = CStr(c(i))
    If Len(ttmp) < 4 And k <> 1 Then  '當出現某個陣列中的數為0890的情況,如果不補0,就會出錯了。當然也要考第一個數防止出現數字最前面出現多餘的0的情況
      For j = 1 To 4 - Len(ttmp)
        ttmp = "0" + ttmp
      Next
    End If
    laststr2 = laststr2 + ttmp
    k = 2
 End If
Next i
sumstr2 = laststr2   '用於下次相加
'--------------------firstsum與DC75236的相乘結束------------------------
'--------------------開始sumstr1與sumstr2的相加------------------------
astr1 = sumstr1         '相加數1
astr2 = sumstr2         '相加數2
For i = 0 To 6          '陣列初始化
 a(i) = 0
Next i
i = 0
k = 1
Do
alen = Len(astr1)
 If alen <= 4 Then
   k = 2
   a(i) = CLng(astr1)
 Else
   a(i) = CLng(Right(astr1, 4))              '每次從低位取4位
   astr1 = Mid(astr1, 1, alen - 4)
 End If
 i = i + 1
Loop While k = 1
'到這裡完成將10進位制數第4位放入陣列a
For i = 0 To 6          '陣列初始化
 b(i) = 0
Next i
i = 0
k = 1
Do
alen = Len(astr2)
 If alen <= 4 Then
   k = 2
   b(i) = CLng(astr2)
 Else
   b(i) = CLng(Right(astr2, 4))              '每次取4位
   astr2 = Mid(astr2, 1, alen - 4)
 End If
i = i + 1
Loop While k = 1
'到這裡完成將10進位制數第4位放入陣列b
For i = 0 To 13          '陣列初始化
 c(i) = 0
Next i
i = 0
tmp2 = 0
Do While a(i) <> 0 Or b(i) <> 0
 tmp = a(i) + b(i) + tmp2
 c(i) = (tmp Mod 10000)          '只留4位
 tmp2 = Int(tmp / 10000)       '商自動進入下一位
 i = i + 1
 If i = 7 Then
   Exit Do
 End If
Loop
c(i) = tmp2         '最後一個進位值
k = 1
For i = 13 To 0 Step -1
 If c(i) <> 0 Or k <> 1 Then
    ttmp = CStr(c(i))
    If Len(ttmp) < 4 And k <> 1 Then  '當出現某個陣列中的數為0890的情況,如果不補0,就會出錯了。當然也要考第一個數防止出現數字最前面出現多餘的0的情況
      For j = 1 To 4 - Len(ttmp)
        ttmp = "0" + ttmp
      Next
    End If
    laststr3 = laststr3 + ttmp
    k = 2
 End If
Next i
laststr3=laststr3+"+"
'---------------------sumstr1與sumstr2的相加結束--------------------------------
Text2.Text = laststr3
Else
 h = MsgBox("本序號產生器暫不支援中文註冊名,或是你還沒有輸入註冊名!", 0, "你的輸入有誤!")
End If
End Sub


6、註冊資訊儲存在登錄檔:
[HKEY_LOCAL_MACHINE\Software\PGWARE\PCMedik]
"Name"="newlaos[CCG][DFCG]"
"Serial"="33153925271260536+"

相關文章