首页 > 代码精文 > C/C++ > skin++ 大牛的破解之法
2015
06-07

skin++ 大牛的破解之法

skin技术,大家都不会陌生,比如winamp,可以灵活的更换界面风格。早期的实现定制的外观方法都需要程序本身做许多处理,编码太麻烦。

后来出现了专门的Skin插件,ActiveSkin什么的。再后来dll调用的skin软件出现,需要Skin支持的程序调用几个方法,就可以使自己的程序外观完全改变,不需要编程者对skin技术有任何的了解。Skin++通用界面换肤系统V2.0.1就是其中比较出名的一款。

但是让很多“贫民”用户来说,要收费还是比较让人烦的。恰好我前几天做了个小项目,顺便用了下朋友推荐的这款软件。

*[软件原理分析]:

逆向了下这款软件,因为这款软件是商业软件,没方法得到源代码,所以我也是主观的猜测。

原理上基本上是这样:

通过消息钩子来改变已有控件的外观,函数原型是SetWindowsHookEx(WH_CALLWNDPROC, HookProc, 0, lThreadID);

这个函数就不多做解释了,查阅MSDN。设置类型为WH_CALLWNDPROC的HOOK。

然后是截获消息,当然不同控件发出的相同消息也是要分开处理的,简单的方法是得到窗口句柄,而通过窗口句柄得到窗口类,一般在HOOK的CALLBACK 函数中可以获得。接下来就是消息处理,一般都是从截获WM_CREATE消息开始,再就是WM_PAINT,其他诸如鼠标消息之类的也是要处理的,就不再多说。但是这里的细节部分,比如钩子的记录,会出现很多烦琐的东西,解决方案是为窗口类型建立类,然后由实例去解决窗口消息的处理和窗口状态数据的记录。获得了窗口句柄以后,使用SetWindowLong技术将窗口句柄关联到窗口类上。并且可以根据窗口的风格让同一个类做出不同风格的显示效果。

具体的代码实现限于我的水平和时间问题,就不多做纠缠。

*[软件用法说明]:

到skin++的官方网站http://www.uipower.com去下载试用版。安装。

在VC平台下设置include和lib,tools/options/directory。也可以把SkinPPDemoSystem(VC)/ VCcases下的include和lib文件的文件拷贝到VC的对应目录。在project/settings/link里添上 SkinPPWTL.lib 。

然后将DLL目录里的SkinPPWTL.dll拷贝到windows目录的system32目录下(注意这个是没破解的)。

生成project的时候,将Skins目录里的某张皮肤拷贝到项目目录下,然后在源代码里加上#include "SkinPPWTL.h",int CMainFrame::OnCreate或者CMFC_SkinApp::InitInstance下加上skinppLoadSkin(_T ("xxx.ssk"));即可。

详细的代码可以参考附带的demo。

如果不是正版用户,在生成可执行文件后运行会弹出对话框要求注册。下面我们就破解掉它。关键是对SkinPPWTL.dll的破解。

*[软件破解分析]:

这款软件好象保护不是很强,explorer "http://www.uipower.com"。我不太习惯叫这类弹出型限制为nag,呵呵。

SkinPPWTL.dll,一般没正式购买的版本会不厌其烦的弹出“Skin++ allows you to add skinning ability to your applications.For informationon obtaining a license to use this control,please visit [url]www.uipower.com[/url] or e-mail sales@uipwer.com.Are you registering?”。

那我们破除它。

10033097 |. 68 7C120710 PUSH skinppwt.1007127C ; ASCII "UIPower : ...?"

1003309C |. E8 F7E9FCFF CALL skinppwt.10001A98

100330A1 |. 8365 FC 00 AND DWORD PTR SS:[EBP-4],0

100330A5 |. 51 PUSH ECX

100330A6 |. 8BCC MOV ECX,ESP

100330A8 |. 8965 EC MOV DWORD PTR SS:[EBP-14],ESP

100330AB |. 68 10030710 PUSH skinppwt.10070310 ; ASCII "UIPOWER"

100330B0 |. E8 E3E9FCFF CALL skinppwt.10001A98

100330B5 |. FF35 A8270710 PUSH DWORD PTR DS:[100727A8]

100330BB |. 834D FC FF OR DWORD PTR SS:[EBP-4],FFFFFFFF

100330BF |. E8 B7F10000 CALL skinppwt.1004227B

100330C4 |. 83C4 14 ADD ESP,14

100330C7 |. 83F8 06 CMP EAX,6

100330CA |. 75 18 JNZ SHORT skinppwt.100330E4

100330CC |. 6A 05 PUSH 5 ; /IsShown = 5

100330CE |. 6A 00 PUSH 0 ; |DefDir = NULL

100330D0 |. 6A 00 PUSH 0 ; |Parameters = NULL

100330D2 |. 68 64120710 PUSH skinppwt.10071264 ; |FileName = "http://www.uipower.com"

100330D7 |. 68 5C120710 PUSH skinppwt.1007125C ; |Operation = "open"

100330DC |. 6A 00 PUSH 0 ; |hWnd = NULL

100330DE |. FF15 3C840510 CALL DWORD PTR DS:[<&SHELL32.ShellExecut>; /ShellExecuteA

100330E4 |> 8B4D F4 MOV ECX,DWORD PTR SS:[EBP-C]

100330E7 |. 64:890D 000000>MOV DWORD PTR FS:[0],ECX

100330EE |. C9 LEAVE

100330EF /. C3 RETN

最让人讨厌的是这句:

100330BF |. E8 B7F10000 CALL SkinPPWT.1004227B

跟进去就能看到是一个函数MessageBoxIndirect调用.

直接NOP掉。

接着看下面这个:

100330CA |. 75 18 JNZ SHORT skinppwt.100330E4

jump掉:

100330CA . EB 18 JMP SHORT SkinPPWT.100330E4

这里查找75 18的时候可以把上下文加上,这样:83 F8 06 75 18 6A 05然后替换为83 F8 06 EB 18 6A 05即可。

保存SkinPPWTL.dll。拷贝到两个地方:skin++安装目录的VCcases/Bin目录下和windows目录的system32目录下。

*[软件服务破解]:

有了这个skin++,当然是需要更多皮肤了,而软件本身只提供了不到10张。而正版的用户才能下载官方网站上的皮肤。不管那么多,我到官方网站转了一圈,分析了下网站下载链接,发现了一个好玩的东西。可以通过下面的方法下载到更多的皮肤:

用迅雷新建批量下载任务,这样:

http://www.uipower.com/skindown/hit.asp?id=(*)

(*) 范围115-160。

下载...正常应该能拿到50多张皮肤...Enjoy!

上面是网友gz1X写的部分,我试验了,破解很成功,达到了去掉每次启动程序都弹出的询问注册的CMessageDialog,但是我想加点个人认为有必要的东西:

1、使用的调试软件:

软件:Ollydbg

下载链接:http://www.ithtw.com/wp-content/uploads/soft/Ollydbg.7z

2、软件的使用:

选择打开要破解的SkinPPWTL.dll文件之后按上述步骤完成修改之后,就有一个保存修改的问题,我在使用的时候找遍了整个菜单栏,硬是没有发现有保存修改这个项的存在,后来发现操作方法如下:

a.被修改处右击,选择“复制到可执行文件”,选择“所有修改”

b.出现提示框“把选中的内容复制到可执行文件”,选择“全部复制”

c.弹出一个新的窗口,直接点X,关闭该子窗口,提示“文件已更改”,选择“是”,再弹“另存为”框,此时不要做任何修改,切记不可改文件名,接着提示“文件已存在”,问是否覆盖,点“是”,覆盖原文件,关闭Ollydbg,打完收功。

到此,对于达到最终目的来说,软件的这些操作已经足够,但程序使用后依然存在一个严重问题:程序所有窗口的标题栏右边都有“SKIN++ UNREGISTERED!!!”字样,这样对于一个程序员来说,无异于没做,然而网友gz1X没有将此问题完善。经过调试,终于成功破解,操作步骤如下:

a.在反汇编窗口中右击,出来一个菜单,我们在 查找->所有参考文本字串 上左键点击

b.现在出来另一个对话框,我们在这个对话框里右击,选择“查找文本”菜单项,输入“SKIN++ UNREGISTERED!!!”(注意这里查找内容要区分大小写)来查找,找到一处,位置在 008DACE2.

c.在此行,汇编指令为:push 00920784,这条指令用于将“SKIN++ UNREGISTERED!!!”所在的内存地址传递给子程序,我们只需要将这个地址修改一下就可以改变显示的字符了,这个字符串一共22个字符,压栈的地址最后两位84+22=A6,于是我们将这条指令改为:push 009297A6,保存,退出。

再试试,问题是不是已经解决?

最后编辑:
作者:leehom
本博客主要是把自己的经验记录于此,方便自己以后查阅及其他遇到类似问题的朋友参考。如果你有觉得不错的文章,可以注册会员发布文章或者邮箱发给我文章地址,谢谢!
捐 赠如果觉得文章还不错,请麻烦点下广告,算是赞助下本站服务器费用,谢谢!

留下一个回复