• 标 题: 中级实例教程——之《楚汉棋缘V1.36》 
  • 作 者:afanty
  • 时 间:2003/04/27 01:31pm
  • 链 接:http://bbs.pediy.com

前言:

   跟踪《楚汉棋缘》的算法只不过三个晚上约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与大数运算》,谢谢!