在此先对被破解的软件作者致以深深的歉意,你的程序很好,只可惜WP7不支持支付宝付款,要不就直接购买了。本次破解只为了自己个人使用,没有对外发布。
也算不上什么真正的破解,因为本人对IL还是一个模糊的阶段,对里面的东西还不了解,所以本次破解也是一个生搬硬套的过程。
前几天为了给人机交互课上的报告做准备,就下了一个软件便于演示。这款软件不太大,可是功能真的很丰富实用。这里就不方便说出这款软件的名字了。
先介绍一些用到的工具吧。
1、Windows Phone Power Tools
2、Reflector + Reflexil插件
3、ILSpy
4、Ildasm
5、ilasm
6、notepad++(平时用习惯了)
里面有个功能,只提供一次试用,第二次使用就提示购买了。把程序卸了再重新部署,发现可以再次试用,由此可以判断试用次数是保存在程序独立存储里面,而不是电脑服务器记录deviceid。找到入口点了。
尝试一:
1、部署完成后,使用一次,打开WP Power Tools,找到对应的程序,用文本编辑器先打开_ApplicationSetting文件,查看里面键值。发现里面基本上都是程序的一些配置,这时候发现下面这个键值。根据英文翻译,大概可以猜出这个就是要处理的。
2、是int类型,尝试把value改成0,保存。发现程序可以再次使用该功能。
3、刷新程序目录,重新打开_ApplicationSetting,发现该键值又变成了1,由此可以初步断定程序在启动的时候判断该值是否为1,如果是,则提示购买。否则做++处理。
4、尝试“温和”欺骗,把value改为-10,根据步骤3猜想,这样可以使用10次,保存后打开程序。发现还是提示购买。
5、由此可以判断程序启动时候判断该键值value是否为1,不为1则直接改成1.
看样子欺骗性使用失败了。
尝试二:
有了第一步的失败,决定先看看程序的代码。
1、解压程序的xap包,发现有多个dll,有一个名为XXX.Utilities.dll 的库,用reflector打开,发现代码未做混淆,大喜。
2、发现一个名为AppSettings的类,打开查看代码。
3、代码已经很直观了,可是这种命名方式真的很蛋疼(虽然只有2个变量,原谅本人的强迫症),于是使用ILSpy打开该dll,这下就感觉直观多了。
4、在reflector中【Tools】-【Reflexil】,选中TryGetValueWithDefault方法,这时候Reflexil可以显示这段代码的IL。因为本人对IL没什么基础,所以感觉很蛋疼。这时候脑子里只有个思路,就是判断key是否为EverConnected,如果是则返回0.这样就可以继续使用程序的功能了。
5、上网补了一下IL,发现还是没有头绪。这时候突然想起来,直接建一个类库工程然后编写相同的代码编译后不就行了,于是打开VS,新建了一个Windows Phone Class Library项目,源程序的代码写下了下面代码
using System;using System.IO.IsolatedStorage;namespace XXX.Utilities{ public static class AppSettings { private static IsolatedStorageSettings appSettings = IsolatedStorageSettings.ApplicationSettings; public static void Set(string key, object value) { try { AppSettings.appSettings[key] = value; AppSettings.appSettings.Save(); } catch { } } public static TValue TryGetValueWithDefault(string key, TValue defaultValue) { TValue result = defaultValue; if (AppSettings.ContainsKey(key)) { object obj = AppSettings.appSettings[key]; if (obj is TValue) { result = (TValue)((object)obj); } } return result; } public static bool ContainsKey(string key) { return AppSettings.appSettings.Contains(key); } }}
6、编译后,提取dll,使用ILDasm查看IL代码,对比Utilities对应的方法,发现IL是一致的。于是失落的心里又燃气了火焰。
7、直接修改新建的工程里面代码
public static TValue TryGetValueWithDefault(string key, TValue defaultValue) { TValue result = defaultValue; if (AppSettings.ContainsKey(key)) { object obj = AppSettings.appSettings[key]; if (obj is TValue) { if (key == "EverConnected") result = (TValue)((object)0); else result = (TValue)((object)obj); } } return result; }
8、编译后,再次用ILdasm打开dll,对比Utilities对应的IL,使用Reflexil修改IL,都修改完后保存,这时候Reflector直接把dll的“源码”和Resources文件给保存到了磁盘上,发现直接编译保存的工程,需要引用其它类库,比较麻烦。
尝试三:
上面步骤也基本上告以失败,从网上查到资料,直接使用ilasm就可以直接编译了。
1、使用ILdasm打开Utilities DLL,点击【File】-【Dump】,即可将IL文件保存到磁盘,有时候还会附属Resources文件
2、用记事本打开il文件,找到对应的方法,替换对应的IL,如果方法过多的话,可以直接查找方法名称。
3、保存il文件。
4、使用控制台进入il文件路劲,然后执行下面命令
5、回车后即会进行编译,几秒后会提示操作成功。此时目录下会多一个dll文件。
6、将生成的dll放到解压后的xap目录下,替换原来的XXX.Utilities.dll,压缩文件夹,修改扩展名为xap,然后部署到手机上测试。
7、部署成功后,进入程序,操作没有反映,过了代码8秒左右程序异常退出,再次进入还是如此。通过错误信息发现是keynotfoundException,分析代码,无果。
8、只好从其它方法再次入手,重新部署程序,直接查看_ApplicationSetting,发现没有EverConnected键,再次判断程序第一次是通过判断是否存在EverConnected来初始化,接着修改下面代码
public static bool ContainsKey(string key) { if (key == "EverConnected") return false; else return AppSettings.appSettings.Contains(key); }
9、重试第二步,再次部署,bingo~
=============================华丽的分割线===================================
这次破解技术上并没有什么高深的,只能通过“雕虫小技”来实现修改IL,希望以后可以更加深入学习。
希望通过这次经验,能重拾自己的激情,为下学期校招找到一个好工作再次努力!
最后再次对程序作者致以深深的歉意。