菜鸟看懂算法以后之二___几点其它收获
作者:jney2
日期:14:26 2005-4-26
一、研究64位的除法函数汇编代码时,我在精华收藏版中搜索该算法的特征码“D1D2”,发现完整列出并分析该算法汇编代码的文章有8篇:
1、超级电脑伴侣 V1.12
2、新概念英语句霸 2
3、《网络警察》V2.4
4、英语会话精灵
5、家庭银行家 v2b53
6、商舟@广告直邮群发大师2002
7、极速传真[SpeedFax] 2.4
8、HomeBankerV2.0 b53
估计在算法中使用该函数的程序应是数不胜数。而这几篇文章都没觉察得这只不过是日常中简单的除法,均以“转换”、“左移”等字眼带过,当然我也是花了相当的时间才搞清楚。
所以,弄清楚除法函数就显得蛮重要了!
二、注册算法也“盗版”
中华压缩10.8的注册算法与家庭银行家 v2b53的注册算法除了被除数不同外,其它一模一样。中华压缩:0x33FAB9386=13953110918 (作者的手机?这可是重要的隐私哦!),家庭银行家 v2b53:0x25CC7BC0D36=2597511236918
关于算法:在家庭银行家 v2b53 注册机(MASM32)中,发信人:lq7972 写到:
【总结】
这个软件还是耍了蛮多把戏的
注册算法
1. 注册用户名的长度在(3~25)间
2. 从注册用户名最末向前取,计算出一个中间值,然后把它转为元素是十进制值的整数数组;有两个值要注意:0xC7BC0D36、0x0000025C
3. 利用第2步中的结果计算真正的注册码,这个码长须为12位,计算结果若小了就在前面补0,若超过了12位,取前面12个字符
在中华压缩10.8中,baby2008写到:
【算法总结】:
算法比较简单,怪不得很多教程都以它的前期版本为教程,注册算法是:
1、用户名Name要求: 3<用户名长度<25
2、Name后面开始取字符,
3、用常数$33FAB9386 / Name[i] 的ASCII 取余数,并转换成10进制字符串
4、连接上述的10进制字符串,记为Serail
5、取Name[i]字符到<用户名长度-6结束
6、将Serail转换成int64,并以12位16进制字符串输出,如果长度超过12位,截取12后的所有字符即为注册码。
看来天下程序一大抄呀!
三、指出这几篇文章中的几个错误,免得比我还菜的菜鸟看了误入岐途:
1、在《超级电脑伴侣 V1.12算法流程,另有问题请教大家! 》中 发信人:PowerBoy
00405985 |. B9 40000000 MOV ECX,40
0040598A |. 57 PUSH EDI
0040598B |. 31FF XOR EDI,EDI
0040598D |. 31F6 XOR ESI,ESI //循环计算64次
0040598F |> D1E0 /SHL EAX,1 //EAX=EAX SHL 1
00405991 |. D1D2 |RCL EDX,1 //EDX=EDX RCL 1
00405993 |. D1D6 |RCL ESI,1 //ESI=ESI RCL 1
00405995 |. D1D7 |RCL EDI,1 //EDI=EDI RCL 1
00405997 |. 39EF |CMP EDI,EBP //EBP=28363
00405999 |. 72 0B |JB SHORT 1.004059A6
0040599B |. 77 04 |JA SHORT 1.004059A1
0040599D |. 39DE |CMP ESI,EBX
0040599F |. 72 05 |JB SHORT 1.004059A6
004059A1 |> 29DE |SUB ESI,EBX //ESI=ESI-EBX
004059A3 |. 19EF |SBB EDI,EBP
004059A5 |. 40 |INC EAX
004059A6 |>^E2 E7 \LOOPD SHORT 1.0040598F//EBX作为循环的标志 **********
004059A8 |. 89F0 MOV EAX,ESI //EAX=ESI
更正:EBX在此处不是作为循环的标志,ECX才是循环的计数器,LOOPD循环指令是与ECX配合使用的;
2、在《商舟@广告直邮群发大师2002》中, 发信人:fly
##############################################
呵呵,看看TRW犯的“小错误”!^-^
?EAX
DEC=-1717838278
HEX=999BDE3A
##############################################
更正:TRW是没有犯“小错误”的,是fly把本应是四字的数据截成了双字,HEX=999BDE3A如果按32位算,它的最高位为1,就应该是负整数,所以这不是TRW犯的“小错误”。
3、在《商舟@广告直邮群发大师2002》中, 发信人:fly
:0050DDBB 6945EC851A0000 imul eax, dword ptr [ebp-14], 00001A85 ********
====>EAX=1A85
更正:这条指令的解释是:EAX=1A85×dword ptr [ebp-14]。所以dword ptr [ebp-14]也是参数,只不过调试时dword ptr [ebp-14]的值刚好为1罢了。
4、在《商舟@广告直邮群发大师2002》中, 发信人:fly
【总 结】:
程序对自给的44030620021284410进行运算得出999BDE3A, ********
999BDE3A-我的硬盘序列号-自给的1A85=758EA8AF。 ********
758EA8AF算术左移64次=456C93E
456C93E+1=456C93F ―― 这就是真码的16进制值!
奇怪了!难道每次都要重新注册?
更正:44030620021284410换算成十六进制就是:0x9C6D9D999BDE3A,这才是完整的64位整数。
由于我找不到原软件,只能推测算法:(44030620021284410-硬盘序列号-参数A×6789)/参数B=注册码 (均是十进制)
5、在《英语会话精灵 2.0 --谨以此文献给初学破解的爱好者》中,发信人:youth[chat001]
0040916B |> 51 /PUSH ECX
0040916C |. 6A 00 |PUSH 0
0040916E |. 51 |PUSH ECX
0040916F |. 8B03 |MOV EAX,DWORD PTR DS:[EBX] ;/初始值为:(UserNo-0x1f6171f)*0x1b,见0047A083-0047A08B
00409171 |. 8B53 04 |MOV EDX,DWORD PTR DS:[EBX+4] ;\
00409174 |. E8 DCD5FFFF |CALL untopbar.00406755
00409179 |. 59 |POP ECX
0040917A |. 92 |XCHG EAX,EDX
0040917B |. 80C2 30 |ADD DL,30
0040917E |. 80FA 3A |CMP DL,3A
00409181 |. 72 03 |JB SHORT untopbar.00409186
00409183 |. 80C2 07 |ADD DL,7
00409186 |> 4E |DEC ESI
00409187 |. 8816 |MOV BYTE PTR DS:[ESI],DL
00409189 |. 51 |PUSH ECX
0040918A |. 6A 00 |PUSH 0
0040918C |. 51 |PUSH ECX
0040918D |. 8B03 |MOV EAX,DWORD PTR DS:[EBX]
0040918F |. 8B53 04 |MOV EDX,DWORD PTR DS:[EBX+4]
00409192 |. E8 C9D4FFFF |CALL untopbar.00406660
00409197 |. 59 |POP ECX
00409198 |. 8903 |MOV DWORD PTR DS:[EBX],EAX
0040919A |. 8953 04 |MOV DWORD PTR DS:[EBX+4],EDX
0040919D |. 09D0 |OR EAX,EDX
0040919F |.^75 CA \JNZ SHORT untopbar.0040916B
=VV==<<由00409174调用>>==VV===============================================================
(此过程很简单,就是将16进制转化为10进制后输出) ***********
00406755 /$ 55 PUSH EBP
00406756 |. 53 PUSH EBX
00406757 |. 56 PUSH ESI
00406758 |. 57 PUSH EDI
00406759 |. 8B5C24 14 MOV EBX,DWORD PTR SS:[ESP+14]
0040675D |. 8B4C24 18 MOV ECX,DWORD PTR SS:[ESP+18]
00406761 |. 0BC9 OR ECX,ECX
00406763 |. 75 08 JNZ SHORT untopbar.0040676D
00406765 |. 0BD2 OR EDX,EDX
00406767 |. 74 33 JE SHORT untopbar.0040679C
00406769 |. 0BDB OR EBX,EBX
0040676B |. 74 2F JE SHORT untopbar.0040679C
0040676D |> 8BE9 MOV EBP,ECX
0040676F |. B9 40000000 MOV ECX,40
00406774 |. 33FF XOR EDI,EDI
00406776 |. 33F6 XOR ESI,ESI
00406778 |> D1E0 /SHL EAX,1
0040677A |. D1D2 |RCL EDX,1
0040677C |. D1D6 |RCL ESI,1
0040677E
更正:这篇文章的算法是对的,因为它可以根据CALL的值逆推,此处的注释却是错的,因为此处除法函数,真正的16进制转化为10进制函数应该是CALL untopbar.00406660。
备注:1、标有*号的是错误的地方,这几个错误均是因为研究除法函数才发现的。我因为受其中的误导而浪费了不少功夫。所以特地指出来,其它的错误我可就管不着罗!
2、jney2提示:看本文前,请你看一下第一篇:菜鸟看懂算法以后之一__头痛的64次左移。
本文完。
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)