中級例項教程――之《楚漢棋緣V1.36》

看雪資料發表於2015-11-15

前言:

   跟蹤《楚漢棋緣》的演算法只不過三個晚上約6、7個小時的時間,
而寫出序號產生器卻用了近一個月,大量的時間都花在大數運算庫的調
試上,在這篇教程之後,俺將寫一篇針對RSA 演算法的詳細教程。

   俺是一個象棋愛好者,曾用ID“臭棋簍子”獲得聯眾“大師”
級稱號,但是俺經常會輸給一個象棋程式《將族》。《將族》是90
年代初中國象棋程式史上劃時代的產品,近十年來一直是俺的最愛,
可惜隨著作業系統不斷升級,修改《將族》以讓它能夠繼續工作也
越來越困難。於是我一直在尋找一個棋力相當的新產品希望能夠代
替它,直到碰到《楚漢棋緣 V1.3x》,看來大陸在象棋演算法的研究
上落後臺灣幾乎有10年之久!


研究物件:

   《楚漢棋緣 V1.36》,這裡做個宣告:俺的教程使用softice
為唯一工具,無脫殼與靜態分析必要。


程式特點:

   重啟驗證防爆破,RSA防序號產生器,Borland C++編譯,“Borland
造”的東西(包括BC++、C++ Builder、DELPHI 等)都不能透過下
getwindowtext 之類的斷點獲得螢幕輸入,斷點必須下在windows
訊息迴圈上,推薦使用 bpx callwindowproca。程式對使用者名稱及假
碼均進行了多次變換,最終的驗證是使用者名稱變碼與假碼變碼之間的
驗證。


前期工作:

   進入註冊介面,填入使用者名稱及假碼,切入softice,下斷點bpx
callwindowproca,F5 回到程式,隨便動動滑鼠即被中斷進入Sice,
下s 0 l ffffff "假碼", 然後bpm 假碼地址,F5回到程式,按下
“註冊”按鈕,讓假碼這把“鑰匙”帶我們去找驗證函式!

   
演算法分析:

   好了,程式對假碼開始進行處理的地方就是我們要進行分析的
驗證函式,找到這一函式的入口並記下地址,這樣以後可以直接在
這一地址上下斷點。

   如下所示,這一函式有900 多行程式碼,還包含了數不清的call,
不過請不要驚慌,如果你仔細看俺的註釋,會發現幾乎所有的call
俺都是毫不猶豫地用 F10來對付的,對演算法的把握完全是透過歸納
總結逐步建立起來的。


:u 430be0 L e81
001B:00430BE0  PUSH      EBP
001B:00430BE1  MOV       EBP,ESP
001B:00430BE3  ADD       ESP,FFFFFE94
001B:00430BE9  PUSH      EBX
001B:00430BEA  PUSH      ESI
001B:00430BEB  PUSH      EDI
001B:00430BEC  MOV       [EBP-0094],EDX
001B:00430BF2  MOV       DWORD PTR [EBP-0088],004EBB08
001B:00430BFC  MOV       [EBP-0084],ESP
001B:00430C02  MOV       EDI,EAX
001B:00430C04  MOV       DWORD PTR [EBP-008C],004A8C0B
001B:00430C0E  MOV       WORD PTR [EBP-80],0000
001B:00430C14  XOR       EAX,EAX
001B:00430C16  MOV       [EBP-74],EAX
001B:00430C19  MOV       EDX,FS:[00000000]
001B:00430C20  MOV       [EBP-0090],EDX
001B:00430C26  LEA       ECX,[EBP-0090]
001B:00430C2C  MOV       FS:[00000000],ECX
//以上估計是函式呼叫環境的儲存及異常處理入口的設定

001B:00430C33  MOV       WORD PTR [EBP-80],0014
//[ebp-xx]通常是屬於當前函式體的區域性變數
//給變數[ebp-80]賦初值為20
001B:00430C39  MOV       EDX,004EB5CE
//[4eb5ce]="L5WXT6VMB4GE3RUYJ9HASF8KQNPD7CI",用來幹嘛呢?
//暫且稱之為密碼錶吧
001B:00430C3E  LEA       EAX,[EBP-04]
//[ebp-04]=[12f80c]=16
001B:00430C41  CALL      004B7350
//eax=12f80c,沒有發生變化,而**eax=密碼錶
//edx發生了變化,=12f780
001B:00430C46  INC       DWORD PTR [EBP-74]
//變數[ebp-74]加1
001B:00430C49  XOR       ECX,ECX
001B:00430C4B  MOV       WORD PTR [EBP-80],0008
001B:00430C51  MOV       WORD PTR [EBP-80],0020
001B:00430C57  MOV       [EBP-08],ECX
001B:00430C5A  XOR       EAX,EAX
001B:00430C5C  INC       DWORD PTR [EBP-74]
001B:00430C5F  XOR       EDX,EDX
001B:00430C61  MOV       WORD PTR [EBP-80],0008
001B:00430C67  MOV       WORD PTR [EBP-80],002C
001B:00430C6D  MOV       [EBP-0C],EAX
001B:00430C70  XOR       ECX,ECX
001B:00430C72  INC       DWORD PTR [EBP-74]
001B:00430C75  MOV       WORD PTR [EBP-80],0008
001B:00430C7B  MOV       WORD PTR [EBP-80],0038
001B:00430C81  MOV       [EBP-10],EDX
001B:00430C84  LEA       EDX,[EBP-00C4]
001B:00430C8A  INC       DWORD PTR [EBP-74]
001B:00430C8D  MOV       WORD PTR [EBP-80],0008
001B:00430C93  MOV       WORD PTR [EBP-80],0044
001B:00430C99  MOV       [EBP-14],ECX
001B:00430C9C  INC       DWORD PTR [EBP-74]
001B:00430C9F  XOR       EAX,EAX
001B:00430CA1  MOV       WORD PTR [EBP-80],0008
001B:00430CA7  MOV       [EBP-0098],EAX
//將[ebp-08]到[ebp-14]四個32位地址清零
//將[ebp-98]也清零
//並將計數器[ebp-74]加5
001B:00430CAD  PUSH      14
001B:00430CAF  PUSH      00
001B:00430CB1  PUSH      EDX
001B:00430CB2  CALL      004A8778
//[eax]=[12f74c]=0
//[ecx]=[12f75c]=0
//不知道在幹什麼
001B:00430CB7  MOV       WORD PTR [EBP-80],0050
//變數[ebp-80]在被頻繁地賦值,暫不明白有何用
001B:00430CBD  XOR       ECX,ECX
001B:00430CBF  ADD       ESP,0C
001B:00430CC2  MOV       [EBP-24],ECX
//[ebp-24]=0
001B:00430CC5  LEA       EDX,[EBP-24]
001B:00430CC8  INC       DWORD PTR [EBP-74]
001B:00430CCB  MOV       EAX,[EDI+00000308]
001B:00430CD1  CALL      004776F4
//eax=6
//剛剛被賦值為零的[ebp-24]發生了變化
//*[ebp-24]="doggie",是俺輸入的使用者名稱!
//所以,eax=6應該是返回使用者名稱的長度
001B:00430CD6  CMP       DWORD PTR [EBP-24],00
001B:00430CDA  JZ        00430CE1
001B:00430CDC  MOV       ECX,[EBP-24]
001B:00430CDF  JMP       00430CE6
001B:00430CE1  MOV       ECX,004EB5EE
001B:00430CE6  PUSH      EDI
001B:00430CE7  MOV       EDI,ECX
//edi=使用者名稱地址
001B:00430CE9  XOR       EAX,EAX
//eax=0
001B:00430CEB  OR        ECX,-01
//ecx=-1
001B:00430CEE  REPNZ SCASB
//迴圈edi+1、計數器ecx-1
//直到[edi]=eax或ecx=0,而ecx一開始就<0
001B:00430CF0  NOT       ECX
//ecx=使用者名稱長度+1
001B:00430CF2  SUB       EDI,ECX
//恢復edi=使用者名稱地址
001B:00430CF4  LEA       ESI,[EBP-00C4]
001B:00430CFA  XCHG      ESI,EDI
001B:00430CFC  MOV       EDX,ECX
001B:00430CFE  MOV       EAX,EDI
001B:00430D00  SHR       ECX,02
//ecx=ecx/4
001B:00430D03  LEA       EAX,[EBP-24]
001B:00430D06  REPZ MOVSD
//以雙字為單位將esi中的使用者名稱複製至edi,即[ebp-c4]
001B:00430D08  MOV       ECX,EDX
001B:00430D0A  MOV       EDX,00000002
001B:00430D0F  AND       ECX,03
001B:00430D12  REPZ MOVSB
//將剩下的位元組從esi複製至edi
001B:00430D14  POP       EDI
001B:00430D15  DEC       DWORD PTR [EBP-74]
001B:00430D18  CALL      004B74A8
//*eax,即使用者名稱的源地址[ebp-24]被清零
//估計call 4b74a8相當於物件delete
//所以在call之前減1的變數[ebp-74]估計是物件例項計數器
001B:00430D1D  MOV       DWORD PTR [EDI+00000390],0001E240
//1e240十進位制=123456,應該是拿來做變換用的常量
001B:00430D27  MOV       DWORD PTR [EDI+00000394],00000000
001B:00430D31  XOR       ESI,ESI
001B:00430D33  LEA       EBX,[EBP-00C4]
//[ebp-c4]是前面被裝入使用者名稱的地址
001B:00430D39  XOR       EAX,EAX
001B:00430D3B  INC       ESI
001B:00430D3C  MOV       AL,[EBX]
001B:00430D3E  INC       EBX
001B:00430D3F  MOV       EDX,EAX
001B:00430D41  IMUL      EDX,EAX
001B:00430D44  ADD       EDX,EAX
001B:00430D46  ADD       [EBP-0098],EDX
001B:00430D4C  CMP       ESI,14
001B:00430D4F  JL        00430D39
//從esi=1到20迴圈
//[ebp-98]+=(使用者名稱第esi位)*(使用者名稱第esi位+1)
//[ebp-98]就是使用者名稱的變碼
//可見使用者名稱只有前20位有效
001B:00430D51  MOV       EAX,[EBP-0098]
001B:00430D57  XOR       EDX,EDX
001B:00430D59  ADD       [EDI+00000390],EAX
//使用者名稱變碼再+123456
001B:00430D5F  ADC       [EDI+00000394],EDX
001B:00430D65  PUSH      DWORD PTR [EDI+00000394]
001B:00430D6B  PUSH      DWORD PTR [EDI+00000390]
001B:00430D71  PUSH      004EB5EF
//[4eb5ef]="%ld",按“長整數”格式化?
001B:00430D76  LEA       EAX,[EBP-10]
001B:00430D79  PUSH      EAX
001B:00430D7A  CALL      004B75F8
//**eax=*[ebp-10]=使用者名稱變碼十進位制字串形式
//可見call 4b75f8是某種字串物件的格式化賦值函式
001B:00430D7F  ADD       ESP,10
001B:00430D82  LEA       EDX,[EBP-00D8]
001B:00430D88  PUSH      14
001B:00430D8A  PUSH      00
001B:00430D8C  PUSH      EDX
001B:00430D8D  CALL      004A8778
//觀察結果結合上次呼叫此函式的記錄可知
//將edx,即[ebp-d8]後的20個位元組清零
001B:00430D92  ADD       ESP,0C
001B:00430D95  LEA       ECX,[EBP-0108]
001B:00430D9B  PUSH      2D
001B:00430D9D  PUSH      00
001B:00430D9F  PUSH      ECX
001B:00430DA0  CALL      004A8778
//將ecx,即[ebp-108]後的45個位元組清零
001B:00430DA5  ADD       ESP,0C
001B:00430DA8  CMP       DWORD PTR [EBP-10],00
001B:00430DAC  JZ        00430DB3
001B:00430DAE  MOV       EAX,[EBP-10]
001B:00430DB1  JMP       00430DB8
001B:00430DB3  MOV       EAX,004EB5F3
001B:00430DB8  PUSH      EDI
001B:00430DB9  MOV       EDI,EAX
001B:00430DBB  XOR       EAX,EAX
001B:00430DBD  OR        ECX,-01
001B:00430DC0  REPNZ SCASB
001B:00430DC2  NOT       ECX
001B:00430DC4  SUB       EDI,ECX
001B:00430DC6  LEA       ESI,[EBP-00D8]
001B:00430DCC  XCHG      ESI,EDI
001B:00430DCE  MOV       EDX,ECX
001B:00430DD0  MOV       EAX,EDI
001B:00430DD2  SHR       ECX,02
001B:00430DD5  REPZ MOVSD
001B:00430DD7  MOV       ECX,EDX
001B:00430DD9  LEA       EDX,[EBP-28]
001B:00430DDC  AND       ECX,03
001B:00430DDF  REPZ MOVSB
//將使用者名稱變碼轉移到[ebp-d8]
001B:00430DE1  POP       EDI
001B:00430DE2  XOR       EAX,EAX
001B:00430DE4  MOV       WORD PTR [EBP-80],005C
001B:00430DEA  MOV       [EBP-28],EAX
001B:00430DED  INC       DWORD PTR [EBP-74]
001B:00430DF0  MOV       EAX,[EDI+0000030C]
001B:00430DF6  CALL      004776F4
//上次呼叫4776f4是取使用者名稱
//這次當然是假碼了,存入[esp-28]
001B:00430DFB  LEA       EDX,[EBP-28]
001B:00430DFE  LEA       EAX,[EBP-08]
001B:00430E01  CALL      004B74D8
//假碼由[ebp-28]轉移到了[ebp-08]
001B:00430E06  DEC       DWORD PTR [EBP-74]
001B:00430E09  LEA       EAX,[EBP-28]
001B:00430E0C  MOV       EDX,00000002
001B:00430E11  CALL      004B74A8
//現在基本可以確定call 4b74a8就是delete了
001B:00430E16  PUSH      EDI
001B:00430E17  LEA       EDI,[EBP-0158]
001B:00430E1D  MOV       ESI,004EB504
001B:00430E22  MOV       ECX,00000014
001B:00430E27  REPZ MOVSD
//將[ebp-158]後的20個雙字清零
001B:00430E29  POP       EDI
001B:00430E2A  XOR       EDX,EDX
001B:00430E2C  MOV       WORD PTR [EBP-80],0008
001B:00430E32  MOV       EAX,[EDI+00000308]
001B:00430E38  CALL      0047760C
001B:00430E3D  MOV       EAX,[EDI+0000030C]
001B:00430E43  XOR       EDX,EDX
001B:00430E45  CALL      0047760C
001B:00430E4A  MOV       EAX,[EDI+00000310]
001B:00430E50  XOR       EDX,EDX
001B:00430E52  CALL      0047760C
001B:00430E57  MOV       EAX,[EDI+00000380]
001B:00430E5D  MOV       DL,01
001B:00430E5F  CALL      0047760C
001B:00430E64  MOV       WORD PTR [EBP-80],0068
001B:00430E6A  MOV       EDX,004EB5F4
001B:00430E6F  LEA       EAX,[EBP-2C]
001B:00430E72  CALL      004B7350
001B:00430E77  INC       DWORD PTR [EBP-74]
001B:00430E7A  MOV       EAX,[EAX]
001B:00430E7C  XOR       EDX,EDX
001B:00430E7E  MOV       [EBP-30],EDX
001B:00430E81  LEA       EDX,[EBP-30]
001B:00430E84  INC       DWORD PTR [EBP-74]
001B:00430E87  CALL      00423550
001B:00430E8C  LEA       EAX,[EBP-30]
001B:00430E8F  MOV       EAX,[EAX]
001B:00430E91  CALL      0047236C
//“關閉程式重啟後才能完成註冊”
//之前一連串的call不知道是幹什麼的
//估計與windows介面操作有關
001B:00430E96  DEC       DWORD PTR [EBP-74]
001B:00430E99  LEA       EAX,[EBP-30]
001B:00430E9C  MOV       EDX,00000002
001B:00430EA1  CALL      004B74A8
001B:00430EA6  DEC       DWORD PTR [EBP-74]
001B:00430EA9  LEA       EAX,[EBP-2C]
001B:00430EAC  MOV       EDX,00000002
001B:00430EB1  CALL      004B74A8
//清除[ebp-30]、[ebp-2c]
001B:00430EB6  MOV       WORD PTR [EBP-80],0074
001B:00430EBC  MOV       EDX,004EB619
001B:00430EC1  LEA       EAX,[EBP-18]
001B:00430EC4  CALL      004B7350
//第一次呼叫4b7350,不知道幹什麼
001B:00430EC9  INC       DWORD PTR [EBP-74]
001B:00430ECC  MOV       EDX,004EB61A
001B:00430ED1  MOV       WORD PTR [EBP-80],0008
001B:00430ED7  MOV       WORD PTR [EBP-80],0080
001B:00430EDD  LEA       EAX,[EBP-34]
001B:00430EE0  CALL      004B7350
//第二次呼叫4b7350,發現*[ebp-34]變成了"-"
//而函式呼叫之前賦過值的[edx]="-"
//猜測也是一種字串賦值函式
001B:00430EE5  INC       DWORD PTR [EBP-74]
001B:00430EE8  LEA       EDX,[EBP-34]
001B:00430EEB  LEA       EAX,[EBP-08]
001B:00430EEE  CALL      004B7674
//函式呼叫之前設定了兩個引數:[ebp-08]、[ebp-34]
//[ebp-08]是假碼,[ebp-34]是"-"
//函式返回值在後面被作為跳轉並退出的判斷依據
//聯想到很多軟體的註冊碼都是用"-"進行分段的
//估計此函式是判斷假碼中是否含有"-"
//將假碼修改成用"-"分段的格式,重新來過
//發現函式返回值eax=第一個"-"在假碼中的位置
001B:00430EF3  MOV       [EBP-009C],EAX
//將eax的值寫入變數[ebp-9c]
001B:00430EF9  DEC       DWORD PTR [EBP-74]
001B:00430EFC  LEA       EAX,[EBP-34]
001B:00430EFF  MOV       EDX,00000002
001B:00430F04  CALL      004B74A8
//清除[ebp-34]
001B:00430F09  MOV       WORD PTR [EBP-80],0008
001B:00430F0F  CMP       DWORD PTR [EBP-009C],00
001B:00430F16  JNZ       00430F8A
//若假碼中含"-"則跳轉
001B:00430F18  DEC       DWORD PTR [EBP-74]
001B:00430F1B  LEA       EAX,[EBP-18]
001B:00430F1E  MOV       EDX,00000002
001B:00430F23  CALL      004B74A8
001B:00430F28  DEC       DWORD PTR [EBP-74]
001B:00430F2B  LEA       EAX,[EBP-14]
001B:00430F2E  MOV       EDX,00000002
001B:00430F33  CALL      004B74A8
001B:00430F38  DEC       DWORD PTR [EBP-74]
001B:00430F3B  LEA       EAX,[EBP-10]
001B:00430F3E  MOV       EDX,00000002
001B:00430F43  CALL      004B74A8
001B:00430F48  DEC       DWORD PTR [EBP-74]
001B:00430F4B  LEA       EAX,[EBP-0C]
001B:00430F4E  MOV       EDX,00000002
001B:00430F53  CALL      004B74A8
001B:00430F58  DEC       DWORD PTR [EBP-74]
001B:00430F5B  LEA       EAX,[EBP-08]
001B:00430F5E  MOV       EDX,00000002
001B:00430F63  CALL      004B74A8
001B:00430F68  DEC       DWORD PTR [EBP-74]
001B:00430F6B  LEA       EAX,[EBP-04]
001B:00430F6E  MOV       EDX,00000002
001B:00430F73  CALL      004B74A8
001B:00430F78  MOV       ECX,[EBP-0090]
001B:00430F7E  MOV       FS:[00000000],ECX
001B:00430F85  JMP       0043195A
//一系列的清除物件動作,之後退出
001B:00430F8A  MOV       WORD PTR [EBP-80],008C
001B:00430F90  XOR       EAX,EAX
001B:00430F92  LEA       EDX,[EBP-38]
001B:00430F95  MOV       [EBP-38],EAX
001B:00430F98  PUSH      EDX
//[ebp-38]清零後入棧
001B:00430F99  INC       DWORD PTR [EBP-74]
001B:00430F9C  MOV       EDX,00000001
001B:00430FA1  MOV       ECX,[EBP-009C]
//ecx="-"在假碼中的位置
001B:00430FA7  LEA       EAX,[EBP-08]
//eax=假碼地址
001B:00430FAA  DEC       ECX
//ecx=假碼第一段的長度
001B:00430FAB  CALL      004B7698
//返回值[eax]=前面入棧的[ebp-38]
//*[ebp-38]=假碼第一段
001B:00430FB0  LEA       EDX,[EBP-38]
001B:00430FB3  LEA       EAX,[EBP-18]
001B:00430FB6  CALL      004B74D8
001B:00430FBB  DEC       DWORD PTR [EBP-74]
001B:00430FBE  LEA       EAX,[EBP-38]
001B:00430FC1  MOV       EDX,00000002
001B:00430FC6  CALL      004B74A8
//將假碼一段從[ebp-38]轉移至[ebp-18]
//並清除[ebp-38]
001B:00430FCB  LEA       EAX,[EBP-08]
001B:00430FCE  MOV       ECX,[EBP-009C]
001B:00430FD4  MOV       EDX,00000001
001B:00430FD9  CALL      004B762C
//將[ebp-08]中的假碼刪去其第一段
001B:00430FDE  MOV       ESI,00000001
//esi通常被用做迴圈變數
001B:00430FE3  LEA       EBX,[EBP-0158]
001B:00430FE9  CMP       ESI,[EBP-009C]
001B:00430FEF  JGE       0043104D
001B:00430FF1  MOV       WORD PTR [EBP-80],0098
001B:00430FF7  XOR       EAX,EAX
001B:00430FF9  LEA       EDX,[EBP-3C]
001B:00430FFC  MOV       [EBP-3C],EAX
001B:00430FFF  PUSH      EDX
001B:00431000  INC       DWORD PTR [EBP-74]
001B:00431003  MOV       EDX,ESI
001B:00431005  LEA       EAX,[EBP-18]
001B:00431008  MOV       ECX,00000001
001B:0043100D  CALL      004B7698
//返回值[eax]為前面入棧的[ebp-3c]
//*[ebp-3c]=假碼一段第一個字元
//此函式在一個以esi為迴圈變數的迴圈體內
//幾次執行後可總結出此函式的作用是:
//將呼叫前[eax]中的字串從第edx位元組開始
//複製ecx個位元組到之前被push的地址中
//並返回其指標到eax
001B:00431012  LEA       EDX,[EBP-3C]
001B:00431015  LEA       EAX,[EBP-10]
001B:00431018  CALL      004B74D8
001B:0043101D  DEC       DWORD PTR [EBP-74]
001B:00431020  LEA       EAX,[EBP-3C]
001B:00431023  MOV       EDX,00000002
001B:00431028  CALL      004B74A8
//將[ebp-3c]中的假碼一段當前字元轉移到[ebp-10]
//並清除[ebp-3c]
001B:0043102D  LEA       EDX,[EBP-10]
001B:00431030  LEA       EAX,[EBP-04]
//[ebp-04]是前面被俺命名為“密碼錶”的一個長字串
001B:00431033  CALL      004B7674
//前面曾用call 4b7674函式檢查"-"在假碼中的位置
//稍加推測,這裡是返回假碼中某字元在密碼錶中的位置
001B:00431038  MOV       WORD PTR [EBP-80],0008
001B:0043103E  DEC       EAX
001B:0043103F  MOV       [EBX],EAX
//將eax-1存入ebx
//ebx在迴圈開始前被賦值為[ebp-158]
//ebx在迴圈中每次+4
//所以假碼一段的第i個字元的查表值存在[ebp-158+i*4]
//i從0開始,到假碼一段長度-1
001B:00431041  INC       ESI
001B:00431042  ADD       EBX,04
001B:00431045  CMP       ESI,[EBP-009C]
001B:0043104B  JL        00430FF1
//迴圈“查表”動作
001B:0043104D  XOR       EDI,EDI
001B:0043104F  MOV       ESI,[EBP-009C]
//[ebp-9c]=假碼一段長度+1
001B:00431055  ADD       ESI,-02
//esi=假碼一段長度-1
001B:00431058  LEA       EBX,[ESI*4+EBP-0158]
001B:0043105F  TEST      ESI,ESI
001B:00431061  JL        004310C1
001B:00431063  MOV       [EBP-015C],ESI
001B:00431069  FILD      DWORD PTR [EBP-015C]
//將esi讀入浮點暫存器轉化成real8
001B:0043106F  ADD       ESP,-08
001B:00431072  FSTP      REAL8 PTR [ESP]
001B:00431075  PUSH      403E0000
//403e0000是30的real8格式
001B:0043107A  PUSH      00
001B:0043107C  CALL      004AFE38
//浮點暫存器st(0)返回30的esi次方
//用wf指令可檢視浮點暫存器的值
001B:00431081  MOV       EAX,[EBX]
001B:00431083  XOR       EDX,EDX
001B:00431085  MOV       [EBP-0164],EAX
001B:0043108B  MOV       [EBP-0160],EDX
001B:00431091  FILD      QWORD PTR [EBP-0164]
001B:00431097  ADD       ESP,10
001B:0043109A  XOR       ECX,ECX
001B:0043109C  MOV       [EBP-016C],EDI
//將上次結果記入[ebp-16c]
001B:004310A2  MOV       [EBP-0168],ECX
001B:004310A8  FMULP     ST(1),ST
//假碼查表值的第i位乘上30的(i-1)次方
001B:004310AA  FILD      QWORD PTR [EBP-016C]
001B:004310B0  FADDP     ST(1),ST
//累加運算結果
001B:004310B2  CALL      004AF9F0
001B:004310B7  MOV       EDI,EAX
//將結果記入edi
001B:004310B9  DEC       ESI
001B:004310BA  ADD       EBX,-04
001B:004310BD  TEST      ESI,ESI
001B:004310BF  JGE       00431063
//迴圈操作
//相當於將假碼一段的查表值倒序後
//再由30進位制轉化為10進位制
001B:004310C1  PUSH      EDI
001B:004310C2  PUSH      004EB61C
001B:004310C7  LEA       EDX,[EBP-10]
001B:004310CA  PUSH      EDX
001B:004310CB  CALL      004B75F8
001B:004310D0  ADD       ESP,0C
001B:004310D3  LEA       EDX,[EBP-10]
001B:004310D6  LEA       EAX,[EBP-0C]
001B:004310D9  CALL      004B74EC
//再轉換成十進位制表示的字串存入[ebp-0c]
//不妨稱之為假碼一段變碼
001B:004310DE  MOV       WORD PTR [EBP-80],00A4
001B:004310E4  MOV       EDX,004EB620
001B:004310E9  LEA       EAX,[EBP-1C]
001B:004310EC  CALL      004B7350
001B:004310F1  INC       DWORD PTR [EBP-74]
001B:004310F4  MOV       EDX,004EB621
001B:004310F9  MOV       WORD PTR [EBP-80],0008
001B:004310FF  MOV       WORD PTR [EBP-80],00B0
001B:00431105  LEA       EAX,[EBP-40]
001B:00431108  CALL      004B7350
001B:0043110D  INC       DWORD PTR [EBP-74]
001B:00431110  LEA       EDX,[EBP-40]
001B:00431113  LEA       EAX,[EBP-08]
001B:00431116  CALL      004B7674
//檢查"-"在假碼二段中的位置
001B:0043111B  MOV       [EBP-009C],EAX
001B:00431121  DEC       DWORD PTR [EBP-74]
001B:00431124  LEA       EAX,[EBP-40]
001B:00431127  MOV       EDX,00000002
001B:0043112C  CALL      004B74A8
001B:00431131  MOV       WORD PTR [EBP-80],00BC
001B:00431137  XOR       ECX,ECX
001B:00431139  LEA       EAX,[EBP-44]
001B:0043113C  MOV       [EBP-44],ECX
001B:0043113F  PUSH      EAX
001B:00431140  INC       DWORD PTR [EBP-74]
001B:00431143  LEA       EAX,[EBP-08]
001B:00431146  MOV       ECX,[EBP-009C]
001B:0043114C  MOV       EDX,00000001
001B:00431151  DEC       ECX
001B:00431152  CALL      004B7698
//將假碼二段提取出來放入[ebp-44]
001B:00431157  LEA       EDX,[EBP-44]
001B:0043115A  LEA       EAX,[EBP-1C]
001B:0043115D  CALL      004B74D8
001B:00431162  DEC       DWORD PTR [EBP-74]
001B:00431165  LEA       EAX,[EBP-44]
001B:00431168  MOV       EDX,00000002
001B:0043116D  CALL      004B74A8
001B:00431172  LEA       EAX,[EBP-08]
001B:00431175  MOV       ECX,[EBP-009C]
001B:0043117B  MOV       EDX,00000001
001B:00431180  CALL      004B762C
001B:00431185  MOV       ESI,00000001
001B:0043118A  LEA       EBX,[EBP-0158]
001B:00431190  CMP       ESI,[EBP-009C]
001B:00431196  JGE       004311F4
001B:00431198  MOV       WORD PTR [EBP-80],00C8
001B:0043119E  XOR       EAX,EAX
001B:004311A0  LEA       EDX,[EBP-48]
001B:004311A3  MOV       [EBP-48],EAX
001B:004311A6  PUSH      EDX
001B:004311A7  INC       DWORD PTR [EBP-74]
001B:004311AA  MOV       EDX,ESI
001B:004311AC  LEA       EAX,[EBP-1C]
001B:004311AF  MOV       ECX,00000001
001B:004311B4  CALL      004B7698
001B:004311B9  LEA       EDX,[EBP-48]
001B:004311BC  LEA       EAX,[EBP-10]
001B:004311BF  CALL      004B74D8
001B:004311C4  DEC       DWORD PTR [EBP-74]
001B:004311C7  LEA       EAX,[EBP-48]
001B:004311CA  MOV       EDX,00000002
001B:004311CF  CALL      004B74A8
001B:004311D4  LEA       EDX,[EBP-10]
001B:004311D7  LEA       EAX,[EBP-04]
001B:004311DA  CALL      004B7674
001B:004311DF  MOV       WORD PTR [EBP-80],0008
001B:004311E5  DEC       EAX
001B:004311E6  MOV       [EBX],EAX
001B:004311E8  INC       ESI
001B:004311E9  ADD       EBX,04
001B:004311EC  CMP       ESI,[EBP-009C]
001B:004311F2  JL        00431198
001B:004311F4  XOR       EDI,EDI
001B:004311F6  CMP       DWORD PTR [EBP-0158],1E
001B:004311FD  JNZ       00431251
001B:004311FF  MOV       WORD PTR [EBP-80],00D4
001B:00431205  LEA       EAX,[EBP-4C]
001B:00431208  MOV       DL,30
001B:0043120A  CALL      004B745C
001B:0043120F  INC       DWORD PTR [EBP-74]
001B:00431212  LEA       EDX,[EBP-4C]
001B:00431215  LEA       EAX,[EBP-0C]
001B:00431218  CALL      004B74EC
001B:0043121D  DEC       DWORD PTR [EBP-74]
001B:00431220  LEA       EAX,[EBP-4C]
001B:00431223  MOV       EDX,00000002
001B:00431228  CALL      004B74A8
001B:0043122D  MOV       WORD PTR [EBP-80],0008
001B:00431233  XOR       EDX,EDX
001B:00431235  LEA       EAX,[EBP-0154]
001B:0043123B  MOV       ECX,[EAX]
001B:0043123D  MOV       [EAX-04],ECX
001B:00431240  INC       EDX
001B:00431241  ADD       EAX,04
001B:00431244  CMP       EDX,13
001B:00431247  JL        0043123B
001B:00431249  DEC       DWORD PTR [EBP-009C]
001B:0043124F  JMP       004311F6
001B:00431251  MOV       ESI,[EBP-009C]
001B:00431257  ADD       ESI,-02
001B:0043125A  LEA       EBX,[ESI*4+EBP-0158]
001B:00431261  TEST      ESI,ESI
001B:00431263  JL        004312C3
001B:00431265  MOV       [EBP-015C],ESI
001B:0043126B  FILD      DWORD PTR [EBP-015C]
001B:00431271  ADD       ESP,-08
001B:00431274  FSTP      REAL8 PTR [ESP]
001B:00431277  PUSH      403E0000
001B:0043127C  PUSH      00
001B:0043127E  CALL      004AFE38
001B:00431283  MOV       EAX,[EBX]
001B:00431285  XOR       EDX,EDX
001B:00431287  MOV       [EBP-0164],EAX
001B:0043128D  MOV       [EBP-0160],EDX
001B:00431293  FILD      QWORD PTR [EBP-0164]
001B:00431299  ADD       ESP,10
001B:0043129C  XOR       ECX,ECX
001B:0043129E  MOV       [EBP-016C],EDI
001B:004312A4  MOV       [EBP-0168],ECX
001B:004312AA  FMULP     ST(1),ST
001B:004312AC  FILD      QWORD PTR [EBP-016C]
001B:004312B2  FADDP     ST(1),ST
001B:004312B4  CALL      004AF9F0
001B:004312B9  MOV       EDI,EAX
001B:004312BB  DEC       ESI
001B:004312BC  ADD       EBX,-04
001B:004312BF  TEST      ESI,ESI
001B:004312C1  JGE       00431265
//以上求假碼二段變碼
001B:004312C3  PUSH      EDI
001B:004312C4  PUSH      004EB623
001B:004312C9  LEA       EDX,[EBP-10]
001B:004312CC  PUSH      EDX
001B:004312CD  CALL      004B75F8
001B:004312D2  ADD       ESP,0C
001B:004312D5  LEA       EDX,[EBP-10]
001B:004312D8  LEA       EAX,[EBP-0C]
001B:004312DB  CALL      004B74EC
//將假碼二段變碼新增到假碼一段變碼之後
//變碼地址為[ebp-0c]
001B:004312E0  MOV       WORD PTR [EBP-80],00E0
001B:004312E6  MOV       EDX,004EB627
001B:004312EB  LEA       EAX,[EBP-20]
001B:004312EE  CALL      004B7350
001B:004312F3  INC       DWORD PTR [EBP-74]
001B:004312F6  MOV       EDX,004EB628
001B:004312FB  MOV       WORD PTR [EBP-80],0008
001B:00431301  MOV       WORD PTR [EBP-80],00EC
001B:00431307  LEA       EAX,[EBP-50]
001B:0043130A  CALL      004B7350
001B:0043130F  INC       DWORD PTR [EBP-74]
001B:00431312  LEA       EDX,[EBP-50]
001B:00431315  LEA       EAX,[EBP-08]
001B:00431318  CALL      004B7674
001B:0043131D  MOV       [EBP-009C],EAX
001B:00431323  DEC       DWORD PTR [EBP-74]
001B:00431326  LEA       EAX,[EBP-50]
001B:00431329  MOV       EDX,00000002
001B:0043132E  CALL      004B74A8
001B:00431333  CMP       DWORD PTR [EBP-009C],00
001B:0043133A  JNZ       00431353
001B:0043133C  CMP       DWORD PTR [EBP-08],00
001B:00431340  JZ        0043134A
001B:00431342  MOV       ECX,[EBP-08]
001B:00431345  MOV       EAX,[ECX-04]
001B:00431348  JMP       0043134C
001B:0043134A  XOR       EAX,EAX
001B:0043134C  INC       EAX
001B:0043134D  MOV       [EBP-009C],EAX
001B:00431353  MOV       WORD PTR [EBP-80],00F8
001B:00431359  XOR       EDX,EDX
001B:0043135B  LEA       ECX,[EBP-54]
001B:0043135E  MOV       [EBP-54],EDX
001B:00431361  PUSH      ECX
001B:00431362  INC       DWORD PTR [EBP-74]
001B:00431365  MOV       EDX,00000001
001B:0043136A  MOV       ECX,[EBP-009C]
001B:00431370  LEA       EAX,[EBP-08]
001B:00431373  DEC       ECX
001B:00431374  CALL      004B7698
001B:00431379  LEA       EDX,[EBP-54]
001B:0043137C  LEA       EAX,[EBP-20]
001B:0043137F  CALL      004B74D8
001B:00431384  DEC       DWORD PTR [EBP-74]
001B:00431387  LEA       EAX,[EBP-54]
001B:0043138A  MOV       EDX,00000002
001B:0043138F  CALL      004B74A8
001B:00431394  LEA       EAX,[EBP-08]
001B:00431397  MOV       ECX,[EBP-009C]
001B:0043139D  MOV       EDX,00000001
001B:004313A2  CALL      004B762C
001B:004313A7  MOV       ESI,00000001
001B:004313AC  LEA       EBX,[EBP-0158]
001B:004313B2  CMP       ESI,[EBP-009C]
001B:004313B8  JGE       00431416
001B:004313BA  MOV       WORD PTR [EBP-80],0104
001B:004313C0  XOR       EAX,EAX
001B:004313C2  LEA       EDX,[EBP-58]
001B:004313C5  MOV       [EBP-58],EAX
001B:004313C8  PUSH      EDX
001B:004313C9  INC       DWORD PTR [EBP-74]
001B:004313CC  MOV       EDX,ESI
001B:004313CE  LEA       EAX,[EBP-20]
001B:004313D1  MOV       ECX,00000001
001B:004313D6  CALL      004B7698
001B:004313DB  LEA       EDX,[EBP-58]
001B:004313DE  LEA       EAX,[EBP-10]
001B:004313E1  CALL      004B74D8
001B:004313E6  DEC       DWORD PTR [EBP-74]
001B:004313E9  LEA       EAX,[EBP-58]
001B:004313EC  MOV       EDX,00000002
001B:004313F1  CALL      004B74A8
001B:004313F6  LEA       EDX,[EBP-10]
001B:004313F9  LEA       EAX,[EBP-04]
001B:004313FC  CALL      004B7674
001B:00431401  MOV       WORD PTR [EBP-80],0008
001B:00431407  DEC       EAX
001B:00431408  MOV       [EBX],EAX
001B:0043140A  INC       ESI
001B:0043140B  ADD       EBX,04
001B:0043140E  CMP       ESI,[EBP-009C]
001B:00431414  JL        004313BA
001B:00431416  XOR       EDI,EDI
001B:00431418  CMP       DWORD PTR [EBP-0158],1E
001B:0043141F  JNZ       00431473
001B:00431421  MOV       WORD PTR [EBP-80],0110
001B:00431427  LEA       EAX,[EBP-5C]
001B:0043142A  MOV       DL,30
001B:0043142C  CALL      004B745C
001B:00431431  INC       DWORD PTR [EBP-74]
001B:00431434  LEA       EDX,[EBP-5C]
001B:00431437  LEA       EAX,[EBP-0C]
001B:0043143A  CALL      004B74EC
001B:0043143F  DEC       DWORD PTR [EBP-74]
001B:00431442  LEA       EAX,[EBP-5C]
001B:00431445  MOV       EDX,00000002
001B:0043144A  CALL      004B74A8
001B:0043144F  MOV       WORD PTR [EBP-80],0008
001B:00431455  XOR       EDX,EDX
001B:00431457  LEA       EAX,[EBP-0154]
001B:0043145D  MOV       ECX,[EAX]
001B:0043145F  MOV       [EAX-04],ECX
001B:00431462  INC       EDX
001B:00431463  ADD       EAX,04
001B:00431466  CMP       EDX,13
001B:00431469  JL        0043145D
001B:0043146B  DEC       DWORD PTR [EBP-009C]
001B:00431471  JMP       00431418
001B:00431473  MOV       ESI,[EBP-009C]
001B:00431479  ADD       ESI,-02
001B:0043147C  LEA       EBX,[ESI*4+EBP-0158]
001B:00431483  TEST      ESI,ESI
001B:00431485  JL        004314E5
001B:00431487  MOV       [EBP-015C],ESI
001B:0043148D  FILD      DWORD PTR [EBP-015C]
001B:00431493  ADD       ESP,-08
001B:00431496  FSTP      REAL8 PTR [ESP]
001B:00431499  PUSH      403E0000
001B:0043149E  PUSH      00
001B:004314A0  CALL      004AFE38
001B:004314A5  MOV       EAX,[EBX]
001B:004314A7  XOR       EDX,EDX
001B:004314A9  MOV       [EBP-0164],EAX
001B:004314AF  MOV       [EBP-0160],EDX
001B:004314B5  FILD      QWORD PTR [EBP-0164]
001B:004314BB  ADD       ESP,10
001B:004314BE  XOR       ECX,ECX
001B:004314C0  MOV       [EBP-016C],EDI
001B:004314C6  MOV       [EBP-0168],ECX
001B:004314CC  FMULP     ST(1),ST
001B:004314CE  FILD      QWORD PTR [EBP-016C]
001B:004314D4  FADDP     ST(1),ST
001B:004314D6  CALL      004AF9F0
001B:004314DB  MOV       EDI,EAX
001B:004314DD  DEC       ESI
001B:004314DE  ADD       EBX,-04
001B:004314E1  TEST      ESI,ESI
001B:004314E3  JGE       00431487
001B:004314E5  PUSH      EDI
001B:004314E6  PUSH      004EB62A
001B:004314EB  LEA       EDX,[EBP-10]
001B:004314EE  PUSH      EDX
001B:004314EF  CALL      004B75F8
001B:004314F4  ADD       ESP,0C
001B:004314F7  LEA       EDX,[EBP-10]
001B:004314FA  LEA       EAX,[EBP-0C]
001B:004314FD  CALL      004B74EC
//將假碼三段變碼加入[ebp-0c]
001B:00431502  CMP       DWORD PTR [EBP-08],00
001B:00431506  JZ        00431510
001B:00431508  MOV       ECX,[EBP-08]
001B:0043150B  MOV       EAX,[ECX-04]
001B:0043150E  JMP       00431512
001B:00431510  XOR       EAX,EAX
001B:00431512  TEST      EAX,EAX
001B:00431514  JLE       00431712
001B:0043151A  MOV       WORD PTR [EBP-80],0128
001B:00431520  MOV       EDX,004EB62E
001B:00431525  LEA       EAX,[EBP-60]
001B:00431528  CALL      004B7350
001B:0043152D  INC       DWORD PTR [EBP-74]
001B:00431530  MOV       WORD PTR [EBP-80],011C
001B:00431536  CMP       DWORD PTR [EBP-08],00
001B:0043153A  JZ        00431544
001B:0043153C  MOV       EDX,[EBP-08]
001B:0043153F  MOV       ECX,[EDX-04]
001B:00431542  JMP       00431546
001B:00431544  XOR       ECX,ECX
001B:00431546  INC       ECX
001B:00431547  XOR       EAX,EAX
001B:00431549  MOV       [EBP-009C],ECX
001B:0043154F  LEA       EDX,[EBP-64]
001B:00431552  MOV       WORD PTR [EBP-80],0134
001B:00431558  MOV       [EBP-64],EAX
001B:0043155B  PUSH      EDX
001B:0043155C  INC       DWORD PTR [EBP-74]
001B:0043155F  MOV       EDX,00000001
001B:00431564  MOV       ECX,[EBP-009C]
001B:0043156A  LEA       EAX,[EBP-08]
001B:0043156D  DEC       ECX
001B:0043156E  CALL      004B7698
001B:00431573  LEA       EDX,[EBP-64]
001B:00431576  LEA       EAX,[EBP-60]
001B:00431579  CALL      004B74D8
001B:0043157E  DEC       DWORD PTR [EBP-74]
001B:00431581  LEA       EAX,[EBP-64]
001B:00431584  MOV       EDX,00000002
001B:00431589  CALL      004B74A8
001B:0043158E  LEA       EAX,[EBP-08]
001B:00431591  MOV       ECX,[EBP-009C]
001B:00431597  MOV       EDX,00000001
001B:0043159C  CALL      004B762C
001B:004315A1  MOV       ESI,00000001
001B:004315A6  LEA       EBX,[EBP-0158]
001B:004315AC  CMP       ESI,[EBP-009C]
001B:004315B2  JGE       00431610
001B:004315B4  MOV       WORD PTR [EBP-80],0140
001B:004315BA  XOR       EAX,EAX
001B:004315BC  LEA       EDX,[EBP-68]
001B:004315BF  MOV       [EBP-68],EAX
001B:004315C2  PUSH      EDX
001B:004315C3  INC       DWORD PTR [EBP-74]
001B:004315C6  MOV       EDX,ESI
001B:004315C8  LEA       EAX,[EBP-60]
001B:004315CB  MOV       ECX,00000001
001B:004315D0  CALL      004B7698
001B:004315D5  LEA       EDX,[EBP-68]
001B:004315D8  LEA       EAX,[EBP-10]
001B:004315DB  CALL      004B74D8
001B:004315E0  DEC       DWORD PTR [EBP-74]
001B:004315E3  LEA       EAX,[EBP-68]
001B:004315E6  MOV       EDX,00000002
001B:004315EB  CALL      004B74A8
001B:004315F0  LEA       EDX,[EBP-10]
001B:004315F3  LEA       EAX,[EBP-04]
001B:004315F6  CALL      004B7674
001B:004315FB  MOV       WORD PTR [EBP-80],011C
001B:00431601  DEC       EAX
001B:00431602  MOV       [EBX],EAX
001B:00431604  INC       ESI
001B:00431605  ADD       EBX,04
001B:00431608  CMP       ESI,[EBP-009C]
001B:0043160E  JL        004315B4
001B:00431610  XOR       EDI,EDI
001B:00431612  CMP       DWORD PTR [EBP-0158],1E
001B:00431619  JNZ       0043166D
001B:0043161B  MOV       WORD PTR [EBP-80],014C
001B:00431621  LEA       EAX,[EBP-6C]
001B:00431624  MOV       DL,30
001B:00431626  CALL      004B745C
001B:0043162B  INC       DWORD PTR [EBP-74]
001B:0043162E  LEA       EDX,[EBP-6C]
001B:00431631  LEA       EAX,[EBP-0C]
001B:00431634  CALL      004B74EC
001B:00431639  DEC       DWORD PTR [EBP-74]
001B:0043163C  LEA       EAX,[EBP-6C]
001B:0043163F  MOV       EDX,00000002
001B:00431644  CALL      004B74A8
001B:00431649  MOV       WORD PTR [EBP-80],011C
001B:0043164F  XOR       EDX,EDX
001B:00431651  LEA       EAX,[EBP-0154]
001B:00431657  MOV       ECX,[EAX]
001B:00431659  MOV       [EAX-04],ECX
001B:0043165C  INC       EDX
001B:0043165D  ADD       EAX,04
001B:00431660  CMP       EDX,13
001B:00431663  JL        00431657
001B:00431665  DEC       DWORD PTR [EBP-009C]
001B:0043166B  JMP       00431612
001B:0043166D  MOV       ESI,[EBP-009C]
001B:00431673  ADD       ESI,-02
001B:00431676  LEA       EBX,[ESI*4+EBP-0158]
001B:0043167D  TEST      ESI,ESI
001B:0043167F  JL        004316DF
001B:00431681  MOV       [EBP-015C],ESI
001B:00431687  FILD      DWORD PTR [EBP-015C]
001B:0043168D  ADD       ESP,-08
001B:00431690  FSTP      REAL8 PTR [ESP]
001B:00431693  PUSH      403E0000
001B:00431698  PUSH      00
001B:0043169A  CALL      004AFE38
001B:0043169F  MOV       EAX,[EBX]
001B:004316A1  XOR       EDX,EDX
001B:004316A3  MOV       [EBP-0164],EAX
001B:004316A9  MOV       [EBP-0160],EDX
001B:004316AF  FILD      QWORD PTR [EBP-0164]
001B:004316B5  ADD       ESP,10
001B:004316B8  XOR       ECX,ECX
001B:004316BA  MOV       [EBP-016C],EDI
001B:004316C0  MOV       [EBP-0168],ECX
001B:004316C6  FMULP     ST(1),ST
001B:004316C8  FILD      QWORD PTR [EBP-016C]
001B:004316CE  FADDP     ST(1),ST
001B:004316D0  CALL      004AF9F0
001B:004316D5  MOV       EDI,EAX
001B:004316D7  DEC       ESI
001B:004316D8  ADD       EBX,-04
001B:004316DB  TEST      ESI,ESI
001B:004316DD  JGE       00431681
001B:004316DF  PUSH      EDI
001B:004316E0  PUSH      004EB62F
001B:004316E5  LEA       EDX,[EBP-10]
001B:004316E8  PUSH      EDX
001B:004316E9  CALL      004B75F8
001B:004316EE  ADD       ESP,0C
001B:004316F1  LEA       EDX,[EBP-10]
001B:004316F4  LEA       EAX,[EBP-0C]
001B:004316F7  CALL      004B74EC
//將假碼四段變碼加入[ebp-0c]
001B:004316FC  DEC       DWORD PTR [EBP-74]
001B:004316FF  LEA       EAX,[EBP-60]
001B:00431702  MOV       EDX,00000002
001B:00431707  CALL      004B74A8
001B:0043170C  MOV       WORD PTR [EBP-80],0008
001B:00431712  CMP       DWORD PTR [EBP-0C],00
001B:00431716  JZ        0043171D
001B:00431718  MOV       ECX,[EBP-0C]
001B:0043171B  JMP       00431722
001B:0043171D  MOV       ECX,004EB633
001B:00431722  MOV       EDI,ECX
001B:00431724  XOR       EAX,EAX
001B:00431726  OR        ECX,-01
001B:00431729  LEA       ESI,[EBP-0108]
001B:0043172F  REPNZ SCASB
001B:00431731  NOT       ECX
001B:00431733  SUB       EDI,ECX
001B:00431735  MOV       EDX,ECX
001B:00431737  XCHG      ESI,EDI
001B:00431739  SHR       ECX,02
001B:0043173C  MOV       EAX,EDI
001B:0043173E  REPZ MOVSD
001B:00431740  MOV       ECX,EDX
001B:00431742  AND       ECX,03
001B:00431745  REPZ MOVSB
//將四段合併後的假碼變碼轉移到[ebp-108]
//可見註冊碼是分成四段的
//另外回頭去看本驗證函式在前面曾有
//將[ebp-d8]後20位元組清零
//將[ebp-108]後45位元組清零
//的可疑動作,現在清楚了
//[ebp-d8]是使用者名稱變碼
//[ebp-108]是假碼變碼
001B:00431747  XOR       EAX,EAX
001B:00431749  XOR       EDX,EDX
001B:0043174B  MOV       [EBP-00A0],EAX
001B:00431751  XOR       ECX,ECX
001B:00431753  MOV       WORD PTR [EBP-80],0008
001B:00431759  MOV       [EBP-00A4],EDX
001B:0043175F  MOV       [EBP-00A8],ECX
001B:00431765  XOR       EAX,EAX
001B:00431767  XOR       EDX,EDX
001B:00431769  MOV       [EBP-00AC],EAX
001B:0043176F  MOV       [EBP-00B0],EDX
//一大堆清零動作
001B:00431775  LEA       ECX,[EBP-00A8]
001B:0043177B  LEA       EAX,[EBP-0108]
001B:00431781  PUSH      ECX
001B:00431782  PUSH      EAX
001B:00431783  CALL      0043CC8C
//將假碼變碼變成了一個很大的整數
001B:00431788  ADD       ESP,08
001B:0043178B  LEA       EDX,[EBP-00A0]
001B:00431791  PUSH      EDX
001B:00431792  PUSH      004EB634
//[4eb634]="C7B71C573A60F571"
//看起來像一個16進位制的大數
001B:00431797  CALL      0043CAC0
//將字串轉換成了數值,但變成了
//C1EDC715C3A60F571
//高位變了低位不變
//猜測是數值形式有符號及進位標誌造成的
001B:0043179C  ADD       ESP,08
001B:0043179F  LEA       ECX,[EBP-00A4]
001B:004317A5  PUSH      ECX
001B:004317A6  PUSH      004EB645
//[4eb645]="10001"
001B:004317AB  CALL      0043CAC0
//將字串變成數值
001B:004317B0  ADD       ESP,08
001B:004317B3  LEA       EAX,[EBP-00B0]
001B:004317B9  PUSH      EAX
001B:004317BA  MOV       EDX,[EBP-00A0]
001B:004317C0  PUSH      EDX
001B:004317C1  MOV       ECX,[EBP-00A4]
001B:004317C7  PUSH      ECX
001B:004317C8  MOV       EAX,[EBP-00A8]
001B:004317CE  PUSH      EAX
001B:004317CF  CALL      0043BC38
//以假碼變碼、C7B71C573A60F571、10001為引數
//計算出另一個數
001B:004317D4  ADD       ESP,10
001B:004317D7  LEA       EDX,[EBP-00AC]
001B:004317DD  PUSH      EDX
001B:004317DE  LEA       ECX,[EBP-00D8]
001B:004317E4  PUSH      ECX
001B:004317E5  CALL      0043CAC0
//將這個數與使用者名稱變碼做比較
//不同則跳出函式!!!
//觀察C7B71C573A60F571=14391002295252874609
//14391002295252874609=3040705643*4732783763
//是兩個大素數的積
//而10001化成十進位制=65537
//是典型的公鑰
//所以,RSA無疑
001B:004317EA  ADD       ESP,08
001B:004317ED  MOV       EAX,[EBP-00B0]
001B:004317F3  PUSH      EAX
001B:004317F4  MOV       EDX,[EBP-00AC]
001B:004317FA  PUSH      EDX
001B:004317FB  CALL      00439DF0
001B:00431800  ADD       ESP,08
001B:00431803  TEST      EAX,EAX
001B:00431805  JNZ       004318CD
001B:0043180B  MOV       ECX,[004F538C]
001B:00431811  LEA       EDI,[EBP-00C4]
001B:00431817  MOV       EAX,[ECX]
001B:00431819  ADD       EAX,000020F1
001B:0043181E  MOV       ESI,EAX
001B:00431820  XOR       EAX,EAX
001B:00431822  OR        ECX,-01
001B:00431825  REPNZ SCASB
001B:00431827  NOT       ECX
001B:00431829  SUB       EDI,ECX
001B:0043182B  MOV       EDX,ECX
001B:0043182D  XCHG      ESI,EDI
001B:0043182F  SHR       ECX,02
001B:00431832  MOV       EAX,EDI
001B:00431834  REPZ MOVSD
001B:00431836  MOV       ECX,EDX
001B:00431838  AND       ECX,03
001B:0043183B  REPZ MOVSB
001B:0043183D  MOV       EAX,[004F538C]
001B:00431842  LEA       EDI,[EBP-0108]
001B:00431848  MOV       EDX,[EAX]
001B:0043184A  XOR       EAX,EAX
001B:0043184C  ADD       EDX,0000210A
001B:00431852  OR        ECX,-01
001B:00431855  REPNZ SCASB
001B:00431857  NOT       ECX
001B:00431859  SUB       EDI,ECX
001B:0043185B  MOV       ESI,EDX
001B:0043185D  XCHG      ESI,EDI
001B:0043185F  MOV       EDX,ECX
001B:00431861  MOV       EAX,EDI
001B:00431863  SHR       ECX,02
001B:00431866  REPZ MOVSD
001B:00431868  MOV       ECX,EDX
001B:0043186A  AND       ECX,03
001B:0043186D  REPZ MOVSB
001B:0043186F  MOV       EAX,[EBP-00B0]
001B:00431875  PUSH      EAX
001B:00431876  MOV       EDX,[EBP-00AC]
001B:0043187C  PUSH      EDX
001B:0043187D  CALL      00439DF0
001B:00431882  ADD       ESP,08
001B:00431885  TEST      EAX,EAX
001B:00431887  JNZ       004318CD
001B:00431889  MOV       ECX,[004F538C]
001B:0043188F  XOR       ESI,ESI
001B:00431891  MOV       EAX,[ECX]
001B:00431893  MOV       BYTE PTR [EAX+00002141],01
001B:0043189A  CALL      004B00C0
001B:0043189F  CDQ
001B:004318A0  MOV       ECX,00000032
001B:004318A5  IDIV      ECX
001B:004318A7  LEA       EAX,[ESI*4+ESI]
001B:004318AA  MOV       ECX,[004F538C]
001B:004318B0  ADD       DL,65
001B:004318B3  LEA       EAX,[EAX*2+ESI]
001B:004318B6  SHL       EAX,03
001B:004318B9  MOV       ECX,[ECX]
001B:004318BB  SUB       EAX,ESI
001B:004318BD  LEA       EAX,[EAX*4+ESI]
001B:004318C0  INC       ESI
001B:004318C1  CMP       ESI,03
001B:004318C4  MOV       [EAX*4+ECX+00000A26],DL
001B:004318CB  JL        0043189A
001B:004318CD  DEC       DWORD PTR [EBP-74]
001B:004318D0  LEA       EAX,[EBP-20]
001B:004318D3  MOV       EDX,00000002
001B:004318D8  CALL      004B74A8
001B:004318DD  DEC       DWORD PTR [EBP-74]
001B:004318E0  LEA       EAX,[EBP-1C]
001B:004318E3  MOV       EDX,00000002
001B:004318E8  CALL      004B74A8
001B:004318ED  DEC       DWORD PTR [EBP-74]
001B:004318F0  LEA       EAX,[EBP-18]
001B:004318F3  MOV       EDX,00000002
001B:004318F8  CALL      004B74A8
001B:004318FD  DEC       DWORD PTR [EBP-74]
001B:00431900  LEA       EAX,[EBP-14]
001B:00431903  MOV       EDX,00000002
001B:00431908  CALL      004B74A8
001B:0043190D  DEC       DWORD PTR [EBP-74]
001B:00431910  LEA       EAX,[EBP-10]
001B:00431913  MOV       EDX,00000002
001B:00431918  CALL      004B74A8
001B:0043191D  DEC       DWORD PTR [EBP-74]
001B:00431920  LEA       EAX,[EBP-0C]
001B:00431923  MOV       EDX,00000002
001B:00431928  CALL      004B74A8
001B:0043192D  DEC       DWORD PTR [EBP-74]
001B:00431930  LEA       EAX,[EBP-08]
001B:00431933  MOV       EDX,00000002
001B:00431938  CALL      004B74A8
001B:0043193D  DEC       DWORD PTR [EBP-74]
001B:00431940  LEA       EAX,[EBP-04]
001B:00431943  MOV       EDX,00000002
001B:00431948  CALL      004B74A8
001B:0043194D  MOV       ECX,[EBP-0090]
001B:00431953  MOV       FS:[00000000],ECX
001B:0043195A  POP       EDI
001B:0043195B  POP       ESI
001B:0043195C  POP       EBX
001B:0043195D  MOV       ESP,EBP
001B:0043195F  POP       EBP
001B:00431960  RET
//在驗證假碼之後,此函式還將使用者名稱、假碼再做變換並寫入檔案
//在重啟之後肯定還有多次驗證
//對於本教程來說,這些都已經不重要
//應為我們追求的是正確的註冊碼,而不是爆破


序號產生器演算法:

   序號產生器演算法當然就是註冊驗證演算法的逆演算法啦!我們先來總結
一下驗證演算法:

   1、使用者名稱的變化
     
      設使用者名稱為char username[len];
      使用者名稱變碼為 long name;
      則有:
      int num;
      name = 0;
      for(int i=0;i<len;i++)
      {
          num = username[i]-48;
          num = num*(num+1);
          name = name+num;
      }
      name = name+123456;


   2、假碼的變化

      設假碼為char passcode[4][len];
      密碼錶為 char* table="L5WXT6VMB4GE3RUYJ9HASF8KQNPD7CI";
      假碼變碼為 long code[4];
      則有:
      int num;
      char ch;
      for(int i=0;i<4;i++)
      {
          code[i]=0;
          for(int j=len-1;j>=0;j--)
          {
              ch = passcode[i][j];
              for(int k=0;k<30;k++)
              {
                  if(table[k]==ch)
                  {
                      num=k;
                      break;
                  }
              }
              code[i]=code[i]*30+num;
          }
       }      
     
     
   3、RSA驗證      
     
      模 n =14391002295252874609
      公鑰 d =65537
      可計算出私鑰 e =3084742971672649089

      既然 假碼變碼^d mod n = 使用者名稱變碼
      所以 假碼變碼 = 使用者名稱變碼^e mod n

   對以上演算法求逆就是序號產生器演算法,留給有興趣的朋友自己練習
練習吧,呵呵,有一點點難度哦。


結語:

   如果你在寫序號產生器的過程中對現有的大數運算庫不是很滿意,敬
請關注俺的下篇教程《RSA與大數運算》,謝謝!  
 

相關文章