A-new 发表于 2009-4-4 23:58

A-PDF Restrictions Remover 算法分析

【文章标题】: A-PDF Restrictions Remover 1.52
【文章作者】: A-new
【作者主页】: www.A-new.cn
【软件名称】: A-PDF Restrictions Remover 1.52
【下载地址】: 自己搜索下载
【加壳方式】: ASprotect
【编写语言】: Delphi
【使用工具】: OD
【软件介绍】: 去除PDF文件的密码等限制的工具。
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
由于加壳了,用PEiD查壳是ASProtect 1.2x - 1.3x ,但是用ExeInfoPE查一下是ASprotect ver 2.1 / 2.^ ,为了分析之便我们用Volx大侠的脚本脱一下壳。脱壳过程就不多赘述。

脱壳后的功能有损失,但是注册这里的是完整的,这里我们之分析它的注册机制。

首先我用dede载入查看一下main窗体的“关于”按钮的事件(因为点关于的话会跳出来注册的框框,注册的就没有输入注册码的框框了),按钮事件地址:00586778

然后我们跟一下就找到了关键了(也可以通过下MessageBoxExA断点来找)

004A6560   $55            push    ebp                              ;
004A6561   .8BEC          mov   ebp, esp
004A6563   .83C4 DC       add   esp, -24
004A6566   .33D2          xor   edx, edx
004A6568   .8955 DC       mov   dword ptr , edx

向下看
004A659A   .E8 11E9F5FF   call    00404EB0
004A659F   .75 11         jnz   short 004A65B2                   ;NOP之,第一个爆破点
004A65A1   .8B45 FC       mov   eax, dword ptr
004A65A4   .E8 EBE4F5FF   call    00404A94
004A65A9   .C645 FB 01    mov   byte ptr , 1
004A65AD   .E9 2E010000   jmp   004A66E0                        
004A65B2   >8D55 E4       lea   edx, dword ptr
004A65B5   .A1 C4915800   mov   eax, dword ptr

有三处004A65AD, 004A65E9, 004A6697调往004A66E0尝试性修改,让这个跳转实现可以爆破,继续
004A65C7   .E8 E4E8F5FF   call    00404EB0
004A65CC   .74 20         je      short 004A65EE                  上面不NOP,这个NOP
004A65CE   .833D C4915800>cmp   dword ptr , 0
004A65D5   .74 17         je      short 004A65EE                  这个也NOP,也许也是个爆破点
004A65D7   .8B45 FC       mov   eax, dword ptr
004A65DA   .8B15 C4915800 mov   edx, dword ptr
004A65E0   .E8 03E5F5FF   call    00404AE8
004A65E5   .C645 FB 01    mov   byte ptr , 1
004A65E9   .E9 F2000000   jmp   004A66E0
004A65EE   >8B45 FC       mov   eax, dword ptr

继续往下看
004A6638   .8B45 F4       mov   eax, dword ptr
004A663B   .E8 4818F9FF   call    00437E88
004A6640   .BA 2C674A00   mov   edx, 004A672C                  ;ASCII "Software\A-PDF\RR\Register"
004A6645   .8B45 F4       mov   eax, dword ptr
004A6648   .E8 C719F9FF   call    00438014
004A664D   .8D4D E0       lea   ecx, dword ptr
004A6650   .BA 50674A00   mov   edx, 004A6750                  ;ASCII "RegisterCode"
004A6655   .8B45 F4       mov   eax, dword ptr
004A6658   .E8 F31DF9FF   call    00438450                         ;读取注册码
004A665D   .8B55 E0       mov   edx, dword ptr
004A6660   .8B45 FC       mov   eax, dword ptr
004A6663   .E8 80E4F5FF   call    00404AE8
004A6668   .8D55 DC       lea   edx, dword ptr
004A666B   .8B45 FC       mov   eax, dword ptr
004A666E   .8B00          mov   eax, dword ptr
004A6670   .E8 B3FDFFFF   call    004A6428                         ;计算注册码MD5值
004A6675   .8B45 DC       mov   eax, dword ptr
004A6678   .8B15 38825900 mov   edx, dword ptr           ;UnPacked.005891C0
004A667E   .8B12          mov   edx, dword ptr
004A6680   .E8 23EAF5FF   call    004050A8                           关键call
004A6685   .85C0          test    eax, eax
004A6687   .7E 10         jle   short 004A6699                  又一个爆破点
004A6689   .C645 FB 01    mov   byte ptr , 1
004A668D   .E8 AEDEF5FF   call    00404540
004A6692   .E8 A9DEF5FF   call    00404540
004A6697   .EB 47         jmp   short 004A66E0
004A6699   >33C0          xor   eax, eax
004A669B   .5A            pop   edx
004A669C   .59            pop   ecx
004A669D   .59            pop   ecx
004A669E   .64:8910       mov   dword ptr fs:, edx

根据跟踪这个软件的注册码放在两个地方
第一注册码在HKEY_CURRENT_USER\Software\A-PDF\RR\Register\RegisterCode
第二注册码在HKEY_LOCAL_MACHINE\SOFTWARE\A-PDF\RR\Register\RegisterCode
第一注册码不对的情况下读取第二注册码。
用OD插件查看加密算法知道是MD5加密
004A6670   .E8 B3FDFFFF   call    004A6428 这个call就是计算我们输入的注册码的MD5值
跟进这个call

004A6428/$55            push    ebp
004A6429|.8BEC          mov   ebp, esp
004A642B|.33C9          xor   ecx, ecx
004A642D|.51            push    ecx
004A642E|.51            push    ecx
004A642F|.51            push    ecx
004A6430|.51            push    ecx
004A6431|.53            push    ebx
004A6432|.56            push    esi
004A6433|.57            push    edi
004A6434|.8BFA          mov   edi, edx
004A6436|.8945 FC       mov   dword ptr , eax
004A6439|.8B45 FC       mov   eax, dword ptr
004A643C|.E8 13EBF5FF   call    00404F54
004A6441|.33C0          xor   eax, eax
004A6443|.55            push    ebp
004A6444|.68 DC644A00   push    004A64DC
004A6449|.64:FF30       push    dword ptr fs:
004A644C|.64:8920       mov   dword ptr fs:, esp
004A644F|.8D45 F8       lea   eax, dword ptr
004A6452|.E8 3DE6F5FF   call    00404A94
004A6457|.8B45 FC       mov   eax, dword ptr
004A645A|.E8 05E9F5FF   call    00404D64
004A645F|.8BF0          mov   esi, eax
004A6461|.85F6          test    esi, esi
004A6463|.7E 43         jle   short 004A64A8
004A6465|.BB 01000000   mov   ebx, 1
004A646A|>8D45 F4       /lea   eax, dword ptr
004A646D|.8B55 FC       |mov   edx, dword ptr
004A6470|.8A541A FF   |mov   dl, byte ptr
004A6474|.E8 03E8F5FF   |call    00404C7C
004A6479|.8B45 F4       |mov   eax, dword ptr
004A647C|.BA F4644A00   |mov   edx, 004A64F4                   ;ASCII "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
004A6481|.E8 22ECF5FF   |call    004050A8
004A6486|.85C0          |test    eax, eax
004A6488|.7E 1A         |jle   short 004A64A4
004A648A|.8D45 F0       |lea   eax, dword ptr
004A648D|.8B55 FC       |mov   edx, dword ptr
004A6490|.8A541A FF   |mov   dl, byte ptr
004A6494|.E8 E3E7F5FF   |call    00404C7C
004A6499|.8B55 F0       |mov   edx, dword ptr
004A649C|.8D45 F8       |lea   eax, dword ptr
004A649F|.E8 C8E8F5FF   |call    00404D6C
004A64A4|>43            |inc   ebx
004A64A5|.4E            |dec   esi
004A64A6|.^ 75 C2         \jnz   short 004A646A
004A64A8|>8B45 F8       mov   eax, dword ptr
004A64AB|.E8 B4E8F5FF   call    00404D64
004A64B0|.50            push    eax
004A64B1|.8B45 F8       mov   eax, dword ptr
004A64B4|.E8 ABEAF5FF   call    00404F64
004A64B9|.8BCF          mov   ecx, edi
004A64BB|.5A            pop   edx
004A64BC|.E8 5FF2FFFF   call    004A5720                         ;进了这个call就开始计算MD5值了
004A64C1|.33C0          xor   eax, eax
004A64C3|.5A            pop   edx
004A64C4|.59            pop   ecx
004A64C5|.59            pop   ecx
004A64C6|.64:8910       mov   dword ptr fs:, edx
004A64C9|.68 E3644A00   push    004A64E3
004A64CE|>8D45 F0       lea   eax, dword ptr
004A64D1|.BA 04000000   mov   edx, 4
004A64D6|.E8 DDE5F5FF   call    00404AB8
004A64DB\.C3            retn

不说MD5了,偶也不怎么熟悉,网上资料也好多。看下上面注释的关键call
004A6680   .E8 23EAF5FF   call    004050A8                        关键call
004A6685   .85C0          test    eax, eax
004A6687   .7E 10         jle   short 004A6699                  又一个爆破点
004A6689   .C645 FB 01    mov   byte ptr , 1
004A668D   .E8 AEDEF5FF   call    00404540
004A6692   .E8 A9DEF5FF   call    00404540
004A6697   .EB 47         jmp   short 004A66E0
004A6699   >33C0          xor   eax, eax

跟进这个关键call看看这个东东是怎么注册的吧
004050A8   $ /E9 FBDC0000   jmp   00412DA8
一个大跳转,跳吧。
00412DA8   > \53            push    ebx
00412DA9   .56            push    esi
00412DAA   .83C4 F0       add   esp, -10
00412DAD   .85D2          test    edx, edx
00412DAF   .74 4E         je      short 00412DFF
00412DB1   .85C0          test    eax, eax
00412DB3   .74 4A         je      short 00412DFF
00412DB5   .8B72 FC       mov   esi, dword ptr    esi存入应该是EDX这些字符串的最后一个字符的位置
00412DB8   .8B58 FC       mov   ebx, dword ptr    ebx存入MD5值字符串的长度0x20
00412DBB   .39DE          cmp   esi, ebx               对比
00412DBD   .7C 40         jl      short 00412DFF         大于跳,貌似不可能跳
00412DBF   .85DB          test    ebx, ebx
00412DC1   . /7E 3C         jle   short 00412DFF
00412DC3   . |4B            dec   ebx                      ebx-1
00412DC4   . |01D6          add   esi, edx               
00412DC6   . |01DA          add   edx, ebx               edx+1F 字符串去掉前 31位
00412DC8   . |897424 08   mov   dword ptr , esi   
00412DCC   . |01D8          add   eax, ebx
00412DCE   . |895424 04   mov   dword ptr , edx
00412DD2   . |F7DB          neg   ebx                      EBX取补码
00412DD4   . |0FB608      movzx   ecx, byte ptr       MD5值最后一位传给ECX
00412DD7   . |891C24      mov   dword ptr , ebx   esp存入当前软件注册对比字符串的地址
00412DDA   . |0F85 99000000 jnz   00412E79               偶这里它跳了
00412DE0   . |83EE 02       sub   esi, 2
00412DE3   . |897424 0C   mov   dword ptr , esi
00412DE7   > |3A0A          cmp   cl, byte ptr
00412DE9   . |74 41         je      short 00412E2C
00412DEB   . |3A4A 01       cmp   cl, byte ptr
00412DEE   . |74 4C         je      short 00412E3C
00412DF0   . |83C2 02       add   edx, 2
00412DF3   . |3B5424 0C   cmp   edx, dword ptr
00412DF7   . |72 0A         jb      short 00412E03
00412DF9   . |3B5424 08   cmp   edx, dword ptr
00412DFD   .^|72 E8         jb      short 00412DE7
00412DFF   > \31C0          xor   eax, eax                  爆破点 EAX不为零即可 观察了一下ECX不为零改成mov eax,ecx
00412E01   .EB 30         jmp   short 00412E33
00412E03   >3A0A          cmp   cl, byte ptr           对比CL
00412E05   .74 25         je      short 00412E2C
00412E07   .3A4A 01       cmp   cl, byte ptr
00412E0A   .74 30         je      short 00412E3C
00412E0C   .3A4A 02       cmp   cl, byte ptr
00412E0F   .74 18         je      short 00412E29
00412E11   .3A4A 03       cmp   cl, byte ptr
00412E14   .74 23         je      short 00412E39
00412E16   .83C2 04       add   edx, 4                     去掉对比过的四位
00412E19   .3B5424 0C   cmp   edx, dword ptr
00412E1D   .^ 72 E4         jb      short 00412E03
00412E1F   .3B5424 08   cmp   edx, dword ptr
00412E23   .^ 72 C2         jb      short 00412DE7
00412E25   .31C0          xor   eax, eax                        
00412E27   .EB 0A         jmp   short 00412E33
00412E29   >83C2 02       add   edx, 2
00412E2C   >42            inc   edx
00412E2D   .89D0          mov   eax, edx
00412E2F   .2B4424 04   sub   eax, dword ptr
00412E33   >83C4 10       add   esp, 10
00412E36   .5E            pop   esi
00412E37   .5B            pop   ebx
00412E38   .C3            retn
00412E39   >83C2 02       add   edx, 2
00412E3C   >83C2 02       add   edx, 2
00412E3F   .31C0          xor   eax, eax
00412E41   .3B5424 08   cmp   edx, dword ptr
00412E45   .77 06         ja      short 00412E4D
00412E47   .89D0          mov   eax, edx
00412E49   .2B4424 04   sub   eax, dword ptr
00412E4D   >83C4 10       add   esp, 10
00412E50   .5E            pop   esi
00412E51   .5B            pop   ebx
00412E52   .C3            retn
00412E53   >3A0A          cmp   cl, byte ptr                ;继续查找MD5值最后一位字符
00412E55   .74 75         je      short 00412ECC                      找到就跳
00412E57   .3A4A 01       cmp   cl, byte ptr
00412E5A   .74 43         je      short 00412E9F
00412E5C   .3A4A 02       cmp   cl, byte ptr
00412E5F   .74 68         je      short 00412EC9
00412E61   .3A4A 03       cmp   cl, byte ptr
00412E64   .74 36         je      short 00412E9C
00412E66   .83C2 04       add   edx, 4                              四位一组,去掉对比过的四位
00412E69   .3B5424 0C   cmp   edx, dword ptr          ;字符串是否算完
00412E6D   .^ 72 E4         jb      short 00412E53
00412E6F   .3B5424 08   cmp   edx, dword ptr
00412E73   .72 0B         jb      short 00412E80
00412E75      31C0          xor   eax, eax
00412E77   .EB 4A         jmp   short 00412EC3                   ;
00412E79   >83EE 02       sub   esi, 2                              ESI指向对比字符串最后一个字
00412E7C   .897424 0C   mov   dword ptr , esi         ;赋值让esp+c作为循环条件
00412E80   >3A0A          cmp   cl, byte ptr                   
00412E82   .74 48         je      short 00412ECC                      不同 跳
00412E84   >3A4A 01       cmp   cl, byte ptr
00412E87   .74 16         je      short 00412E9F                      不同 跳
00412E89   >83C2 02       add   edx, 2                              字符串去掉前两位
00412E8C   .3B5424 0C   cmp   edx, dword ptr          ;字符串是否算完
00412E90   .^ 72 C1         jb      short 00412E53                      小于跳,说明字符串对比完毕
00412E92   .3B5424 08   cmp   edx, dword ptr
00412E96   .^ 72 E8         jb      short 00412E80
00412E98      31C0          xor   eax, eax                            又是爆破点 和上面那个xor一样,最好同时修改
00412E9A   .EB 27         jmp   short 00412EC3                   ;
00412E9C   >83C2 02       add   edx, 2
00412E9F   >8B3424      mov   esi, dword ptr
00412EA2   >0FB71C30      movzx   ebx, word ptr           ;MD5加密注册码
00412EA6   .66:3B5C32 01cmp   bx, word ptr          ;当前 前1F位
00412EAB   .^ 75 DC         jnz   short 00412E89
00412EAD   .83C6 02       add   esi, 2
00412EB0   .^ 7C F0         jl      short 00412EA2
00412EB2   .83C2 02       add   edx, 2
00412EB5   .31C0          xor   eax, eax
00412EB7   .3B5424 08   cmp   edx, dword ptr
00412EBB   .77 06         ja      short 00412EC3
00412EBD   .89D0          mov   eax, edx
00412EBF   .2B4424 04   sub   eax, dword ptr
00412EC3   >83C4 10       add   esp, 10
00412EC6   .5E            pop   esi
00412EC7   .5B            pop   ebx
00412EC8   .C3            retn


看寄存器
EAX 00C3DD48 ASCII "A61A40943E07257E084EA3F62DFDB1C8" 你输入的注册码的MD5值
EDX 0047D210 ASCII "DF3EFE476845B087113F10CED5CAB52FOB81F366BAD5……
EDX很长的是这个注册的关键,就不贴出来了,记得0047D210这个地址就好了。

这里就不再赘述了,主要算法已经清晰了,我只跟了几轮,上面注释写的是第一轮的结果,对比字符串太长了,人懒啊

其实主要的算法是输入注册码,并对注册码进行MD5运算,然后用MD5值和程序中的一大串字符作对比,只要匹配就注册成功

功力有限,MD5逆不东,就不写注册机了。

这个东东也只能爆破,有三处爆破点,后面两处比较完美
--------------------------------------------------------------------------------
【版权声明】: 本文原创于吾爱破解论坛, 转载请注明作者并保持文章的完整, 谢谢!

                                                       2009年04月04日 23:53:50

zzage 发表于 2009-4-5 00:10

像A哥学习!!!!

iawen 发表于 2009-4-5 00:14

似乎自己以前也分析过,有点够印象,呵呵!

wgz001 发表于 2009-4-5 20:30

很详细学习了   :)

xfight 发表于 2009-4-6 00:48

很详细学习了

Register 发表于 2009-4-7 19:39

没地方下载呀,给个软件下载地方,光看文章会忘的

A-new 发表于 2009-4-8 15:38

没地方下载呀,给个软件下载地方,光看文章会忘的
Register 发表于 2009-4-7 19:39 http://www.52pojie.cn/images/common/back.gif
直接baidu或者google一下就好了

qifeon 发表于 2009-4-8 20:41

好好学习下阿牛的算法。

stnchk 发表于 2009-4-9 12:08

太牛了 学习了哦~~~

热火朝天 发表于 2009-4-11 00:58

看得有点晕了,呵呵,还是下来跟一下
页: [1] 2
查看完整版本: A-PDF Restrictions Remover 算法分析