PDFcamp Printer (PDF Writer) V2.2 最新版算法分析及注册机源码
标 题: 【原创】PDFcamp Printer (PDF Writer) V2.2 最新版破解分析作 者: playboysen
时 间: 2008-06-18
【文章标题】:【原创】PDFcamp Printer (PDF Writer) V2.2 最新版破解分析
【文章作者】: playboysen
【作者邮箱】: [email protected]
【作者相册】: 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
大家看到了,只有一个文本框,没有机器码和用户名输入提示,输入任意假码后点“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单步032961D9 8BB424 D0000000 mov esi, dword ptr
032961E0 8B3D 04112903 mov edi, dword ptr ; USER32.GetDlgItemTextA
032961E6 8D4C24 4C lea ecx, dword ptr
032961EA 68 80000000 push 80
032961EF 51 push ecx
032961F0 68 EC030000 push 3EC
032961F5 56 push esi
032961F6 FFD7 call edi
032961F8 8D5424 0C lea edx, dword ptr
032961FC 6A 40 push 40
032961FE 52 push edx
032961FF 68 EF030000 push 3EF
03296204 56 push esi
03296205 FFD7 call edi
03296207 8D4424 0C lea eax, dword ptr ; 取假码
0329620B 8D4C24 4C lea ecx, dword ptr
0329620F 50 push eax ; 假码入栈
03296210 51 push ecx
03296211 E8 FA220000 call 03298510 ; 关键Call,F7跟进
03296216 85C0 test eax, eax
03296218 0F84 9A000000 je 032962B8 ;关键跳转,不能跳
0329621E 8D5424 0C lea edx, dword ptr
03296222 8D4424 4C lea eax, dword ptr 在03296211处F7跟进后到这里03298510 8B5424 08 mov edx, dword ptr
03298514 85D2 test edx, edx
03298516 74 27 je short 0329853F
03298518 803A 00 cmp byte ptr , 0
0329851B 74 22 je short 0329853F ; 比较输入的注册码是否为空
0329851D 57 push edi
0329851E 8BFA mov edi, edx
03298520 83C9 FF or ecx, FFFFFFFF
03298523 33C0 xor eax, eax
03298525 F2:AE repne scas byte ptr es:
03298527 F7D1 not ecx
03298529 49 dec ecx
0329852A 5F pop edi
0329852B 83F9 0D cmp ecx, 0D ; ecx中是假码位数,与13相比较,如果注册码小于等于13位就跳向错误
0329852E 7E 0F jbe short 0329853F
03298530 52 push edx
03298531 E8 4AFFFFFF call 03298480 ; 唯一的“算法”比较处F7进去
03298536 F7D8 neg eax
03298538 1BC0 sbb eax, eax
0329853A F7D8 neg eax
0329853C C2 0800 retn 8在03298531处F7跟进到下面03298483 56 push esi
03298484 8B7424 20 mov esi, dword ptr
03298488 8D5424 04 lea edx, dword ptr
0329848C 57 push edi
0329848D 8A06 mov al, byte ptr
0329848F 8A4E 01 mov cl, byte ptr
03298492 884424 14 mov byte ptr , al
03298496 32C0 xor al, al
03298498 52 push edx
03298499 884424 19 mov byte ptr , al
0329849D 884C24 0C mov byte ptr , cl
032984A1 884424 0D mov byte ptr , al
032984A5 E8 D0000000 call 0329857A ; 跟踪发现,至此假码第二位的十六进制放入ECX,得知此处为关键比较1,F7跟进
032984AA 8BF8 mov edi, eax
032984AC 8D4424 18 lea eax, dword ptr
032984B0 50 push eax
032984B1 E8 C4000000 call 0329857A ; 此处为关键比较2
032984B6 03F8 add edi, eax ; 上面两个call过去后这里的add的作用是:把注册码一二位数值的16进制值分别减去30后,两个余数相加——>结果放到EDI
032984B8 83C4 08 add esp, 8
032984BB 83FF 08 cmp edi, 8 ; EDI必须是8****注册码的第一个约束条件****
032984BE 74 0A je short 032984CA
032984C0 5F pop edi
032984C1 33C0 xor eax, eax
032984C3 5E pop esi
032984C4 83C4 18 add esp, 18
032984C7 C2 0400 retn 4
032984CA 807E 02 56 cmp byte ptr , 56 ; 注册码第三位是“V”
032984CE 74 0A je short 032984DA
032984D0 5F pop edi
032984D1 33C0 xor eax, eax
032984D3 5E pop esi
032984D4 83C4 18 add esp, 18
032984D7 C2 0400 retn 4
032984DA 807E 03 32 cmp byte ptr , 32 ; 注册码第四位是“2”
032984DE 74 0A je short 032984EA
032984E0 5F pop edi
032984E1 33C0 xor eax, eax
032984E3 5E pop esi
032984E4 83C4 18 add esp, 18
032984E7 C2 0400 retn 4
032984EA 807E 05 31 cmp byte ptr , 31 ; 注册码第六位是“1”
032984EE 74 0A je short 032984FA
032984F0 5F pop edi
032984F1 33C0 xor eax, eax
032984F3 5E pop esi
032984F4 83C4 18 add esp, 18
032984F7 C2 0400 retn 4
032984FA 8A4E 0F mov cl, byte ptr ; 注册码第十六位的十六进制放入cl
032984FD 33C0 xor eax, eax
032984FF 80F9 38 cmp cl, 38 ; 注册码第十六位是“8”
03298502 5F pop edi
03298503 0F94C0 sete al ;如果条件全部满足则al置1
03298506 5E pop esi
03298507 83C4 18 add esp, 18
0329850A C2 0400 retn 4
0329850D 90 nop
0329850E 90 nop在跟进032984A5的CALL,到这里7C944C36 55 push ebp
7C944C37 8BEC mov ebp, esp
7C944C39 56 push esi
7C944C3A 8B75 08 mov esi, dword ptr
7C944C3D 85F6 test esi, esi
7C944C3F 0F84 B3AA0200 je 7C96F6F8
7C944C45 833D 70C1997C 0>cmp dword ptr , 1
7C944C4C 0FB606 movzx eax, byte ptr ; 假码第二位十六进制放入eax
7C944C4F 0F8F AAAA0200 jg 7C96F6FF
7C944C55 8B0D 30C3997C mov ecx, dword ptr
7C944C5B 0FB60441 movzx eax, byte ptr
7C944C5F 83E0 08 and eax, 8
7C944C62 85C0 test eax, eax
7C944C64 0F85 A4AA0200 jnz 7C96F70E ; 这几句没看懂什么功能,但并不影响分析
7C944C6A 0FB60E movzx ecx, byte ptr ; 假码第二位十六进制放入ecx
7C944C6D 46 inc esi
7C944C6E 83F9 2D cmp ecx, 2D ; 假码第二位十六进制与“-”连接符比较
7C944C71 8BD1 mov edx, ecx
7C944C73 74 2A je short 7C944C9F
7C944C75 83F9 2B cmp ecx, 2B
7C944C78 74 25 je short 7C944C9F
7C944C7A 33C0 xor eax, eax
7C944C7C 83F9 30 cmp ecx, 30 ; ********************************
7C944C7F 7C 19 jl short 7C944C9A ; 这四句是比较第二位是否为数字
7C944C81 83F9 39 cmp ecx, 39
7C944C84 7F 14 jg short 7C944C9A ; **************************************
7C944C86 83E9 30 sub ecx, 30 ; 假码第二位十六进制减去30——>值放入ECX
7C944C89 83F9 FF cmp ecx, -1
7C944C8C^ 74 8A je short 7C944C18
7C944C8E 8D0480 lea eax, dword ptr
7C944C91 8D0441 lea eax, dword ptr ; ecx+eax*2(其实这里eax大部分时候是0,那么这句就是把ecx值放入eax)——>值放入EAX
7C944C94 0FB60E movzx ecx, byte ptr
7C944C97 46 inc esi
7C944C98^ EB E2 jmp short 7C944C7C
7C944C9A 83C9 FF or ecx, FFFFFFFF
7C944C9D^ EB EA jmp short 7C944C89
7C944C9F 0FB60E movzx ecx, byte ptr
7C944CA2 46 inc esi
7C944CA3^ EB D5 jmp short 7C944C7A至此分析全部结束,算法过程总结如下:
首先注册码必须大于13位;
注册码第一二位16进制分别减去30后的余数之和必须等于8 ;
注册码第三位必须是 V;
第四位 2 ;
第六位 1 ;
十六位 8 ;
比如这组注册码可用:
17V201playboyse8
注册机及其源码已经放出,详情请看10楼!!
附件在这里:
https://www.chinapyg.com/viewthread.php?tid=34083&extra=page%3D1
[ 本帖最后由 playboysen 于 2008-7-27 07:35 编辑 ] 不错 搞算法CALL在DLL中的一个不错的下段方法 这个软件不错 简单跟踪了一下
04B08499 884424 19 MOV BYTE PTR SS:,AL
04B0849D 884C24 0C MOV BYTE PTR SS:,CL
04B084A1 884424 0D MOV BYTE PTR SS:,AL ; 放第一位和第二位
04B084A5 E8 D0000000 CALL pdfui.04B0857A ; 关键CALL 下文跟进分析
04B084AA 8BF8 MOV EDI,EAX ; 第二位 -30 结果送EDI
04B084AC 8D4424 18 LEA EAX,DWORD PTR SS: ; 传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:,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:,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:,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: ; 第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: ; 将参数送地址 ESI
7C944C3D 85F6 TEST ESI,ESI
7C944C3F 0F84 B3AA0200 JE ntdll.7C96F6F8
7C944C45 833D 70C1997C 0>CMP DWORD PTR DS:,1
7C944C4C 0FB606 MOVZX EAX,BYTE PTR DS: ; 将参数(内存单元的一个字节)做零扩展送EAX
7C944C4F 0F8F AAAA0200 JG ntdll.7C96F6FF
7C944C55 8B0D 30C3997C MOV ECX,DWORD PTR DS: ; ECX=20
7C944C5B 0FB60441 MOVZX EAX,BYTE PTR DS: ; 零扩展并传送至EAX20+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:
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: ; 将参数(内存单元的一个字节)做零扩展送EAX
7C944C4F 0F8F AAAA0200 JG ntdll.7C96F6FF
7C944C55 8B0D 30C3997C MOV ECX,DWORD PTR DS: ; ECX=7C946CAA =20
7C944C5B 0FB60441 MOVZX EAX,BYTE PTR DS: ; 零扩展并传送至EAX20+EAX*2
7C944C5F 83E0 08 AND EAX,8 ; 和8做与运算
7C944C62 85C0 TEST EAX,EAX
7C944C64 0F85 A4AA0200 JNZ ntdll.7C96F70E
我们注意到 ECX为定值 ECX=7C946CAA 且 =20
若参数 为 数字 0123456789则 ECX+EAX*2 结果范围为 7C946D0A ~ 7C946D1C
ECX+30H*2 = 7C946D0A
ECX+39H*2 = 7C946D1C
我们来查看一下该内存的数据 , 发现偶地址全都是数值 84 且 奇地址为 00(因为奇地址我们用不到)
如果是 84 执行 AND EAX,8 结果EAX=0
84H的2进制: 10000100
8的2进制: 00001000
则该跳转不实现 继续向下走 适参数 - 30H, 因为结果要求两个参数 KEY1 + KEY2 = 8, 如果KEY非数字的话 必然不需要继续判断了 肯定KEY1+KEY2 不等于 8所以这几句也可以理解成 判断参数是否为数字 对了,软件的注册信息是保存在以下两个位置:
"RegisterNO"="17V201playboyse8"
和
"RegisterNO"="17V201playboyse8"
如果要练手的话,必须同时删除上面两处注册信息才能变回未注册版本,请留意/:023 不知道怎么回事 我下载后 运行不起来 提示说RPC服务器不可用.... 这个能爆破吗?要是能,怎么个爆法 这个软件很有代表性,没有exe的主程序,只是相当于office的插件,所有功能用dll文件来实现,而且dll文件是加了壳的,要爆破当然可以,你要做的有以下几步:
1.想办法找到主程序dll和实现注册功能的dll(有的程序并不是一个dll)
2.对dll文件常规脱壳,并修复重定位表(前提是此文件加的壳比较简单,且没有自校验)
3.反汇编去找关键并修改保存
可以看到,整个过程是比较痛苦的,而且你不能保证爆破后的软件百分之百没有暗桩,所以如果有可能,这类程序还是尽量去分析算法或者去跟踪注册码,相应还省力一些的。 原帖由 flyskey 于 2008-6-19 00:28 发表 https://www.chinapyg.com/images/common/back.gif
不知道怎么回事 我下载后 运行不起来 提示说RPC服务器不可用....
对不起,你说了这个问题以后我就开始进行了反复测试,终于找到了问题的症结,呵呵
因为本软件是虚拟打印机,所以你的打印机相关服务必须是“启动”的,而现在深度或者番茄的精简XP等都对系统服务进行了优化,打印机相关服务默认是“禁止”的,所以会导致无法安装。解决的方法是:
开始——运行——输入“services.msc”
会打开“本地服务设置”,往下找在print Spooler上双击将其设置成“启动”即可(具体设置如下图)
顺便写出注册机,源码公布如下(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 编辑 ]
页:
[1]