起因
最近在对接一个第三方平台。该平台只提供了Java版本的SDK,C#版本的还处于敬请期待状态。由于C#可以复用绝大部分代码,便考虑找一个Java到C#的转换器,在试用了几个软件之后,发现还是Java to C# Converter(下文简称Converter)好用一点。然而基本版功能受限(文件夹不能超过1000行代码,代码片段不能超过100行),高级版的则要$169。
在经历过自己写小程序转换Java、手写代码、利用Converter分批次转换、查找替换等方式完成C#版本之后。终于按捺不住心中的好奇心,研究了下软件的破解。
希望
首先看看这个软件是不是C#写的,将文件拖入ILSpy,一看之下,果然有惊喜。
嗯,惊喜就是虽然该软件是利用C#+WinForm写成的,但是很明显的经过了混淆。吓得我赶忙利用ILSpy的Save Code功能将其保存为工程文件。看能不能重新编译成可执行程序。
失望
首先试试双击工程文件,VS没反应。换用dotPeek依然如此。
然后新建工程,将项目添加到工程中,一大堆错误,无外乎是变量名不正确。换用dotPeek依然如此。如果时间充足的话,可以细心研读代码,修复错误,重新编译。一来错误太多、二来我也不想花太多时间在读代码上面、三来我的目的不在这上面。于是果断放弃该方式。
新希望
思路
我们知道,C#程序是编译成IL的,恰好我知道Reflexil可以直接编辑IL。上Reflexil官网一看,现在也支持ILSpy(以前我以为只支持Reflector),那就直接在ILSpy中改写IL。
查找编辑位置
要编辑IL的话,关键是要找对地方。软件未注册的话,好多时候都会弹出一个对话框,Converter也与此类似。
直接在VS中查找相应的字符串,如最开始的The Free Edtion of。经过简单分析后不难看出_g22.cs正是我们要找的地方。
internal static bool _g41(List<string> Copyright_Tangible_Software_Solutions_p0)
{
if (_g22._g24 == _g3.FreeEdition)
{
if (_g22._m21 != 100)
{
Copyright_Tangible_Software_Solutions_g810._g844(Copyright_Tangible_Software_Solutions_g810._g843);
return false;
}
if (Copyright_Tangible_Software_Solutions_p0 == null)
{
return true;
}
int num = 0;
for (int i = 0; i < Copyright_Tangible_Software_Solutions_p0.Count; i++)
{
if (Copyright_Tangible_Software_Solutions_p0[i].Trim().Length > 0 && !Copyright_Tangible_Software_Solutions_p0[i].TrimStart(new char[0])._g1079("//"))
{
num++;
if (num > _g22._m21)
{
new _g376(string.Concat(new string[]
{
"The Free Edition of ",
Application.ProductName,
" doesn't allow conversion of snippets with more than ",
_g22._m21.ToString(),
" lines at a time."
}));
return false;
}
}
}
}
return true;
}
下面还有两个函数,_g42和_g43形式与此类似,_g42应该是文件夹的许可,_g43不知道是做什么的。从函数的代码上看,感觉直接将返回值改成true就好了。不管那么多,先来试试改写_g41。
准备工作
在网站上下了reflexil.for.ILSpy.2.0.AIO(我愣了下才反应过来AIO是All In One的意思),解压后将里面的DLL复制到ILSpy目录下。打开ILSpy(如果ILSpy复制前是打开,则需重启),在View中点击Reflexil v2.0,然后在ILSpy中打开Converter的可执行文件,找到_g22类中的_g41函数。如下图所示:
Instructions标签页就是进行IL编辑操作的地方。虽然在Reflexil中可以直接编辑源码:在Instructions标签页的表格中选择Replace all with code,在弹出的窗口中编辑源码。但是在Converter中默认的代码方法体无任何内容,而且Complie也会访问错误(虽然并没有错误)。于是果断放弃这种方式。
编辑IL
编辑IL还有一个问题就是我们要将IL改变成什么样。在本例中就是return true对应的IL是什么 。这个问题说难也难,说简单也简单。只要我们在VS中编写一段同样的代码,生成后在ILSpy中以IL方式查看即可。
C#形式的代码
IL形式的代码
接下来就是将Instructions标签页表格中的IL改为与上图的IL一样。整个过程很简单,删除、添加、修改,只要保持指令与目标一致。值得一提的是,总共6条指令(nop将就留下吧),只有第4条有操作数,可将其最后添加。因为是跳转语句,需要在Operand type中选择Instruction reference,然后在Operand选择要跳转的指令位置。
大功告成
在ILSpy中Converter可执行文件上单击右键,在弹出的右键菜单中选择Save As,保存好文件(可以对Converter原文件作好备份后直接覆盖)。验证后发现针对代码片段的限制确实失效了。
如果对_g42和_g43也如法炮制,就会发现针对文件夹的限制也会失效。
结语
我是抱着研究学习的态度来尝试破解的,破解之后也没有作其他用途。本着跟大家沟通交流的初衷将这个过程写下来,请各位多多赐教,同时,也希望大家多支持正版。
然而我辛辛苦苦作出的C#版本最终一点用都没派上,这真是一个温暖人心的结局。