整理电脑的时候发现的.是我开始学算法的时候写的,花了整晚.
比较经典的每位取值算法,我想对像我这样的小鸟们一定有帮助,所以厚着脸皮发出来.PS:Winter兄弟一定也破了-.-
最新版的小小工具盒1.22也照样能注册成功,所以说他的算法还是没变。看来作者对自己的算法蛮有信心的:)
还记的那时考DFCG时我用的就是其中一篇就是这个,但因软件发布时间超过15天被踞之门外..想想我蛮傻的。不过也使我想通了,其实只要自己肯学有毅力,我想在哪里都是一样的吧?
==================================================================================
【工程作者】深海游侠
【作者邮箱】shenhaiyouxia@163.com
==================================================================================
【软件名称】小小工具盒 1.11
【下载地址】http://www.onlinedown.net/soft/26370.htm
【软件介绍】
一款十分不错的系统辅助工具!
==================================================================================
【工程平台】WIN ME
【调试工具】TRW2000系列
==================================================================================
【破解过程】
直接TRW2000载入,下万能断点,程序断下,PMODULE:
016F:00405B7A 8D94248C000000 LEA EDX,[ESP+8C]
016F:00405B81 6880000000 PUSH DWORD 80
016F:00405B86 52 PUSH EDX
016F:00405B87 6815040000 PUSH DWORD 0415
016F:00405B8C 53 PUSH EBX
016F:00405B8D FFD6 CALL ESI
016F:00405B8F 50 PUSH EAX
016F:00405B90 FFD7 CALL EDI
016F:00405B92 8D84248C000000 LEA EAX,[ESP+8C] ------>EAX=假码
016F:00405B99 8D4C240C LEA ECX,[ESP+0C] ------>ECX=用户名
016F:00405B9D 50 PUSH EAX
016F:00405B9E 51 PUSH ECX
016F:00405B9F E85C050000 CALL 00406100 ------>关键算法CALL,跟进
016F:00405BA4 83C408 ADD ESP,BYTE +08
016F:00405BA7 A388194100 MOV [00411988],EAX
016F:00405BAC 85C0 TEST EAX,EAX
016F:00405BAE 5F POP EDI
016F:00405BAF 0F8498000000 JZ NEAR 00405C4D ------>关键跳
016F:00405BB5 8D542408 LEA EDX,[ESP+08]
016F:00405BB9 52 PUSH EDX
016F:00405BBA 6808194100 PUSH DWORD 00411908
016F:00405BBF FF1508B14000 CALL `KERNEL32!lstrcpyA`
016F:00405BC5 33C9 XOR ECX,ECX
016F:00405BC7 8A440C08 MOV AL,[ESP+ECX+08]
016F:00405BCB 84C0 TEST AL,AL
016F:00405BCD 740F JZ 00405BDE
016F:00405BCF 2C02 SUB AL,02
016F:00405BD1 88440C08 MOV [ESP+ECX+08],AL
016F:00405BD5 41 INC ECX
016F:00405BD6 81F980000000 CMP ECX,80
016F:00405BDC 7CE9 JL 00405BC7
016F:00405BDE 33C9 XOR ECX,ECX
016F:00405BE0 8A840C88000000 MOV AL,[ESP+ECX+88]
016F:00405BE7 84C0 TEST AL,AL
016F:00405BE9 7412 JZ 00405BFD
016F:00405BEB FEC8 DEC AL
016F:00405BED 88840C88000000 MOV [ESP+ECX+88],AL
016F:00405BF4 41 INC ECX
016F:00405BF5 81F980000000 CMP ECX,80
016F:00405BFB 7CE3 JL 00405BE0
016F:00405BFD 8B3528B14000 MOV ESI,[0040B128]
016F:00405C03 8D442408 LEA EAX,[ESP+08]
016F:00405C07 68F8164100 PUSH DWORD 004116F8
016F:00405C0C 50 PUSH EAX
016F:00405C0D 68ACD54000 PUSH DWORD 0040D5AC
016F:00405C12 68D8D04000 PUSH DWORD 0040D0D8
016F:00405C17 FFD6 CALL ESI
016F:00405C19 8D8C2488000000 LEA ECX,[ESP+88]
016F:00405C20 68F8164100 PUSH DWORD 004116F8 ---> FileName = "D:\Program Files\小小工具盒\ToolBox.ini"
016F:00405C25 51 PUSH ECX
016F:00405C26 68A8D54000 PUSH DWORD 0040D5A8 --->Key = "bm"(这里我们不难看出他的成功标志,当然这是用OD的情况下,如果你用的TWR可以下命令看。我用的就是TRW)
016F:00405C2B 68D8D04000 PUSH DWORD 0040D0D8
016F:00405C30 FFD6 CALL ESI
016F:00405C32 6A40 PUSH BYTE +40
016F:00405C34 6860D44000 PUSH DWORD 0040D460
016F:00405C39 6870D64000 PUSH DWORD 0040D670 ---->Text = "注册成功! 谢谢您的支持!"
016F:00405C3E 53 PUSH EBX
016F:00405C3F FF1538B24000 CALL `USER32!MessageBoxA` ====>注册成功CALL
016F:00405C45 6A01 PUSH BYTE +01
016F:00405C47 53 PUSH EBX
016F:00405C48 E9E4FEFFFF JMP 00405B31
016F:00405C4D 6A40 PUSH BYTE +40
016F:00405C4F 686CD64000 PUSH DWORD 0040D66C
016F:00405C54 6850D64000 PUSH DWORD 0040D650 ----->Text = "注册码不正确,请重新输入!"
016F:00405C59 53 PUSH EBX
016F:00405C5A FF1538B24000 CALL `USER32!MessageBoxA` ----->注册失败CALL
016F:00405C60 6814040000 PUSH DWORD 0414
016F:00405C65 53 PUSH EBX
016F:00405C66 FFD6 CALL ESI
016F:00405C68 50 PUSH EAX
016F:00405C69 FF15B4B14000 CALL `USER32!SetFocus`
016F:00405C6F 5E POP ESI
016F:00405C70 33C0 XOR EAX,EAX
016F:00405C72 5B POP EBX
016F:00405C73 81C400010000 ADD ESP,0100
016F:00405C79 C21000 RET 10
关键算法CALL:
016F:00405B9F E85C050000 CALL 00406100
|
016F:00406100 83EC2C SUB ESP,BYTE +2C
016F:00406103 53 PUSH EBX
016F:00406104 55 PUSH EBP
016F:00406105 8B6C2438 MOV EBP,[ESP+38]
016F:00406109 56 PUSH ESI
016F:0040610A 57 PUSH EDI
016F:0040610B 8BFD MOV EDI,EBP
016F:0040610D 83C9FF OR ECX,BYTE -01 ----->ECX or -1
016F:00406110 33C0 XOR EAX,EAX
016F:00406112 F2AE REPNE SCASB ----->串命令
016F:00406114 F7D1 NOT ECX ----->求补
016F:00406116 49 DEC ECX ----->ECX=ECX-1(上面几步到这里等于变相把用户名位数入ECX)
016F:00406117 C744241C00000000 MOV DWORD [ESP+1C],00
016F:0040611F 83F904 CMP ECX,BYTE +04 ----->位数和4比较
016F:00406122 BE01000000 MOV ESI,01
016F:00406127 894C2418 MOV [ESP+18],ECX
016F:0040612B 7D07 JNL 00406134 ----->大于等于就跳
016F:0040612D 8B442444 MOV EAX,[ESP+44] ----->EAX假码
016F:00406131 C60000 MOV BYTE [EAX],00 ----->上面跳就是要避开这里,这里等于把你注册码第一位赋00,00什么都不是了。怎么比较?
016F:00406134 8A5C2444 MOV BL,[ESP+44] ----->跳到这里
016F:00406138 33FF XOR EDI,EDI
016F:0040613A 85C9 TEST ECX,ECX
016F:0040613C 0F8E31010000 JNG NEAR 00406273 ----->是否输入用户名?
016F:00406142 83F908 CMP ECX,BYTE +08 ----->是否小于等于8位
016F:00406145 7E08 JNG 0040614F
016F:00406147 83FF05 CMP EDI,BYTE +05
016F:0040614A 7E03 JNG 0040614F
016F:0040614C 8D79FE LEA EDI,[ECX-02]
016F:0040614F 8D5701 LEA EDX,[EDI+01]
016F:00406152 33C0 XOR EAX,EAX
016F:00406154 3BD1 CMP EDX,ECX
016F:00406156 8D4C2424 LEA ECX,[ESP+24]
016F:0040615A 0F9CC0 SETL AL ----->这里要看上面计算,在这种情况下AL一定会是1吧?
016F:0040615D 33D2 XOR EDX,EDX ----->EDX清0
016F:0040615F 6A24 PUSH BYTE +24 ----->36压栈,事后看这个也蛮重要的,后面计算要靠他了。
016F:00406161 8A142F MOV DL,[EDI+EBP] ----->用户名第一位以ASCII码形式入AL
016F:00406164 51 PUSH ECX
016F:00406165 52 PUSH EDX
016F:00406166 8944242C MOV [ESP+2C],EAX ----->EAX=1入[ESP+2C],用于下面比较
016F:0040616A E812060000 CALL 00406781 ----->分支算法(1)。因为一两句说不清,我们跟进吧
016F:0040616F 8B44242C MOV EAX,[ESP+2C] ----->经过上面CALL的计算,结果入EAX,你可以看下你的计算结果。我的是2r.当然过了这句就EAX就变了!
016F:00406173 83C40C ADD ESP,BYTE +0C
016F:00406176 85C0 TEST EAX,EAX
016F:00406178 7420 JZ 0040619A ----->只要你用户名够这里就不会跳吧
016F:0040617A 33C9 XOR ECX,ECX
016F:0040617C 8D442430 LEA EAX,[ESP+30]
016F:00406180 8A4C2F01 MOV CL,[EDI+EBP+01] ----->注册码某位入CL,看EDI的值,第一次来的话这里是第2位!
016F:00406184 6A24 PUSH BYTE +24 ----->24再次压栈,
016F:00406186 50 PUSH EAX
016F:00406187 51 PUSH ECX
016F:00406188 E8F4050000 CALL 00406781 ----->再经过上面的计算,我的是3c
016F:0040618D 83C40C ADD ESP,BYTE +0C
016F:00406190 C744241404000000 MOV DWORD [ESP+14],04 ----->04→[ESP+14]
016F:00406198 EB08 JMP SHORT 004061A2 ----->跳
016F:0040619A C744241402000000 MOV DWORD [ESP+14],02
016F:004061A2 8B442414 MOV EAX,[ESP+14] ----->[ESP+14]→EAX,主要看流程,也就是说我们要来几次。
016F:004061A6 33D2 XOR EDX,EDX ----->EDX计数器!清0
016F:004061A8 85C0 TEST EAX,EAX
016F:004061AA 89542410 MOV [ESP+10],EDX
016F:004061AE 0F8EAE000000 JNG NEAR 00406262 ----->小于等于0才会跳,如果你用户名位数符合要求那就没事拉。
016F:004061B4 83FA03 CMP EDX,BYTE +03 ----->大于3才会跳,确认你是第几次来这里!第一次就不会跳!如果你第一次来,那么EDX就开始充当计算器了!
016F:004061B7 7767 JA 00406220
016F:004061B9 FF2495A0634000 JMP NEAR [EDX*4+004063A0] ----->看EDX的值确定跳哪里计算,也就是说看你第几次来这里确定你跳哪里!当然要看[EDX*4+004063A0]里面的值!
016F:004061C0 8A5C2425 MOV BL,[ESP+25] ----->第1次来?那么把刚才上面算出的结果r入BL,(r的十六进制ASCII码是72)
016F:004061C4 FECB DEC BL ----->BL-1,我的就是72-1=71
016F:004061C6 EB58 JMP SHORT 00406220 ----->跳下去比较吧!71就是我注册码的第一位了。就是q(注册码第1,5位)
016F:004061C8 8B442420 MOV EAX,[ESP+20]
016F:004061CC 85C0 TEST EAX,EAX ----->第2次跳这里。
016F:004061CE 7406 JZ 004061D6
016F:004061D0 8A5C2430 MOV BL,[ESP+30] ----->刚才算出的2r3c的3入BL,注册码第二位为3。记的看好顺序!!他打乱循序的!是否到这里还要看EAX的值!我的EAX为1所以没跳!
016F:004061D4 EB4A JMP SHORT 00406220 ----->跳下去比较!(注册码第2,6位)
016F:004061D6 8A5C2424 MOV BL,[ESP+24] ----->EAX为1?那么把刚才算出的2r3c的2入BL,
016F:004061DA EB44 JMP SHORT 00406220
016F:004061DC 8D542424 LEA EDX,[ESP+24] ----->第3次到这里,EDX=2r
016F:004061E0 52 PUSH EDX
016F:004061E1 E8F6010000 CALL 004063DC ----->把是小写的字母转大写,数字不变
016F:004061E6 0FBE442428 MOVSX EAX,BYTE [ESP+28] ----->转后结果EAX=2R
016F:004061EB 6A01 PUSH BYTE +01
016F:004061ED 50 PUSH EAX
016F:004061EE E8BDFBFFFF CALL 00405DB0 ----->查表计算,分支CALL(2)跟进看看。
016F:004061F3 8BD8 MOV EBX,EAX ----->算出的结果入EBX
016F:004061F5 83C40C ADD ESP,BYTE +0C
016F:004061F8 80EB02 SUB BL,02 ----->EBX-2结果为注册码第3位
016F:004061FB EB1F JMP SHORT 0040621C ----->跳下去比较(注册码第3,7位)
016F:004061FD 8D4C2430 LEA ECX,[ESP+30] ----->第4次到了这里,ECX=3c
016F:00406201 51 PUSH ECX
016F:00406202 E8D5010000 CALL 004063DC ----->把是小写的字母转大写,数字不变
016F:00406207 0FBE542435 MOVSX EDX,BYTE [ESP+35] ----->ECX=3C
016F:0040620C 6A01 PUSH BYTE +01
016F:0040620E 52 PUSH EDX
016F:0040620F E89CFBFFFF CALL 00405DB0 ----->查表计算
016F:00406214 8BD8 MOV EBX,EAX ----->计算结果入EBX
016F:00406216 83C40C ADD ESP,BYTE +0C
016F:00406219 80EB03 SUB BL,03 ----->BL-3结果为注册码第4位(注册码第4,8位)
016F:0040621C 8B542410 MOV EDX,[ESP+10]
016F:00406220 84DB TEST BL,BL ----->晕你的不会BL为0吧
016F:00406222 7515 JNZ 00406239 ----->跳
016F:00406224 8BDE MOV EBX,ESI
016F:00406226 F7DB NEG EBX
016F:00406228 1ADB SBB BL,BL
016F:0040622A 33C0 XOR EAX,EAX
016F:0040622C 80E3E0 AND BL,E0
016F:0040622F 80C361 ADD BL,61
016F:00406232 85F6 TEST ESI,ESI
016F:00406234 0F94C0 SETZ AL
016F:00406237 8BF0 MOV ESI,EAX
016F:00406239 8B4C241C MOV ECX,[ESP+1C] ----->计数器,看你算了几位
016F:0040623D 8B442444 MOV EAX,[ESP+44] ----->假码
016F:00406241 8A0401 MOV AL,[ECX+EAX] ----->算的那一位入AL
016F:00406244 41 INC ECX ----->计数器+1
016F:00406245 3AC3 CMP AL,BL ----->比较
016F:00406247 894C241C MOV [ESP+1C],ECX ----->再存进来
016F:0040624B 0F8543010000 JNZ NEAR 00406394 ----->不等?那你完了
016F:00406251 8B442414 MOV EAX,[ESP+14] ----->EAX=4,就是当那个2r3c的计数器
016F:00406255 42 INC EDX ----->EDX初始为0,也是计算器
016F:00406256 3BD0 CMP EDX,EAX ----->比较2r3c算完了么?
016F:00406258 89542410 MOV [ESP+10],EDX ----->计数器EDX入[ESP+10],EDX用途就是016F:004061B9 FF2495A0634000 JMP NEAR [EDX*4+004063A0] 这里确定去向!
016F:0040625C 0F8C52FFFFFF JL NEAR 004061B4 ----->没有继续算!
016F:00406262 8B442418 MOV EAX,[ESP+18] ----->EAX位用户名位数
016F:00406266 83C702 ADD EDI,BYTE +02 ----->EDI=2
016F:00406269 3BF8 CMP EDI,EAX ----->这里可以看出每次算两位用户名,1位用户名能算出两个注册码
016F:0040626B 8BC8 MOV ECX,EAX
016F:0040626D 0F8CCFFEFFFF JL NEAR 00406142 ----->是否用户名每位都算了?
016F:00406273 8D2C09 LEA EBP,[ECX+ECX] ----->用户名位数*2入EBP
016F:00406276 8BFD MOV EDI,EBP ----->EBP→EDI
016F:00406278 83FF10 CMP EDI,BYTE +10 ----->EDI和16比较,也就是说用户名位数如果是16/2=8位以上的话,而且上面比较都通过。那么下面就不用计算,直接成功!
016F:0040627B 0F8D06010000 JNL NEAR 00406387 ----->没有通过?那继续下面的计算。(本来到这里我还以为算完了呢,没想到下面还有。晕!继续)
016F:00406281 8B4C241C MOV ECX,[ESP+1C] ----->这里开始是计算的第二部分!ECX=假码前面的位数,我的是8
016F:00406285 8B542444 MOV EDX,[ESP+44] ----->假码
016F:00406289 03CA ADD ECX,EDX ----->ECX=假码后8位
016F:0040628B 8D77F8 LEA ESI,[EDI-08] ----->用户名位数*2-08,我的是4位所以ESI=0
016F:0040628E 894C2444 MOV [ESP+44],ECX ----->ECX→[ESP+44]下面好用
016F:00406292 8BCF MOV ECX,EDI
016F:00406294 8D442424 LEA EAX,[ESP+24]
016F:00406298 2BCD SUB ECX,EBP
016F:0040629A 6A24 PUSH BYTE +24
016F:0040629C 50 PUSH EAX
016F:0040629D 8BC1 MOV EAX,ECX ----->ECX→EAX
016F:0040629F 99 CDQ
016F:004062A0 2BC2 SUB EAX,EDX ----->上面的都好理解,我不废话了,EAX=EAX-EDX,这里也要循环的!
016F:004062A2 33D2 XOR EDX,EDX ----->EDX清0
016F:004062A4 D1F8 SAR EAX,1 ----->EAX算术右移1位
016F:004062A6 D1E0 SHL EAX,1 ----->再逻辑左移一位,EAX=EAX*2
016F:004062A8 2BC8 SUB ECX,EAX ----->ECX=ECX-EAX
016F:004062AA 8B442448 MOV EAX,[ESP+48] ----->EAX位用户名
016F:004062AE 8A1401 MOV DL,[ECX+EAX] ----->用户名某位入DL,看上面计算后ECX的值.(这里也很重要!要看取用户名哪一位计算)
016F:004062B1 52 PUSH EDX
016F:004062B2 E8CA040000 CALL 00406781 ----->上面讲过,利用用户名算随即码。我的还是2r3c
016F:004062B7 83C40C ADD ESP,BYTE +0C
016F:004062BA 83FE07 CMP ESI,BYTE +07
016F:004062BD 0F87AA000000 JA NEAR 0040636D
016F:004062C3 FF24B5B0634000 JMP NEAR [ESI*4+004063B0] ----->和第一部分计算彼此,只不过第一部分EDX为计数器,这里ESI为计数器!
016F:004062CA 8A5C2425 MOV BL,[ESP+25] ----->第1次跳这里,我的是r,也就是72
016F:004062CE 80EB03 SUB BL,03 ----->BL=BL-3,72-3=6F也就是o
016F:004062D1 E997000000 JMP 0040636D ----->跳下去比较(注册码第9位)
016F:004062D6 0FBE4C2424 MOVSX ECX,BYTE [ESP+24] ----->第2次到这里,ECX=33,也就是3c中的3
016F:004062DB 6A00 PUSH BYTE +00
016F:004062DD 51 PUSH ECX
016F:004062DE E8CDFAFFFF CALL 00405DB0 ----->查表计算
016F:004062E3 83C408 ADD ESP,BYTE +08
016F:004062E6 8AD8 MOV BL,AL ----->结果入BL
016F:004062E8 E980000000 JMP 0040636D ----->下去比较(注册码第10位)
016F:004062ED 8A5C2425 MOV BL,[ESP+25] ----->第3次到这里,因为通过上面CDQ部分计算我们得知,这里还是用户名c的计算结果2r,所以BL=114,r
016F:004062F1 FECB DEC BL ----->BL-1,72-1=71,q
016F:004062F3 EB78 JMP SHORT 0040636D ----->跳下去比较(注册码第11位)
016F:004062F5 8A5C2424 MOV BL,[ESP+24] ----->第4次到这里,BL=33,3c的3
016F:004062F9 80EB06 SUB BL,06 ----->BL-6=2D,就是字符-
016F:004062FC EB6F JMP SHORT 0040636D ----->比较(注册码第12位)
016F:004062FE 8D542424 LEA EDX,[ESP+24] ----->第5次到这里,我的EDX=2r,要看上面计算的结果!
016F:00406302 52 PUSH EDX
016F:00406303 E8D4000000 CALL 004063DC ----->小写字母转大写,数字不变
016F:00406308 8A5C2429 MOV BL,[ESP+29] ----->2R中的R入BL,BL=52
016F:0040630C 83C404 ADD ESP,BYTE +04
016F:0040630F 80EB09 SUB BL,09 ----->BL-9,52-9=49,I
016F:00406312 EB59 JMP SHORT 0040636D ----->比较(注册码第13位)
016F:00406314 8A5C2424 MOV BL,[ESP+24] ----->第6次到这里,BL为3c中的3,BL=33
016F:00406318 80EB04 SUB BL,04 ----->BL-4,33-4=2F,就是/
016F:0040631B EB50 JMP SHORT 0040636D ----->比较(注册码第14位)
016F:0040631D 0FBE442424 MOVSX EAX,BYTE [ESP+24] ----->第7次到这里,EAX=32,2r中的2
016F:00406322 0FBE4C2425 MOVSX ECX,BYTE [ESP+25] ----->ECX=72,2r中的r
016F:00406327 03C1 ADD EAX,ECX ----->累加
016F:00406329 99 CDQ
016F:0040632A 2BC2 SUB EAX,EDX
016F:0040632C 8BD8 MOV EBX,EAX ----->入EBX
016F:0040632E D1FB SAR EBX,1 ----->EBX算术右移1位,EBX=EBX/2
016F:00406330 EB3B JMP SHORT 0040636D ----->比较(注册码第15位)
016F:00406332 0FBE542424 MOVSX EDX,BYTE [ESP+24] ----->第8次到这里,EDX=33,3c中的3
016F:00406337 0FBE442425 MOVSX EAX,BYTE [ESP+25] ----->EDX=63,3c中的c
016F:0040633C 8D4C2424 LEA ECX,[ESP+24] ----->ECX="3c"
016F:00406340 C644242500 MOV BYTE [ESP+25],00 ----->[ESP+25]=0
016F:00406345 8D4402FD LEA EAX,[EDX+EAX-03] ----->EAX=EAX+EDX-03 EAX=33+63-3=93
016F:00406349 51 PUSH ECX ----->ECX压栈
016F:0040634A 99 CDQ
016F:0040634B 2BC2 SUB EAX,EDX ----->EAX=EAX-EDX EAX=93-0=93
016F:0040634D D1F8 SAR EAX,1 ----->EAX算术右移1位,EAX=EAX/2,EAX=49
016F:0040634F 88442428 MOV [ESP+28],AL
016F:00406353 E884000000 CALL 004063DC ----->小写转大写,因为49是大写I,所以我的不用转
016F:00406358 0FBE542428 MOVSX EDX,BYTE [ESP+28] ----->EDX=49,转后结果
016F:0040635D 6A01 PUSH BYTE +01
016F:0040635F 52 PUSH EDX
016F:00406360 E84BFAFFFF CALL 00405DB0 ----->又一次查表计算,
016F:00406365 8BD8 MOV EBX,EAX ----->结果48入EBX
016F:00406367 83C40C ADD ESP,BYTE +0C
016F:0040636A 80EB02 SUB BL,02 ----->EBX-2,48-2=46(F)(注册码第16位)
016F:0040636D 8B4C2444 MOV ECX,[ESP+44] ----->上面的8次都要到这里ECX为后8为假码,根据跳的次数,开头不一样!
016F:00406371 8A01 MOV AL,[ECX] ----->要比较的这一位入AL
016F:00406373 41 INC ECX ----->计数器+1
016F:00406374 3AC3 CMP AL,BL ----->比较
016F:00406376 894C2444 MOV [ESP+44],ECX ----->就是这里了,又要入[ESP+44]
016F:0040637A 7518 JNZ 00406394 ----->每次都要到这里比较
016F:0040637C 47 INC EDI
016F:0040637D 46 INC ESI ----->大计数器+1
016F:0040637E 83FE08 CMP ESI,BYTE +08 ----->是否算完8位?
016F:00406381 0F8C0BFFFFFF JL NEAR 00406292 ----->算完OK,全部结果!
016F:00406387 5F POP EDI
016F:00406388 5E POP ESI
016F:00406389 5D POP EBP
016F:0040638A B801000000 MOV EAX,01 ------>我们要的东东!
016F:0040638F 5B POP EBX
016F:00406390 83C42C ADD ESP,BYTE +2C
016F:00406393 C3 RET ------>从这里返回就是胜利!
016F:00406394 5F POP EDI
016F:00406395 5E POP ESI
016F:00406396 5D POP EBP
016F:00406397 33C0 XOR EAX,EAX ------>这句是导致我们失败的原因!
016F:00406399 5B POP EBX
016F:0040639A 83C42C ADD ESP,BYTE +2C
016F:0040639D C3 RET ------>从这里返回就是失败!
分支算法(1):
016F:0040616A E812060000 CALL 00406781
|
016F:00406781 55 PUSH EBP
016F:00406782 8BEC MOV EBP,ESP
016F:00406784 837D100A CMP DWORD [EBP+10],BYTE +0A ------>第一次到这里[EBP+10]的值是36,我们在上面看到过的。
016F:00406788 750C JNZ 00406796 ------>一定跳
016F:0040678A 837D0800 CMP DWORD [EBP+08],BYTE +00
016F:0040678E 7D06 JNL 00406796
016F:00406790 6A01 PUSH BYTE +01
016F:00406792 6A0A PUSH BYTE +0A
016F:00406794 EB05 JMP SHORT 0040679B
016F:00406796 6A00 PUSH BYTE +00
016F:00406798 FF7510 PUSH DWORD [EBP+10]
016F:0040679B FF750C PUSH DWORD [EBP+0C]
016F:0040679E FF7508 PUSH DWORD [EBP+08]
016F:004067A1 E808000000 CALL 004067AE ------>到下面
016F:004067A6 8B450C MOV EAX,[EBP+0C] ------>下面计算完返回到这里,下EAX看到计算结果,我的是2r
016F:004067A9 83C410 ADD ESP,BYTE +10
016F:004067AC 5D POP EBP
016F:004067AD C3 RET
016F:004067AE 55 PUSH EBP ------>到这里
016F:004067AF 8BEC MOV EBP,ESP
016F:004067B1 837D1400 CMP DWORD [EBP+14],BYTE +00
016F:004067B5 8B4D0C MOV ECX,[EBP+0C]
016F:004067B8 53 PUSH EBX
016F:004067B9 56 PUSH ESI
016F:004067BA 57 PUSH EDI
016F:004067BB 740B JZ 004067C8
016F:004067BD 8B7508 MOV ESI,[EBP+08]
016F:004067C0 C6012D MOV BYTE [ECX],2D
016F:004067C3 41 INC ECX
016F:004067C4 F7DE NEG ESI
016F:004067C6 EB03 JMP SHORT 004067CB
016F:004067C8 8B7508 MOV ESI,[EBP+08] ------>用户名某一位以ASCII形式入ESI,开始算了,第一次来就是第一位!
016F:004067CB 8BF9 MOV EDI,ECX
016F:004067CD 8BC6 MOV EAX,ESI ------>ESI→EAX
016F:004067CF 33D2 XOR EDX,EDX ------>EDX清0
016F:004067D1 F77510 DIV DWORD [EBP+10] ------>EAX/24,商入EAX,余数入EDX
016F:004067D4 8BC6 MOV EAX,ESI ------>某一位重新入EAX
016F:004067D6 8BDA MOV EBX,EDX ------>刚才的余数EDX→EBX
016F:004067D8 33D2 XOR EDX,EDX ------>EDX清0
016F:004067DA F77510 DIV DWORD [EBP+10] ------>EAX/24,商入EAX,余数入EDX
016F:004067DD 83FB09 CMP EBX,BYTE +09 ------>第一位算的余数和09比较
016F:004067E0 8BF0 MOV ESI,EAX ------>第二次算出的商EAX→ESI
016F:004067E2 7605 JNA 004067E9 ------>余数小于等于09就跳
016F:004067E4 80C357 ADD BL,57 ------>不跳?那么BL=BL+57
016F:004067E7 EB03 JMP SHORT 004067EC ------>看清跳的地址!
016F:004067E9 80C330 ADD BL,30 ------>如果上面不跳,那么余数BL+30
016F:004067EC 8819 MOV [ECX],BL ------>到这里,BL入[ECX]
016F:004067EE 41 INC ECX ------>ECX+1
016F:004067EF 85F6 TEST ESI,ESI ------>跟后我们发现要循环算1次!因为商无论如何也不会比36大,所以再循环除的时候ESI必定为0!
016F:004067F1 77DA JA 004067CD ------>循环
016F:004067F3 802100 AND BYTE [ECX],00 ------>从这里开始一直到下面跳转实际就是把刚才循环两次算出的两个值由低到高排列。(不知道我说的对不对)
016F:004067F6 49 DEC ECX
016F:004067F7 8A17 MOV DL,[EDI]
016F:004067F9 8A01 MOV AL,[ECX]
016F:004067FB 8811 MOV [ECX],DL
016F:004067FD 8807 MOV [EDI],AL
016F:004067FF 49 DEC ECX
016F:00406800 47 INC EDI
016F:00406801 3BF9 CMP EDI,ECX
016F:00406803 72F2 JC 004067F7 ------>好了排列好了
016F:00406805 5F POP EDI
016F:00406806 5E POP ESI
016F:00406807 5B POP EBX
016F:00406808 5D POP EBP
016F:00406809 C3 RET ------>返回上面
查表计算CALL
016F:0040620F E89CFBFFFF CALL 00405DB0
|
016F:00405DB0 81EC20010000 SUB ESP,0120 ------>先清理一下ESP的地方,下面都是表!
016F:00405DB6 BA37000000 MOV EDX,37
016F:00405DBB 56 PUSH ESI
016F:00405DBC 89542420 MOV [ESP+20],EDX
016F:00405DC0 899424B0000000 MOV [ESP+B0],EDX
016F:00405DC7 8B94242C010000 MOV EDX,[ESP+012C] ------>EDX=1,下面计算用!
016F:00405DCE B938000000 MOV ECX,38
016F:00405DD3 B839000000 MOV EAX,39
016F:00405DD8 BE36000000 MOV ESI,36
016F:00405DDD 894C2424 MOV [ESP+24],ECX
016F:00405DE1 89442428 MOV [ESP+28],EAX
016F:00405DE5 898C24B4000000 MOV [ESP+B4],ECX
016F:00405DEC 898424B8000000 MOV [ESP+B8],EAX
016F:00405DF3 C744240430000000 MOV DWORD [ESP+04],30
016F:00405DFB C744240831000000 MOV DWORD [ESP+08],31
016F:00405E03 C744240C32000000 MOV DWORD [ESP+0C],32
016F:00405E0B C744241033000000 MOV DWORD [ESP+10],33
016F:00405E13 C744241434000000 MOV DWORD [ESP+14],34
016F:00405E1B C744241835000000 MOV DWORD [ESP+18],35
016F:00405E23 8974241C MOV [ESP+1C],ESI
016F:00405E27 C744242C61000000 MOV DWORD [ESP+2C],61
016F:00405E2F C744243062000000 MOV DWORD [ESP+30],62
016F:00405E37 C744243463000000 MOV DWORD [ESP+34],63
016F:00405E3F C744243864000000 MOV DWORD [ESP+38],64
016F:00405E47 C744243C65000000 MOV DWORD [ESP+3C],65
016F:00405E4F C744244066000000 MOV DWORD [ESP+40],66
016F:00405E57 C744244467000000 MOV DWORD [ESP+44],67
016F:00405E5F C744244868000000 MOV DWORD [ESP+48],68
016F:00405E67 C744244C69000000 MOV DWORD [ESP+4C],69
016F:00405E6F C74424506A000000 MOV DWORD [ESP+50],6A
016F:00405E77 C74424546B000000 MOV DWORD [ESP+54],6B
016F:00405E7F C74424586C000000 MOV DWORD [ESP+58],6C
016F:00405E87 C744245C6D000000 MOV DWORD [ESP+5C],6D
016F:00405E8F C74424606E000000 MOV DWORD [ESP+60],6E
016F:00405E97 C74424646F000000 MOV DWORD [ESP+64],6F
016F:00405E9F C744246870000000 MOV DWORD [ESP+68],70
016F:00405EA7 C744246C71000000 MOV DWORD [ESP+6C],71
016F:00405EAF C744247072000000 MOV DWORD [ESP+70],72
016F:00405EB7 C744247473000000 MOV DWORD [ESP+74],73
016F:00405EBF C744247874000000 MOV DWORD [ESP+78],74
016F:00405EC7 C744247C75000000 MOV DWORD [ESP+7C],75
016F:00405ECF C784248000000076+MOV DWORD [ESP+80],76
016F:00405EDA C784248400000077+MOV DWORD [ESP+84],77
016F:00405EE5 C784248800000078+MOV DWORD [ESP+88],78
016F:00405EF0 C784248C00000079+MOV DWORD [ESP+8C],79
016F:00405EFB C78424900000007A+MOV DWORD [ESP+90],7A
016F:00405F06 C784249400000030+MOV DWORD [ESP+94],30
016F:00405F11 C784249800000031+MOV DWORD [ESP+98],31
016F:00405F1C C784249C00000032+MOV DWORD [ESP+9C],32
016F:00405F27 C78424A000000033+MOV DWORD [ESP+A0],33
016F:00405F32 C78424A400000034+MOV DWORD [ESP+A4],34
016F:00405F3D C78424A800000035+MOV DWORD [ESP+A8],35
016F:00405F48 89B424AC000000 MOV [ESP+AC],ESI
016F:00405F4F C78424BC00000041+MOV DWORD [ESP+BC],41
016F:00405F5A C78424C000000042+MOV DWORD [ESP+C0],42
016F:00405F65 C78424C400000043+MOV DWORD [ESP+C4],43
016F:00405F70 C78424C800000044+MOV DWORD [ESP+C8],44
016F:00405F7B C78424CC00000045+MOV DWORD [ESP+CC],45
016F:00405F86 C78424D000000046+MOV DWORD [ESP+D0],46
016F:00405F91 C78424D400000047+MOV DWORD [ESP+D4],47
016F:00405F9C C78424D800000048+MOV DWORD [ESP+D8],48
016F:00405FA7 C78424DC00000049+MOV DWORD [ESP+DC],49
016F:00405FB2 C78424E00000004A+MOV DWORD [ESP+E0],4A
016F:00405FBD C78424E40000004B+MOV DWORD [ESP+E4],4B
016F:00405FC8 C78424E80000004C+MOV DWORD [ESP+E8],4C
016F:00405FD3 C78424EC0000004D+MOV DWORD [ESP+EC],4D
016F:00405FDE C78424F00000004E+MOV DWORD [ESP+F0],4E
016F:00405FE9 C78424F40000004F+MOV DWORD [ESP+F4],4F
016F:00405FF4 C78424F800000050+MOV DWORD [ESP+F8],50
016F:00405FFF C78424FC00000051+MOV DWORD [ESP+FC],51
016F:0040600A C784240001000052+MOV DWORD [ESP+0100],52
016F:00406015 C784240401000053+MOV DWORD [ESP+0104],53
016F:00406020 C784240801000054+MOV DWORD [ESP+0108],54
016F:0040602B C784240C01000055+MOV DWORD [ESP+010C],55
016F:00406036 C784241001000056+MOV DWORD [ESP+0110],56
016F:00406041 C784241401000057+MOV DWORD [ESP+0114],57
016F:0040604C C784241801000058+MOV DWORD [ESP+0118],58
016F:00406057 C784241C01000059+MOV DWORD [ESP+011C],59
016F:00406062 C78424200100005A+MOV DWORD [ESP+0120],5A
016F:0040606D 33C0 XOR EAX,EAX ------->EAX清0,计数器
016F:0040606F 8D0CD2 LEA ECX,[EDX+EDX*8] ------->因为上面EDX已经制1,所以ECX=1+1*8=9
016F:00406072 8BB42428010000 MOV ESI,[ESP+0128] ------->ESI=我们上面已经算出的那个数!我注册码第16位打比方,ESI=49,算到这里时是I
016F:00406079 C1E104 SHL ECX,04 ------->ECX逻辑左移4位,ECX=ECX*10,9*10=90
016F:0040607C 8D4C0C04 LEA ECX,[ESP+ECX+04] ------->ECX=ESP+ECX+04,看表!就是[ESP+94],是30。就是数字0
016F:00406080 3B31 CMP ESI,[ECX] ------->比较,我的不相等,I和0当然不等!
016F:00406082 7409 JZ 0040608D
016F:00406084 40 INC EAX ------->EAX+1,就是看你用了几次才在表中找到一样的字符!我这次是用了12次,就是18次
016F:00406085 83C104 ADD ECX,BYTE +04 ------->ECX+4,就是说再此时ECX=[ESP+98]
016F:00406088 83F824 CMP EAX,BYTE +24 ------->一定跳吧!除非你的字符是在表里没有,那你完了。(等于循环!)
016F:0040608B 7CF3 JL 00406080
016F:0040608D 8D14D2 LEA EDX,[EDX+EDX*8] ------->在表中找到了?那看看EDX=1+1*8=9
016F:00406090 C1E202 SHL EDX,02 ------->逻辑左移2位,EDX=EDX*4=24
016F:00406093 2BD0 SUB EDX,EAX ------->EDX=EDX-EAX,EDX=24-12=12
016F:00406095 5E POP ESI
016F:00406096 8B84948C000000 MOV EAX,[ESP+EDX*4+8C] ------->好拉,查表找你相应的字符吧!EAX=[ESP+EDX*4+8C],我这次是EAX=[ESP+D4],赶紧查表!恩,找到了是47。
016F:0040609D 81C420010000 ADD ESP,0120 ------->好拉,恢复ESP,下面返回!
总结:
1>具体有两大计算部分:
第1部分:把用户名以每2位的方式计算出随机码,利用随机码来计算注册码。
第2部分:只用到用户名前2位,循环使用!
下面我给出我的用户名算出的随机码,具体计算方法上边我注释中有:
我的用户名是cxxx,通过上边的解释我们知道c-2r x-3c x-3c x-3c x-3c
计算流程和用户名位数有关,分两种情况:
1,当用户名位数在8位以下的话,必须经过两部分算法计算。
2,当用户名位数在8位以上的话(包括8位),只需进行第一部分算法计算。
具体算法过程我在上边注解中已经说明,有点乱,大家见谅。
2>下面我拿我的用户名给大家推算一遍:(我的用户名是cxxx,通过上边的解释我们知道c-2r x-3c x-3c x-3c x-3c,而且随机码的使用并不是按照顺序的!)
随机码(根据用户名算出) 注册码
第1位 r(72) 72-1=71(q)
第2位 3(33) 33(3)
第3位 2r (小写转大写,查表计算) 58-2=56(V)
第4位 3c (小写转大写,查表计算) 4E-3=4B(K)
第5位 c(63) 63-1=62(b)
第6位 3(33) 33(3)
第7位 3c (小写转大写,查表计算) 57-2=55(U)
第8位 3c (小写转大写,查表计算) 4E-3=4B(K)
第9位 r(72) 72-3=6F(o)
第10位 3(33) (查表计算) 77(w)
第11位 r(72) 72-1=71(q)
第12位 3(33) 33-6=2D(-)
第13位 2r (小写转大写,取R计算) 52-9=49(I)
第14位 3(33) 33-4=2F(/)
第15位 2r ((2+r)/2) A4/2=52(R)
第16位 3c ([(3+c)-3]/2,小转大,查表-2) 48-2=46(F) (中间计算过程我省略了)
最右边的一排字符就是我的注册码:
用户名: cxxx
注册码: q3VKb3UKowq-I/RF
因为我的用户名是8位以下的,所以要经过两部分算法计算.
下面我再给个用户名在8位以上的注册码:
用户名: cxxxxxxx
注册码: q3VKb3UKb3UKb3UK
因为这个用户名在8位以上,所以只要用第一部分算法计算.
2>恢复注册方法:
在软件目录下有一系统隐藏配置文件ToolBox.ini,打开后删除其实bm=后面的字符即可。
注:这个配置文件因为是系统隐藏,所以你即使打开隐藏文件也可能看不到,可以先把他“整个文件包”压缩,然后即可在压缩包中看到这个文件。
3>破后感评:
因为最近好忙,所以这几天没有在组织里发表什么文章,但早在以前我就已经写出了这篇文章,因我做系统时不幸丢失,所以这篇是赶写出来的。
其实干什么光靠说是不行的,要自己亲身去尝试。这个软件很适合一些像我这样的小鸟们自己去尝试。假如我写的文章对你有点帮助,那么我的目的也就达到了。
雨终于停了,我也可以松口气了...
不论【OCN】论坛是否存在,但你还是永远存在在我心中,因为是你让我步入了CRACK的殿堂!
希望【OCN】的兄弟们事事顺利,CRACK技术更上一层楼!
2004.7.12夜
深海游侠
==================================================================================
【工程声明】本过程只供内部学习之用!如要转载请保持过程完整!
==================================================================================
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)