前两天同学给我发了个.net编写的cpu优化的程序,由于注册机制无法正常使用,他寻思看我能不能有什么解决办法。以前搞过一些简单的crackme,但对.net程序的机制还很陌生。破解过程当中遇到了很多问题,发个帖子叙述一下具体情况,当中一些遗留问题也希望能得到达人们的指点~
解压后就这些文件,DLLInject是主程序,HID是机器码文件生成用的,那个dll文件至今不知道做什么用的(猜测可能是优化CPU时用到)。直接运行DLLInject会弹出需要注册的对话框。
这种对话框乍看来只有许可证文件存在程序才能正常运行,点击OK程序就退出了。后来才查到这样的验证机制是.net本身提供的System.ComponentModel.LicenseXXX。.net许可证机制提供了框架,具体的许可证校验算法肯定还是作者自己实现的,以配合硬件机器码完成验证。
用Reflector无法正常载入,看来文件还被特意修改过啊,解决方法:http://hi.baidu.com/dreamzgj/blog/item/3c0bc18e243592f0513d928a.html。不过马上又出现了新的错误:Reflector Error:Module '…' contains zero or multiple module definitions。解决方法:http://hi.baidu.com/dreamzgj/blog/item/5cd5f1456fedc388b2b7dc8a.html。都是同一个人写的文章。这回Reflector载入虽然还是提示数组越界的错误(看来还有其他被修改的小地方),名称也都被混淆过(另外用StrongNameRemove根本不能正常载入该程序),但起码可以看个大致结构了,entrypoint函数(S9oGE4FMD)还是无法显示。
其他很多函数内容都是形如下式,都是一些看起来毫无作用的垃圾信息。估计是干扰函数或者是运行时动态修复吧。
用ILDASM把代码导成il形式看入口函数终于能正常查看了,也是为数不多的能看到一些语句的函数(其他函数都是返回个null值就没了)。
.method assembly static void S9oGE4FMD(string[] A_0) cil managed noinlining
{
.entrypoint
.custom instance void [mscorlib]System.STAThreadAttribute::.ctor() = ( 01 00 00 00 )
.custom instance void [System]System.ComponentModel.EditorBrowsableAttribute::.ctor(valuetype [System]System.ComponentModel.EditorBrowsableState) = ( 01 00 02 00 00 00 00 00 )
.custom instance void [mscorlib]System.Diagnostics.DebuggerHiddenAttribute::.ctor() = ( 01 00 00 00 )
// Code size 50 (0x32)
.maxstack 3
IL_0000: br IL_0007
IL_0005: pop
IL_0006: ldc.i4.0
.try
{
IL_0007: call bool [Microsoft.VisualBasic]Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase::get_UseCompatibleTextRendering()
IL_000c: call void [System.Windows.Forms]System.Windows.Forms.Application::SetCompatibleTextRenderingDefault(bool)
IL_0011: ldtoken EIOtYCk427B2j46XCZ.aC4npiTU1ygUa7KS3q
IL_0016: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
IL_001b: call void [System]System.ComponentModel.LicenseManager::Validate(class [mscorlib]System.Type)
IL_0020: leave IL_0026
} // end .try
finally
{
IL_0025: endfinally
} // end handler
IL_0026: call class EIOtYCk427B2j46XCZ.aC4npiTU1ygUa7KS3q usJHEvC4iTtNdZDPye.bhVRye8yqVI1niw4o6::vaCk4npiU()
IL_002b: ldarg.0
IL_002c: callvirt instance void [Microsoft.VisualBasic]Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase::Run(string[])
IL_0031: ret
} // end of method aC4npiTU1ygUa7KS3q::S9oGE4FMD
无奈还是直接把validate函数去掉试试吧,不过得直接在二进制文件上改(ILDASM导出的xx.il文件用ILASM虽然编译成功但执行时会弹出错误)。用IDA打开exe文件,找到两个函数的调用字节码的文件偏移,再用ultraedit打开exe填写0x00(nop)覆盖对应位置。不过执行后还是会弹出许可证那个窗口,看来程序在运行中还多次调用了Validate函数,静态找不到其他的调用迹象,动态又不太顺利。
用DotNet_Id的查了一下壳,天啊,原来是加过壳啊,难怪分析起来这么费劲呢。
http://jithook.blogspot.com上面提供了各个版本的MaxToCode的脱壳工具,最新版本是RE-MaxV3.40。MaxToCode加壳后,会生成一个dll文件随着exe文件一起在运行时提供支持,脱壳工具要载入dll后才能脱壳。不过这个DLLInject.exe配的pe.dll看来并不是这个MaxToCode壳用的dll(删了该dll,DLLInject.exe也能正常运行)。MaxToCode支持把dll融入到exe中,如果它真的是加了MaxToCode的话那一定是融合了,但没有找到提取方法。看来之前载入错误,编译后不能运行都是这个壳导致的。
突发奇想,我寻思想改掉System.ComponentModel.LicenseManager下验证函数本身应该就能绕过了吧。
先从Validate函数开始改起吧,两个版本的都要处理一下。ret字节码0x2a。在C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\system.dll文件的相应偏移位置找到对应字节码修理一下。
改前:
改后:
由于第二个版本的Validate有返回值(类型为License)所以在返回前要在把一个license放到堆栈上,再ret。
执行程序仍旧弹框框,可问题是删掉system.dll还是弹框框!难道程序没有依赖system.dll吗!用Filemon监视了一下程序执行时访问文件的情况才发现,原来程序加载用的system.dll并不是c:\windows\Microsoft.net\...目录下的system.dll而是C:\WINDOWS\assembly\GAC_MSIL\System\2.0.0.0__b77a5c561934e089\ system.dll。
这样就把改好的dll替换一下,再运行程序,发现其他函数isvalid等已经不用改了,程序已经不会被那个许可证困扰了。
这回算是正常运行了吧(这点还真不敢确认,程序没发现有什么功能,该不会是和许可证有关吧),还有那个pe.dll的谜团都有待解开~希望哪位知道的话提示一下~总觉得改了系统的system.dll好像很不妥的方法,似乎绕过了验证。
- 标 题:修改System.dll绕过.net的License
- 作 者:txstc
- 时 间:2011-03-01 23:38:03
- 链 接:http://bbs.pediy.com/showthread.php?t=130183
代码: