您的位置:首页 > 编程语言

mscorwks.dll在.net中的地位以及在.net代码保护方面的应...

2008-03-14 02:05 232 查看
mscorwks.dll是dotnet的核心文件,尤其是在net2.0中,以前分散的功能都集中到了这个dll中。

net1.1中,还有一个文件mscorsvr.dll 和 mscorwks.dll 是同等地位的。

它们分别对应于 windows service程序以及 desktop 程序。

在net2.0中,它们都统一到了 mscorwks。dll中。

同时在net2.0中mscorsn.dll 的功能也合并到了 mscorwks.dll中。

它就是dotnet运行库的核心。

dotnet的执行引擎(ee),内部对象的实现都在这个dll里面。

在我们用reflector查看dotnet类库源代码时经常会遇到一些函数看不到源代码,只是标记成内部实现。这些函数基本上实际实现的代码就在这个dll里面,是native实现的。如反射功能的相关对象以及实现就是这里面。

net程序的执行主要由它来完成,还有另外一个重要的文件mscorjit.dll 被它所调用。

现在我们把 mscorwks.dll 分成两个区 a 和 b,

a 是主要执行引擎(ee)和native 实现。

b 是ee调用jit的处理部分。

net2.0的反射功能是在a区实现的。加密壳如果要实现完美的兼容性(即不破坏dotnet本身的任何功能和特性)就应该在 a 区挂入其内核。

在a区有一个函数实现获取方法体的内容,ee层需要取得方法体内容是通过这个函数来获得的。因此完美的方法就是 替换这个函数,用加密壳的内核实现这个函数。

这样的最大缺点就是反射漏洞,因为反射也是调用这个函数取得方法体的。

在这个基础上要要破坏反射有什么办法呢?

在反射是需要调用method的成员函数getmethodbody,这个函数是native实现的,就在mscorwks。dll中,因此加密壳可以hook这个函数做一些预防处理。

但是效果不理想,破解者可以恢复这个函数的原始实现。

还有一个方法,不是完美,但是有效,即不直接替换获取方法体的函数,

而是只替换编译前获取方法体的地方。这样只在要编译方法时才提供内核解密服务。

效果如何?也不太理想,破解这可以修改反射的实现函数,直接jmp到加密壳的内核服务。

这种方式就是dnguard v1.0采用的方法,似乎也是某壳目前版本的方法。

当然,dnguard 1.0还简单的加入了放内存修改,不过这个效果也能太乐观,破解者也能够把这部分屏蔽掉。

因为反射在a区实现,如果壳的内核也挂接a区,反射就比较容易修复。

在我做dnguard 2.0之前,我曾想过一种方法,能使反射无效,甚至难于修复。

即同时在内核挂接在 a 区,和 b区。

先来介绍一下一个函数要被执行是是怎么个流程。

首先,ee会检查函数是否编译?编译了就直接调用了。没有编译就进行编译。由一个prestub实现。

然后ee取得方法体,对方法头和seh table进行简单解析,转换成结构。

(这些在a区完成),进入b区调用jit进行编译。

在a区ee只关系方法头和sehtable,而b区调用jit时 il字节码才有实际意义。

所以可以将内核分别挂接这两个区,a区中只提供header和seh,b区中提供il字节码。

不过在我开始做dnguard v2.0后就放弃了这个想法,因为这样还是不安全。

参考这里:深入jit,实现dotnet代码的加解密

不管内核是在a区还是b区,如果一个加密壳的内核只限于在mscorwks.dll进行挂接实现。那么都无法脱逃 jit层脱壳机的脱壳。我在写文章“深入jit,实现dotnet代码的加解密 ”时已经进行过测试了。

今回到这里,下回介绍mscorjit。dll。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: