飘云阁

 找回密码
 加入我们

QQ登录

只需一步,快速开始

查看: 4379|回复: 8

[原创] PDFcamp Printer (PDF Writer) V2.2 最新版算法分析及注册机源码

[复制链接]
  • TA的每日心情
    难过
    2022-2-6 09:25
  • 签到天数: 6 天

    [LV.2]偶尔看看I

    发表于 2008-6-18 15:19:06 | 显示全部楼层 |阅读模式
    标 题: 【原创】PDFcamp Printer (PDF Writer) V2.2 最新版破解分析
    作 者: playboysen
    时 间: 2008-06-18


    【文章标题】:【原创】PDFcamp Printer (PDF Writer) V2.2 最新版破解分析
    【文章作者】: playboysen
    【作者邮箱】: playboysen@126.com
    【作者相册】: playboysen2.photo.163.com
    【软件名称】: PDFcamp Printer (PDF Writer) V2.2
    【使用工具】: ollydbg
    【操作平台】: Windows XP SP2
    【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!


          接触破解一年多,付出的心血多少自己知道,每天面对一堆的汇编指令,多少次想到了放弃,但是最终还是坚守住了自己的兴趣,一年多来经手的软件不下200个,大多是对她们实行”**“,只因水平不高,还看不太懂算法,这个小程序是我算法分析的**作,虽然简单,但是整体分析下来却很不易,希望能给小鸟一点提示,高手掠过:
          
          PDFcamp Printer,可以将doc、xls、ppt、txt文档直接“打印”成pdf文件,未注册版本试用30天,且转换后的pdf文件有水印。程序只有几百K,安装后在安装目录中没有主文件,经过半天的摸索才找到如何注册,汗,呵呵,随便打开一个word文档,选择“文件”——“打印(Ctrl+P)”,调出打印框后点“属性”可以看到它的界面,在About选项卡中就有注册框了,如图1
    未命名.jpeg (29.95 KB, 下载次数: 23)
          大家看到了,只有一个文本框,没有机器码和用户名输入提示,输入任意假码后点“Register”,弹出提示框 “Your register number error ……”,用Wsyscheck查看word.exe加载的模块发现两个可疑dll—— pdfui.dll和pdfprn.dll(而且这两个文件是加了UPX壳的),由此猜测它是dll文件注册类型
          
          打开任意一个word文档,OD附加word.exe,bp GetWindowTextA下断后点注册,OD提示断下,Alt+F9返回后F8单步
    1. 032961D9    8BB424 D0000000 mov     esi, dword ptr [esp+D0]
    2. 032961E0    8B3D 04112903   mov     edi, dword ptr [3291104]         ; USER32.GetDlgItemTextA
    3. 032961E6    8D4C24 4C       lea     ecx, dword ptr [esp+4C]
    4. 032961EA    68 80000000     push    80
    5. 032961EF    51              push    ecx
    6. 032961F0    68 EC030000     push    3EC
    7. 032961F5    56              push    esi
    8. 032961F6    FFD7            call    edi
    9. 032961F8    8D5424 0C       lea     edx, dword ptr [esp+C]
    10. 032961FC    6A 40           push    40
    11. 032961FE    52              push    edx
    12. 032961FF    68 EF030000     push    3EF
    13. 03296204    56              push    esi
    14. 03296205    FFD7            call    edi
    15. 03296207    8D4424 0C       lea     eax, dword ptr [esp+C]           ; 取假码
    16. 0329620B    8D4C24 4C       lea     ecx, dword ptr [esp+4C]
    17. 0329620F    50              push    eax                              ; 假码入栈
    18. 03296210    51              push    ecx
    19. 03296211    E8 FA220000     call    03298510                         ; 关键Call,F7跟进
    20. 03296216    85C0            test    eax, eax
    21. 03296218    0F84 9A000000   je      032962B8                       ;关键跳转,不能跳
    22. 0329621E    8D5424 0C       lea     edx, dword ptr [esp+C]
    23. 03296222    8D4424 4C       lea     eax, dword ptr [esp+4C]
    复制代码
    在03296211处F7跟进后到这里
    1. 03298510    8B5424 08       mov     edx, dword ptr [esp+8]
    2. 03298514    85D2            test    edx, edx
    3. 03298516    74 27           je      short 0329853F
    4. 03298518    803A 00         cmp     byte ptr [edx], 0
    5. 0329851B    74 22           je      short 0329853F                   ; 比较输入的注册码是否为空
    6. 0329851D    57              push    edi
    7. 0329851E    8BFA            mov     edi, edx
    8. 03298520    83C9 FF         or      ecx, FFFFFFFF
    9. 03298523    33C0            xor     eax, eax
    10. 03298525    F2:AE           repne   scas byte ptr es:[edi]
    11. 03298527    F7D1            not     ecx
    12. 03298529    49              dec     ecx
    13. 0329852A    5F              pop     edi
    14. 0329852B    83F9 0D         cmp     ecx, 0D                          ; ecx中是假码位数,与13相比较,如果注册码小于等于13位就跳向错误
    15. 0329852E    7E 0F           jbe     short 0329853F
    16. 03298530    52              push    edx
    17. 03298531    E8 4AFFFFFF     call    03298480                         ; 唯一的“算法”比较处F7进去
    18. 03298536    F7D8            neg     eax
    19. 03298538    1BC0            sbb     eax, eax
    20. 0329853A    F7D8            neg     eax
    21. 0329853C    C2 0800         retn    8
    复制代码
    在03298531处F7跟进到下面
    1. 03298483    56              push    esi
    2. 03298484    8B7424 20       mov     esi, dword ptr [esp+20]
    3. 03298488    8D5424 04       lea     edx, dword ptr [esp+4]
    4. 0329848C    57              push    edi
    5. 0329848D    8A06            mov     al, byte ptr [esi]
    6. 0329848F    8A4E 01         mov     cl, byte ptr [esi+1]
    7. 03298492    884424 14       mov     byte ptr [esp+14], al
    8. 03298496    32C0            xor     al, al
    9. 03298498    52              push    edx
    10. 03298499    884424 19       mov     byte ptr [esp+19], al
    11. 0329849D    884C24 0C       mov     byte ptr [esp+C], cl
    12. 032984A1    884424 0D       mov     byte ptr [esp+D], al
    13. 032984A5    E8 D0000000     call    0329857A                         ; 跟踪发现,至此假码第二位的十六进制放入ECX,得知此处为关键比较1,F7跟进
    14. 032984AA    8BF8            mov     edi, eax
    15. 032984AC    8D4424 18       lea     eax, dword ptr [esp+18]
    16. 032984B0    50              push    eax
    17. 032984B1    E8 C4000000     call    0329857A                         ; 此处为关键比较2
    18. 032984B6    03F8            add     edi, eax                         ; 上面两个call过去后这里的add的作用是:把注册码一二位数值的16进制值分别减去30后,两个余数相加——>结果放到EDI
    19. 032984B8    83C4 08         add     esp, 8
    20. 032984BB    83FF 08         cmp     edi, 8                           ; EDI必须是8  ****注册码的第一个约束条件****
    21. 032984BE    74 0A           je      short 032984CA
    22. 032984C0    5F              pop     edi
    23. 032984C1    33C0            xor     eax, eax
    24. 032984C3    5E              pop     esi
    25. 032984C4    83C4 18         add     esp, 18
    26. 032984C7    C2 0400         retn    4
    27. 032984CA    807E 02 56      cmp     byte ptr [esi+2], 56             ; 注册码第三位是“V”
    28. 032984CE    74 0A           je      short 032984DA
    29. 032984D0    5F              pop     edi
    30. 032984D1    33C0            xor     eax, eax
    31. 032984D3    5E              pop     esi
    32. 032984D4    83C4 18         add     esp, 18
    33. 032984D7    C2 0400         retn    4
    34. 032984DA    807E 03 32      cmp     byte ptr [esi+3], 32             ; 注册码第四位是“2”
    35. 032984DE    74 0A           je      short 032984EA
    36. 032984E0    5F              pop     edi
    37. 032984E1    33C0            xor     eax, eax
    38. 032984E3    5E              pop     esi
    39. 032984E4    83C4 18         add     esp, 18
    40. 032984E7    C2 0400         retn    4
    41. 032984EA    807E 05 31      cmp     byte ptr [esi+5], 31             ; 注册码第六位是“1”
    42. 032984EE    74 0A           je      short 032984FA
    43. 032984F0    5F              pop     edi
    44. 032984F1    33C0            xor     eax, eax
    45. 032984F3    5E              pop     esi
    46. 032984F4    83C4 18         add     esp, 18
    47. 032984F7    C2 0400         retn    4
    48. 032984FA    8A4E 0F         mov     cl, byte ptr [esi+F]             ; 注册码第十六位的十六进制放入cl
    49. 032984FD    33C0            xor     eax, eax
    50. 032984FF    80F9 38         cmp     cl, 38                           ; 注册码第十六位是“8”
    51. 03298502    5F              pop     edi
    52. 03298503    0F94C0          sete    al                               ;如果条件全部满足则al置1
    53. 03298506    5E              pop     esi
    54. 03298507    83C4 18         add     esp, 18
    55. 0329850A    C2 0400         retn    4
    56. 0329850D    90              nop
    57. 0329850E    90              nop
    复制代码
    在跟进032984A5的CALL,到这里
    1. 7C944C36    55              push    ebp
    2. 7C944C37    8BEC            mov     ebp, esp
    3. 7C944C39    56              push    esi
    4. 7C944C3A    8B75 08         mov     esi, dword ptr [ebp+8]
    5. 7C944C3D    85F6            test    esi, esi
    6. 7C944C3F    0F84 B3AA0200   je      7C96F6F8
    7. 7C944C45    833D 70C1997C 0>cmp     dword ptr [7C99C170], 1
    8. 7C944C4C    0FB606          movzx   eax, byte ptr [esi]              ; 假码第二位十六进制放入eax
    9. 7C944C4F    0F8F AAAA0200   jg      7C96F6FF
    10. 7C944C55    8B0D 30C3997C   mov     ecx, dword ptr [7C99C330]      
    11. 7C944C5B    0FB60441        movzx   eax, byte ptr [ecx+eax*2]
    12. 7C944C5F    83E0 08         and     eax, 8
    13. 7C944C62    85C0            test    eax, eax
    14. 7C944C64    0F85 A4AA0200   jnz     7C96F70E                         ; 这几句没看懂什么功能,但并不影响分析
    15. 7C944C6A    0FB60E          movzx   ecx, byte ptr [esi]              ; 假码第二位十六进制放入ecx
    16. 7C944C6D    46              inc     esi
    17. 7C944C6E    83F9 2D         cmp     ecx, 2D                          ; 假码第二位十六进制与“-”连接符比较
    18. 7C944C71    8BD1            mov     edx, ecx
    19. 7C944C73    74 2A           je      short 7C944C9F
    20. 7C944C75    83F9 2B         cmp     ecx, 2B
    21. 7C944C78    74 25           je      short 7C944C9F
    22. 7C944C7A    33C0            xor     eax, eax
    23. 7C944C7C    83F9 30         cmp     ecx, 30                          ; ********************************
    24. 7C944C7F    7C 19           jl      short 7C944C9A                   ; 这四句是比较第二位是否为数字
    25. 7C944C81    83F9 39         cmp     ecx, 39
    26. 7C944C84    7F 14           jg      short 7C944C9A                   ; **************************************
    27. 7C944C86    83E9 30         sub     ecx, 30                          ; 假码第二位十六进制减去30——>值放入ECX
    28. 7C944C89    83F9 FF         cmp     ecx, -1
    29. 7C944C8C  ^ 74 8A           je      short 7C944C18
    30. 7C944C8E    8D0480          lea     eax, dword ptr [eax+eax*4]
    31. 7C944C91    8D0441          lea     eax, dword ptr [ecx+eax*2]       ; ecx+eax*2(其实这里eax大部分时候是0,那么这句就是把ecx值放入eax)——>值放入EAX
    32. 7C944C94    0FB60E          movzx   ecx, byte ptr [esi]
    33. 7C944C97    46              inc     esi
    34. 7C944C98  ^ EB E2           jmp     short 7C944C7C
    35. 7C944C9A    83C9 FF         or      ecx, FFFFFFFF
    36. 7C944C9D  ^ EB EA           jmp     short 7C944C89
    37. 7C944C9F    0FB60E          movzx   ecx, byte ptr [esi]
    38. 7C944CA2    46              inc     esi
    39. 7C944CA3  ^ EB D5           jmp     short 7C944C7A
    复制代码
    至此分析全部结束,算法过程总结如下:
    首先注册码必须大于13位;
    注册码第一二位16进制分别减去30后的余数之和必须等于8 ;
    注册码第三位必须是 V;
    第四位 2 ;
    第六位 1 ;
    十六位 8 ;

    比如这组注册码可用:
    17V201playboyse8

    注册机及其源码已经放出,详情请看10楼!!

    附件在这里:
    https://www.chinapyg.com/viewthr ... &extra=page%3D1

    [ 本帖最后由 playboysen 于 2008-7-27 07:35 编辑 ]

    评分

    参与人数 1威望 +80 飘云币 +80 收起 理由
    Nisy + 80 + 80 PYG有你更精彩!

    查看全部评分

    PYG19周年生日快乐!

    该用户从未签到

    发表于 2008-6-18 15:36:45 | 显示全部楼层
    不错 搞算法CALL在DLL中的一个不错的下段方法
    PYG19周年生日快乐!

    该用户从未签到

    发表于 2008-6-18 16:30:41 | 显示全部楼层
    这个软件不错 简单跟踪了一下

    04B08499    884424 19       MOV BYTE PTR SS:[ESP+19],AL
    04B0849D    884C24 0C       MOV BYTE PTR SS:[ESP+C],CL
    04B084A1    884424 0D       MOV BYTE PTR SS:[ESP+D],AL               ; 放第一位和第二位
    04B084A5    E8 D0000000     CALL pdfui.04B0857A                      ;   关键CALL 下文跟进分析
    04B084AA    8BF8            MOV EDI,EAX                              ; 第二位 -30 结果送EDI
    04B084AC    8D4424 18       LEA EAX,DWORD PTR SS:[ESP+18]            ; 传KEY第一位
    04B084B0    50              PUSH EAX
    04B084B1    E8 C4000000     CALL pdfui.04B0857A                      ; JMP 到 ntdll.atoi
    04B084B6    03F8            ADD EDI,EAX                              ; 余数做加法
    04B084B8    83C4 08         ADD ESP,8
    04B084BB    83FF 08         CMP EDI,8                                ; 前两位要位 数字 且 余数之和为8
    04B084BE    74 0A           JE SHORT pdfui.04B084CA
    04B084C0    5F              POP EDI
    04B084C1    33C0            XOR EAX,EAX
    04B084C3    5E              POP ESI
    04B084C4    83C4 18         ADD ESP,18
    04B084C7    C2 0400         RETN 4
    04B084CA    807E 02 56      CMP BYTE PTR DS:[ESI+2],56               ; 第三位为 V
    04B084CE    74 0A           JE SHORT pdfui.04B084DA
    04B084D0    5F              POP EDI
    04B084D1    33C0            XOR EAX,EAX
    04B084D3    5E              POP ESI
    04B084D4    83C4 18         ADD ESP,18
    04B084D7    C2 0400         RETN 4
    04B084DA    807E 03 32      CMP BYTE PTR DS:[ESI+3],32               ; 第四位为 2
    04B084DE    74 0A           JE SHORT pdfui.04B084EA
    04B084E0    5F              POP EDI
    04B084E1    33C0            XOR EAX,EAX
    04B084E3    5E              POP ESI
    04B084E4    83C4 18         ADD ESP,18
    04B084E7    C2 0400         RETN 4
    04B084EA    807E 05 31      CMP BYTE PTR DS:[ESI+5],31               ; 第五位为 1
    04B084EE    74 0A           JE SHORT pdfui.04B084FA
    04B084F0    5F              POP EDI
    04B084F1    33C0            XOR EAX,EAX
    04B084F3    5E              POP ESI
    04B084F4    83C4 18         ADD ESP,18
    04B084F7    C2 0400         RETN 4
    04B084FA    8A4E 0F         MOV CL,BYTE PTR DS:[ESI+F]               ; 第16位为8
    04B084FD    33C0            XOR EAX,EAX
    04B084FF    80F9 38         CMP CL,38
    04B08502    5F              POP EDI
    04B08503    0F94C0          SETE AL                                  ; 设置AL
    04B08506    5E              POP ESI
    04B08507    83C4 18         ADD ESP,18
    04B0850A    C2 0400         RETN 4

    关键CALL 04B0857A 其实就是判断参数是否为数字 并求其数值

    7C944C3A    8B75 08         MOV ESI,DWORD PTR SS:[EBP+8]             ; 将参数送地址 ESI
    7C944C3D    85F6            TEST ESI,ESI
    7C944C3F    0F84 B3AA0200   JE ntdll.7C96F6F8
    7C944C45    833D 70C1997C 0>CMP DWORD PTR DS:[7C99C170],1
    7C944C4C    0FB606          MOVZX EAX,BYTE PTR DS:[ESI]              ; 将参数(内存单元的一个字节)做零扩展送EAX
    7C944C4F    0F8F AAAA0200   JG ntdll.7C96F6FF
    7C944C55    8B0D 30C3997C   MOV ECX,DWORD PTR DS:[7C99C330]          ; ECX=20
    7C944C5B    0FB60441        MOVZX EAX,BYTE PTR DS:[ECX+EAX*2]        ; 零扩展并传送至EAX  20+EAX*2
    7C944C5F    83E0 08         AND EAX,8                                ; 和8做与运算
    7C944C62    85C0            TEST EAX,EAX
    7C944C64    0F85 A4AA0200   JNZ ntdll.7C96F70E
    7C944C6A    0FB60E          MOVZX ECX,BYTE PTR DS:[ESI]
    7C944C6D    46              INC ESI
    7C944C6E    83F9 2D         CMP ECX,2D                               ; 是否是 -
    7C944C71    8BD1            MOV EDX,ECX
    7C944C73    74 2A           JE SHORT ntdll.7C944C9F                  ; 是的话则跳走
    7C944C75    83F9 2B         CMP ECX,2B                               ; +
    7C944C78    74 25           JE SHORT ntdll.7C944C9F
    7C944C7A    33C0            XOR EAX,EAX
    7C944C7C    83F9 30         CMP ECX,30                               ; 和 0 比较
    7C944C7F    7C 19           JL SHORT ntdll.7C944C9A
    7C944C81    83F9 39         CMP ECX,39                               ; 9
    7C944C84    7F 14           JG SHORT ntdll.7C944C9A
    7C944C86    83E9 30         SUB ECX,30                               ; - 30
    7C944C89    83F9 FF         CMP ECX,-1


    简单给兄弟解释一下这几句指令:

    7C944C4C    0FB606          MOVZX EAX,BYTE PTR DS:[ESI]              ; 将参数(内存单元的一个字节)做零扩展送EAX
    7C944C4F    0F8F AAAA0200   JG ntdll.7C96F6FF
    7C944C55    8B0D 30C3997C   MOV ECX,DWORD PTR DS:[7C99C330]          ; ECX=7C946CAA [ECX]=20
    7C944C5B    0FB60441        MOVZX EAX,BYTE PTR DS:[ECX+EAX*2]        ; 零扩展并传送至EAX  20+EAX*2
    7C944C5F    83E0 08         AND EAX,8                                ; 和8做与运算
    7C944C62    85C0            TEST EAX,EAX
    7C944C64    0F85 A4AA0200   JNZ ntdll.7C96F70E

    我们注意到 ECX为定值 ECX=7C946CAA 且 [ECX]=20
    若参数 为 数字 0123456789  则 ECX+EAX*2 结果范围为 7C946D0A ~ 7C946D1C

    ECX+30H*2 = 7C946D0A
    ECX+39H*2 = 7C946D1C

    我们来查看一下该内存的数据 , 发现偶地址全都是数值 84 且 奇地址为 00(因为奇地址我们用不到)
    00.GIF

    如果是 84 执行 AND EAX,8 结果EAX=0
    84H的2进制: 10000100
    8  的2进制: 00001000

    则该跳转不实现 继续向下走 适参数 - 30H, 因为结果要求两个参数 KEY1 + KEY2 = 8, 如果KEY非数字的话 必然不需要继续判断了 肯定KEY1+KEY2 不等于 8  所以这几句也可以理解成 判断参数是否为数字
    PYG19周年生日快乐!
  • TA的每日心情
    难过
    2022-2-6 09:25
  • 签到天数: 6 天

    [LV.2]偶尔看看I

     楼主| 发表于 2008-6-18 17:34:07 | 显示全部楼层
    对了,软件的注册信息是保存在以下两个位置:
    [HKEY_LOCAL_MACHINE\SOFTWARE\verypdf\pdfcamp]
    "RegisterNO"="17V201playboyse8"

    [HKEY_CURRENT_USER\Software\verypdf\pdfcamp]
    "RegisterNO"="17V201playboyse8"

    如果要练手的话,必须同时删除上面两处注册信息才能变回未注册版本,请留意/:023
    PYG19周年生日快乐!

    该用户从未签到

    发表于 2008-6-19 00:28:32 | 显示全部楼层
    不知道怎么回事 我下载后 运行不起来 提示说RPC服务器不可用....
    PYG19周年生日快乐!
  • TA的每日心情
    开心
    2019-7-27 18:31
  • 签到天数: 6 天

    [LV.2]偶尔看看I

    发表于 2008-6-19 09:18:37 | 显示全部楼层
    这个能爆破吗?要是能,怎么个爆法
    PYG19周年生日快乐!
  • TA的每日心情
    难过
    2022-2-6 09:25
  • 签到天数: 6 天

    [LV.2]偶尔看看I

     楼主| 发表于 2008-6-19 11:48:19 | 显示全部楼层
    这个软件很有代表性,没有exe的主程序,只是相当于office的插件,所有功能用dll文件来实现,而且dll文件是加了壳的,要爆破当然可以,你要做的有以下几步:
        1.想办法找到主程序dll和实现注册功能的dll(有的程序并不是一个dll)
        2.对dll文件常规脱壳,并修复重定位表(前提是此文件加的壳比较简单,且没有自校验)
        3.反汇编去找关键并修改保存
        可以看到,整个过程是比较痛苦的,而且你不能保证爆破后的软件百分之百没有暗桩,所以如果有可能,这类程序还是尽量去分析算法或者去跟踪注册码,相应还省力一些的。
    PYG19周年生日快乐!
  • TA的每日心情
    难过
    2022-2-6 09:25
  • 签到天数: 6 天

    [LV.2]偶尔看看I

     楼主| 发表于 2008-7-20 18:51:26 | 显示全部楼层
    原帖由 flyskey 于 2008-6-19 00:28 发表
    不知道怎么回事 我下载后 运行不起来 提示说RPC服务器不可用....

    对不起,你说了这个问题以后我就开始进行了反复测试,终于找到了问题的症结,呵呵
    因为本软件是虚拟打印机,所以你的打印机相关服务必须是“启动”的,而现在深度或者番茄的精简XP等都对系统服务进行了优化,打印机相关服务默认是“禁止”的,所以会导致无法安装。解决的方法是:
    开始——运行——输入“services.msc”
    会打开“本地服务设置”,往下找在print Spooler上双击将其设置成“启动”即可(具体设置如下图)
    image002.jpeg (39.35 KB, 下载次数: 2)
    PYG19周年生日快乐!
  • TA的每日心情
    难过
    2022-2-6 09:25
  • 签到天数: 6 天

    [LV.2]偶尔看看I

     楼主| 发表于 2008-7-27 07:33:41 | 显示全部楼层
    顺便写出注册机,源码公布如下(Delphi 7.0编译通过):
    procedure TForm1.btn1Click(Sender: TObject);
    var
    a,b,c,Temp:integer;
    begin
        randomize; //初始化随机数
        repeat
        a:=Random(10);
        b:=Random(10);
        c:=Random(10);
        Temp:=a + b;
        until Temp=8;
        Form1.Edit1.Text:=IntToStr(a) + IntToStr(b) + 'V2'+IntToStr(c)+'1Senhuan018';
    end;

    end.

    [ 本帖最后由 playboysen 于 2008-7-27 08:06 编辑 ]

    注册机及其源码.rar

    214.04 KB, 下载次数: 28, 下载积分: 飘云币 -2 枚

    PYG19周年生日快乐!
    您需要登录后才可以回帖 登录 | 加入我们

    本版积分规则

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