- 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 编辑 ] |   
 
 
 
 |