首页
社区
课程
招聘
[原创]***装修软件算法分析--新手第一次
发表于: 2007-7-17 14:12 7410

[原创]***装修软件算法分析--新手第一次

2007-7-17 14:12
7410

【文章标题】: ***软件算法分析--新手第一次
【文章作者】: 一休
【作者邮箱】:
【作者主页】:
【作者QQ号】:
【软件名称】: ***装修软件
【软件大小】: 356M
【下载地址】: 自己搜索下载
【加壳方式】: 无
【保护方式】: 序列号+功能限制
【编写语言】: Delphi 7.0
【使用工具】: OD
【操作平台】: WindowsXP-SP2
【软件介绍】:
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
  先用PointH.exe找到那个断点,下断。一路F8下来,来到这里:
  
  0073B2E6  |.  8B55 F8       mov     edx, [ebp-8]    ;机器码[edx]="4910825475137942"  注册码
  0073B2E9  |.  8B45 FC       mov     eax, [ebp-4]    ;注册码[eax]="4935906723251451"  机器玛
  0073B2EC  |.  E8 F7EEF7FF   call    006BA1E8
  
  进入注册码验证函数
  006BA144   > /BB 04000000   mov     ebx, 4
  006BA149   . |8B45 E4       mov     eax, dword ptr [ebp-1C]
  006BA14C   . |8BF0          mov     esi, eax
  006BA14E   . |8B45 E0       mov     eax, dword ptr [ebp-20]
  006BA151   . |8945 DC       mov     dword ptr [ebp-24], eax
  006BA154   . |8B45 D8       mov     eax, dword ptr [ebp-28]
  006BA157   . |8945 D4       mov     dword ptr [ebp-2C], eax
  006BA15A   > /8A06          mov     al, byte ptr [esi]       ;al=机器码第一位
  006BA15C   . |8B55 DC       mov     edx, dword ptr [ebp-24]
  006BA15F   . |2A02          sub     al, byte ptr [edx]       ;[edx]=注册码第一位,这里用机器码的第一位减去注册码的第一位。
  
  006B9FF4  /$  8BC8          mov     ecx, eax
  006B9FF6  |.  84C9          test    cl, cl
  006B9FF8  |.  7D 13         jge     short 006BA00D      ;如果cl>=o,转移到006BA00D
  006B9FFA  |.  0FBEC1        movsx   eax, cl
  006B9FFD  |.  05 2C010000   add     eax, 12C
  006BA002  |.  B9 0A000000   mov     ecx, 0A
  006BA007  |.  99            cdq
  006BA008  |.  F7F9          idiv    ecx                     ;用(DX,AX)除以 ecx
  006BA00A  |.  8BC2          mov     eax, edx           ;把上面除法的余数赋值给eax
  006BA00C  |.  C3            retn
  006BA00D  |>  80F9 0A       cmp     cl, 0A
  006BA010  |.  7C 0F         jl      short 006BA021
  006BA012  |.  0FBEC1        movsx   eax, cl
  006BA015  |.  B9 0A000000   mov     ecx, 0A
  006BA01A  |.  99            cdq
  006BA01B  |.  F7F9          idiv    ecx
  006BA01D  |.  8BC2          mov     eax, edx
  006BA01F  |.  EB 02         jmp     short 006BA023
  006BA021  |>  8BC1          mov     eax, ecx
  006BA023  \>  C3            retn                          ;从006B9FF4到006BA023这个函数过程,把前面减法运算结果作为输入,如果al中结果大于等于零则直接返回这个值,反之用0Ah减去(-al),把结果输出。
  
  006BA166   .  8B55 D4       mov     edx, dword ptr [ebp-2C]
  006BA169   .  8802          mov     byte ptr [edx], al
  006BA16B   .  FF45 D4       inc     dword ptr [ebp-2C]  
  006BA16E   .  FF45 DC       inc     dword ptr [ebp-24]  ;指针指向注册码的下一位
  006BA171   .  46            inc     esi      ;指针指向机器码的下一位
  006BA172   .  4B            dec     ebx
  006BA173   .^ 75 E5         jnz     short 006BA15A              
  006BA175   .  8345 D8 04    add     dword ptr [ebp-28], 4
  006BA179   .  8345 E0 04    add     dword ptr [ebp-20], 4
  006BA17D   .  8345 E4 04    add     dword ptr [ebp-1C], 4  ;指针移动到下一组数据
  006BA181   .  4F            dec     edi
  006BA182   .^ 75 C0         jnz     short 006BA144              
  006BA184   .  33C0          xor     eax, eax
  006BA186   .  BF 04000000   mov     edi, 4
  006BA18B   .  8D55 9C       lea     edx, dword ptr [ebp-64]     "把上面用机器码减去注册码生成的新数列的指针给edx
  006BA18E   >  BB 04000000   mov     ebx, 4
  006BA193   .  8BF2          mov     esi, edx
  006BA195   >  0206          add     al, byte ptr [esi]
  006BA197   .  46            inc     esi
  006BA198   .  4B            dec     ebx
  006BA199   .^ 75 FA         jnz     short 006BA195
  006BA19B   .  83C2 04       add     edx, 4
  006BA19E   .  4F            dec     edi
  006BA19F   .^ 75 ED         jnz     short 006BA18E              ;把新数列的所有位加起来给al
  006BA1A1   .  0FBED0        movsx   edx, al
  006BA1A4   .  8B0D 18057800 mov     ecx, dword ptr [780518]     ;ecx=781db8
  006BA1AA   .  8911          mov     dword ptr [ecx], edx
  006BA1AC   .  24 0F         and     al, 0F                      ;只保留个位,去掉其它位
  006BA1AE   .  0FBED0        movsx   edx, al
  006BA1B1   .  8BCA          mov     ecx, edx                ;把用机器码减去注册码生成的新数列的每一位累加后的个位赋值给ecx
  006BA1B3   .  85C9          test    ecx, ecx
  006BA1B5   .  79 03         jns     short 006BA1BA
  006BA1B7   .  83C1 03       add     ecx, 3
  006BA1BA   >  C1F9 02       sar     ecx, 2                   ;右移两位,相当于用ecx除以4取商给ecx
                              inc     ecx                      ;最新版本这里多了一句;在研究上一个版本时,就是这里把我卡住了。因为没有这一句,逆运算就不是百分之百可进行的。
  006BA1BD   .  894D F0       mov     dword ptr [ebp-10], ecx  ;把商加一后的结果保存在[ebp-10]这个地方,后面变换数列要用到
  006BA1C0   .  81E2 03000080 and     edx, 80000003            ;取末两位,相当于用上面ecx除以4取余数给edx
  006BA1C6   .  79 05         jns     short 006BA1CD
  006BA1C8   .  4A            dec     edx
  006BA1C9   .  83CA FC       or      edx, FFFFFFFC
  006BA1CC   .  42            inc     edx
  006BA1CD   >  42            inc     edx                      ;余数加一
  006BA1CE   .  BF 04000000   mov     edi, 4
  006BA1D3   .  8D45 9C       lea     eax, dword ptr [ebp-64]
  006BA1D6   .  8945 D0       mov     dword ptr [ebp-30], eax
  006BA1D9   >  BB 04000000   mov     ebx, 4
  006BA1DE   .  8B45 D0       mov     eax, dword ptr [ebp-30]
  006BA1E1   >  8B4D F0       mov     ecx, dword ptr [ebp-10]  ;商加一后的结果
  006BA1E4   .  8D4C8D 8C     lea     ecx, dword ptr [ebp+ecx*4-74] ;新的结果保存地址为从ebp-74到ebp-64
  006BA1E8   .  8D7411 FB     lea     esi, dword ptr [ecx+edx-5]  ;其实,结果保存地址=ebp-74+(商×4)+余数
  006BA1EC   .  8A08          mov     cl, byte ptr [eax]    ;按顺序取出用机器码减去注册码生成的新数列的值
  006BA1EE   .  880E          mov     byte ptr [esi], cl    ;从“ebp-74+(商×4)+余数”开始写入新的数列
  006BA1F0   .  42            inc     edx
  006BA1F1   .  83FA 04       cmp     edx, 4
  006BA1F4   .  7E 08         jle     short 006BA1FE
  006BA1F6   .  BA 01000000   mov     edx, 1
  006BA1FB   .  FF45 F0       inc     dword ptr [ebp-10]
  006BA1FE   >  837D F0 04    cmp     dword ptr [ebp-10], 4
  006BA202   .  7E 07         jle     short 006BA20B
  006BA204   .  C745 F0 01000>mov     dword ptr [ebp-10], 1
  006BA20B   >  40            inc     eax
  006BA20C   .  4B            dec     ebx
  006BA20D   .^ 75 D2         jnz     short 006BA1E1
  006BA20F   .  8345 D0 04    add     dword ptr [ebp-30], 4
  006BA213   .  4F            dec     edi
  006BA214   .^ 75 C3         jnz     short 006BA1D9                  "循环,把原来的数列按照一定的顺序写到从[ebp-74]开始的16个字节
  006BA216   .  BB 04000000   mov     ebx, 4
  006BA21B   .  8D45 90       lea     eax, dword ptr [ebp-70]
  006BA21E   .  8945 CC       mov     dword ptr [ebp-34], eax
  006BA221   >  BF 03000000   mov     edi, 3
  006BA226   .  8B45 CC       mov     eax, dword ptr [ebp-34]
  006BA229   .  8BF0          mov     esi, eax
  006BA22B   >  8A06          mov     al, byte ptr [esi]
  006BA22D   .  2A46 FC       sub     al, byte ptr [esi-4]            "用上面变换后的数列的第五个数减去第一个数,然后依次做减法直到最后一个数。
  
  006B9FF4  /$  8BC8          mov     ecx, eax
  006B9FF6  |.  84C9          test    cl, cl
  006B9FF8  |.  7D 13         jge     short 006BA00D
  006B9FFA  |.  0FBEC1        movsx   eax, cl
  006B9FFD  |.  05 2C010000   add     eax, 12C
  006BA002  |.  B9 0A000000   mov     ecx, 0A
  006BA007  |.  99            cdq
  006BA008  |.  F7F9          idiv    ecx
  006BA00A  |.  8BC2          mov     eax, edx
  006BA00C  |.  C3            retn
  006BA00D  |>  80F9 0A       cmp     cl, 0A
  006BA010  |.  7C 0F         jl      short 006BA021
  006BA012  |.  0FBEC1        movsx   eax, cl
  006BA015  |.  B9 0A000000   mov     ecx, 0A
  006BA01A  |.  99            cdq
  006BA01B  |.  F7F9          idiv    ecx
  006BA01D  |.  8BC2          mov     eax, edx
  006BA01F  |.  EB 02         jmp     short 006BA023
  006BA021  |>  8BC1          mov     eax, ecx
  006BA023  \>  C3            retn                       ;从006B9FF4到006BA023这个函数过程,把前面减法运算结果作为输入,如果al中结果大于等于零则直接返回这个值,反之用0Ah减去(-al),把结果输出。
  
  006BA235    .  8806          mov     byte ptr [esi], al   ;把结果保存回去
  006BA237    .  83C6 04       add     esi, 4
  006BA23A    .  4F            dec     edi
  006BA23B    .^ 75 EE         jnz     short 006BA22B
  006BA23D    .  FF45 CC       inc     dword ptr [ebp-34]
  006BA240    .  4B            dec     ebx
  006BA241    .^ 75 DE         jnz     short 006BA221       ;经过12次循环,得到新的数列
  006BA243    .  BF 04000000   mov     edi, 4
  006BA248    .  8D45 8D       lea     eax, dword ptr [ebp-73]
  006BA24B    .  8945 CC       mov     dword ptr [ebp-34], eax
  006BA24E    >  BB 03000000   mov     ebx, 3
  006BA253    .  8B45 CC       mov     eax, dword ptr [ebp-34]
  006BA256    .  8BF0          mov     esi, eax
  006BA258    >  8A06          mov     al, byte ptr [esi]
  006BA25A    .  2A46 FF       sub     al, byte ptr [esi-1]        "用上面新数列的第二位减去第一位。
  
  006B9FF4   /$  8BC8          mov     ecx, eax
  006B9FF6   |.  84C9          test    cl, cl
  006B9FF8   |.  7D 13         jge     short 006BA00D
  006B9FFA   |.  0FBEC1        movsx   eax, cl
  006B9FFD   |.  05 2C010000   add     eax, 12C
  006BA002   |.  B9 0A000000   mov     ecx, 0A
  006BA007   |.  99            cdq
  006BA008   |.  F7F9          idiv    ecx
  006BA00A   |.  8BC2          mov     eax, edx
  006BA00C   |.  C3            retn
  006BA00D   |>  80F9 0A       cmp     cl, 0A
  006BA010   |.  7C 0F         jl      short 006BA021
  006BA012   |.  0FBEC1        movsx   eax, cl
  006BA015   |.  B9 0A000000   mov     ecx, 0A
  006BA01A   |.  99            cdq
  006BA01B   |.  F7F9          idiv    ecx
  006BA01D   |.  8BC2          mov     eax, edx
  006BA01F   |.  EB 02         jmp     short 006BA023
  006BA021   |>  8BC1          mov     eax, ecx
  006BA023   \>  C3            retn      ;从006B9FF4到006BA023这个函数过程,把前面减法运算结果作为输入,如果al中结果大于等于零则直接返回这个值,反之用0Ah减去(-al),把结果输出。
  
  006BA262    .  8806          mov     byte ptr [esi], al ;结果赋值回去
  006BA264    .  46            inc     esi
  006BA265    .  4B            dec     ebx
  006BA266    .^ 75 F0         jnz     short 006BA258
  006BA268    .  8345 CC 04    add     dword ptr [ebp-34], 4
  006BA26C    .  4F            dec     edi
  006BA26D    .^ 75 DF         jnz     short 006BA24E       ;循环12次又得到新的数列
  006BA26F    .  BF 04000000   mov     edi, 4
  006BA274    .  8D45 8C       lea     eax, dword ptr [ebp-74]
  006BA277    .  8945 CC       mov     dword ptr [ebp-34], eax
  006BA27A    >  BB 04000000   mov     ebx, 4
  006BA27F    .  8B45 CC       mov     eax, dword ptr [ebp-34]
  006BA282    >  B2 09         mov     dl, 9
  006BA284    .  2A10          sub     dl, byte ptr [eax]
  006BA286    .  8810          mov     byte ptr [eax], dl         "把新数列各位用9减去后从新赋值
  006BA288    .  40            inc     eax
  006BA289    .  4B            dec     ebx
  006BA28A    .^ 75 F6         jnz     short 006BA282
  006BA28C    .  8345 CC 04    add     dword ptr [ebp-34], 4
  006BA290    .  4F            dec     edi
  006BA291    .^ 75 E7         jnz     short 006BA27A          ;循环16次,更新数列
  006BA293    .  BF 01000000   mov     edi, 1
  006BA298    .  8D85 7CFFFFFF lea     eax, dword ptr [ebp-84]
  006BA29E    .  8945 CC       mov     dword ptr [ebp-34], eax
  006BA2A1    >  BB 04000000   mov     ebx, 4
  006BA2A6    .  8D45 90       lea     eax, dword ptr [ebp-70]
  006BA2A9    .  8B55 CC       mov     edx, dword ptr [ebp-34]
  006BA2AC    >  B9 05000000   mov     ecx, 5
  006BA2B1    .  2BCF          sub     ecx, edi
  006BA2B3    .  8A4C08 FB     mov     cl, byte ptr [eax+ecx-5]
  006BA2B7    .  880A          mov     byte ptr [edx], cl         "把上面的数列中,从每(4个)组里的第四位(从四位到一位)数依次付值到新数列的第一个(从一组到四组)组数里(例:1234 5678 6587 2143->4873 3784 2651 1562)
  006BA2B9    .  42            inc     edx
  006BA2BA    .  83C0 04       add     eax, 4
  006BA2BD    .  4B            dec     ebx
  006BA2BE    .^ 75 EC         jnz     short 006BA2AC
  006BA2C0    .  47            inc     edi
  006BA2C1    .  8345 CC 04    add     dword ptr [ebp-34], 4
  006BA2C5    .  83FF 05       cmp     edi, 5
  006BA2C8    .^ 75 D7         jnz     short 006BA2A1               ;循环16次
  006BA2CA    .  BF 04000000   mov     edi, 4
  006BA2CF    .  8D45 BC       lea     eax, dword ptr [ebp-44]
  006BA2D2    .  8945 CC       mov     dword ptr [ebp-34], eax
  006BA2D5    .  8D85 7CFFFFFF lea     eax, dword ptr [ebp-84]
  006BA2DB    .  8945 D0       mov     dword ptr [ebp-30], eax
  006BA2DE    >  BB 04000000   mov     ebx, 4
  006BA2E3    .  8B45 CC       mov     eax, dword ptr [ebp-34]  ;[eax]=上面经过种种变换后的数列
  006BA2E6    .  8B55 D0       mov     edx, dword ptr [ebp-30]  ;[edx]=软件机器码
  006BA2E9    >  8A08          mov     cl, byte ptr [eax]
  006BA2EB       3A0A          cmp     cl, byte ptr [edx]         "比较上面计算出来的数列与软件本身的机器码是否相同.
  006BA2ED    .  74 0C         je      short 006BA2FB             "如果不同则转到 "序列号输入错误"
  006BA2EF    .  64:8F05 00000>pop     dword ptr fs:[0]
  006BA2F6    .  83C4 08       add     esp, 8
  006BA2F9       EB 40         jmp     short 006BA33B
  006BA2FB    >  42            inc     edx
  006BA2FC    .  40            inc     eax
  006BA2FD    .  4B            dec     ebx
  006BA2FE    .^ 75 E9         jnz     short 006BA2E9
  006BA300    .  8345 D0 04    add     dword ptr [ebp-30], 4
  006BA304    .  8345 CC 04    add     dword ptr [ebp-34], 4
  006BA308    .  4F            dec     edi
  006BA309    .^ 75 D3         jnz     short 006BA2DE             "如果相同,继续比较下一位,然后就进入已注册软件了,哈哈!
  
  为了能更好的理解这个算法,下面写一个例子:
  
            机器码:4935 9067 2325 1451
    你输入的注册码:4910 8254 7513 7942  随便输入的16个数字
    机器码减注册码:0025 1813 5812 4519      各个位之和=37h,个位数除以4得1余3,1×4+3=7,所以下行从第(7+1)位开始按顺序写入
          重新排序:8124 5190 0251 8135  用第五个数减去第一个数,得出下一行
          更新数列:8124 7076 3285 5950  每一组用后一个数减去前一个数,得出下一行
          更新数列:8395 7342 3996 5419  用9减去每一位,得出下一行
          更新数列:1604 2657 6003 4580  由每组的第四位开始,重新组成下一列数据
    生成与机器码比较数列:4730 0508 6605 1264  这时,如果生成与机器码比较数列与机器码完全相同,那么软件就被注册了。
  
  前面那些汇编语言就是实现上面这些功能的,明白了验证注册码的算法,相信大家都能很容易写出他的逆运算的程序啦。
  
--------------------------------------------------------------------------------
【经验总结】
  对于这种简单的数据变换,就不总结什么了吧。
  
--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!

                                                       2007年07月17日 13:57:44


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 7
支持
分享
最新回复 (6)
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
占个位置顶一下
算法我喜欢啊 呵呵
2007-7-17 21:46
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
学习一下  谢谢分享
2007-7-17 23:25
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
楼主请给出该软件的下载地址,我想实践一下。。谢谢。
2007-7-23 08:22
0
雪    币: 200
活跃值: (46)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
MARK!

坚定了我重新学汇编的信心,谢谢。以前学校里没学好
2007-7-25 23:20
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
一休
同学的这个帖子我没有看到啊,过来纯支持一下。

注释到位,分析透彻,值得我的小鸟学习!
2007-7-27 00:43
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
恩。有道理。书到用时方恨少啊。我得回去啃汇编去
2007-7-27 00:58
0
游客
登录 | 注册 方可回帖
返回
//