- UID
- 32386
注册时间2007-6-1
阅读权限10
最后登录1970-1-1
周游历练
该用户从未签到
|
【文章标题】: DCG_2_2算法分析
【文章作者】: kangroo
【作者邮箱】: [email protected]
【作者QQ号】: 87636423
【软件名称】: DCG_2_2
【软件大小】: 503KB
【下载地址】: 自己搜索下载
【加壳方式】: 无
【保护方式】: 根据输入的用户名计算注册码
【编写语言】: Borland Delphi v6.0-v7.0
【使用工具】: ollydbg peid
【操作平台】: XP/2000
【软件介绍】: DCG官方出品的CRACKME
【作者声明】: 这是我的第一篇算法分析,网络上也有类似破文,事先申明绝对靠自己一步步分析出来,花了2天时间,写的不好,高手就别看了,要是看了还望多多指教.
--------------------------------------------------------------------------------
【详细过程】
字符串参考 找到单击注册按钮发生事件代码:
00466580 >/. 55 PUSH EBP ; TForm1@Button1Click
00466581 |. 8BEC MOV EBP,ESP
00466583 |. 83C4 E8 ADD ESP,-18
00466586 |. 33C9 XOR ECX,ECX
00466588 |. 894D E8 MOV DWORD PTR SS:[EBP-18],ECX
0046658B |. 894D EC MOV DWORD PTR SS:[EBP-14],ECX
0046658E |. 894D F4 MOV DWORD PTR SS:[EBP-C],ECX
00466591 |. 8955 F0 MOV DWORD PTR SS:[EBP-10],EDX
00466594 |. 8945 FC MOV DWORD PTR SS:[EBP-4],EAX
00466597 |. 33C0 XOR EAX,EAX
00466599 |. 55 PUSH EBP
0046659A |. 68 60664600 PUSH <DCG_2_2.System.@HandleFinally;>
0046659F |. 64:FF30 PUSH DWORD PTR FS:[EAX]
004665A2 |. 64:8920 MOV DWORD PTR FS:[EAX],ESP
004665A5 |. 68 BF580000 PUSH 58BF ; /Arg1 = 000058BF
004665AA |. 66:B9 6DCE MOV CX,0CE6D ; |
004665AE |. B2 01 MOV DL,1 ; |
004665B0 |. A1 84614600 MOV EAX,DWORD PTR DS:[466184] ; |将字符TSecurity指针存到EAX
004665B5 |. E8 22FCFFFF CALL DCG_2_2.004661DC ; \DCG_2_2.004661DC
004665BA |. 8945 F8 MOV DWORD PTR SS:[EBP-8],EAX
004665BD |. 33C0 XOR EAX,EAX
004665BF |. 55 PUSH EBP
004665C0 |. 68 36664600 PUSH <DCG_2_2.System.@HandleFinally;>
004665C5 |. 64:FF30 PUSH DWORD PTR FS:[EAX]
004665C8 |. 64:8920 MOV DWORD PTR FS:[EAX],ESP
004665CB |. 8D45 F4 LEA EAX,DWORD PTR SS:[EBP-C]
004665CE |. 50 PUSH EAX
004665CF |. 8D55 EC LEA EDX,DWORD PTR SS:[EBP-14]
004665D2 |. 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4]
004665D5 |. 8B80 FC020000 MOV EAX,DWORD PTR DS:[EAX+2FC]
004665DB >|. E8 08BBFCFF CALL DCG_2_2.004320E8 ; Controls.TControl.GetText(TControl):TCaption;
004665E0 |. 8B55 EC MOV EDX,DWORD PTR SS:[EBP-14] ; 指向用户名的指针保存EDX
004665E3 |. 66:B9 E14D MOV CX,4DE1 ; 4DE1是下面关键CALL计算所需常数
004665E7 |. 8B45 F8 MOV EAX,DWORD PTR SS:[EBP-8] ;
004665EA |. E8 41FCFFFF CALL DCG_2_2.00466230 ; 关键CALL
004665EF |. 8D55 E8 LEA EDX,DWORD PTR SS:[EBP-18]
004665F2 |. 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4]
004665F5 |. 8B80 00030000 MOV EAX,DWORD PTR DS:[EAX+300]
004665FB >|. E8 E8BAFCFF CALL DCG_2_2.004320E8 ; Controls.TControl.GetText(TControl):TCaption;
00466600 |. 8B45 E8 MOV EAX,DWORD PTR SS:[EBP-18] ; 将正确的注册码送入EAX
00466603 |. 8B55 F4 MOV EDX,DWORD PTR SS:[EBP-C] ; 将假码送入EDX
00466606 >|. E8 A1DDF9FF CALL DCG_2_2.004043AC ; 比较真正的注册码和假码
0046660B 75 13 JNZ SHORT DCG_2_2.00466620 ;关键跳转, 不相同就跳转
0046660D |. 6A 00 PUSH 0 ; /Style = MB_OK|MB_APPLMODAL
0046660F |. 68 6C664600 PUSH DCG_2_2.0046666C ; |Valid Key
00466614 |. 68 6C664600 PUSH DCG_2_2.0046666C ; |Valid Key
00466619 |. 6A 00 PUSH 0 ; |hOwner = NULL
0046661B >|. E8 D400FAFF CALL <JMP.&user32.MessageBoxA> ; \user32.MessageBoxA()
关键CALL跟入分析:
00466230 /$ 55 PUSH EBP
00466231 |. 8BEC MOV EBP,ESP
00466233 |. 83C4 E4 ADD ESP,-1C
00466236 |. 53 PUSH EBX
00466237 |. 33DB XOR EBX,EBX
00466239 |. 895D E4 MOV DWORD PTR SS:[EBP-1C],EBX ; 堆栈存有用户名字符串个数被清零
0046623C |. 66:894D F6 MOV WORD PTR SS:[EBP-A],CX ; 记数器存到0012F5E6
00466240 |. 8955 F8 MOV DWORD PTR SS:[EBP-8],EDX ; 将字符串指针存到12F5E8
00466243 |. 8945 FC MOV DWORD PTR SS:[EBP-4],EAX ; 上面2句和本句保存数据为以后调用作准备,该句是保存字符串TSecurity指针
00466246 |. 33C0 XOR EAX,EAX
00466248 |. 55 PUSH EBP
00466249 |. 68 E9624600 PUSH DCG_2_2.004662E9 ; 4662e9入栈
0046624E |. 64:FF30 PUSH DWORD PTR FS:[EAX] ; 0012f5fc入栈
00466251 |. 64:8920 MOV DWORD PTR FS:[EAX],ESP ; 将ESP指针012F5C4存入上面的地址FS中
00466254 |. 66:8B45 F6 MOV AX,WORD PTR SS:[EBP-A] ; 常数4DE1-->AX
00466258 |. 66:8945 EE MOV WORD PTR SS:[EBP-12],AX ; 4DE1存入12F5DE
0046625C |. 8B45 08 MOV EAX,DWORD PTR SS:[EBP+8] ; 将0012F620存入EAX
0046625F |. E8 3CDDF9FF CALL DCG_2_2.00403FA0
00466264 |. 8B45 F8 MOV EAX,DWORD PTR SS:[EBP-8] ; EAX指针指向用户名地址
00466267 |. E8 F4DFF9FF CALL DCG_2_2.00404260 ; 取得用户名字符串长度并将其结果存入EAX
0046626C |. 85C0 TEST EAX,EAX ; 检测用户是否存在
0046626E |. 7E 63 JLE SHORT DCG_2_2.004662D3 ; 用户名小于0就退出
00466270 |. 8945 E8 MOV DWORD PTR SS:[EBP-18],EAX ; eax中的字符串个数,存储用户名长度在地址12F5D8
00466273 |. C745 F0 01000>MOV DWORD PTR SS:[EBP-10],1 ; 在0012f5e0地址处存储 1
0046627A |> 8B45 F8 /MOV EAX,DWORD PTR SS:[EBP-8] ; 将12f5e8保存的用户名的指针存入EAX
0046627D |. 8B55 F0 |MOV EDX,DWORD PTR SS:[EBP-10] ; 获得本次循环取值的位置
00466280 |. 8A4410 FF |MOV AL,BYTE PTR DS:[EAX+EDX-1] ; 将用户名其中一个字母存在AL中,所取字母位置由EDX决定
00466284 |. 0FB755 EE |MOVZX EDX,WORD PTR SS:[EBP-12] ; 常数4DE1传送到EDX低16位地址,高地址清0
00466288 |. C1EA 08 |SHR EDX,8 ; EDX向右移出一个字节edx=N/100h
0046628B |. 32C2 |XOR AL,DL ; 第一个用户名字符的ASCII与4D发生异或运算
0046628D |. 8845 F5 |MOV BYTE PTR SS:[EBP-B],AL ; 将计算结果26存储在12F5E5的指针地址处
00466290 |. 33C0 |XOR EAX,EAX ; eax清零
00466292 |. 8A45 F5 |MOV AL,BYTE PTR SS:[EBP-B] ; 将计算结果送到AL中
00466295 |. 66:0345 EE |ADD AX,WORD PTR SS:[EBP-12] ; 内存中常数4DE1和计算结果26进行add运算,计算结果保存在AX
00466299 |. 8B55 FC |MOV EDX,DWORD PTR SS:[EBP-4] ; 将字符串TSecurity指针存入EDX,不知道该句是什么作用
0046629C |. 66:F76A 04 |IMUL WORD PTR DS:[EDX+4] ; 将计算结果和内存中的数CE6D进行乘运算,CE6D是常数
004662A0 |. 8B55 FC |MOV EDX,DWORD PTR SS:[EBP-4] ; 将字符串TSecurity指针移动到EDX
004662A3 |. 66:0342 06 |ADD AX,WORD PTR DS:[EDX+6] ; 58bf和计算结果进行add运算
004662A7 |. 66:8945 EE |MOV WORD PTR SS:[EBP-12],AX ; 将计算结果保存到12F5DE
004662AB |. 8D4D E4 |LEA ECX,DWORD PTR SS:[EBP-1C]
004662AE |. 33C0 |XOR EAX,EAX
004662B0 |. 8A45 F5 |MOV AL,BYTE PTR SS:[EBP-B] ; 将46628B计算结果送入AL
004662B3 |. BA 02000000 |MOV EDX,2
004662B8 |. E8 831CFAFF |CALL DCG_2_2.00407F40 ; 将计算结果转成十六进制字符串
004662BD |. 8B55 E4 |MOV EDX,DWORD PTR SS:[EBP-1C] ; 该地址指向46625B计算的结果,就是异或运算结果的值
004662C0 |. 8B45 08 |MOV EAX,DWORD PTR SS:[EBP+8]
004662C3 |. E8 A0DFF9FF |CALL DCG_2_2.00404268 ; 连接上面CALL所转换得到的字符串,最后得到正确注册码
004662C8 |. 8B45 08 |MOV EAX,DWORD PTR SS:[EBP+8]
004662CB |. FF45 F0 |INC DWORD PTR SS:[EBP-10] ; 堆栈中数值用来计算用户名的字符串个数的位置,将其值加一为下次循环做准备
004662CE |. FF4D E8 |DEC DWORD PTR SS:[EBP-18] ; 计算用户名字符串个数减一,用EDX做为循环记数器为下次循环计算做好准备
004662D1 |.^ 75 A7 \JNZ SHORT DCG_2_2.0046627A ; 判断用户名是否取完,没取完继续回跳计算
004662D3 |> 33C0 XOR EAX,EAX
004662D5 |. 5A POP EDX
004662D6 |. 59 POP ECX
004662D7 |. 59 POP ECX
004662D8 |. 64:8910 MOV DWORD PTR FS:[EAX],EDX
004662DB |. 68 F0624600 PUSH DCG_2_2.004662F0
004662E0 |> 8D45 E4 LEA EAX,DWORD PTR SS:[EBP-1C]
004662E3 |. E8 B8DCF9FF CALL DCG_2_2.00403FA0
004662E8 \. C3 RETN
004662E9 .^ E9 62D5F9FF JMP DCG_2_2.00403850
004662EE .^ EB F0 JMP SHORT DCG_2_2.004662E0
004662F0 . 5B POP EBX
004662F1 . 8BE5 MOV ESP,EBP
004662F3 . 5D POP EBP
004662F4 . C2 0400 RETN 4
最后分析结果:
2个常数 CE6D 和 58BF 和一个初始化值 4DE1
(用户名ASCII xor N/100H )=x其中 N 的初始化值为4DE1,而后有 N=M了
M={[(x add N)*CE6D]add 58BF}
将每一次生成的x转换成字符连接起来就是注册码了
编程刚开始学,所以也就没能力做注册机了,还望大家见谅!
给一个有效的KEY把
NAME:kangroo
serial:265247C28CA6F5
文中有什么 不对的地方还望高手指正! 谢谢!
--------------------------------------------------------------------------------
【版权声明】: 】本文纯属技术交流, 转载请注明作者信息并保持文章的完整, 谢谢!
2007年06月05日 10:09:20
[ 本帖最后由 kangroo 于 2007-6-5 14:03 编辑 ] |
|