[转]某皮肤控件破解手记
http://www.rainsts.net/article.asp?id=683
.NET Reactor 花里胡哨的界面使用了一套国产的皮肤控件…… 老实说,这套控件做得非常不错,只是其安全措施太弱了。本文只是一个简单的破解记录,并不提供任何破解后的文件。当使用未注册版本时,会弹出如下提示框。
所谓注册,也就是将注册序列号写到 SkinEngine.SerialNumber 属性中。晕~~~~ 居然留下如此明显的破解入口。首先用 Reflector 打开控件 DLL 文件,很显然使用 XenoCode 做过混淆,还好没有 CodeVeil 那样的 Native Shell。
分析 SerialNumber 会被哪些方法调用。
跳转到 xa427f1b2281f554b,很显然我们要 "对付" 的目标就是下面这些代码。
internal xa427f1b2281f554b(IntPtr handle, SkinEngine engine) : base(handle, engine) { // ... if ((SkinEngine.Random % 0xc350) == 0) { try { if (x448fd9ab43628c71.x1c12011307e0a753.Contains(base.xdc87e2b99332cd4a.SerialNumber.Trim())) { x448fd9ab43628c71.xf4f948f95d7023bb(); } if (!SkinEngine.DSA.VerifyData(SkinEngine.DSAHash, Convert.FromBase64String(base.xdc87e2b99332cd4a.SerialNumber))) { x448fd9ab43628c71.xf4f948f95d7023bb(); } } catch { x448fd9ab43628c71.xf4f948f95d7023bb(); } } }
x448fd9ab43628c71.xf4f948f95d7023bb() 的作用是弹出我们前面提到的那个对话框。接下来要做的其实很简单,要么在 "if ((SkinEngine.Random % 0xc350) == 0)" 之前终止该方法,要么修改这个判断表达式,当然还可以修改 SkinEngine.Random 的返回值。
d:\temp> ildasm.exe xxxxx.dll /out=test.il
柿子捡软的捏,我们直接修改 SkinEngine.get_Raindom()。一来可以让判断表达式不成立,二来避免 SkinEngine.Random 里面有其他的 "花活"。
.method assembly hidebysig specialname static int32 get_Random() cil managed { // Code size 59 (0x3b) .maxstack 3 .locals init (int32 V_0) ldc.i4 0xc351 ret // ... }
最后当然是重新编译回去了。(别忘了去掉 .publickey)
d:\temp> ilasm.exe /dll /optimize /res=xxx.res /out=xxx.dll test.il
重新编译测试代码,证实破解有效。