前言:
跟踪《楚汉棋缘》的算法只不过三个晚上约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来对付的,对算法的把握完全是通过归纳
总结逐步建立起来的。
001B:00430C33
: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
//以上估计是函数调用环境的保存及异常处理入口的设置
//[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与大数运算》,谢谢!