软件简介:数独(SUDUKU):一种数字逻辑游戏,其概念源自[拉丁方块],由18世纪瑞士数学家发明。是国际上流行的一种用来锻炼逻辑思维及策略的工具。目前正在以前所未有的速度在中国大地流传。最近几天稍关注了一下相关软件,发现目前适合国人的有以下三款:完美数独、数独博士、数独终结者。三者各有千秋,本文简要介绍数独终结者2.2Build2633版的限制解除方法。
加密特点:该软件基于.net环境编制,有七天的无限制使用。程序启动时会弹出试用版的提示。超过七天则不能进入主界面。
破解手记:.net环境下的反编译工具主要有Reflector和Xenocode Fox款,两者都很强大,能比较完美的反编译出各类语言的源代码,比较而言,Reflector是免费软件,执行速度较快,而且支持pascal语言的反编译显示。Xenocode Fox 的强项在于其可以显示函数在二进制文件中的偏移量,这点很重要,两者可以结合使用。用Reflector载入isudoku.exe,定位到函数入口处(这是Reflector很实用的功能之一),能看到以下代码:
bool flag;
Preferences.RegistrationStatus = RegistrationStatus.TrialExpired;
string str = "";
string userName = str;
string serialNumber = str;
if (RegistryHelper.ReadRegInfo(ref userName, ref serialNumber))
{
if (RegistrationHelper.VerifyRegistrationCode(serialNumber, userName))
{
goto Label_00D3;
}
flag = false;
}
else
{
flag = false;
}
可见程序启动之后首先就校验注册码,Label_00D3为赋已注册标记处,由于我们需要暴破它,因此我们要让其直接跳转到Label_00D3处,在Reflector中将代码显示IL格式,可以看出上面的代码编译成托管代码如下:
L_000b: ldc.i4.2
L_000c: call void Luckybird.iSudoku.Preferences::set_RegistrationStatus(valuetype Luckybird.iSudoku.RegistrationStatus)
L_0011: ldstr ""
L_0016: stloc.s str
L_0018: ldloc.s str
L_001a: stloc.s str3
L_001c: ldloc.s str
L_001e: stloc.s str2
L_0020: ldloca.s str3
L_0022: ldloca.s str2
L_0024: call bool Luckybird.iSudoku.Utilities.RegistryHelper::ReadRegInfo(string&, string&)
L_0029: stloc.0
L_002a: ldloc.0
L_002b: brfalse.s L_003f
L_002d: ldloc.s str2
L_002f: ldloc.s str3
L_0031: call bool Luckybird.iSudoku.Utilities.RegistrationHelper::VerifyRegistrationCode(string, string)
L_0036: brtrue L_00d3
L_003b: ldc.i4.0
L_003c: stloc.0
L_003d: br.s L_0041
L_003f: ldc.i4.0
L_0040: stloc.0
由于我们没有注册码,则 L_002b: brfalse.s L_003f处肯定会跳过去(相当于执行最外层的else语句),我们的目标就是要让其直接跳至L_00d3处,则可以通过Xenocode Fox 找到该函数所在的位置,用UE定位到该处,将其修改为无条件长转移指令(需注意修改位置,ReadRegInfo语句后的两句为堆栈平衡语句不可覆盖),修改后的代码如下:
L_000b: ldc.i4.2
L_000c: call void Luckybird.iSudoku.Preferences::set_RegistrationStatus(valuetype Luckybird.iSudoku.RegistrationStatus)
L_0011: ldstr ""
L_0016: stloc.s str
L_0018: ldloc.s str
L_001a: stloc.s str3
L_001c: ldloc.s str
L_001e: stloc.s str2
L_0020: ldloca.s str3
L_0022: ldloca.s str2
L_0024: call bool Luckybird.iSudoku.Utilities.RegistryHelper::ReadRegInfo(string&, string&)
L_0029: stloc.0
L_002a: ldloc.0
L_002b: br L_00d3
L_0030: stloc.0
L_0031: call bool Luckybird.iSudoku.Utilities.RegistrationHelper::VerifyRegistrationCode(string, string)
L_0036: brtrue L_00d3
L_003b: ldc.i4.0
L_003c: stloc.0
L_003d: br.s L_0041
L_003f: ldc.i4.0
L_0040: stloc.0
保存退出,发现程序直接提示过期,看来没这么简单。
分析RegistrationStatus可知其为一属性,它指向一枚举类型:
internal enum RegistrationStatus
{
Registered,
Trial,
TrialExpired,
InvalidLicense
}
其读写函数如下:
public static RegistrationStatus RegistrationStatus
{
get
{
return _registrationStatus;
}
set
{
_registrationStatus = value;
}
}
该属性的赋值过程被多次调用,因此比较好的办法就是将其改为如下形式:
public static RegistrationStatus RegistrationStatus
{
get
{
return RegistrationStatus.Registered;
}
set
{
_registrationStatus = RegistrationStatus.Registered;
}
}
保存退出后运行程序没有发现异常。
补充:关于枚举类型的默认值修改可通过分析枚举类型、值的大小,结合枚举名称进行定位修改(本例改后没有效果,仅记录下来供参考),比如枚举中包含int32 abcd=1,则可以先通过搜索abcd定位一次,然后搜索04 01结合其它枚举值进行精确定位(32位整数形赋1是04 01,64位整数开型赋1是08 01)。
软件及破解补丁下载地址:
http://oriface.ys168.com/