吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 53036|回复: 82
收起左侧

[原创] 破解实战-第十战(完结)

  [复制链接]
我是用户 发表于 2013-6-19 23:07
本帖最后由 我是用户 于 2013-6-23 13:46 编辑

【软件名称】: LanHelper算法分析与注册机的编写
【作者邮箱】: 2714608453@qq.com
【下载地址】: 见附件
【加壳方式】: 无
【使用工具】: OD
【操作平台】: XP SP2
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!

前言:
      不知不觉一个系列就完成了,前后断断续续的快一个月,这几天一直在找适合做最后一战的软件,闲来无事翻了翻以前的代码,发现以前在黑X发过的一篇文章的存稿,好吧就是它了.




今天给大家带来的是LanHelper(局域网助手)的算法分析和注册机的编写。想必这个软件大家都用过,都干过不少坏事吧,嘿嘿~~!但是这个软件有30天的试用期,超过时间就会提示注册。网上关于这个程序的破解方法有很多,但大多数是爆破的,很少涉及到算法分析的,今天就让我们来分析一下这个程序的算法。

LanHelper这个软件的算法有以下三个特点:1。注册码分段验证;2。采用了大量的浮点计算和数学运算;3。使用SEH异常处理来代替关键跳,更加隐匿。

1.定位关键代码

拿到程序,第一件要做的事是什么?当然是查壳喽。把程序载入Peid.
如图片1

图片1.bmp
从Peid上我们知道,程序是Borland Delphi 6.0 - 7.0写的。打开程序,提示“您的30天试用期已到期“。点击“输入注册号码”,在编辑框内输入试练码“hzycy“,“123456789”,注册,弹出错误提示.

如图片2
图片2.bmp
把程序载入OD,字符串搜索“您输入的注册码有误”,很遗憾的是OD并没有找到这个字符串。但是别灰心,这个程序是Borland Delphi 6.0 - 7.0写的。我们把它载入DeDe,等待程序转储分析完毕,点击DeDe中的窗体选项,在模块名中找到TForm_Reg.
见图片3
图片3.bmp
右边显示出了窗口的信息,我们可以看到TButton有很多个,经过一些偿试,我们准确定位出关键代码004DCB40。在OD上下好CC断点。开始注册。

2.算法分析与注册机的编写

输入试练码,点击确定,程序成功断下来,这说明我们定位的关键代码是正确的。很多程序都会在验证注册码时核实用户名和假码是否为空,当然这个程序也不例外.

见代码1。
[C++] 纯文本查看 复制代码
004DCB6D .  E8 5616FAFF   call  0047E1C8                ;获得用户名
004DCB72 .  8B45 B8       mov   eax, dword ptr [ebp-48]
004DCB75 .  8D55 BC       lea   edx, dword ptr [ebp-44]
004DCB78 .  E8 47CCF2FF   call  004097C4
004DCB7D .  837D BC 00    cmp   dword ptr [ebp-44], 0
004DCB81 .  74 22         je    short 004DCBA5          ;判断用户名是否为空
004DCB83 .  8D55 B0       lea   edx, dword ptr [ebp-50]
004DCB86 .  8B45 FC       mov   eax, dword ptr [ebp-4]
004DCB89 .  8B80 04030000 mov   eax, dword ptr [eax+304]
004DCB8F .  E8 3416FAFF   call  0047E1C8                ;取假码
004DCB94 .  8B45 B0       mov   eax, dword ptr [ebp-50]
004DCB97 .  8D55 B4       lea   edx, dword ptr [ebp-4C]
004DCB9A .  E8 25CCF2FF   call  004097C4
004DCB9F .  837D B4 00    cmp   dword ptr [ebp-4C], 0
004DCBA3 .  75 44         jnz   short 004DCBE9          ;判断假码是否为空

0047E1C8这个Call是用来取用用户名和假码的,004097C4是用来判断用户名和假码是否为空的。如果不为空,则进入真正的算法Call 004DF3B4中,这里面才是对我们有真正价值的地方。   

因为这个程序大量运用了00430F74这个Call进行验证,所以分析算法之前,我们先来分析一下这个Call,为了方便,我们把这个Call记为Call1.

见代码2。
[C++] 纯文本查看 复制代码
00430F74  /$  55            push    ebp
................................................       ;省略代码为检测参数1,2是否为0
00430FC7  |.  EB 5A         jmp     short 00431023
00430FC9  |>  DB6D 08       fld     tbyte ptr [ebp+8]  ;装入参数1到st(0)
00430FCC  |.  E8 4B1CFDFF   call    00402C1C           ;判断参数1的小数部分是否为0
00430FD1  |.  D81D 2C104300 fcomp   dword ptr [43102C] ;比较是否为0
00430FD7  |.  DFE0          fstsw   ax
00430FD9  |.  9E            sahf
00430FDA  |.  75 30         jnz     short 0043100C     ;通过参数1判断流程
00430FDC  |.  DB6D 08       fld     tbyte ptr [ebp+8]  ;流程2
00430FDF  |.  D9E1          fabs
00430FE1  |.  DB2D 30104300 fld     tbyte ptr [431030]
00430FE7  |.  DED9          fcompp
00430FE9  |.  DFE0          fstsw   ax
00430FEB  |.  9E            sahf
00430FEC  |.  72 1E         jb      short 0043100C
00430FEE  |.  66:8B45 1C    mov     ax, word ptr [ebp+1C]
00430FF2  |.  50            push    eax
00430FF3  |.  FF75 18       push    dword ptr [ebp+18]
00430FF6  |.  FF75 14       push    dword ptr [ebp+14]
00430FF9  |.  DB6D 08       fld     tbyte ptr [ebp+8]
00430FFC  |.  E8 4B1CFDFF   call    00402C4C
00431001  |.  E8 2AFFFFFF   call    00430F30
00431006  |.  DB7D F0       fstp    tbyte ptr [ebp-10]
00431009  |.  9B            wait
0043100A  |.  EB 17         jmp     short 00431023
0043100C  |>  DB6D 14       fld     tbyte ptr [ebp+14] ;参数2(流程1)
0043100F  |.  D9ED          fldln2                     ;将Loge2装st(0)
00431011  |.  D9C9          fxch    st(1)              ;st(0)与st(1)交换
00431013  |.  D9F1          fyl2x                      ;计算以2为基数的对数
00431015  |.  DB6D 08       fld     tbyte ptr [ebp+8]  ;将参数1装入st(0)
00431018  |.  DEC9          fmulp   st(1), st          ;st(1)与st(0)相乘
0043101A  |.  E8 D51BFDFF   call    00402BF4           ;进入
0043101F  |.  DB7D F0       fstp    tbyte ptr [ebp-10]
00431022  |.  9B            wait
00431023  |>  DB6D F0       fld     tbyte ptr [ebp-10] ;计算的结果装入st(0)
00431026  |.  8BE5          mov     esp, ebp
00431028  |.  5D            pop     ebp
00431029  \.  C2 1800       retn    18


Call1有两个参数,参数1为浮点数,参数2由fstp  tbyte ptr [esp]装入。通过代码2我们可知,Call1里有两个验证流程,分别记为流程1,流程2。并通过参数1的小数部分是否为0来判断流程。小数部分不为0则跳到流程1执行,为0刚跳到流程2。这里我们先分析流程1,进入流程1处的004028F4中.

见代码3。
[C++] 纯文本查看 复制代码
00402BF4  /$  D9EA   fldl2e               ;  将log2e装入st(0)
00402BF6  |.  DEC9   fmulp   st(1), st    ;  st(1)与st(0)相乘
00402BF8  |.  D9C0   fld     st           ;  装入st到st(0)
00402BFA  |.  D9FC   frndint              ;  取整(四舍五入)
00402BFC  |.  DCE9   fsub    st(1), st    ;  st(1)-st(0)
00402BFE  |.  D9C9   fxch    st(1)        ;  st(0)与st(1)交换
00402C00  |.  D9F0   f2xm1                ;  2的st(0)次幂-1
00402C02  |.  D9E8   fld1                 ;  将1装入(st)
00402C04  |.  DEC1   faddp   st(1), st    ;  st(1)加上st(0)相加
00402C06  |.  D9FD   fscale               ;  2的st(0)次方
00402C08  |.  DDD9   fstp    st(1)
00402C0A  \.  C3     retn


可见Call1运用了大量的浮点运算和数学运算,是不是看的我们眼花呢?为了大家能更加直观的理解这个Call1的作用,我把它翻译成了c++代码(不包括流程2).

见图片4。
图片4.bmp
相信这样,大家就能看的懂了吧。因为决定流程2的参数是固定的,所以我们在遇见时再做具体分析。

好了,准备工作做完了,现在该进入正题了。

为了更好的说明这个软件的验证过程,我将对注册码进行分段的分析。

第一段(前6位)
见代码4。
[C++] 纯文本查看 复制代码
004DF479  .B2 01         mov  dl, 1          ;dl=1
004DF47B  .BE 01000000   mov  esi, 1         ;esi=1
004DF480  .B8 142C5B00   mov  eax, 005B2C14  ;005B2C14保存的是前6位的注册码
004DF485  >8B4D F0       mov  ecx, dword ptr [ebp-10]     ;假码给ecx
004DF488  .0FB64C31 FF   movzx  ecx, byte ptr [ecx+esi-1] ;依次取假码的前6位
004DF48D  .  3B08        cmp     ecx, dword ptr [eax] ;与dword ptr [eax]的值比较
004DF48F  .  74 02       je   short 004DF493           ;  相等就跳
004DF491  .  33D2        xor     edx, edx             ;  如果不等edx=0
004DF493  >  46          inc     esi                  ;  esi+1
004DF494  .  83C0 04     add     eax, 4               ;  eax+4(取下一位)
004DF497  .  83FE 07     cmp     esi, 7               ;  比较是否取完
004DF49A  .^ 75 E9       jnz     short 004DF485
004DF49C  .  84D2        test    dl, dl               ;  判断dl是否为0
004DF49E  .  0F84 F8030000 je      004DF89C             ;  跳向失败


由代码4可知,注册码的前6位是固定不变的。程序依次对假码的前六位进行验证,只要有一位与注册码的前6位不符,dl就会为0,导致程序验证失败。我们在数据窗口中按下CTRL+G,输入005B2C14.

见图片5。
图片5.bmp
可知注册码的前6位是LH4A8N。我们重启程序,输入LH4A8N123456,继续分析。

第二段(单独判断第9位)
见代码5。
[C++] 纯文本查看 复制代码
004DF510   .  8B45 F8       mov     eax, dword ptr [ebp-8]  ;  eax为假码的地址
004DF513   .  8A58 08       mov     bl, byte ptr [eax+8]    ;  bl为假码第九位
004DF516   .  33C0          xor     eax, eax                ;  eax=0
004DF518   .  8AC3          mov     al, bl                  ;  al=bl
004DF51A   .  8945 A0       mov     dword ptr [ebp-60], eax
004DF51D   .  DB45 A0       fild    dword ptr [ebp-60]      ;  装入整数到st(0)(假码第九位)
004DF520   .  83C4 F4       add     esp, -0C
004DF523   .  DB3C24        fstp    tbyte ptr [esp]         ;  参数2
004DF526   .  9B            wait
004DF527   .  68 FA3F0000   push    3FFA
004DF52C   .  68 39052FA7   push    A72F0539
004DF531   .  68 C1CB2978   push    7829CBC1                ;  参数1
004DF536   .  E8 391AF5FF   call    00430F74                ;  关键Call1(重点分析)
004DF53B   .  DD5D E8       fstp    qword ptr [ebp-18]      ;  运算后的结果存入[ebp-18]
004DF53E   .  9B            wait
004DF53F   .  DB2D 08F94D00 fld     tbyte ptr [4DF908]      ;  装入实数到st(0)
004DF545   .  DC6D E8       fsubr   qword ptr [ebp-18]      ;  与运算后的结果相减
004DF548   .  D9E1          fabs                            ;  求绝对值
004DF54A   .  83C4 F4       add     esp, -0C
004DF54D   .  DB3C24        fstp    tbyte ptr [esp]         ;  参数2
004DF550   .  9B            wait
004DF551   .  68 00400000   push    4000
004DF556   .  68 F1290080   push    800029F1
004DF55B   .  68 D2C6116B   push    6B11C6D2                ;  参数1
004DF560   .  E8 0F1AF5FF   call    00430F74
004DF565   .  DB2D 14F94D00 fld     tbyte ptr [4DF914]      ;  装入实数到st(0)
004DF56B   .  DED9          fcompp                          ;  CMP来比较2个无符号数
004DF56D   .  DFE0          fstsw   ax
004DF56F   .  9E            sahf
004DF570   .  0F82 26030000 jb      004DF89C                ;  小于就跳向失败


通过代码5可知,程序通过两个Call1来验证注册码的第九位。第一个Call1的参数1为假码的第九位,参数2为0.0408163265306122432。因为参数2的小数部分不为0,所以跳到流程1处执行,计算后的结果记为A9。第二个Call1的参数1为A9,参数2为2.0000100000000000000,小数部分不为0,跳向流程1,计算后的结果记为A90。然后A90与tbyte ptr[4DF914](也就是6.8999999999999989760e-07)比较,如果小于,就跳向失败。知道了这个,我们就可以用穷举法来找出第九位。我们通过查ASCII码可知,第九位的取值范围是33到126。我们用一个while循环来对在这个范围的值依次进行验证,如果满足条件,则跳出提示。

具体代码见图片6。
图片6.bmp
运行这段代码,弹出提示.

见图片7。
图片7.bmp
可见第九位为一定值“#”,将假码改为LH4A8N12#456,重启程序。

第三段:(判断第7,8,10位)
见代码6。
[C++] 纯文本查看 复制代码
004DF4AC   .  8B45 F8       mov     eax, dword ptr [ebp-8]           ;  eax为假码的地址
004DF4AF   .  8A58 06       mov     bl, byte ptr [eax+6]             ;  bl为假码第七位
004DF4B2   .  33C0          xor     eax, eax                         ;  eax=0
004DF4B4   .  8AC3          mov     al, bl                           ;  al=bl
004DF4B6   .  8945 A0       mov     dword ptr [ebp-60], eax
004DF4B9   .  DB45 A0       fild    dword ptr [ebp-60]
004DF4BC   .  83C4 F4       add     esp, -0C
004DF4BF   .  DB3C24        fstp    tbyte ptr [esp]                  ;  参数2为假码第七位
004DF4C2   .  9B            wait
004DF4C3   .  68 FE3F0000   push    3FFE
004DF4C8   .  68 BD529691   push    919652BD
004DF4CD   .  68 3411363C   push    3C361134                         ;  参数1
004DF4D2   .  E8 9D1AF5FF   call    00430F74
004DF4D7   .  DC45 E0       fadd    qword ptr [ebp-20]               ;  计算后的结果保存在[ebp-20]
004DF4DA   .  DD5D E0       fstp    qword ptr [ebp-20]               ;  存入
004DF4DD   .  9B            wait
004DF4DE   .  8B45 F8       mov     eax, dword ptr [ebp-8]           ;  eax为假码的地址
004DF4E1   .  8A58 07       mov     bl, byte ptr [eax+7]             ;  bl为假码第八位
004DF4E4   .  33C0          xor     eax, eax                         ;  eax=0
004DF4E6   .  8AC3          mov     al, bl                           ;  al=bl
004DF4E8   .  8945 A0       mov     dword ptr [ebp-60], eax
004DF4EB   .  DB45 A0       fild    dword ptr [ebp-60]
004DF4EE   .  83C4 F4       add     esp, -0C
004DF4F1   .  DB3C24        fstp    tbyte ptr [esp]                  ;  参数2为假码第八位
004DF4F4   .  9B            wait
004DF4F5   .  68 FD3F0000   push    3FFD
004DF4FA   .  68 2F4CA6AA   push    AAA64C2F
004DF4FF   .  68 234A7B83   push    837B4A23                         ;  参数1
004DF504   .  E8 6B1AF5FF   call    00430F74                         ;  相同
004DF509   .  DC45 E0       fadd    qword ptr [ebp-20]               ;  计算后的结果加上[ebp-20]
004DF50C   .  DD5D E0       fstp    qword ptr [ebp-20]               ;  存入
004DF50F   .  9B            wait
.................    //省略代码为判断第九位
004DF576   .  8B45 F8       mov     eax, dword ptr [ebp-8]           ;  eax为假码的地址
004DF579   .  8A58 09       mov     bl, byte ptr [eax+9]             ;  bl为假码第十位
004DF57C   .  33C0          xor     eax, eax                         ;  eax=0
004DF57E   .  8AC3          mov     al, bl                           ;  al=bl
004DF580   .  8945 A0       mov     dword ptr [ebp-60], eax
004DF583   .  DB45 A0       fild    dword ptr [ebp-60]
004DF586   .  83C4 F4       add     esp, -0C
004DF589   .  DB3C24        fstp    tbyte ptr [esp]                  ;  参数2为假码第十位
004DF58C   .  9B            wait
004DF58D   .  68 FD3F0000   push    3FFD
004DF592   .  68 92244992   push    92492492
004DF597   .  68 49922449   push    49249249                         ;  参数1
004DF59C   .  E8 D319F5FF   call    00430F74
004DF5A1   .  DC45 E0       fadd    qword ptr [ebp-20]               ;  计算后的结果加上[ebp-20],并保存
004DF5A4   .  DD5D E0       fstp    qword ptr [ebp-20]
004DF5A7   .  9B            wait
004DF5A8   .  DD45 E0       fld     qword ptr [ebp-20]
004DF5AB   .  83C4 F4       add     esp, -0C
004DF5AE   .  DB3C24        fstp    tbyte ptr [esp]                  ;  参数2为计算后的结果[ebp-20]
004DF5B1   .  9B            wait
004DF5B2   .  68 00400000   push    4000
004DF5B7   .  68 133BB193   push    93B13B13
004DF5BC   .  68 B1133BB1   push    B13B13B1                         ;  参数1
004DF5C1   .  E8 AE19F5FF   call    00430F74
004DF5C6   .  DD5D E8       fstp    qword ptr [ebp-18]               ;  计算后的结果保存在[ebp-18]中
004DF5C9   .  9B            wait
004DF5CA   .  DD45 E8       fld     qword ptr [ebp-18]
004DF5CD   .  D825 20F94D00 fsub    dword ptr [4DF920]               ;  与dword ptr[4DF920]相减
004DF5D3   .  D9E1          fabs                                     ;  取绝对值
004DF5D5   .  DB2D 24F94D00 fld     tbyte ptr [4DF924]               ;  装入tbyte ptr [4DF924]到st(0)
004DF5DB   .  DED9          fcompp                                   ;  比较
004DF5DD   .  DFE0          fstsw   ax
004DF5DF   .  9E            sahf
004DF5E0   .  0F82 B6020000 jb      004DF89C                         ;  小于就跳向失败

通过代码6可知,程序通过了4个Call1来验证第7,8,10位。这四个Call1的参数1的小数部分都不为0,都跳到流程1执行。前三个Call1的参数2分别第7,8,10位的ASCII码,计算后的结果分别为A7,A8,A10,第四个Call1的参数2为A7+A8+10,计算后的结果记为A101。A101减去dword ptr [4DF920](也就是685.5000),结果取绝对值。再与tbyte ptr [4DF924](也就是0.8865299999999998976)比较,小于就跳向失败。和第二段一样,我们可以用4个for循环,对第7,8,10位进行验证。

具体代码见图片8
图片8.bmp
运行这段代码,弹出提示.

见图片9。
图片9.bmp
我们把假码改成LH4A8N'w#~1234567890,重启程序。

第四段:(判断第11,12,13,14位)(SEH异常验证)
见代码7。
[C++] 纯文本查看 复制代码
004DF644   .  8945 A0       mov     dword ptr [ebp-60], eax          ;  第十一位
004DF647   .  DB45 A0       fild    dword ptr [ebp-60]
004DF64A   .  83C4 F4       add     esp, -0C
004DF64D   .  DB3C24        fstp    tbyte ptr [esp]                  ;  第十一位
004DF650   .  9B            wait
004DF651   .  B8 09000000   mov     eax, 9                           ;  eax=9
004DF656   .  E8 0519F5FF   call    00430F60                         ;  计算[esp]的eax次方,计算结果记为A11
004DF65B   .  33C0          xor     eax, eax
004DF65D   .  8AC3          mov     al, bl                           ;  第十一位
004DF65F   .  F7E8          imul    eax                              ;  eax*eax
004DF661   .  F7E8          imul    eax                              ;  eax*eax
004DF663   .  66:8945 9C    mov     word ptr [ebp-64], ax            ;  取ax给ebp-64
004DF667   .  DF45 9C       fild    word ptr [ebp-64]                ;  将word ptr [ebp-64]装入st(0)
004DF66A   .  DEC9          fmulp   st(1), st                        ;  A11与st再乘
004DF66C   .  DC45 E0       fadd    qword ptr [ebp-20]               ;  加上[ebp-20](初始为0)
004DF66F   .  DD5D E0       fstp    qword ptr [ebp-20]               ;  保存在ebp-20中
004DF672   .  9B            wait
004DF673   .  8B45 F8       mov     eax, dword ptr [ebp-8]           ;  eax为假码地址
004DF676   .  8A58 0B       mov     bl, byte ptr [eax+B]             ;  bl为第十二位
004DF679   .  33C0          xor     eax, eax
004DF67B   .  8AC3          mov     al, bl                           ;  al=bl
004DF67D   .  83C0 0B       add     eax, 0B                          ;  eax+0XB
004DF680   .  71 05         jno     short 004DF687                   ;  不溢出就跳
004DF682   .  E8 7544F2FF   call    00403AFC
004DF687   >  8945 A0       mov     dword ptr [ebp-60], eax
004DF68A   .  DB45 A0       fild    dword ptr [ebp-60]
004DF68D   .  D9FA          fsqrt                                    ;  第十二位+0xB开方
004DF68F   .  E8 B835F2FF   call    00402C4C                         ;  取开方后的整数
004DF694   .  8BF0          mov     esi, eax                         ;  esi=开方后的整数
004DF696   .  C745 D8 01000>mov     dword ptr [ebp-28], 1
004DF69D   .  C745 DC 00000>mov     dword ptr [ebp-24], 0
004DF6A4   .  83FE 01       cmp     esi, 1                           ;  是否为1
004DF6A7   .  76 2D         jbe     short 004DF6D6
004DF6A9   >  8BC6          mov     eax, esi                         ;  循环开始(算阶乘)
004DF6AB   .  33D2          xor     edx, edx
004DF6AD   .  52            push    edx
004DF6AE   .  50            push    eax
004DF6AF   .  8B45 D8       mov     eax, dword ptr [ebp-28]
004DF6B2   .  8B55 DC       mov     edx, dword ptr [ebp-24]
004DF6B5   .  E8 2A65F2FF   call    00405BE4                         ;  相乘
004DF6BA   .  71 05         jno     short 004DF6C1
004DF6BC   .  E8 3B44F2FF   call    00403AFC
004DF6C1   >  8945 D8       mov     dword ptr [ebp-28], eax
004DF6C4   .  8955 DC       mov     dword ptr [ebp-24], edx
004DF6C7   .  83EE 01       sub     esi, 1
004DF6CA   .  73 05         jnb     short 004DF6D1
004DF6CC   .  E8 2B44F2FF   call    00403AFC
004DF6D1   >  83FE 01       cmp     esi, 1
004DF6D4   .^ 77 D3         ja      short 004DF6A9                   ;  循环结束
004DF6D6   >  FF75 DC       push    dword ptr [ebp-24]
004DF6D9   .  FF75 D8       push    dword ptr [ebp-28]               ;  阶乘后的值
004DF6DC   .  33C0          xor     eax, eax                         ;  eax=0
004DF6DE   .  8AC3          mov     al, bl                           ;  第十二位
004DF6E0   .  F7E8          imul    eax                              ;  相乘
004DF6E2   .  F7E8          imul    eax                              ;  相乘
004DF6E4   .  0FBFC0        movsx   eax, ax                          ;  取ax
004DF6E7   .  33D2          xor     edx, edx                         ;  EDX=0
004DF6E9   .  8AD3          mov     dl, bl                           ;  第十二位
004DF6EB   .  F7EA          imul    edx                              ;  相乘
004DF6ED   .  71 05         jno     short 004DF6F4
004DF6EF   .  E8 0844F2FF   call    00403AFC
004DF6F4   >  99            cdq                                      ;  护展成四字节
004DF6F5   .  E8 EA64F2FF   call    00405BE4                         ;  相乘
004DF6FA   .  71 05         jno     short 004DF701                   ;  与前面的结果相乘
004DF6FC   .  E8 FB43F2FF   call    00403AFC
004DF701   >  8945 94       mov     dword ptr [ebp-6C], eax
004DF704   .  8955 98       mov     dword ptr [ebp-68], edx
004DF707   .  DF6D 94       fild    qword ptr [ebp-6C]               ;  装入第十二位运算结果
004DF70A   .  DC45 E0       fadd    qword ptr [ebp-20]               ;  与[ebp-20]相加
004DF70D   .  DD5D E0       fstp    qword ptr [ebp-20]
004DF710   .  9B            wait
004DF711   .  8B45 F8       mov     eax, dword ptr [ebp-8]           ;  eax为假码地址
004DF714   .  8A58 0C       mov     bl, byte ptr [eax+C]             ;  第十三位
004DF717   .  33C0          xor     eax, eax
004DF719   .  8AC3          mov     al, bl                           ;  al=bl
004DF71B   .  8945 A0       mov     dword ptr [ebp-60], eax
004DF71E   .  DB45 A0       fild    dword ptr [ebp-60]
004DF721   .  83C4 F4       add     esp, -0C
004DF724   .  DB3C24        fstp    tbyte ptr [esp]                  ;  参数2为假码第十三位
004DF727   .  9B            wait
004DF728   .  68 01400000   push    4001
004DF72D   .  68 000000C0   push    C0000000
004DF732   .  6A 00         push    0                                ;  参数1(此时进入流程2)
004DF734   .  E8 3B18F5FF   call    00430F74
004DF739   .  33C0          xor     eax, eax
004DF73B   .  8AC3          mov     al, bl
004DF73D   .  8945 A0       mov     dword ptr [ebp-60], eax
004DF740   .  DB45 A0       fild    dword ptr [ebp-60]
004DF743   .  DEC9          fmulp   st(1), st                        ;  相乘
004DF745   .  DC45 E0       fadd    qword ptr [ebp-20]               ;  与[ebp-20]相加
004DF748   .  DD5D E0       fstp    qword ptr [ebp-20]
004DF74B   .  9B            wait
004DF74C   .  8B45 F8       mov     eax, dword ptr [ebp-8]
004DF74F   .  8A58 0D       mov     bl, byte ptr [eax+D]             ;  第十四位
004DF752   .  8BC3          mov     eax, ebx
004DF754   .  25 FF000000   and     eax, 0FF
004DF759   .  33D2          xor     edx, edx
004DF75B   .  8945 D8       mov     dword ptr [ebp-28], eax
004DF75E   .  8955 DC       mov     dword ptr [ebp-24], edx
004DF761   .  DF6D D8       fild    qword ptr [ebp-28]
004DF764   .  83C4 F4       add     esp, -0C
004DF767   .  DB3C24        fstp    tbyte ptr [esp]                  ;  参数2为假码第十四位
004DF76A   .  9B            wait
004DF76B   .  68 00400000   push    4000
004DF770   .  68 00000080   push    80000000                         ;  2(进入流程2)
004DF775   .  6A 00         push    0
004DF777   .  E8 F817F5FF   call    00430F74
004DF77C   .  8B45 F8       mov     eax, dword ptr [ebp-8]
004DF77F   .  0FB640 0A     movzx   eax, byte ptr [eax+A]            ;  第十一位
004DF783   .  F7E8          imul    eax                              ;  eax*eax
004DF785   .  66:8945 9C    mov     word ptr [ebp-64], ax
004DF789   .  DF45 9C       fild    word ptr [ebp-64]
004DF78C   .  DEC9          fmulp   st(1), st                        ;  相乘
004DF78E   .  8B45 F8       mov     eax, dword ptr [ebp-8]
004DF791   .  8A40 0B       mov     al, byte ptr [eax+B]             ;  第十二位
004DF794   .  25 FF000000   and     eax, 0FF
004DF799   .  8945 A0       mov     dword ptr [ebp-60], eax
004DF79C   .  DB45 A0       fild    dword ptr [ebp-60]
004DF79F   .  DEC9          fmulp   st(1), st                        ;  相乘
004DF7A1   .  DC45 E0       fadd    qword ptr [ebp-20]               ;  与[ebp-20]相加
004DF7A4   .  DD5D E0       fstp    qword ptr [ebp-20]
004DF7A7   .  9B            wait
004DF7A8   .  33C0          xor     eax, eax
004DF7AA   .  55            push    ebp
004DF7AB   .  68 FEF74D00   push    004DF7FE
004DF7B0   .  64:FF30       push    dword ptr fs:[eax]
004DF7B3   .  64:8920       mov     dword ptr fs:[eax], esp          ;  安装SEH异常
004DF7B6   .  DD45 E0       fld     qword ptr [ebp-20]               ;  压入第十一位到第十四位的运算结果
004DF7B9   .  E8 8E34F2FF   call    00402C4C
004DF7BE      2D 8063E7EA   sub     eax, EAE76380                    ;  1026143249280
004DF7C3      81DA EE000000 sbb     edx, 0EE
004DF7C9   .  71 05         jno     short 004DF7D0
004DF7CB   .  E8 2C43F2FF   call    00403AFC
004DF7D0   >  8945 94       mov     dword ptr [ebp-6C], eax
004DF7D3   .  8955 98       mov     dword ptr [ebp-68], edx
004DF7D6   .  DF6D 94       fild    qword ptr [ebp-6C]
004DF7D9   .  DB7D 88       fstp    tbyte ptr [ebp-78]
004DF7DC   .  9B            wait
004DF7DD   .  E8 06CAF2FF   call    0040C1E8                         ;  通过GetLocalTime计算出一个随机数,无用
004DF7E2   .  DB6D 88       fld     tbyte ptr [ebp-78]
004DF7E5   .  DEF9          fdivp   st(1), st                        ;  st(1)%st(0)给st(1)(主要在st0)
004DF7E7   .  DDD8          fstp    st                               ;  st为0,触发异常
004DF7E9   .  33C0          xor     eax, eax
004DF7EB   .  5A            pop     edx
004DF7EC   .  59            pop     ecx
004DF7ED   .  59            pop     ecx
004DF7EE   .  64:8910       mov     dword ptr fs:[eax], edx
004DF7F1   .  E9 A6000000   jmp     004DF89C                         ;  如果没有触发异常,这里必跳


通过代码7可知,程序在对第13,14位进行Call1运算时,参数1分别为6.000000和2.000000。所以进入了流程2,我们写注册机时就不能利用先前写好的Call1。不过,别担心,流程2要比流程1简单.
见代码8。
[C++] 纯文本查看 复制代码
00430FDC  |.  DB6D 08       fld     tbyte ptr [ebp+8]                ;  装入参数1到st(0)(流程2)
00430FDF  |.  D9E1          fabs                                     ;  取绝对值
00430FE1  |.  DB2D 30104300 fld     tbyte ptr [431030]               ;  装入0x7FFFFFFF到st(0)
00430FE7  |.  DED9          fcompp                                   ;  比较
00430FE9  |.  DFE0          fstsw   ax
00430FEB  |.  9E            sahf
00430FEC  |.  72 1E         jb      short 0043100C                   ;  小于就跳(这里死都不跳--!)
00430FEE  |.  66:8B45 1C    mov     ax, word ptr [ebp+1C]
00430FF2  |.  50            push    eax
00430FF3  |.  FF75 18       push    dword ptr [ebp+18]
00430FF6  |.  FF75 14       push    dword ptr [ebp+14]
00430FF9  |.  DB6D 08       fld     tbyte ptr [ebp+8]                ;  装入参数1到st(0)
00430FFC  |.  E8 4B1CFDFF   call    00402C4C                         ;  将参数1取整后装入eax
00431001  |.  E8 2AFFFFFF   call    00430F30                         ;  进入
00431006  |.  DB7D F0       fstp    tbyte ptr [ebp-10]
00431009  |.  9B            wait
0043100A  |.  EB 17         jmp     short 00431023



由代码8可知,流程2的关键处在于Call 00430F30中,我们进入这个Call.

见代码9。
[C++] 纯文本查看 复制代码
00430F30  /$  55            push    ebp
00430F31  |.  8BEC          mov     ebp, esp
00430F33  |.  89C1          mov     ecx, eax
00430F35  |.  99            cdq                                      ;  扩展成四字节
00430F36  |.  D9E8          fld1                                     ;  装入1到st(0)
00430F38  |.  31D0          xor     eax, edx
00430F3A  |.  29D0          sub     eax, edx
00430F3C  |.  74 1A         je      short 00430F58
00430F3E  |.  DB6D 08       fld     tbyte ptr [ebp+8]                ;  装入参数2
00430F41  |.  EB 02         jmp     short 00430F45
00430F43  |>  D8C8          /fmul    st, st                          ;  相乘
00430F45  |>  D1E8           shr     eax, 1                          ;  eax右移位,高位补0,低位进入CF,CF=0就跳
00430F47  |.^ 73 FA         |jnb     short 00430F43                  ;  不小于就跳
00430F49  |.  DCC9          |fmul    st(1), st                       ;  st(1)*st(0)
00430F4B  |.^ 75 F6         \jnz     short 00430F43                  ;  不等就跳
00430F4D  |.  DDD8          fstp    st
00430F4F  |.  83F9 00       cmp     ecx, 0
00430F52  |.  7D 04         jge     short 00430F58
00430F54  |.  D9E8          fld1
00430F56  |.  DEF1          fdivrp  st(1), st
00430F58  |>  9B            wait
00430F59  |.  5D            pop     ebp
00430F5A  \.  C2 0C00       retn    0C


代码9的关键在于中间那个循环。shr为逻辑右移,shr eax,1的意思是将eax向右移到1位,高位补0,低位进入CF,当CF=0时,jnb跳转实现。shr eax,1也可以理解为将 eax除以2,eax为商,edx为余数。当eax不为0时,ZF=0,jnz跳转实现。是不是有点晕啊!不用担心,因为这个循环的次数是根据参数1来决定的,参数1只有两个值,分别是6和2。因此我们没有必要还原这个循环,我们只需对这两个值分别进行特定的计算就行。当参数1为6时.

c++代码见图片10。
图片10.bmp
当参数1为2时,c++代码见图片11。
图片11.bmp
Num13,Num14分别代表假码第13,14位的ASCII码,sd3,sd4分别代表最终的计算结果。是不是很简单啊!分析完流程2,我们继续看代码7,发现程序依旧还是利用Call1和四则运算分别对第11,12,13,14位的假码进行运算,然后相加得出一个具体的值(记为A14)来判断是否通过验证。只不过这种验证更加的隐蔽,它运用了SEH异常处理,我们不能像第二段或第三段直接找出这个值要满足的范围。我们现在从004DF7AA这里看起。程序在004DF7B3处安装了SEH异常,此时我们看堆栈窗口.

见图片12。
图片12.bmp
在代码窗口按下CTRL+G,输入004DF7FE,下好CC断点,继续我们的分析。在004DF7B3处,程序将A14装入st(0)中,而00402C4C这个Call的作用就是把A14取整,然后转换成16进制。因为A14之前是64位的,也就是double类型。一个寄存器是32位的,所以这里用edx和eax一起保存。然后eax减去EAE76380,edx减去0EE,然后再将eax,edx还原成一个double数(A140)。然后通过Call 0040C1E8,利用GetLocalTime计算出一个随机数。然后用这个随机数来除以A140。如果我们输入的不是正确的注册码,程序正常运行下去,并跳到004DF89C处,将全局注册标志清0。所以在这里我们必须触发了这个异常,才能进行下一步的验证。那么这个异常是什么呢?我们仔细看下代码,发现004DF7E5的代码为fdivp st(1),st。我们自然联想到了除0异常,将st(0)的值赋予0,发现程序出现异常,并跳到004DF7FE处执行,也就是我们之前下的CC断点处。限于篇幅,SEH的处理过程我就不多了,黑X论坛上有说明的贴子,大家可以上去看看,不懂的话,也可以在论坛联系我。我们在004DF803处下好CC断点,然后按下F9,发现出现异常后的程序成功的断了下来,并进行下一步验证。好了,我们现在返回去看,将004DF7BE和004DF7C3处的eax和edx组合起来就是0xEEEAE76380,转换成十进制就是1026143249280。也就是说,当最终的计算结果A14为1026143249280时,则通过验证。分析到这里是不是有点累了!没关系,加油,马上就要到达终点了。知道了验证过程,我们就可以用c++来算出这段注册码。

见图片13和图片14。
图片13.bmp
图片14.bmp
代码中的Call2(9,Num11)是用来计算Num11的9次方的,Call3是用来计算阶乘的。运行这段代码,跳出提示.

见图片15。
图片15.bmp
可知第11-14位分别为J&4T。且是定值。我们把假码改成LH4A8N'w#~J&4T12345。重启程序,进行最后一处验证。

第五段(第15,16,17,18,19位的验证)
见代码10。
[C++] 纯文本查看 复制代码
004DF803   .  E8 FC4BF2FF   call    00404404                         ;  跳到这里执行了
004DF808   .  A1 BC355B00   mov     eax, dword ptr [5B35BC]          ;  XL[
004DF80D   .  8B00          mov     eax, dword ptr [eax]
004DF80F   .  83C0 04       add     eax, 4
004DF812   .  50            push    eax
004DF813   .  B9 02000000   mov     ecx, 2
004DF818   .  BA 14000000   mov     edx, 14
004DF81D   .  8B45 F8       mov     eax, dword ptr [ebp-8]           ;  eax为假码地址
004DF820   .  E8 E756F2FF   call    00404F0C
004DF825   .  8B45 F8       mov     eax, dword ptr [ebp-8]
004DF828   .  8A40 12       mov     al, byte ptr [eax+12]            ;  第十九位
004DF82B   .  25 FF000000   and     eax, 0FF                         ;  取ax低位
004DF830   .  33D2          xor     edx, edx
004DF832   .  8945 B0       mov     dword ptr [ebp-50], eax
004DF835   .  8955 B4       mov     dword ptr [ebp-4C], edx
004DF838   .  6A 00         push    0
004DF83A   .  6A 1A         push    1A                               ;  除数1A
004DF83C   .  8B45 D0       mov     eax, dword ptr [ebp-30]          ;  第十五位
004DF83F   .  8B55 D4       mov     edx, dword ptr [ebp-2C]
004DF842   .  0345 C8       add     eax, dword ptr [ebp-38]          ;  第十五位+第十六位
004DF845   .  1355 CC       adc     edx, dword ptr [ebp-34]
004DF848   .  71 05         jno     short 004DF84F
004DF84A   .  E8 AD42F2FF   call    00403AFC
004DF84F   >  0345 C0       add     eax, dword ptr [ebp-40]          ;  再加第十七位
004DF852   .  1355 C4       adc     edx, dword ptr [ebp-3C]
004DF855   .  71 05         jno     short 004DF85C
004DF857   .  E8 A042F2FF   call    00403AFC
004DF85C   >  0345 B8       add     eax, dword ptr [ebp-48]          ;  再加第十八位
004DF85F   .  1355 BC       adc     edx, dword ptr [ebp-44]
004DF862   .  71 05         jno     short 004DF869
004DF864   .  E8 9342F2FF   call    00403AFC
004DF869   >  E8 CA64F2FF   call    00405D38                         ;  第15至18位的和除以1A,并取余数.
004DF86E   .  71 05         jno     short 004DF875
004DF870   .  E8 8742F2FF   call    00403AFC
004DF875   >  83C0 41       add     eax, 41                          ;  加上0x41
004DF878   .  83D2 00       adc     edx, 0
004DF87B   .  71 05         jno     short 004DF882
004DF87D   .  E8 7A42F2FF   call    00403AFC
004DF882   >  8945 A8       mov     dword ptr [ebp-58], eax          ;  计算后的结果保存在[ebp-58]中
004DF885   .  8955 AC       mov     dword ptr [ebp-54], edx
004DF888   .  8B45 B0       mov     eax, dword ptr [ebp-50]          ;  eax为第十九位
004DF88B   .  8B55 B4       mov     edx, dword ptr [ebp-4C]
004DF88E   .  3B55 AC       cmp     edx, dword ptr [ebp-54]          ;  必为0
004DF891   .  75 03         jnz     short 004DF896
004DF893   .  3B45 A8       cmp     eax, dword ptr [ebp-58]          ;  第十五到第十八位的计算结果要等于第十九位
004DF896   >  75 04         jnz     short 004DF89C                   ;  不等就跳
004DF898   .  C645 F7 01    mov     byte ptr [ebp-9], 1              ;  全局注册标志
004DF89C   >  33C0          xor     eax, eax
004DF89E   .  5A            pop     edx
004DF89F   .  59            pop     ecx
004DF8A0   .  59            pop     ecx


由代码10可知,程序先累加第15位到18位的ASCII码,累加之和记为A19。然后用A19除以0X1A,并取其余数。结果再加上0X41,并与第十九位比较。如果相等,则在004DF898处注册全局标志。如果我们要爆破的话,可以在这里改。写注册机时,依旧是用5个for循环进行穷举.

具体代码见图片16。
图片16.bmp
运行这段代码,跳出提示.

见图17。
图片17.bmp
小结:
所以我们用注册机最后得出的注册码是LH4A8N'w#~J&4T!!!9A。重启程序,输入LH4A8N'w#~J&4T!!!9A,弹出成功注册提示.

见图片18。
图片18.bmp
由图片18可知,程序还有重启验证。当注册码通过以上验证的时候,并会将其保存在注册表中,这在一定程序上阻止了爆破。但是在整个验算过程中,用户名并没有参与验算,而且也并没有取机器特征码,导致了多机一码的情况出现,我认为这是一个失败之处。不过这个程序的用来练习算法,考验耐心是最适合不过的了,--!。至此文章就写的差不多了,由于第四段验证的代码太长,所以只说明了主要部分,详细的分析我都注释在代码上了,大家可以去看看。


C++注册机源码如下:
[C++] 纯文本查看 复制代码
void CMyDlg::OnButton1() 
{
        // TODO: Add your control notification handler code here        
        //Call1    代表00430F74
        //Call2    代表00430F60
        //Call3    代表00405BE4 阶乘
        CString Key="LH4A8N",Key0;         //注册码
        double Para[10]={0.0} ; //定义参数数组并初始化为0
        Para[0]=0.5686999999999998976;   //第七位
        Para[1]=0.3332999999999999488;   //第八位
        Para[2]=0.0408163265306122432;   //第九位
        Para[3]=2.0000100000000000000;   //第九位计算结果
    Para[4]=0.2857142857142856704;   //第十位
        Para[5]=2.3076923076923074560;   //第七,八,十位计算的结果
        Para[6]=6.0000000000000000000;   //第十三位
        Para[7]=2.0000000000000000000;   //第十四位

 
    double Para1=1.1561553999999997440;        //tbyte ptr [4DF908]
        double Para2=6.8999999999999989760e-07;    //tbyte ptr [4DF914]
        double Para3=685.5000;                     //dword ptr [4DF920]
        double Para4=0.8865299999999998976;        //tbyte ptr [4DF924]
    double Para5=2147483647.0000000000;        //tbyte ptr [431030]

        double temp=0.0,ebp20=0.0,ebp18=0.0;
    DWORD eax=0;
        int Num7=0,Num8=0,Num9=0,Num10=0,Num11=0,Num12=0,Num13=0,Num14=0,Num15=0,Num16=0,Num17=0,Num18=0,Num19=0;
        CString temp9="第九位为",temp7="第七位为",temp8="第八位为",temp10="第十位为",temp0="是否取其它值",
                temp11="第十一位为",temp12="第十二位为",temp13="第十三位为",temp14="第十四位为",temp15="第十五位为",
                temp16="第十六位为",temp17="第十七位为",temp18="第十八位为",temp19="第十九位为";
        double sd1,sd2,sd3,sd4,sd;
        char p;
        //第九位

                Num9=33;
                while (Num9<127)
                {
                        temp=Call1(Para[2],Num9);                
                        temp=fabs(Para1-temp);
                        sd=Call1(Para[3],temp);
                        if (Para2>=sd)                
                        {                                
                                p=(char)Num9;
                                temp9+=p;
                                AfxMessageBox(temp9);                  
                        }
                        Num9++;
                }
        
    //第九位


        //第7位        第8位 第10位

        int n=1;
        for (Num7=33;Num7<127;Num7++)
                {
                        sd1=Call1(Para[0],Num7);
                        ebp20+=sd1;
                        for (Num8=33;Num8<127;Num8++)
                        {
                                sd2=Call1(Para[1],Num8);
                                ebp20+=sd2;
                                for (Num10=33;Num10<127;Num10++)
                                {
                                        sd3=Call1(Para[4],Num10);    
                                        ebp20+=sd3;
                                        sd4=Call1(Para[5],ebp20);
                                        temp=fabs(sd4-Para3);
                                        if (Para4>temp)
                                        {                
                                                p=(char)Num7;
                                                Key0=p;
                                                temp7+=p;                                                
                                                p=(char)Num8;
                                                Key0+=p;
                                                Key0+="#";
                                                temp8+=p;
                                                p=(char)Num10;
                                                Key0+=p;
                                                temp10+=p;                                                
                                                temp0=temp7+"\n"+temp8+"\n"+temp10+"\n"+"是否取其它值";                                                
                                            n=AfxMessageBox(temp0,MB_OKCANCEL,NULL);                                                
                                                if(n!=1)
                                                {
                                                        Key+=Key0;
                                                        break;                                                
                                                }                                                
                                                temp7="第七位为";
                                                temp8="第八位为";
                                                temp10="第十位为";
                                        }
                                        ebp20-=sd3;
                                        if(n!=1)
                                        {                                                        
                                                break;                                                
                                        }        
                                        
                                }
                                ebp20-=sd2;
                                if(n!=1)
                                {                                                        
                                        break;                                                
                                }        
                                
                        }
                        ebp20-=sd1;
                        if(n!=1)
                        {                                                        
                                break;                                                
                        }        
        
                }
                ebp20=0;   //清零
        //第7位        第8位 第10位

        //第11,12,13,14位
                LONG64 eax1,eax2;
                signed short ax;
                signed long eax3;
        
                double as;
                for (Num11=33;Num11<127;Num11++)
                {                
                        eax=Num11*Num11;
                
                        ax=eax*eax;                
                                
                        as=double(ax);
                        sd1=as*Call2(9,Num11);
                        ebp20+=sd1;
                        for (Num12=33;Num12<127;Num12++)
                        {
                                eax=Num12+0x0B;                        
                                eax=(int)sqrt(eax);
                                temp=Call3(eax);
                                eax=Num12*Num12;                        
                                eax=eax*eax;
                                ax=eax;
                                eax=0;
                                eax3=ax;
                                eax3=eax3*Num12;                                
                                eax2=eax3*temp;                                
                                ebp20+=eax2;
                                for(Num13=33;Num13<127;Num13++)
                                {
                                        
                                        sd3=Num13*Num13;
                                        sd3=sd3*sd3;
                                        temp=Num13*Num13;                                        
                                        sd3=sd3*temp;
                                        sd3=sd3*Num13;
                                        ebp20+=sd3;
                                        for (Num14=33;Num14<127;Num14++)
                                        {                                                
                                                sd4=Num14*Num14;
                                                eax1=Num11*Num11;                                        
                                                eax1=eax1*sd4*Num12;
                                                ebp20+=eax1;                                                
                        if(INT64(ebp20)-1026143249280==0)
                                                {
                                                        p=char(Num11);
                                                        temp11=temp11+p;                                                        
                                                        p=char(Num12);
                                                        temp12=temp12+p;
                                                        p=char(Num13);
                                                        temp13=temp13+p;
                                                        p=char(Num14);
                                                        temp14=temp14+p;
                                                        temp14=temp11+"\n"+temp12+"\n"+temp13+"\n"+temp14;
                                                        AfxMessageBox(temp14);
                                                }
                                                ebp20-=eax1;
                                        }
                                        ebp20-=sd3;
                                }
                                ebp20-=eax2;
                        }
                        ebp20-=sd1;                        
                }

        //第11,12,13,14位
    //第15,16,17,18,19位
        int Num=0,Num0;
        n=1;
        for (Num19=33;Num19<127;Num19++)
        {
                                
        for (Num15=33;Num15<127;Num15++)
        {
                Num+=Num15;
                for (Num16=33;Num16<127;Num16++)
                {
                        Num+=Num16;
                        for (Num17=33;Num17<127;Num17++)
                        {
                                Num+=Num17;
                                for (Num18=33;Num18<127;Num18++)
                                {
                                        Num+=Num18;
                                        Num0=Num % 0x1A;                                        
                                        Num0+=0x41;
                                        if (Num0==Num19)
                                        {
                                                p=(char)Num15;
                                                Key0=p;
                                                temp15+=p;                                                
                                                p=(char)Num16;
                                                Key0+=p;
                                                temp16+=p;                                        
                                                p=(char)Num17;
                                                Key0+=p;
                                                temp17+=p;
                                                p=(char)Num18;
                                                Key0+=p;
                                                temp18+=p;
                                                p=(char)Num19;
                                                Key0+=p;
                                                temp19+=p;
                                                temp0=temp15+"\n"+temp16+"\n"+temp17+"\n"+temp18+"\n"+temp19+"\n"+"是否取其它值";
                                            n=AfxMessageBox(temp0,MB_OKCANCEL,NULL);
                                                if(n!=1)
                                                {
                                                        Key+="J&4T";
                                                        Key+=Key0;
                                                        break;                                                
                                                }                                                
                                                temp15="第十五位为";
                                                temp16="第十六位为";
                                                temp17="第十七位为";
                                                temp18="第十八位为";
                                                temp19="第十九位为";                                                
                                        }
                                        Num-=Num18;
                                        if(n!=1)
                                        {                                                        
                                                break;                                                
                                                }        
                                }
                                Num-=Num17;
                                if(n!=1)
                                {                                                        
                                        break;
                                }        
                        }
                        Num-=Num16;
                        if(n!=1)
                        {                                                        
                                break;
                        }        
                }
                Num-=Num15;
                if(n!=1)
                {                                                        
                        break;        
                }        

        }
        if(n!=1)
        {                                                        
                break;
        }        
        }
    m_Key.SetWindowText(Key);
        



        
    
}
//temp=(log(假码第七位l)/log(2)*Key[0]*参数8*log(2)(e))-int(log(假码第七位l)/log(2)*Key[0]*参数8*log(2)(e));
//temp=2的temp次方-1+1
//2的temp次方
double CMyDlg::Call1(double x, double y)  
{
        //x为参数1,y为参数2,dTemp1为运算的结果
        double dTemp1,dTemp2;        
        dTemp1=log(y)/log(2)*loge2*x*log2e;        
        dTemp2=int(dTemp1);
        dTemp1=dTemp1-dTemp2;
        dTemp1=pow(2,dTemp1);
    dTemp1=pow(2,dTemp2)*dTemp1;
        return dTemp1;
}

double CMyDlg::Call2(double x, double y)
{
        double dTemp3;
        dTemp3=y*pow(2,x);
        return dTemp3;
}

void CMyDlg::OnButton2() 
{
        // TODO: Add your control notification handler code here
        

}

DWORD CMyDlg::Call3(int x)
{
        DWORD j=1;
        for (int i=1;i<=x;i++)
        {
                j=i*j;
        }
        return j;

}



后记:
       感谢支持我教程的朋友们,小菜是第一次做系列教程,有些地方表达不太清楚请见谅,因为本系列教程定位需要有一定基础的,所以下一步小菜也希望能出一些新手教程来帮助大家进步,具体下一系列的教程还没定位,希望大家能提些意见,也希望大家继续支持我,谢谢大家



=================================================================

传送门:
           破解实战-第一战:http://www.52pojie.cn/thread-197281-1-1.html
           破解实战-第二战:http://www.52pojie.cn/thread-197598-1-1.html
           破解实战-第三站:http://www.52pojie.cn/thread-197957-1-1.html
           破解实战-第四站:http://www.52pojie.cn/thread-198203-1-1.html
           破解实战-第五战:http://www.52pojie.cn/thread-198365-1-1.html
           破解实战-第六战:http://www.52pojie.cn/thread-198930-1-1.html
           破解实战-第七战:http://www.52pojie.cn/thread-199459-1-1.html
           破解实战-第八战:http://www.52pojie.cn/thread-199834-1-1.html
           破解实战-第九战:http://www.52pojie.cn/thread-200655-1-1.html           
           破解实战-第十战:http://www.52pojie.cn/thread-200798-1-1.html





LanHelper.rar

1.4 MB, 下载次数: 591, 下载积分: 吾爱币 -1 CB

免费评分

参与人数 12热心值 +12 收起 理由
yeluosuif + 1 谢谢@Thanks!
GodIand + 1 膜拜大牛。。看的小菜眼花缭乱。。
Double_Z + 1 我很赞同!
吴先生 + 1 谢谢@Thanks!
wo3561758 + 1 收藏起来先
gyc990326 + 1 唉,黑X在2013年灰飞烟灭了,好怀念
小雨细无声 + 1 去到楼主这个水平,要熬多久啊。
blmk + 1 谢谢@Thanks!
baiyunem + 1 老大,附件涅。。。
bansjs + 1 太高级了,太深奥了,看不懂,不过还是谢谢.
Chief + 1 欢迎分析讨论交流,[吾爱破解论坛]有你更精.
qqlinhai + 1 基础的恒大已经做了,继续搞高级的^_^

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

X-Signal 发表于 2015-7-27 13:01
这个程序是Borland Delphi 6.0 - 7.0写的。我们把它载入DeDe,等待程序转储分析完毕,点击DeDe中的窗体选项,在模块名中找到TForm_Reg
DeDe是啥?
qqlinhai 发表于 2013-6-19 23:11
yhesdaf 发表于 2013-6-19 23:15
我来支持楼主了  第一次顶楼主的帖子  我会翻出前边的教程慢慢学
1354669803 发表于 2013-6-19 23:16
算法看了我头疼
linli 发表于 2013-6-19 23:17
支持,不错的教程,谢谢
bansjs 发表于 2013-6-19 23:29
太高级了,太深奥了,看不懂,不过还是谢谢楼主了
小雨细无声 发表于 2013-6-20 07:59
看不懂,不过我是不干坏事好银,谢谢大神分享!
疯狂天使 发表于 2013-6-20 11:20
支持楼主,很有借鉴!
yuxiaopc 发表于 2013-6-20 11:39
暂时先收藏,等水平高了,在慢慢研究。
52crack 发表于 2013-6-20 12:29
最后这个真是重量级的,膜拜了!!!
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-4-19 22:29

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表