VeryPDF Split-Merge v3.0破解思路+算法分析+注册机制作
本帖最后由 wangzhe311 于 2015-8-16 17:03 编辑【文章标题】: VeryPDF Split-Merge v3.0破解思路+算法分析+注册机制作【文章作者】: wangzhe311
【作者邮箱】: wangzhe311@126.com
【软件名称】: VeryPDF Split-Merge v3.0
【软件大小】: 2.29M
【下载地址】: http://www.verypdf.com/app/pdf-split-merge/try-and-buy.html#buy
【加壳方式】: 无壳
【保护方式】: 无壳
【编写语言】: Microsoft Visual C++ v6.0
【使用工具】: PEID,OD,小生我怕怕注册机生成器等
【操作平台】: winxp
【软件介绍】: PDF文件分割与合并
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
【详细过程】
太忙了,以致于都没有时间研究这个了。最近都有点生疏了。就当拿来练手吧。
目标:VeryPDF Split-Merge v3.0英文小软件。用于PDF分割合并。
首先用peid查下壳,例行程序吧。显示无壳,用Microsoft Visual C++ v6.0编写的程序。
接下来,直接OD载入。
下面进入分析阶段。首先运行一下程序,看有什么反应。
出现了注册提示框。点试用,看未注册版本有什么特点。
弹出如下提示,表明有50次试用。
OK,先用第一种方法,调用堆栈。重载一下程序,运行,出来如下提示后,暂停程序。
按K键打开堆栈窗口。
找到最后一个在程序领空的地方,右键,显示调用。来到下面代码部分:
0042114C|. /74 0C je short 0042115A ;关键跳转,可直接改成jmp跳过注册窗口。
0042114E|. |8B10 mov edx, dword ptr
00421150|. |8BC8 mov ecx, eax
00421152|. |FF92 BC000000 call dword ptr ;调用注册窗口的CALL
00421158|. |EB 07 jmp short 00421161
0042115A|> \6A 01 push 1事情变的简单了,直接将0042114C处的je改成jmp,跳过注册窗口。即:0042114C /EB 0C jmp short 0042115A ;关键跳转修改后,右键,复制到可执行文件,全部复制,保存。OK,破解完成。以上是最简单的爆破。
下面我们做个补丁。将我们爆破保存的文件命名crack.EXE.拿出工具keymake。
选其它,制作文件补丁。
填写必要信息,并把原始文件与我们破解的文件选上。然后制作,随便选个界面。
补丁命名为KENGEN.EXE.完成后,测试一下效果。第一种方法完成。
第二种方法,就是稍微复杂一点的。
追码,写注册机。(本人能力有限,算法简单的还行。)重载原程序,利用插件搜索字符串或者是输入假码后调用堆栈。
最后,我们都会找到关键call:
10001972 E8 F9F7FFFF call 10001170 ;关键call10001977 83C4 04 add esp, 4
1000197A 85C0 test eax, eax
1000197C 74 39 je short 100019B7 ;关键跳。
1000197E 6A 40 push 40
10001980 68 58430110 push 10014358 ; ASCII "Thank you."
10001985 68 1C430110 push 1001431C ; ASCII "Thank you for purchasing the PDF Split-Merge v3.0 software."
1000198A 56 push esi
1000198B FF15 34030110 call dword ptr [<&USER32.MessageBoxA>] ; user32.MessageBoxA
在10001972处下断点。重载程序,然后F8跟入。
10001170 83EC 18 sub esp, 18
10001173 53 push ebx
10001174 56 push esi
10001175 8B7424 24 mov esi, dword ptr
10001179 8D5424 08 lea edx, dword ptr
1000117D 57 push edi
1000117E 32DB xor bl, bl
10001180 8A46 0E mov al, byte ptr ; 取注册码的第15位
10001183 8A4E 0F mov cl, byte ptr ; 取注册码的第16位
10001186 52 push edx
10001187 884424 1C mov byte ptr , al
1000118B 885C24 1D mov byte ptr , bl
1000118F 884C24 10 mov byte ptr , cl
10001193 885C24 11 mov byte ptr , bl
10001197 E8 45150000 call 100026E1
1000119C 8BF8 mov edi, eax
1000119E 8D4424 1C lea eax, dword ptr
100011A2 50 push eax
100011A3 E8 39150000 call 100026E1
100011A8 03F8 add edi, eax
100011AA 83C4 08 add esp, 8
100011AD 83FF 0B cmp edi, 0B ; 15位+16位=11
100011B0 74 09 je short 100011BB
100011B2 5F pop edi
100011B3 5E pop esi
100011B4 33C0 xor eax, eax
100011B6 5B pop ebx
100011B7 83C4 18 add esp, 18
100011BA C3 retn
100011BB 8A0E mov cl, byte ptr ; 取注册码的第1位
100011BD 8A56 01 mov dl, byte ptr ; 取注册码的第2位
100011C0 8D4424 0C lea eax, dword ptr
100011C4 884C24 18 mov byte ptr , cl
100011C8 50 push eax
100011C9 885C24 1D mov byte ptr , bl
100011CD 885424 10 mov byte ptr , dl
100011D1 885C24 11 mov byte ptr , bl
100011D5 E8 07150000 call 100026E1
100011DA 8D4C24 1C lea ecx, dword ptr
100011DE 8BF8 mov edi, eax
100011E0 51 push ecx
100011E1 E8 FB140000 call 100026E1
100011E6 03F8 add edi, eax
100011E8 83C4 08 add esp, 8
100011EB 83FF 0A cmp edi, 0A ; 1位+2位=10
100011EE 74 09 je short 100011F9
100011F0 5F pop edi
100011F1 5E pop esi
100011F2 33C0 xor eax, eax
100011F4 5B pop ebx
100011F5 83C4 18 add esp, 18
100011F8 C3 retn
100011F9 807E 05 33 cmp byte ptr , 33 ; 6位=3
100011FD 74 09 je short 10001208
100011FF 5F pop edi
10001200 5E pop esi
10001201 33C0 xor eax, eax
10001203 5B pop ebx
10001204 83C4 18 add esp, 18
10001207 C3 retn
10001208 8A4E 06 mov cl, byte ptr ; 取第7位
1000120B 33C0 xor eax, eax
1000120D 80F9 31 cmp cl, 31 ; 7位=1
10001210 5F pop edi
10001211 5E pop esi
10001212 5B pop ebx
10001213 0F94C0 sete al
10001216 83C4 18 add esp, 18
10001219 C3 retn
见注释。
注册码的算法如下:
1位+2位=10
6位=3
7位=11
5位+16位=11
我们根据规律构造一个注册码如下:19***31*******29
试注册一下。
结果可以成功注册。
那么,注册码并没有对位数进行校验,也就是说我们的注册码可要是大于16位且满足条件就可以了。
到此,我们可以写注册机了。
随意生成一个大于10位的字符串;
随意生成一个介于2-9的数字;
随意生成一个介于1-9的数字;
OK,组合上面的各个部分,生成一个字符串即可。
VB6.0注册机源码如下:
++++++++++++++++++++++++++++++++++++++++++
Private Sub Command1_Click()'其中48~57为0到9十个阿拉伯数字
'65~90为26个大写英文字母
'97~122号为26个小写英文字母
'a = Int(Rnd * (da - xiao + 1) + xiao)
x = ""
For i = 1 To 20
S = Int(Rnd * (3))
Select Case S
Case 0
w = Int(Rnd * (57 - 48 + 1) + 48)
Case 1
w = Int(Rnd * (90 - 65 + 1) + 65)
Case 2
w = Int(Rnd * (122 - 97 + 1) + 97)
End Select
x = x & Chr(w)
If i < 20 Then: x = x '使用小于20是避免出现最后那个连词符
Next
Dim a, b, c, d As Integer
Dim e, f, g, h As String
a = Int(Rnd * 9) + 1
b = 10 - a
c = Int(Rnd * 8) + 2
d = 11 - c
e = Trim(Str(a))
f = Trim(Str(b))
g = Trim(Str(c))
h = Trim(Str(d))
Text1.Text = e & f & Mid(x, 3, 3) & "31" & Mid(x, 8, 7) & g & h
End Sub
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++到这里,破解过程可算是已经结束了。但是也可以自己再往深里探究一下。看看注册码是放在哪里的。
如果是放在注册表中,我们就可以直接导出来,采取导入注册表的方式进行注册。如果是文件写入类型的,
可以带着文件跑。通过下注册表断点,可知道软件启动是否读过注册表,知道注册码是放在哪里的。
通过file monitor对主程序进行检测,我们发现程序启动过程中读取过pdfpg.dat文件。
如图:
我们可以用winhex打开看看。为什么要用它呢,因为软件里面的数据一般是16进制的,记事本不支持。
不多说,找到路径打开看看。
看到了字符串:
46j2531EtU890j92
这就是我们刚才用于注册的注册码。
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
【版权声明】: 本文原创于WANGZHE311, 转载请注明作者并保持文章的完整, 谢谢!
{:1_919:}前排留名 支持大大
页:
[1]