mscorwks
dll是dotNet的核心文件
尤其是在net
中
以前分散的功能都集中到了这个dll中
net中还有一个文件mscorsvrdll 和 mscorwksdll 是同等地位的
它们分别对应于 windows service程序以及 desktop 程序
在net中它们都统一到了 mscorwksdll中
同时在net中mscorsndll 的功能也合并到了 mscorwksdll中
它就是dotnet运行库的核心
DotNet的执行引擎(ee)内部对象的实现都在这个dll里面
在我们用reflector查看dotnet类库源代码时经常会遇到一些函数看不到源代码只是标记成内部实现这些函数基本上实际实现的代码就在这个dll里面是native实现的如反射功能的相关对象以及实现就是这里面
net程序的执行主要由它来完成还有另外一个重要的文件mscorjitdll 被它所调用
现在我们把 mscorwksdll 分成两个区 A 和 B
A 是主要执行引擎(ee)和native 实现
B 是ee调用jit的处理部分
net的反射功能是在A区实现的加密壳如果要实现完美的兼容性(即不破坏DotNet本身的任何功能和特性)就应该在 A 区挂入其内核
在A区有一个函数实现获取方法体的内容ee层需要取得方法体内容是通过这个函数来获得的因此完美的方法就是 替换这个函数用加密壳的内核实现这个函数
这样的最大缺点就是反射漏洞因为反射也是调用这个函数取得方法体的
在这个基础上要要破坏反射有什么办法呢?
在反射是需要调用Method的成员函数GetMethodBody这个函数是native实现的就在mscorwksdll中因此加密壳可以hook这个函数做一些预防处理
但是效果不理想破解者可以恢复这个函数的原始实现
还有一个方法不是完美但是有效即不直接替换获取方法体的函数
而是只替换编译前获取方法体的地方这样只在要编译方法时才提供内核解密服务
效果如何?也不太理想破解这可以修改反射的实现函数直接jmp到加密壳的内核服务
这种方式就是DNGuard v采用的方法似乎也是某壳目前版本的方法
当然DNGuard 还简单的加入了放内存修改不过这个效果也能太乐观破解者也能够把这部分屏蔽掉
因为反射在A区实现如果壳的内核也挂接A区反射就比较容易修复
在我做DNGuard 之前我曾想过一种方法能使反射无效甚至难于修复
即同时在内核挂接在 A 区和 B区
先来介绍一下一个函数要被执行是是怎么个流程
首先EE会检查函数是否编译?编译了就直接调用了没有编译就进行编译由一个prestub实现
然后EE取得方法体对方法头和SEH TAble进行简单解析转换成结构
(这些在A区完成)进入B区调用Jit进行编译
在A区ee只关系方法头和sehtable而B区调用jit时 il字节码才有实际意义
所以可以将内核分别挂接这两个区A区中只提供header和sehB区中提供il字节码
不过在我开始做DNGuard v后就放弃了这个想法因为这样还是不安全
参考这里深入Jit实现dotNet代码的加解密
不管内核是在A区还是B区如果一个加密壳的内核只限于在mscorwksdll进行挂接实现那么都无法脱逃 jit层脱壳机的脱壳我在写文章深入Jit实现dotNet代码的加解密 时已经进行过测试了
今回到这里下回介绍mscorjitdll