本帖最后由 姐又寡闻了 于 2019-6-6 22:26 编辑
PDF-XChange Viewer ,很熟悉呀~ 因为我用它好久了,但可惜早些年对逆向一窍不通,也只是喜欢收藏各种软件,然而时隔不知多久...现在打开尘封的记忆,对他进行了一波分析~
过程可能会非常的长~~长~~~长~~~~~,因为全是为了照顾更多人能看得明白,看得懂。我也写得很累,但是能帮助到更多人来学习逆向,还是很开心的~
这2天在看这个软件系列,其中让我最头疼的就是这款PDF-XChange Viewer的去水印,常规手段没有找到切入点,下面就跟大家一起分享一下这软件破解的分析与查找去除水印的全过程~
首先入手还是习惯性的PEID查一下:
打开软件看下具体限制在哪:
可以看到属于PRO功能的右边有PRO锁的图标,并且点击功能会出提示框告诉我们,我们先点击是看看~
好了,大概看了下限制,基本是这样,有PRO功能,功能也可以用,但是都会提示未注册,并且功能使用后保存后PDF会自动加入水印~
接下来拖入OD开始分析,直接F9让程序跑起来,然后找切入点,首先我考虑的是注册的地方,去那边看看能不能切入。
The Clipboard doesn't contain the valid license key(s),看不懂英文也大概猜出是剪切板复制不是有效的注册码,那么,我们就可以思考到这里肯定有判断我们注册码,我们可以下MessageBoxW,为什么用宽字节,这个大家可以自己测试,但看到这个程序多数字符串都是Unicode就差不多猜到了。
来到了系统领空,直接Alt+F9,点击弹出的消息框后来到程序领空,这时候可以看到上面有个跳是明显跳过这个提示的,我们先试试修改Z标志位,执行看看再说,再次点击粘贴剪贴板按钮,程序中断下来,修改标志,改变程序流程,然后F9
这时候发现原本灰色的继续按钮现在变成正常可点击了,这证明上面这个CALL是一处关键验证,我们先标记一下,然后继续看看点击继续会怎么样:
果然没那么容易,对吧?又变成灰色了,那么我们再思考下,这里是不是也有验证呢?我们也看一下,获取文本我们使用GetWindowTextW来截取
此时程序再次中断下来,老样子,Alt+F9,返回后,我们一路F8向下跟踪分析~
返回后我们看到接下来的这个CALL又是之前我们分析的那个关键CALL,那么我们来看看这个CALL吧~
[Asm] 纯文本查看 复制代码 00ADF930 /$ 51 push ecx
00ADF931 |. 56 push esi
00ADF932 |. 8B7424 0C mov esi,dword ptr ss:[esp+0xC] ; PDFXCvie.00ADFDA9
00ADF936 |. 57 push edi
00ADF937 |. 8B7E 04 mov edi,dword ptr ds:[esi+0x4]
00ADF93A |. 85FF test edi,edi
00ADF93C |. 74 5B je short PDFXCvie.00ADF999
00ADF93E |. 53 push ebx
00ADF93F |. 55 push ebp
00ADF940 |. 8B2D 6CCFF300 mov ebp,dword ptr ds:[0xF3CF6C] ; \t\r\n
00ADF946 |. 8BCE mov ecx,esi
00ADF948 |. 6A 00 push 0x0
00ADF94A |. 55 push ebp
00ADF94B |. E8 507397FF call PDFXCvie.00456CA0
00ADF950 |. 8BD8 mov ebx,eax
00ADF952 |. 85DB test ebx,ebx
00ADF954 |. 7E 26 jle short PDFXCvie.00ADF97C
00ADF956 |. 3BDF cmp ebx,edi
00ADF958 |. 7D 22 jge short PDFXCvie.00ADF97C
00ADF95A |. 8B0E mov ecx,dword ptr ds:[esi] ; PDFXCvie.00E07FC4
00ADF95C |. 2BFB sub edi,ebx
00ADF95E |. 8D047D 020000>lea eax,dword ptr ds:[edi*2+0x2]
00ADF965 |. 50 push eax
00ADF966 |. 8D0459 lea eax,dword ptr ds:[ecx+ebx*2]
00ADF969 |. 50 push eax
00ADF96A |. 51 push ecx
00ADF96B |. E8 406D0100 call PDFXCvie.00AF66B0
00ADF970 |. 8B2D 6CCFF300 mov ebp,dword ptr ds:[0xF3CF6C] ; \t\r\n
00ADF976 |. 83C4 0C add esp,0xC
00ADF979 |. 295E 04 sub dword ptr ds:[esi+0x4],ebx
00ADF97C |> 6A 00 push 0x0
00ADF97E |. 55 push ebp
00ADF97F |. 8BCE mov ecx,esi
00ADF981 |. E8 8A7397FF call PDFXCvie.00456D10
00ADF986 |. 40 inc eax
00ADF987 |. 5D pop ebp ; 00127F40
00ADF988 |. 5B pop ebx ; 00127F40
00ADF989 |. 3B46 04 cmp eax,dword ptr ds:[esi+0x4]
00ADF98C |. 74 0B je short PDFXCvie.00ADF999
00ADF98E |. 8B0E mov ecx,dword ptr ds:[esi] ; PDFXCvie.00E07FC4
00ADF990 |. 33D2 xor edx,edx
00ADF992 |. 8946 04 mov dword ptr ds:[esi+0x4],eax
00ADF995 |. 66:891441 mov word ptr ds:[ecx+eax*2],dx
00ADF999 |> 837E 04 00 cmp dword ptr ds:[esi+0x4],0x0
00ADF99D |. 75 06 jnz short PDFXCvie.00ADF9A5
00ADF99F |. 5F pop edi ; 00127F40
00ADF9A0 |. 33C0 xor eax,eax
00ADF9A2 |. 5E pop esi ; 00127F40
00ADF9A3 |. 59 pop ecx ; 00127F40
00ADF9A4 |. C3 retn
00ADF9A5 |> FF36 push dword ptr ds:[esi] ; PDFXCvie.00E07FC4
00ADF9A7 |. E8 4479FFFF call PDFXCvie.00AD72F0
00ADF9AC |. 83C4 04 add esp,0x4
00ADF9AF |. 85C0 test eax,eax
00ADF9B1 |. 74 09 je short PDFXCvie.00ADF9BC
00ADF9B3 |. 5F pop edi ; 00127F40
00ADF9B4 |. B8 01000000 mov eax,0x1
00ADF9B9 |. 5E pop esi ; 00127F40
00ADF9BA |. 59 pop ecx ; 00127F40
00ADF9BB |. C3 retn
00ADF9BC |> FF36 push dword ptr ds:[esi] ; PDFXCvie.00E07FC4
00ADF9BE |. E8 CD1B0100 call PDFXCvie.00AF1590
00ADF9C3 |. 83C4 04 add esp,0x4
00ADF9C6 |. 85C0 test eax,eax
00ADF9C8 |. 74 09 je short PDFXCvie.00ADF9D3
00ADF9CA |. 5F pop edi ; 00127F40
00ADF9CB |. B8 03000000 mov eax,0x3
00ADF9D0 |. 5E pop esi ; 00127F40
00ADF9D1 |. 59 pop ecx ; 00127F40
00ADF9D2 |. C3 retn
00ADF9D3 |> 6A 00 push 0x0
00ADF9D5 |. 8D4424 14 lea eax,dword ptr ss:[esp+0x14]
00ADF9D9 |. C74424 0C 000>mov dword ptr ss:[esp+0xC],0x0
00ADF9E1 |. 50 push eax
00ADF9E2 |. 8D4424 10 lea eax,dword ptr ss:[esp+0x10]
00ADF9E6 |. C74424 18 000>mov dword ptr ss:[esp+0x18],0x0
00ADF9EE |. 50 push eax
00ADF9EF |. FF76 04 push dword ptr ds:[esi+0x4]
00ADF9F2 |. FF36 push dword ptr ds:[esi] ; PDFXCvie.00E07FC4
00ADF9F4 |. E8 57B80000 call PDFXCvie.00AEB250
00ADF9F9 |. 83C4 14 add esp,0x14
00ADF9FC |. C1E8 1E shr eax,0x1E
00ADF9FF |. F7D0 not eax
00ADFA01 |. 83E0 02 and eax,0x2
00ADFA04 |. 5F pop edi ; 00127F40
00ADFA05 |. 5E pop esi ; 00127F40
00ADFA06 |. 59 pop ecx ; 00127F40
00ADFA07 \. C3 retn
我们大概简略看了一下,最终都是通过赋值EAX来传递,而这里分支可以看到EAX可能有4个结果,我们修改下这个CALL直接让EAX返回分别这4个结果来测试下:
其中,让EAX为3的时候会弹出如下这个提示框,为1的时候貌似是连接网络验证并弹出验证失败提示框。
此时,我想到断网试试呢?~
看来还是不行,这时就不要再一颗树上吊死了,赶紧转个别的方法试试吧,回想起我们之前测试限制的时候不是有提示框吗?直接从那里入手试试吧!根据提示下好断点(GetDlgItem),依旧是Alt+F9,
一路上一直F8,注意观察堆栈,中断很多次,因为还有其他的提示框,比如提示是否执行删除提示框等,这些都不是我们要分析的,直到跟踪到下面这个位置:
重新点击PRO功能按钮,然后跟踪下这个CALL,先粗略走一下,发现寄存器出现明显的字符串提示,那么这里肯定有关键的比对,我们看看哪里是我们需要的重要比对~
这里一开始的一个CALL有点可疑,因为他没提示PRO框,而是赋值EAX并返回了,而我们出CALL也可以看到如果EAX不为0则会继续向下执行功能,那么肯定这是个很关键的一个CALL~
[Asm] 纯文本查看 复制代码 005B59BD |> \E8 9E0B1A00 call PDFXCvie.00756560
005B59C2 |. 85C0 test eax,eax
005B59C4 |. 74 1B je short PDFXCvie.005B59E1
005B59C6 |> B8 01000000 mov eax,0x1
005B59CB |. 5E pop esi
005B59CC |. 8B8C24 780100>mov ecx,dword ptr ss:[esp+0x178]
005B59D3 |. 64:890D 00000>mov dword ptr fs:[0],ecx
005B59DA |. 81C4 84010000 add esp,0x184
005B59E0 |. C3 retn
经验告诉我,这个全局变量是一个关键的flag~ 我们直接 参考地址查找下:
双击来到这里,因为只有这里给他赋值了,那么这里很关键,我们来到段首下好断点~~重新运行程序,看看什么时候赋值,通过上面的分析我们可以判断这个flag为0时才是我们需要的。我们简单来干涉流程实现一下:(0075BA4C 注意这个地址的跳 ,跟踪会发现这个跳直接跳过了,我们打断它)
我们好像成功了,那个全局应该就是关键了,功能测试一下看看会提示框没有~?果然..搞定了~但别高兴太早了~因为虽然这样突破了但是我们保存的时候就会发现~~ 重点来了,水印依然是存在的,这样等于我们只是把烦人的提示PRO框去掉了而已,重要的保存依然并不完美~还得解决!~
注意观察了下水印发现里面有一些英语,大概是这样的:Click to buy NOW,那我们是不是可以搜索下字符串看看有没有发现,再次重载主程序~~唔...搜索不到,ALT+M 再次搜索~,结果一样~
看来一般常规手段是没办法找到切入点了,那么既然水印的出现是在保存文件时才被写入的,我们可以下个CreateFileW来慢慢跟踪看看
保存时程序成功中断下来,我们返回程序领空来跟踪下他干嘛了..一路耐心跟踪下来,发现又再次创建了一些文件,这些文件他肯定跟水印有某种关系~
为了验证是不是跟水印有关,我们简单复制下文件,拿个最小体积的48字节这个文件看看到底是什么?不知道是什么鬼,所以直接拖入C32ASM看看文件结构~
应该是一些相关数据,此时就想,如果生成的新PDF有水印,那么会不会有如下这段数据呢,我们来印证看看~
果然是有发现,确实是写入了这么一段,那么那些会不会都是主要写入水印的数据呢?不管那么多了,我们先把这段填充掉看看会是什么效果。
果然印证了我们的想法,但这么去除不是个办法,而且上面还留有网址连接,鼠标放在那边还明显有个方框,我们必须找到这个调用的地方来做修改才行。所以我们继续来重新跟踪一下~
当他再次创建pvrxx.tmp的时候我们就注意了,肯定就是那个CALL开始创建水印,我们在CALL这里下好断点重新来过~
重新生成PDF,程序中断了,F7步入继续跟踪一下~果然发现了踪影,注意观察堆栈。
我们已经来到关键地方了,这时候应该怎么改我们就要尝试尝试了,盲目修改估计保存的PDF文件也会遭殃,我们先试试返回到进CALL前找找有没有跳过的,并且尝试一波修改~
从上面找跳过CALL的,我们可以发现这个有个JMP可跳过去,但是测试后发现循环后并不走这路,直接是跳过循环,如果我们强制修改肯定会出问题,那这么修改不可取,我们在回到那个CALL里看看,能不能段首执行返回呢?继续试一试!~
果然还是失败了,这么改也不行, 那证明里面这个CALL是必要经过的CALL,我们要找到修改加入水印的那个CALL来返回才行。我们来试试那2个CALL!~最终锁定的是 这个call 00940760
堆栈传了个参数进来,就是这个网址,我们知道那个水印点击就是这个网址,那么差不多了,就是这个CALL直接让他返回,我们在试试~
成功了,我们把所有限制与水印都去除干净了,这下终于可以收工了~ 走了挺多弯路对吧,这就是破解的艰辛,虽然路程崎岖不平,但是一道一道障碍解决那种心情其实也是很兴奋的。
好了文章写到这里也基本全部结束了,希望小伙伴们看完之后都能有一些收获吧。
写这文章也是断断续续的,从早上就开始整理加调试慢慢修改,到完成不知不觉已经都下午快天黑了~写个文章真的好费时间与精力呀~就到这里吧,有机会再会~
另外还想 @苏紫方璇 一下,不知道你有收到我发的私信吗?望回复呀~感谢感谢~
|