Absolute MP3 Splitter Converter算法分析 + 注册机伪码
【破文标题】Absolute MP3 Splitter Converter算法分析 + 注册机伪码【破文作者】vecri
【作者邮箱】[email protected]
【作者主页】
【破解工具】OD, DeDe, RSA工具
【破解平台】Windows XP
【软件名称】Absolute MP3 Splitter Converter V2.7.1
【软件大小】
【原版下载】天空软件站有下的..自己搜下.~
【保护方式】注册码
【软件简介】Absolute MP3 Splitter 是一个强大的音频分割、合并与转换软件,它可以分割一个较大的音频文件为多个较小的片断,并且同样能合并多个音频文件为一个较大的文件。另外,它还可以忽略源格式与目标格式在不同的音频格式之间进行转换,并且保持原品质不变。该软件支持四种流行的音频格式:MP3、WAV、WMA 与 OGG。软件的向导功能使用分割工作非常容易地被用户理解。而且,你还可以对目标文件的 ID3 标签信息进行编
辑。软件除了支持设置音频格式的比特率与频率,同样还支持 MP3 与OGG 文件的 VBR 功能。
【破解声明】我是一只小菜鸟,偶得一点心得,愿与大家分享:)
------------------------------------------------------------------------
【破解过程】这个软件里融合了RSA算法, 和BASE64算法, 不过两者都用得不复杂, 所以对于学习算法的新手来说比较适合.
不多说了, 开始破解. 软件无壳, 国外软件就是好~~呵呵, 一眼就可以看到有个模块名字和RSA有关, 做好心理准备, 寻找大数~~.
在DEDE里找到注册按钮的响应代码的RVA, 并在此下断, 点注册:
//~~~~~~~~~~~~~~~~~响应代码~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00501618/.55 PUSH EBP //在这里下断点
00501619|.8BEC MOV EBP,ESP
0050161B|.6A 00 PUSH 0
0050161D|.6A 00 PUSH 0
0050161F|.53 PUSH EBX
00501620|.8BD8 MOV EBX,EAX
00501622|.33C0 XOR EAX,EAX
00501624|.55 PUSH EBP
00501625|.68 ED165000 PUSH Absolute.005016ED
0050162A|.64:FF30 PUSH DWORD PTR FS:
0050162D|.64:8920 MOV DWORD PTR FS:,ESP
00501630|.8D55 FC LEA EDX,DWORD PTR SS:
00501633|.8B83 14030000 MOV EAX,DWORD PTR DS:
00501639|.E8 A687F6FF CALL Absolute.00469DE4 ;获取用户名放在
0050163E|.8D55 F8 LEA EDX,DWORD PTR SS:
00501641|.8B83 18030000 MOV EAX,DWORD PTR DS:
00501647|.E8 9887F6FF CALL Absolute.00469DE4 ;获取注册码放在
0050164C|.A1 00855000 MOV EAX,DWORD PTR DS:
00501651|.8B00 MOV EAX,DWORD PTR DS:
00501653|.8B4D F8 MOV ECX,DWORD PTR SS: ;注册码
00501656|.8B55 FC MOV EDX,DWORD PTR SS: ;用户名
00501659|.E8 C22D0000 CALL Absolute.00504420 ;关键函数, 跟进
0050165E|.84C0 TEST AL,AL
00501660|.74 58 JE SHORT Absolute.005016BA ;不跳转就成功
00501662|.A1 00855000 MOV EAX,DWORD PTR DS:
00501667|.8B00 MOV EAX,DWORD PTR DS:
00501669|.8B55 FC MOV EDX,DWORD PTR SS:
0050166C|.E8 23310000 CALL Absolute.00504794
00501671|.6A 40 PUSH 40
00501673|.B9 FC165000 MOV ECX,Absolute.005016FC ;ASCII "Congratulations!"
00501678|.BA 10175000 MOV EDX,Absolute.00501710 ;ASCII "Register successfully!Thank you for your support!"
0050167D|.A1 BC875000 MOV EAX,DWORD PTR DS:
00501682|.8B00 MOV EAX,DWORD PTR DS:
00501684|.E8 938AF8FF CALL Absolute.0048A11C
00501689|.A1 00855000 MOV EAX,DWORD PTR DS:
0050168E|.8B00 MOV EAX,DWORD PTR DS:
00501690|.8B80 3C030000 MOV EAX,DWORD PTR DS:
00501696|.33D2 XOR EDX,EDX
00501698|.E8 6786F6FF CALL Absolute.00469D04
0050169D|.A1 00855000 MOV EAX,DWORD PTR DS:
005016A2|.8B00 MOV EAX,DWORD PTR DS:
005016A4|.8B80 40030000 MOV EAX,DWORD PTR DS:
005016AA|.33D2 XOR EDX,EDX
005016AC|.E8 5386F6FF CALL Absolute.00469D04
005016B1|.8BC3 MOV EAX,EBX
005016B3|.E8 8C50F8FF CALL Absolute.00486744
005016B8|.EB 18 JMP SHORT Absolute.005016D2
005016BA|>6A 40 PUSH 40
005016BC|.B9 44175000 MOV ECX,Absolute.00501744 ;ASCII "Sorry"
005016C1|.BA 4C175000 MOV EDX,Absolute.0050174C ;ASCII "Invalid user name or registration code!"
005016C6|.A1 BC875000 MOV EAX,DWORD PTR DS:
005016CB|.8B00 MOV EAX,DWORD PTR DS:
005016CD|.E8 4A8AF8FF CALL Absolute.0048A11C
005016D2|>33C0 XOR EAX,EAX
005016D4|.5A POP EDX
005016D5|.59 POP ECX
005016D6|.59 POP ECX
005016D7|.64:8910 MOV DWORD PTR FS:,EDX
005016DA|.68 F4165000 PUSH Absolute.005016F4
005016DF|>8D45 F8 LEA EAX,DWORD PTR SS:
005016E2|.BA 02000000 MOV EDX,2
005016E7|.E8 BC30F0FF CALL Absolute.004047A8
005016EC\.C3 RETN
看到了吧....如果要爆破,,是如此简单.~~仅要修改
00501660|.74 58 JE SHORT Absolute.005016BA
这一处就行了..
我们这里要找出算法, 做出注册机, 所以F7跟进:
00504420/$55 PUSH EBP
00504421|.8BEC MOV EBP,ESP
00504423|.83C4 E4 ADD ESP,-1C
00504426|.53 PUSH EBX
00504427|.33DB XOR EBX,EBX
00504429|.895D F4 MOV DWORD PTR SS:,EBX
0050442C|.894D F8 MOV DWORD PTR SS:,ECX
0050442F|.8955 FC MOV DWORD PTR SS:,EDX
00504432|.8B45 FC MOV EAX,DWORD PTR SS:
00504435|.E8 FA07F0FF CALL Absolute.00404C34 ;上面是初始化工作
0050443A|.8B45 F8 MOV EAX,DWORD PTR SS:
0050443D|.E8 F207F0FF CALL Absolute.00404C34
00504442|.8D45 EC LEA EAX,DWORD PTR SS:
00504445|.8B15 20F14B00 MOV EDX,DWORD PTR DS: ;Absolute.004BF124
0050444B|.E8 040EF0FF CALL Absolute.00405254
00504450|.8D45 E4 LEA EAX,DWORD PTR SS:
00504453|.8B15 20F14B00 MOV EDX,DWORD PTR DS: ;Absolute.004BF124
00504459|.E8 F60DF0FF CALL Absolute.00405254
0050445E|.33C0 XOR EAX,EAX
00504460|.55 PUSH EBP
00504461|.68 E2445000 PUSH Absolute.005044E2
00504466|.64:FF30 PUSH DWORD PTR FS: ;SEH链的处理, 通常对应C++中的try
00504469|.64:8920 MOV DWORD PTR FS:,ESP
0050446C|.33DB XOR EBX,EBX
0050446E|.8D55 EC LEA EDX,DWORD PTR SS:
00504471|.A1 3C835000 MOV EAX,DWORD PTR DS: ;这里是字符串"65537"
00504476|.E8 5DB4FBFF CALL Absolute.004BF8D8 ;将65537转为大整数, 放在ebp-14
0050447B|.8D55 E4 LEA EDX,DWORD PTR SS:
0050447E|.A1 40835000 MOV EAX,DWORD PTR DS: ;这里是字符串"874802157929661091407425794781"
00504483|.E8 50B4FBFF CALL Absolute.004BF8D8 ;将"874802157929661091407425794781"转为大整数, 放在ebp-1c
00504488|.8D45 FC LEA EAX,DWORD PTR SS:
0050448B|.50 PUSH EAX
0050448C|.8D4D E4 LEA ECX,DWORD PTR SS:
0050448F|.8D55 EC LEA EDX,DWORD PTR SS:
00504492|.8B45 FC MOV EAX,DWORD PTR SS:
00504495|.E8 02EAFBFF CALL Absolute.004C2E9C ;这里是RSA算法核心, 进行powmod运算
0050449A|.8D55 F4 LEA EDX,DWORD PTR SS:
0050449D|.8B45 FC MOV EAX,DWORD PTR SS: ;这是BASE64加密后的结果
005044A0|.E8 33AFFBFF CALL Absolute.004BF3D8 ;变形的BASE64编码
005044A5|.8B45 F8 MOV EAX,DWORD PTR SS:
005044A8|.8B55 F4 MOV EDX,DWORD PTR SS:
005044AB|.E8 E006F0FF CALL Absolute.00404B90 ;编码后与注册码比较
005044B0|.75 02 JNZ SHORT Absolute.005044B4 ;如果两个字符串比较不等, 就完蛋~~
005044B2|.B3 01 MOV BL,1
005044B4|>33C0 XOR EAX,EAX
005044B6|.5A POP EDX
005044B7|.59 POP ECX
005044B8|.59 POP ECX
005044B9|.64:8910 MOV DWORD PTR FS:,EDX
005044BC|.68 E9445000 PUSH Absolute.005044E9
005044C1|>8D45 E4 LEA EAX,DWORD PTR SS:
005044C4|.8B15 20F14B00 MOV EDX,DWORD PTR DS: ;Absolute.004BF124
005044CA|.B9 02000000 MOV ECX,2
005044CF|.E8 9C0EF0FF CALL Absolute.00405370
005044D4|.8D45 F4 LEA EAX,DWORD PTR SS:
005044D7|.BA 03000000 MOV EDX,3
005044DC|.E8 C702F0FF CALL Absolute.004047A8
005044E1\.C3 RETN
下来我们来分析下大数转换的过程, 以后见到类似的过程, 可以基本判定是RSA了.~~
004BF8D8/$55 PUSH EBP ;这里是大数转换函数
004BF8D9|.8BEC MOV EBP,ESP
004BF8DB|.83C4 D8 ADD ESP,-28
004BF8DE|.53 PUSH EBX
004BF8DF|.56 PUSH ESI
004BF8E0|.57 PUSH EDI
004BF8E1|.33C9 XOR ECX,ECX
004BF8E3|.894D D8 MOV DWORD PTR SS:,ECX
004BF8E6|.894D DC MOV DWORD PTR SS:,ECX
004BF8E9|.894D E0 MOV DWORD PTR SS:,ECX
004BF8EC|.894D E4 MOV DWORD PTR SS:,ECX
004BF8EF|.894D EC MOV DWORD PTR SS:,ECX
004BF8F2|.8BDA MOV EBX,EDX
004BF8F4|.8945 FC MOV DWORD PTR SS:,EAX
004BF8F7|.8B45 FC MOV EAX,DWORD PTR SS: ;大数对应字符串S位于
004BF8FA|.E8 3553F4FF CALL Absolute.00404C34 ;串S引用数加1
004BF8FF|.33C0 XOR EAX,EAX
004BF901|.55 PUSH EBP
004BF902|.68 BAFB4B00 PUSH Absolute.004BFBBA
004BF907|.64:FF30 PUSH DWORD PTR FS:
004BF90A|.64:8920 MOV DWORD PTR FS:,ESP
004BF90D|.EB 12 JMP SHORT Absolute.004BF921
004BF90F|>8D45 FC /LEA EAX,DWORD PTR SS:
004BF912|.B9 01000000 |MOV ECX,1
004BF917|.BA 01000000 |MOV EDX,1
004BF91C|.E8 C353F4FF |CALL Absolute.00404CE4 ;如果S不是数字, 那么删掉S的第一个字母,剩下的部分作为新的S
004BF921|>B8 01000000 MOV EAX,1
004BF926|.8B55 FC |MOV EDX,DWORD PTR SS: ;大数对应的字符串S
004BF929|.48 |DEC EAX
004BF92A|.85D2 |TEST EDX,EDX
004BF92C|.74 05 |JE SHORT Absolute.004BF933
004BF92E|.3B42 FC |CMP EAX,DWORD PTR DS: ;EAX=0作为索引访问串S
004BF931|.72 05 |JB SHORT Absolute.004BF938
004BF933|>E8 D43FF4FF |CALL Absolute.0040390C ;如果EAX过大, 会跳到这里造成数组越界异常
004BF938|>40 |INC EAX
004BF939|.8A4402 FF |MOV AL,BYTE PTR DS:
004BF93D|.2C 2D |SUB AL,2D
004BF93F|.74 11 |JE SHORT Absolute.004BF952 ;S中的第一个字母S如果是负号("-"), 那么跳走
004BF941|.04 FD |ADD AL,0FD
004BF943|.2C 0A |SUB AL,0A
004BF945|.72 0B |JB SHORT Absolute.004BF952 ;S如果是数字 ,就跳转, 说明这个循环是来处理S前面
004BF947|.8B45 FC |MOV EAX,DWORD PTR SS: ;的非数字信息的
004BF94A|.E8 F550F4FF |CALL Absolute.00404A44 ;如果S串长度大于0就继续处理
004BF94F|.48 |DEC EAX
004BF950|.^ 7F BD \JG SHORT Absolute.004BF90F
004BF952|>8D45 E4 LEA EAX,DWORD PTR SS:
004BF955|.50 PUSH EAX
004BF956|.B9 01000000 MOV ECX,1
004BF95B|.BA 01000000 MOV EDX,1
004BF960|.8B45 FC MOV EAX,DWORD PTR SS:
004BF963|.E8 3C53F4FF CALL Absolute.00404CA4 ;取S, 即S首字母放到
004BF968|.8B45 E4 MOV EAX,DWORD PTR SS:
004BF96B|.BA D0FB4B00 MOV EDX,Absolute.004BFBD0
004BF970|.E8 1B52F4FF CALL Absolute.00404B90 ;S和负号(-)比较, 即看S对应的大数是负数否.
004BF975|.75 18 JNZ SHORT Absolute.004BF98F ;如果大数不是负数,跳转
004BF977|.C645 EB 00 MOV BYTE PTR SS:,0 ;是大数为正数的标志, 如果为负,将标志置为false
004BF97B|.8D45 FC LEA EAX,DWORD PTR SS:
004BF97E|.B9 01000000 MOV ECX,1
004BF983|.BA 01000000 MOV EDX,1
004BF988|.E8 5753F4FF CALL Absolute.00404CE4 ;如果大数是负数,去掉符号继续分析,并将标志置false
004BF98D|.EB 18 JMP SHORT Absolute.004BF9A7
004BF98F|>C645 EB 01 MOV BYTE PTR SS:,1 ;是大数为正数的标志, 如果为正,将标志置为true
004BF993|.EB 12 JMP SHORT Absolute.004BF9A7
004BF995|>8D45 FC /LEA EAX,DWORD PTR SS:
004BF998|.B9 01000000 |MOV ECX,1
004BF99D|.BA 01000000 |MOV EDX,1
004BF9A2|.E8 3D53F4FF |CALL Absolute.00404CE4 ;如果S为'0', 则去掉S,形成新的串S,继续检查,去掉0
004BF9A7|>8B45 FC MOV EAX,DWORD PTR SS:
004BF9AA|.E8 9550F4FF |CALL Absolute.00404A44 ;取S串长度
004BF9AF|.48 |DEC EAX
004BF9B0|.7E 25 |JLE SHORT Absolute.004BF9D7 ;如果S串中少于2位字符,则跳转
004BF9B2|.8D45 E0 |LEA EAX,DWORD PTR SS:
004BF9B5|.50 |PUSH EAX
004BF9B6|.B9 01000000 |MOV ECX,1
004BF9BB|.BA 01000000 |MOV EDX,1
004BF9C0|.8B45 FC |MOV EAX,DWORD PTR SS:
004BF9C3|.E8 DC52F4FF |CALL Absolute.00404CA4 ;取第1个字母S
004BF9C8|.8B45 E0 |MOV EAX,DWORD PTR SS:
004BF9CB|.BA DCFB4B00 |MOV EDX,Absolute.004BFBDC
004BF9D0|.E8 BB51F4FF |CALL Absolute.00404B90 ;S和'0'比较, 如果不是则跳出循环,说明这个循环是用来去掉
004BF9D5|.^ 74 BE \JE SHORT Absolute.004BF995 ;S前面无用的0
004BF9D7|>8B45 FC MOV EAX,DWORD PTR SS:
004BF9DA|.E8 6550F4FF CALL Absolute.00404A44 ;取S串长度
004BF9DF|.B9 09000000 MOV ECX,9
004BF9E4|.99 CDQ
004BF9E5|.F7F9 IDIV ECX ;S串长度除以9, 因为S中每9个数字转化成一个整数
004BF9E7|.8945 F8 MOV DWORD PTR SS:,EAX ;, 形成一个数组I, 则大数=I + I*10^9 + I*10^18 + ...
004BF9EA|.8B45 FC MOV EAX,DWORD PTR SS:
004BF9ED|.E8 5250F4FF CALL Absolute.00404A44
004BF9F2|.B9 09000000 MOV ECX,9
004BF9F7|.99 CDQ
004BF9F8|.F7F9 IDIV ECX
004BF9FA|.85D2 TEST EDX,EDX
004BF9FC|.74 0B JE SHORT Absolute.004BFA09
004BF9FE|.8345 F8 01 ADD DWORD PTR SS:,1 ;如果S串长度除9不余0, 那么除得出的商加1, 即
004BFA02|.71 05 JNO SHORT Absolute.004BFA09 ;数组I的长度 = S串长度除9取上整
004BFA04|.E8 0B3FF4FF CALL Absolute.00403914 ;如果S串长度过长,造成数组I的长度过大而溢出
004BFA09|>8B45 F8 MOV EAX,DWORD PTR SS:
004BFA0C|.83C0 01 ADD EAX,1
004BFA0F|.71 05 JNO SHORT Absolute.004BFA16
004BFA11|.E8 FE3EF4FF CALL Absolute.00403914 ;看数组I的长度加1 是否溢出, 数组要空出1个位置来
004BFA16|>50 PUSH EAX ;数组I的长度压入
004BFA17|.8D43 04 LEA EAX,DWORD PTR DS:
004BFA1A|.B9 01000000 MOV ECX,1
004BFA1F|.8B15 00F14B00 MOV EDX,DWORD PTR DS: ;Absolute.004BF104
004BFA25|.E8 A262F4FF CALL Absolute.00405CCC ;将数组I的长度设为刚才计算的结果
004BFA2A|.83C4 04 ADD ESP,4 ;平衡堆栈
004BFA2D|.8B45 F8 MOV EAX,DWORD PTR SS: ;存的是大数除9后取上整的结果.即大数在数组中占据的长度
004BFA30|.99 CDQ
004BFA31|.33C9 XOR ECX,ECX
004BFA33|.8B73 04 MOV ESI,DWORD PTR DS: ;处存放的是数组I的地址
004BFA36|.85F6 TEST ESI,ESI ;如果数组I地址为NULL,则造成越界异常
004BFA38|.74 05 JE SHORT Absolute.004BFA3F
004BFA3A|.3B4E FC CMP ECX,DWORD PTR DS:
004BFA3D|.72 05 JB SHORT Absolute.004BFA44 ;如果数组I的长度>0, 就跳转,否则也造成越界异常
004BFA3F|>E8 C83EF4FF CALL Absolute.0040390C
004BFA44|>8904CE MOV DWORD PTR DS:,EAX ;数组元素初始化.?
004BFA47|.8954CE 04 MOV DWORD PTR DS:,EDX
004BFA4B|.8B75 F8 MOV ESI,DWORD PTR SS:
004BFA4E|.83EE 01 SUB ESI,1 ;大数占据的长度减1如果等于0,说明大数小于10^9
004BFA51|.71 05 JNO SHORT Absolute.004BFA58 ;此时可以直接转换
004BFA53|.E8 BC3EF4FF CALL Absolute.00403914
004BFA58|>85F6 TEST ESI,ESI
004BFA5A|.7E 72 JLE SHORT Absolute.004BFACE
004BFA5C|.BF 01000000 MOV EDI,1
004BFA61|>8D45 DC /LEA EAX,DWORD PTR SS:
004BFA64|.50 |PUSH EAX
004BFA65|.8B45 FC |MOV EAX,DWORD PTR SS:
004BFA68|.E8 D74FF4FF |CALL Absolute.00404A44 ;取S串的长度
004BFA6D|.8BD0 |MOV EDX,EAX
004BFA6F|.83EA 08 |SUB EDX,8
004BFA72|.71 05 |JNO SHORT Absolute.004BFA79
004BFA74|.E8 9B3EF4FF |CALL Absolute.00403914 ;如果S串长度-8造成溢出, 即S串长度错误时造成异常
004BFA79|>B9 09000000 |MOV ECX,9
004BFA7E|.8B45 FC |MOV EAX,DWORD PTR SS:
004BFA81|.E8 1E52F4FF |CALL Absolute.00404CA4 ;取S串最后后9个字母, 放在
004BFA86|.8B45 DC |MOV EAX,DWORD PTR SS:
004BFA89|.E8 0299F4FF |CALL Absolute.00409390 ;将后9个数字转为整数
004BFA8E|.99 |CDQ
004BFA8F|.52 |PUSH EDX
004BFA90|.50 |PUSH EAX
004BFA91|.8B43 04 |MOV EAX,DWORD PTR DS:
004BFA94|.85C0 |TEST EAX,EAX
004BFA96|.74 05 |JE SHORT Absolute.004BFA9D
004BFA98|.3B78 FC |CMP EDI,DWORD PTR DS: ;判断是否造成数组越界
004BFA9B|.72 05 |JB SHORT Absolute.004BFAA2
004BFA9D|>E8 6A3EF4FF |CALL Absolute.0040390C
004BFAA2|>8F04F8 |POP DWORD PTR DS: ;将转化成的整数存入数组
004BFAA5|.8F44F8 04 |POP DWORD PTR DS:
004BFAA9|.8B45 FC |MOV EAX,DWORD PTR SS:
004BFAAC|.E8 934FF4FF |CALL Absolute.00404A44 ;取S串长度
004BFAB1|.8BD0 |MOV EDX,EAX
004BFAB3|.83EA 08 |SUB EDX,8
004BFAB6|.71 05 |JNO SHORT Absolute.004BFABD
004BFAB8|.E8 573EF4FF |CALL Absolute.00403914 ;如果S串长度-8造成溢出, 即S串长度错误时造成异常
004BFABD|>8D45 FC |LEA EAX,DWORD PTR SS:
004BFAC0|.B9 09000000 |MOV ECX,9
004BFAC5|.E8 1A52F4FF |CALL Absolute.00404CE4 ;去掉S串后9位数字, 形成新串S, 继续转化
004BFACA|.47 |INC EDI
004BFACB|.4E |DEC ESI
004BFACC|.^ 75 93 \JNZ SHORT Absolute.004BFA61
004BFACE|>8B45 FC MOV EAX,DWORD PTR SS:
004BFAD1|.E8 BA98F4FF CALL Absolute.00409390 ;S转为int
004BFAD6|.99 CDQ
004BFAD7|.8B4D F8 MOV ECX,DWORD PTR SS:
004BFADA|.8B73 04 MOV ESI,DWORD PTR DS:
004BFADD|.85F6 TEST ESI,ESI
004BFADF|.74 05 JE SHORT Absolute.004BFAE6
004BFAE1|.3B4E FC CMP ECX,DWORD PTR DS:
004BFAE4|.72 05 JB SHORT Absolute.004BFAEB ;如果对数组I的访问没有越界,则写入最后9位数
004BFAE6|>E8 213EF4FF CALL Absolute.0040390C
004BFAEB|>8904CE MOV DWORD PTR DS:,EAX
004BFAEE|.8954CE 04 MOV DWORD PTR DS:,EDX ;到这里大数转换完成
004BFAF2|.8D45 EC LEA EAX,DWORD PTR SS:
004BFAF5|.E8 8A4CF4FF CALL Absolute.00404784 ;释放处的字符串资源
004BFAFA|.EB 2A JMP SHORT Absolute.004BFB26
004BFAFC|>6A 00 /PUSH 0 ; /Arg2 = 00000000
004BFAFE|.6A 02 |PUSH 2 ; |Arg1 = 00000002
004BFB00|.8D55 F0 |LEA EDX,DWORD PTR SS: ; |
004BFB03|.8BC3 |MOV EAX,EBX ; |
004BFB05|.E8 22FCFFFF |CALL Absolute.004BF72C ; \大数除以2取余数, EAX为返后结果
004BFB0A|.FF75 F4 |PUSH DWORD PTR SS: ; /Arg2
004BFB0D|.FF75 F0 |PUSH DWORD PTR SS: ; |Arg1
004BFB10|.8D45 D8 |LEA EAX,DWORD PTR SS: ; |
004BFB13|.E8 2898F4FF |CALL Absolute.00409340 ; \将余数转为字符串
004BFB18|.8B55 D8 |MOV EDX,DWORD PTR SS: ;这里是用除二取余法,将10进制的大数数转为2进制
004BFB1B|.8D45 EC |LEA EAX,DWORD PTR SS:
004BFB1E|.8B4D EC |MOV ECX,DWORD PTR SS:
004BFB21|.E8 6A4FF4FF |CALL Absolute.00404A90 ;连接所产生的余数序列, 最终形成的余数序列BS即为大数的2进制形式
004BFB26|>33C0 XOR EAX,EAX ;余数序列BS位于
004BFB28|.8B53 04 |MOV EDX,DWORD PTR DS:
004BFB2B|.85D2 |TEST EDX,EDX
004BFB2D|.74 05 |JE SHORT Absolute.004BFB34
004BFB2F|.3B42 FC |CMP EAX,DWORD PTR DS: ;如果数组I长度小于0,则造成越界异常
004BFB32|.72 05 |JB SHORT Absolute.004BFB39
004BFB34|>E8 D33DF4FF |CALL Absolute.0040390C
004BFB39|>837CC2 04 00|CMP DWORD PTR DS:,0 ;|
004BFB3E|.^ 75 BC |JNZ SHORT Absolute.004BFAFC ;|
004BFB40|.833CC2 01 |CMP DWORD PTR DS:,1 ;|
004BFB44|.^ 75 B6 |JNZ SHORT Absolute.004BFAFC ;|
004BFB46|.B8 01000000 |MOV EAX,1 ;|
004BFB4B|.8B53 04 |MOV EDX,DWORD PTR DS: ;|
004BFB4E|.85D2 |TEST EDX,EDX ;|
004BFB50|.74 05 |JE SHORT Absolute.004BFB57 ;这里都是判断大数除2运算后是否变为0, 此时大数长度为1
004BFB52|.3B42 FC |CMP EAX,DWORD PTR DS: ;如果大数未变为0,则继续除2运算
004BFB55|.72 05 |JB SHORT Absolute.004BFB5C ;|
004BFB57|>E8 B03DF4FF |CALL Absolute.0040390C ;|
004BFB5C|>837CC2 04 00|CMP DWORD PTR DS:,0 ;|
004BFB61|.^ 75 99 |JNZ SHORT Absolute.004BFAFC ;|
004BFB63|.833CC2 00 |CMP DWORD PTR DS:,0 ;|
004BFB67|.^ 75 93 \JNZ SHORT Absolute.004BFAFC ;|
004BFB69|.8D45 EC LEA EAX,DWORD PTR SS: ;循环完毕,大数转2进制串也完成了..~~
004BFB6C|.8B4D EC MOV ECX,DWORD PTR SS:
004BFB6F|.BA DCFB4B00 MOV EDX,Absolute.004BFBDC
004BFB74|.E8 174FF4FF CALL Absolute.00404A90 ;在2进制串前补个0
004BFB79|.8BC3 MOV EAX,EBX
004BFB7B|.E8 60000000 CALL Absolute.004BFBE0
004BFB80|.8BD3 MOV EDX,EBX
004BFB82|.8B45 EC MOV EAX,DWORD PTR SS:
004BFB85|.E8 DA150000 CALL Absolute.004C1164
004BFB8A|.8A45 EB MOV AL,BYTE PTR SS:
004BFB8D|.8803 MOV BYTE PTR DS:,AL ;符号位保存下来
004BFB8F|.33C0 XOR EAX,EAX
004BFB91|.5A POP EDX
004BFB92|.59 POP ECX
004BFB93|.59 POP ECX
004BFB94|.64:8910 MOV DWORD PTR FS:,EDX
004BFB97|.68 C1FB4B00 PUSH Absolute.004BFBC1
004BFB9C|>8D45 D8 LEA EAX,DWORD PTR SS: ;后面都是善后工作了
004BFB9F|.BA 04000000 MOV EDX,4
004BFBA4|.E8 FF4BF4FF CALL Absolute.004047A8
004BFBA9|.8D45 EC LEA EAX,DWORD PTR SS:
004BFBAC|.E8 D34BF4FF CALL Absolute.00404784
004BFBB1|.8D45 FC LEA EAX,DWORD PTR SS:
004BFBB4|.E8 CB4BF4FF CALL Absolute.00404784
004BFBB9\.C3 RETN
来总结一下大数转换的算法:
1. 去掉S串前既不是负号, 也不是数字的部分.
2. 置正负标志位, 如果S串前有负号, 那么这个大数为负并去掉负号继续分析, 否则这个大数为正
3. 去掉S串前的0
4. S中每9个数字转化成一个整数, 形成一个数组I, 则大数=I + I*10^9 + I*10^18 + ...
这一步是最为关键的..如果大家以后分析的程序中有这么一段, 便是实现大数转化的功能
5. 除二取余法,将第4步得出的10进制的大数转为2进制字符串串
(除二取余法: 我想大家应该学过这个吧..是最常用的10进制转2进制的方法)
下面来分析一下最重要的部分:RSA加密部分
先看代码, 再总结一下~
004C2E9C/$55 PUSH EBP
004C2E9D|.8BEC MOV EBP,ESP
004C2E9F|.83C4 D0 ADD ESP,-30
004C2EA2|.53 PUSH EBX
004C2EA3|.56 PUSH ESI
004C2EA4|.57 PUSH EDI
004C2EA5|.33DB XOR EBX,EBX
004C2EA7|.895D D0 MOV DWORD PTR SS:,EBX
004C2EAA|.895D DC MOV DWORD PTR SS:,EBX
004C2EAD|.895D D8 MOV DWORD PTR SS:,EBX
004C2EB0|.895D D4 MOV DWORD PTR SS:,EBX
004C2EB3|.8BF9 MOV EDI,ECX
004C2EB5|.8955 F8 MOV DWORD PTR SS:,EDX
004C2EB8|.8945 FC MOV DWORD PTR SS:,EAX
004C2EBB|.8B45 FC MOV EAX,DWORD PTR SS: ;用户名串
004C2EBE|.E8 711DF4FF CALL Absolute.00404C34 ;用户名串引用数+1
004C2EC3|.8D45 F0 LEA EAX,DWORD PTR SS:
004C2EC6|.8B15 20F14B00 MOV EDX,DWORD PTR DS: ;Absolute.004BF124
004C2ECC|.E8 8323F4FF CALL Absolute.00405254
004C2ED1|.8D45 E8 LEA EAX,DWORD PTR SS: ;对象引用数+1
004C2ED4|.8B15 20F14B00 MOV EDX,DWORD PTR DS: ;Absolute.004BF124
004C2EDA|.E8 7523F4FF CALL Absolute.00405254 ;对象引用数+1
004C2EDF|.8D45 E0 LEA EAX,DWORD PTR SS:
004C2EE2|.8B15 20F14B00 MOV EDX,DWORD PTR DS: ;Absolute.004BF124
004C2EE8|.E8 6723F4FF CALL Absolute.00405254 ;对象引用数+1
004C2EED|.33C0 XOR EAX,EAX
004C2EEF|.55 PUSH EBP
004C2EF0|.68 1E314C00 PUSH Absolute.004C311E
004C2EF5|.64:FF30 PUSH DWORD PTR FS:
004C2EF8|.64:8920 MOV DWORD PTR FS:,ESP
004C2EFB|.8D55 E0 LEA EDX,DWORD PTR SS:
004C2EFE|.B8 38314C00 MOV EAX,Absolute.004C3138
004C2F03|.E8 5CE2FFFF CALL Absolute.004C1164
004C2F08|.8D55 DC LEA EDX,DWORD PTR SS:
004C2F0B|.8BC7 MOV EAX,EDI
004C2F0D|.E8 26E1FFFF CALL Absolute.004C1038
004C2F12|.8B45 DC MOV EAX,DWORD PTR SS: ;RSA中数n的2进制串形式bin(n)
004C2F15|.E8 2A1BF4FF CALL Absolute.00404A44 ;取它的长度len(n)放在EBX
004C2F1A|.8BD8 MOV EBX,EAX
004C2F1C|.8D55 DC LEA EDX,DWORD PTR SS:
004C2F1F|.8B45 FC MOV EAX,DWORD PTR SS: ;用户名
004C2F22|.E8 4DC6FFFF CALL Absolute.004BF574 ;将用户名转为2进制串
004C2F27|.8D45 DC LEA EAX,DWORD PTR SS:
004C2F2A|.8B4D DC MOV ECX,DWORD PTR SS:
004C2F2D|.BA 44314C00 MOV EDX,Absolute.004C3144 ;ASCII "111"
004C2F32|.E8 591BF4FF CALL Absolute.00404A90 ;用户名2进制串bin(name) 和 "111"连接,形成新的bin(name)
004C2F37|.8BF3 MOV ESI,EBX
004C2F39|.83EE 01 SUB ESI,1
004C2F3C|.71 05 JNO SHORT Absolute.004C2F43 ;如果RSA中n的2进制串长度len(n)错误..则引起溢出异常
004C2F3E|.E8 D109F4FF CALL Absolute.00403914
004C2F43|>EB 10 JMP SHORT Absolute.004C2F55
004C2F45|>8D45 DC /LEA EAX,DWORD PTR SS:
004C2F48|.8B4D DC |MOV ECX,DWORD PTR SS:
004C2F4B|.BA 38314C00 |MOV EDX,Absolute.004C3138
004C2F50|.E8 3B1BF4FF |CALL Absolute.00404A90 ;bin(name) = '0' + bin(name);在bin(name)前加0
004C2F55|>8B45 DC MOV EAX,DWORD PTR SS:
004C2F58|.E8 E71AF4FF |CALL Absolute.00404A44 ;在bin(name)前加0直到len(name) % (len(n)-1) == 0
004C2F5D|.99 |CDQ
004C2F5E|.F7FE |IDIV ESI
004C2F60|.85D2 |TEST EDX,EDX
004C2F62|.^ 75 E1 \JNZ SHORT Absolute.004C2F45
004C2F64|.8B45 DC MOV EAX,DWORD PTR SS:
004C2F67|.E8 D81AF4FF CALL Absolute.00404A44
004C2F6C|.8BD3 MOV EDX,EBX
004C2F6E|.83EA 01 SUB EDX,1
004C2F71|.71 05 JNO SHORT Absolute.004C2F78
004C2F73|.E8 9C09F4FF CALL Absolute.00403914
004C2F78|>8BCA MOV ECX,EDX
004C2F7A|.99 CDQ
004C2F7B|.F7F9 IDIV ECX
004C2F7D|.8BF0 MOV ESI,EAX ;len(name) / (len(n)-1)得出的商放到ESI
004C2F7F|.8D45 D8 LEA EAX,DWORD PTR SS:
004C2F82|.E8 FD17F4FF CALL Absolute.00404784 ;释放字符串资源
004C2F87|.85F6 TEST ESI,ESI
004C2F89|.0F8E 1C010000 JLE Absolute.004C30AB
004C2F8F|>8D45 D4 /LEA EAX,DWORD PTR SS:
004C2F92|.50 |PUSH EAX
004C2F93|.8BCB |MOV ECX,EBX
004C2F95|.83E9 01 |SUB ECX,1
004C2F98|.71 05 |JNO SHORT Absolute.004C2F9F
004C2F9A|.E8 7509F4FF |CALL Absolute.00403914
004C2F9F|>BA 01000000 |MOV EDX,1
004C2FA4|.8B45 DC |MOV EAX,DWORD PTR SS:
004C2FA7|.E8 F81CF4FF |CALL Absolute.00404CA4 ;将处的bin(name)复制到
004C2FAC|.EB 12 |JMP SHORT Absolute.004C2FC0
004C2FAE|>8D45 D4 |/LEA EAX,DWORD PTR SS:
004C2FB1|.B9 01000000 ||MOV ECX,1
004C2FB6|.BA 01000000 ||MOV EDX,1
004C2FBB|.E8 241DF4FF ||CALL Absolute.00404CE4 ;去掉'0'继续循环
004C2FC0|>8D45 D0 | LEA EAX,DWORD PTR SS:
004C2FC3|.50 ||PUSH EAX
004C2FC4|.B9 01000000 ||MOV ECX,1
004C2FC9|.BA 01000000 ||MOV EDX,1
004C2FCE|.8B45 D4 ||MOV EAX,DWORD PTR SS:
004C2FD1|.E8 CE1CF4FF ||CALL Absolute.00404CA4 ;取bin(name)的第一个数字
004C2FD6|.8B45 D0 ||MOV EAX,DWORD PTR SS:
004C2FD9|.BA 38314C00 ||MOV EDX,Absolute.004C3138
004C2FDE|.E8 AD1BF4FF ||CALL Absolute.00404B90 ;bin(name)中取出的数字和'0'比较
004C2FE3|.75 0B ||JNZ SHORT Absolute.004C2FF0 ;如果不等于'0'则跳转, 说明这个循环用来去掉bin(name)前的0
004C2FE5|.8B45 D4 ||MOV EAX,DWORD PTR SS:
004C2FE8|.E8 571AF4FF ||CALL Absolute.00404A44
004C2FED|.48 ||DEC EAX
004C2FEE|.^ 7F BE |\JG SHORT Absolute.004C2FAE ;当bin(name)长度大于1时继续循环
004C2FF0|>8D55 F0 |LEA EDX,DWORD PTR SS:
004C2FF3|.8B45 D4 |MOV EAX,DWORD PTR SS:
004C2FF6|.E8 69E1FFFF |CALL Absolute.004C1164
004C2FFB|.8BCB |MOV ECX,EBX
004C2FFD|.83E9 01 |SUB ECX,1
004C3000|.71 05 |JNO SHORT Absolute.004C3007
004C3002|.E8 0D09F4FF |CALL Absolute.00403914 ;如果RSA中n的2进制串长度len(n)错误..则引起溢出异常
004C3007|>8D45 DC |LEA EAX,DWORD PTR SS:
004C300A|.BA 01000000 |MOV EDX,1
004C300F|.E8 D01CF4FF |CALL Absolute.00404CE4 ;释放字符串资源
004C3014|.8B45 D4 |MOV EAX,DWORD PTR SS: ;去掉'0'后的bin(name)
004C3017|.BA 38314C00 |MOV EDX,Absolute.004C3138
004C301C|.E8 6F1BF4FF |CALL Absolute.00404B90 ;bin(name)和'0'比较
004C3021|.75 0D |JNZ SHORT Absolute.004C3030
004C3023|.8D55 E8 |LEA EDX,DWORD PTR SS:
004C3026|.8D45 E0 |LEA EAX,DWORD PTR SS:
004C3029|.E8 0ED6FFFF |CALL Absolute.004C063C
004C302E|.EB 11 |JMP SHORT Absolute.004C3041
004C3030|>8D45 E8 |LEA EAX,DWORD PTR SS:
004C3033|.50 |PUSH EAX
004C3034|.8BCF |MOV ECX,EDI
004C3036|.8B55 F8 |MOV EDX,DWORD PTR SS:
004C3039|.8D45 F0 |LEA EAX,DWORD PTR SS:
004C303C|.E8 AFF6FFFF |CALL Absolute.004C26F0 ;|
004C3041|>8D45 F0 |LEA EAX,DWORD PTR SS: ;|
004C3044|.E8 97CBFFFF |CALL Absolute.004BFBE0 ;|
004C3049|.8D45 D4 |LEA EAX,DWORD PTR SS: ;|
004C304C|.E8 3317F4FF |CALL Absolute.00404784 ;这几步进行了powmod运算..(name)^e mod n
004C3051|.8D55 D4 |LEA EDX,DWORD PTR SS: ;|
004C3054|.8D45 E8 |LEA EAX,DWORD PTR SS: ;|
004C3057|.E8 DCDFFFFF |CALL Absolute.004C1038 ;|
004C305C|.EB 10 |JMP SHORT Absolute.004C306E ;后面都是对结果进行去0和 转为16进制
004C305E|>8D45 D4 |/LEA EAX,DWORD PTR SS: ;之类的操作, 和前面差不多
004C3061|.8B4D D4 ||MOV ECX,DWORD PTR SS:
004C3064|.BA 38314C00 ||MOV EDX,Absolute.004C3138
004C3069|.E8 221AF4FF ||CALL Absolute.00404A90
004C306E|>8B45 D4 | MOV EAX,DWORD PTR SS: ;RSA中的加密结果出现
004C3071|.E8 CE19F4FF ||CALL Absolute.00404A44
004C3076|.99 ||CDQ
004C3077|.F7FB ||IDIV EBX
004C3079|.85D2 ||TEST EDX,EDX
004C307B|.^ 75 E1 |\JNZ SHORT Absolute.004C305E
004C307D|.8D45 D8 |LEA EAX,DWORD PTR SS:
004C3080|.8B55 D4 |MOV EDX,DWORD PTR SS:
004C3083|.E8 C419F4FF |CALL Absolute.00404A4C
004C3088|.8D45 E8 |LEA EAX,DWORD PTR SS:
004C308B|.E8 50CBFFFF |CALL Absolute.004BFBE0
004C3090|.4E |DEC ESI
004C3091|.^ 0F85 F8FEFFFF \JNZ Absolute.004C2F8F
004C3097|.EB 12 JMP SHORT Absolute.004C30AB
004C3099|>8D45 D8 /LEA EAX,DWORD PTR SS:
004C309C|.B9 01000000 |MOV ECX,1
004C30A1|.BA 01000000 |MOV EDX,1
004C30A6|.E8 391CF4FF |CALL Absolute.00404CE4
004C30AB|>B8 01000000 MOV EAX,1
004C30B0|.8B55 D8 |MOV EDX,DWORD PTR SS:
004C30B3|.48 |DEC EAX
004C30B4|.85D2 |TEST EDX,EDX
004C30B6|.74 05 |JE SHORT Absolute.004C30BD
004C30B8|.3B42 FC |CMP EAX,DWORD PTR DS:
004C30BB|.72 05 |JB SHORT Absolute.004C30C2
004C30BD|>E8 4A08F4FF |CALL Absolute.0040390C
004C30C2|>40 |INC EAX
004C30C3|.807C02 FF 30|CMP BYTE PTR DS:,30
004C30C8|.75 0B |JNZ SHORT Absolute.004C30D5
004C30CA|.8B45 D8 |MOV EAX,DWORD PTR SS:
004C30CD|.E8 7219F4FF |CALL Absolute.00404A44
004C30D2|.48 |DEC EAX
004C30D3|.^ 7F C4 \JG SHORT Absolute.004C3099
004C30D5|>8B55 08 MOV EDX,DWORD PTR SS:
004C30D8|.8B45 D8 MOV EAX,DWORD PTR SS:
004C30DB|.E8 50C5FFFF CALL Absolute.004BF630
004C30E0|.8D45 E0 LEA EAX,DWORD PTR SS:
004C30E3|.E8 F8CAFFFF CALL Absolute.004BFBE0
004C30E8|.33C0 XOR EAX,EAX
004C30EA|.5A POP EDX
004C30EB|.59 POP ECX
004C30EC|.59 POP ECX
004C30ED|.64:8910 MOV DWORD PTR FS:,EDX
004C30F0|.68 25314C00 PUSH Absolute.004C3125
004C30F5|>8D45 D0 LEA EAX,DWORD PTR SS:
004C30F8|.BA 04000000 MOV EDX,4
004C30FD|.E8 A616F4FF CALL Absolute.004047A8
004C3102|.8D45 E0 LEA EAX,DWORD PTR SS:
004C3105|.8B15 20F14B00 MOV EDX,DWORD PTR DS: ;Absolute.004BF124
004C310B|.B9 03000000 MOV ECX,3
004C3110|.E8 5B22F4FF CALL Absolute.00405370
004C3115|.8D45 FC LEA EAX,DWORD PTR SS:
004C3118|.E8 6716F4FF CALL Absolute.00404784
004C311D\.C3 RETN
004C311E .^ E9 4510F4FF JMP Absolute.00404168
004C3123 .^ EB D0 JMP SHORT Absolute.004C30F5
004C3125 .5F POP EDI
004C3126 .5E POP ESI
004C3127 .5B POP EBX
004C3128 .8BE5 MOV ESP,EBP
004C312A .5D POP EBP
004C312B .C2 0400 RETN 4
核心算法总结:
1 . 将用户名转为2进制串, 并在串前添加 111,
等价于在16进制的用户名前面加7, 如果用户名是vecri , 16进制为7665637269, 添加7后成为77665637269
2 . 将添加7 后的结果做powmod运算, 例如vecri 的运算结果 = 77665637269(16)^65537(10) mod 874802157929661091407425794781(10)
注意括号里写的是多少进制,^我指的是幂运算而不是异或, 上面的意思是16进制的77665637269, 取65537次方(65537是10进制的), 然后对10进制的874802157929661091407425794781取余数, 余数就是运算的结果, ~(说的有点麻烦, 希望能看懂, 进制搞错就完了)
3. 再将第2步产生的结果转为16进制
下面是这个软件的BASE64算法, 输入是RSA运算后的结果
004BF3D8/$55 PUSH EBP
004BF3D9|.8BEC MOV EBP,ESP
004BF3DB|.81C4 ECFBFFFF ADD ESP,-414
004BF3E1|.53 PUSH EBX
004BF3E2|.56 PUSH ESI
004BF3E3|.57 PUSH EDI
004BF3E4|.33C9 XOR ECX,ECX
004BF3E6|.898D ECFBFFFF MOV DWORD PTR SS:,ECX
004BF3EC|.898D F0FBFFFF MOV DWORD PTR SS:,ECX
004BF3F2|.894D F8 MOV DWORD PTR SS:,ECX
004BF3F5|.8BFA MOV EDI,EDX
004BF3F7|.8945 FC MOV DWORD PTR SS:,EAX
004BF3FA|.B9 00010000 MOV ECX,100
004BF3FF|.8D85 F4FBFFFF LEA EAX,DWORD PTR SS:
004BF405|.8B15 10114000 MOV EDX,DWORD PTR DS: ;Absolute.00401114
004BF40B|.E8 745EF4FF CALL Absolute.00405284
004BF410|.33C0 XOR EAX,EAX
004BF412|.55 PUSH EBP
004BF413|.68 59F54B00 PUSH Absolute.004BF559
004BF418|.64:FF30 PUSH DWORD PTR FS:
004BF41B|.64:8920 MOV DWORD PTR FS:,ESP
004BF41E|.8D85 F4FBFFFF LEA EAX,DWORD PTR SS:
004BF424|.BA FF000000 MOV EDX,0FF
004BF429|.E8 22FEFFFF CALL Absolute.004BF250 ;这里生成了一个元素为"00000000", "00000001",
004BF42E|.8D45 F8 LEA EAX,DWORD PTR SS: ;"00000010", "00000011", 一直到"11111111"
004BF431|.E8 4E53F4FF CALL Absolute.00404784 ;的字符串数组
004BF436|.8B45 FC MOV EAX,DWORD PTR SS: ;为RSA加密后的结果
004BF439|.E8 0656F4FF CALL Absolute.00404A44
004BF43E|.8BD8 MOV EBX,EAX
004BF440|.85DB TEST EBX,EBX
004BF442|.7E 3F JLE SHORT Absolute.004BF483
004BF444|.BE 01000000 MOV ESI,1
004BF449|>8D45 F8 /LEA EAX,DWORD PTR SS:
004BF44C|.8B55 FC |MOV EDX,DWORD PTR SS:
004BF44F|.4E |DEC ESI
004BF450|.85D2 |TEST EDX,EDX
004BF452|.74 05 |JE SHORT Absolute.004BF459
004BF454|.3B72 FC |CMP ESI,DWORD PTR DS:
004BF457|.72 05 |JB SHORT Absolute.004BF45E
004BF459|>E8 AE44F4FF |CALL Absolute.0040390C
004BF45E|>46 |INC ESI
004BF45F|.0FB65432 FF |MOVZX EDX,BYTE PTR DS: ;依次取出RSA加密结果的每个字节数据
004BF464|.8B9495 F4FBFF>|MOV EDX,DWORD PTR SS: ;将取出的字节数据作为访问上面"00000000"-"11111111"
004BF46B|.E8 DC55F4FF |CALL Absolute.00404A4C ;的索引,也就是取出该字节数据的字符串形式
004BF470|.46 |INC ESI ;然后将每个字节数据对应的字符串连接起来
004BF471|.4B |DEC EBX
004BF472|.^ 75 D5 \JNZ SHORT Absolute.004BF449 ;这个循环就是将RSA加密结果转为对应的2进制串,记
004BF474|.EB 0D JMP SHORT Absolute.004BF483 ;做2进制串1
004BF476|>8D45 F8 /LEA EAX,DWORD PTR SS:
004BF479|.BA 70F54B00 |MOV EDX,Absolute.004BF570
004BF47E|.E8 C955F4FF |CALL Absolute.00404A4C
004BF483|>8B45 F8 MOV EAX,DWORD PTR SS:
004BF486|.E8 B955F4FF |CALL Absolute.00404A44 ;取2进制串1的长度,
004BF48B|.B9 06000000 |MOV ECX,6 ;如果该长度不是6的倍数,则在2进制串1后加0, 直到
004BF490|.99 |CDQ ;2进制串1的长度是6的倍数
004BF491|.F7F9 |IDIV ECX
004BF493|.85D2 |TEST EDX,EDX
004BF495|.^ 75 DF \JNZ SHORT Absolute.004BF476
004BF497|.8B45 F8 MOV EAX,DWORD PTR SS:
004BF49A|.E8 A555F4FF CALL Absolute.00404A44
004BF49F|.B9 06000000 MOV ECX,6
004BF4A4|.99 CDQ
004BF4A5|.F7F9 IDIV ECX
004BF4A7|.8BD8 MOV EBX,EAX ;2进制串1的长度除以6. 商放到EBX
004BF4A9|.8BC7 MOV EAX,EDI
004BF4AB|.E8 D452F4FF CALL Absolute.00404784
004BF4B0|.85DB TEST EBX,EBX
004BF4B2|.7E 69 JLE SHORT Absolute.004BF51D
004BF4B4|>8D85 F0FBFFFF /LEA EAX,DWORD PTR SS:
004BF4BA|.50 |PUSH EAX
004BF4BB|.B9 06000000 |MOV ECX,6
004BF4C0|.BA 01000000 |MOV EDX,1
004BF4C5|.8B45 F8 |MOV EAX,DWORD PTR SS:
004BF4C8|.E8 D757F4FF |CALL Absolute.00404CA4 ;每次去2进制串1的前6个数字
004BF4CD|.8B95 F0FBFFFF |MOV EDX,DWORD PTR SS:
004BF4D3|.8D45 F4 |LEA EAX,DWORD PTR SS:
004BF4D6|.E8 11FDFFFF |CALL Absolute.004BF1EC ;前6个数字组成的串对应到一个整数,比如
004BF4DB|.8D85 ECFBFFFF |LEA EAX,DWORD PTR SS: ;"000010"对应2+1=3
004BF4E1|.8B55 F4 |MOV EDX,DWORD PTR SS:
004BF4E4|.4A |DEC EDX
004BF4E5|.83FA 3F |CMP EDX,3F
004BF4E8|.76 05 |JBE SHORT Absolute.004BF4EF
004BF4EA|.E8 1D44F4FF |CALL Absolute.0040390C
004BF4EF|>42 |INC EDX
004BF4F0|.8A92 6B7E5000 |MOV DL,BYTE PTR DS: ;从base64表中查取对应的字母
004BF4F6|.E8 7154F4FF |CALL Absolute.0040496C ;将查取的字母转为字符串
004BF4FB|.8B95 ECFBFFFF |MOV EDX,DWORD PTR SS:
004BF501|.8BC7 |MOV EAX,EDI
004BF503|.E8 4455F4FF |CALL Absolute.00404A4C ;将查取的字母连接成字符串, 最终连接成
004BF508|.8D45 F8 |LEA EAX,DWORD PTR SS: ;的就是BASE64加密的结果
004BF50B|.B9 06000000 |MOV ECX,6
004BF510|.BA 01000000 |MOV EDX,1
004BF515|.E8 CA57F4FF |CALL Absolute.00404CE4 ;去掉2进制串1的前6个数字,继续转化下6个数字
004BF51A|.4B |DEC EBX
004BF51B|.^ 75 97 \JNZ SHORT Absolute.004BF4B4
004BF51D|>33C0 XOR EAX,EAX
004BF51F|.5A POP EDX
004BF520|.59 POP ECX ;后面都是善后工作了
004BF521|.59 POP ECX
004BF522|.64:8910 MOV DWORD PTR FS:,EDX
004BF525|.68 60F54B00 PUSH Absolute.004BF560
004BF52A|>8D85 ECFBFFFF LEA EAX,DWORD PTR SS:
004BF530|.BA 02000000 MOV EDX,2
004BF535|.E8 6E52F4FF CALL Absolute.004047A8
004BF53A|.8D85 F4FBFFFF LEA EAX,DWORD PTR SS:
004BF540|.B9 00010000 MOV ECX,100
004BF545|.8B15 10114000 MOV EDX,DWORD PTR DS: ;Absolute.00401114
004BF54B|.E8 205EF4FF CALL Absolute.00405370
004BF550|.8D45 F8 LEA EAX,DWORD PTR SS:
004BF553|.E8 2C52F4FF CALL Absolute.00404784
004BF558\.C3 RETN
004BF559 .^ E9 0A4CF4FF JMP Absolute.00404168
004BF55E .^ EB CA JMP SHORT Absolute.004BF52A
004BF560 .5F POP EDI
004BF561 .5E POP ESI
004BF562 .5B POP EBX
004BF563 .8BE5 MOV ESP,EBP
004BF565 .5D POP EBP
004BF566 .C3 RETN
这里的BASE64和平常的BASE64不一样. 平常的BASE64其中的表是:
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/
而这里的是:
aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ0123456789+=
整个加密算法都是没有变的, 只是这个表有改动而已. 所以大家以后碰到BASE64时.关键的就是要找出它的转换表
这个BASE64所输出的字符串也就是注册码了..~~~~呵呵。.可以做出内存注册机来.~~
算法总结:
1. RSA中的 e = 65537(10), n = 874802157929661091407425794781(10), 括号中为多少进制
将这两个数从字符串形式做大数转换, 以备RSA加密时使用
2. 将用户名转为2进制串, 并在串前添加 111,
等价于在16进制的用户名前面加7, 如果用户名是vecri , 16进制为7665637269, 添加7后成为77665637269
3. 将添加7 后的结果做powmod运算, 例如vecri 的运算结果 = 77665637269(16)^65537(10) mod 874802157929661091407425794781(10)
注意括号里写的是多少进制,^我指的是幂运算而不是异或, 上面的意思是16进制的77665637269, 取65537次方(65537是10进制的), 然后 对10进制的874802157929661091407425794781取余数, 余数就是运算的结果, ~(说的有点麻烦, 希望能看懂, 进制搞错就完了)
大家可以使用 readyu 大侠提供的RDLP, BigInterCalc来验证
下载位置:
http://bbs.pediy.com/showthread.php?t=47934&highlight=RDLP
http://bbs.pediy.com/showthread.php?t=49005&highlight=RDLP
4. 再将第2步产生的结果转为16进制作为最后一步BASE64编码的输入
5. BASE64编码输出一个字符串, 该字符串就是注册码
附上注册机伪代码(我找了半天没有找到RSA代码, 所以只好献上伪代码了, 找到后会传上注册机. 哪位大侠有C++的RSA代码? 可以传一份不):
char name;
cin >> (name+1); //输入用户名
name = 0x07;
BigInte("65537");
BigIntn("874802157929661091407425794781");
unsignedcharbuffer;
RSAEncrypt(buffer, name, e, n); //RSA加密输出到buffer
unsignedcharregcode;
Base64Encrypt(regcode, buffer); //将 buffer进行base64编码为注册码
cout << "用户名: " << (name+1) << endl;
cout << "注册码: " << regcode << endl;
------------------------------------------------------------------------
【破解总结】这个软件算法并不复杂, 可以好好学习一下BASE64和RSA, 呵呵~~
------------------------------------------------------------------------
【版权声明】本破文纯属技术交流, 转载请注明作者并保持文章的完整, 谢谢! /:good好杂实的破解文章。楼主对加密算法研究得蛮透彻嘛。 好帖子,顶下,佩服楼主的耐心。 好详细,下来研究一下,希望多看到一些楼主精彩文章 这里是不是没人关注密码学算法啊.~~~以后不在这发好了.. 向楼主学习密码学算法,期待楼主更多文章。 密码算法怎才能学通了 /:014 这个东西我以前是直接下载 个破解版去截音乐的, 现在可以自己按楼主的方法去破了~/:014 不是不支持,是目前还搞不懂加密算法,正在努力,希望多看几次可以学会
页:
[1]