.Net Jit层脱壳机的实现原理

简介: 本文将在 .Net 反射脱壳机核心源代码 的基础上介绍,如何实现 Jit层脱壳 机。首先我们选择使用 C++/CLI 来完成这个工作。反射部分需要用到 。Net的相关类库,jit 层 hook 需要使用native c++ 方面的功能。
本文将在 .Net 反射脱壳机核心源代码 的基础上介绍,如何实现 Jit层脱壳 机。

首先我们选择使用 C++/CLI 来完成这个工作。反射部分需要用到 。Net的相关类库,jit 层 hook 需要使用native c++ 方面的功能。
本文假设您已经完成了 hook jit的工作,并截获到了相关结构体。

首先介绍一下代码主要流程:
入口函数
void DumpAssembly(Assembly ass,string path)
枚举所有type,调用
void DumpType(Type tp, BinaryWriter sw)
枚举所有方法,调用
void DumpMethod(MethodBase mb, BinaryWriter sw)

和反射脱壳机不一样的地方就是  最后这个函数 DumpMethod 其它的都基本上一样。

先看反射脱壳的实现:
void DumpMethod(MethodBase mb, BinaryWriter sw)
{
MethodBody mbd = mb.GetMethodBody();
if (mbd == null)
return;
SetOffset(sw, mb.MetadataToken);

WriteHeader(sw, mbd);

WriteILCode(sw, mbd);

WriteSEH(sw, mbd);

}
从上可以看出,dump一个method需要知道4个东西,token,方法头,ILCode,SEH。

jit层脱壳,这个怎么实现呢?
DumpMethod函数只需要 invoke方法,让其进入jit处理过程即可。
这里需要注意一点:
方法是private的,外界无法访问,怎么办?

这里我需要用到 net 2.0的又一个新特性:DynamicMethod 。
看msdn的介绍:
"可以使用 DynamicMethod 类在运行时生成和执行方法,而不必生成动态程序集和动态类型来包含该方法。动态方法是生成和执行少量代码的最有效方式。

动态方法在逻辑上与模块或类型关联。如果与模块关联,动态方法对于该模块在全局范围内有效。如果有足够的权限,动态方法可以跳过实时 (JIT) 可见性检查,访问在该模块中所声明类型的私有数据。可以将动态方法与任何模块关联,无论该模块是否由您创建。

如果动态方法与类型关联,动态方法可以访问该类型的私有成员。除非动态方法需要访问在同一模块中声明的其他类型的私有数据,否则无需跳过 JIT 可见性检查。可以将动态方法与任何类型关联。
"
动态方法可以跳过 jit 可见性检查。这是我们最关心的。通过它我们解决的private方法的问题。

和反射脱壳相比,jit层脱壳真正的DumpMethod 应该是在 hook处理函数中。
即在 hook 到一个jit请求后,回调真正的 DumpMethod 实现来完成 一个方法体的脱壳。

问题:怎么知道当前jit处理的是哪个方法体呢?

"

MethodBase.GetMethodFromHandle (RuntimeMethodHandle) 通过使用方法的内部元数据表示形式(句柄)获取方法信息。

"
这个函数可以解决这个问题。
传入的参数,就是我们在 jit hook中截获的 MethodDesc* 的指针变量。这个结构体在sscli里面是没有其明确资料的。但是它可以通过这个函数转换为 。Net中的 Method对象。

这样前面提到的dump一个方法体需要的 4个东西,这里就知道了两个了, token 和 ILCode(jit hook直接取得的)。

如果是tiny method。方法体也可以重构出来了。之前介绍反射重构的帖子中又详细介绍。

如果是fat method呢?
有两个难点:
1。方法头 中的localsig 的token。 2。SeH 的重构。
完全从jit hook到的结构体中重构需要费一番周折,有可能会和壳的实现相关。
对于有些加密壳,可以通过投机的方式取得这两个东西。(因目前国内某壳也受此影响,在其新版改进之前,暂不公开这个方式)

单纯jit层的加密壳可以从这两点,增加脱壳的难度。

DNGuard 标准版对这两部分做了特许处理。
标准版预计在一个星期内完成。演示版RC1已经基本完成,近两天就会发布。

DNGuard 专业版,除了对这两个的处理,对ILCode也进行了处理,标准版发布后,
需要再花时间对 专业版 IL模拟部分 进行一次全面的检测。

目录
相关文章
|
.NET
一起谈.NET技术,ASP.NET的地址重写(URLRewriter)实现原理及代码示例
  一、概述   访问者输入:http://wu-jian.cnbolgs.com/default.aspx,实际请求和响应的地址却是:http://www.cnblogs.com/wu-jian/default.aspx, 这就是UrlRewrite,除了实现二级域名功能,它在简化用户输入地址、SEO、网站版本迭代更新等多个方面发挥着重要作用。
1093 0
|
调度 C#
一起谈.NET技术,【经验总结】C#常用线程同步方法应用场景和实现原理
  简单描述volatile,Interlocked,lock,Mutex,Semaphore,Spin lock,AutoResetEvent,ManualResetEvent,ReaderWriterLockSlim,MethodImplAttribute,WaitHandle常用同步机制的原理和使用场景。
1262 0
|
.NET
ASP.NET的地址重写“.NET研究”(URLRewriter)实现原理及代码示例
  一、概述   访问者输入:http://wu-jian.cnbolgs.com/default.aspx,实际请求和响应的地址却是:http://www.cnblogs.com/wu-jian/default.aspx, 这就是UrlRewrite,除了实现二级域名功能,它在简化用户输入地址、SEO、网站版本迭代更新等多个方面发挥着重要作用。
788 0
|
调度 C#
【经验总结】C#常用线程同“.NET研究”步方法应用场景和实现原理
  简单描述volatile,Interlocked,lock,Mutex,Semaphore,Spin lock,AutoResetEvent,ManualResetEvent,ReaderWriterLockSlim,MethodImplAttribute,WaitHandle常用同步机制的原理和使用场景。
1355 0
|
开发框架 .NET 编译器
.NET中可空值类型实现原理
为了让.Net中的值类型可以赋值为null,微软特地添加了Nullable类型,也可简写为T?。但是Nullable自身是结构体,也是值类型,那么它是如何实现将null赋值给值类型的呢? 下面通过自定义一个可空值类型来讲解Nullable的实现原理。
883 0
|
API Windows
.Net 虚拟框架的实现原理
.Net 虚拟框架的实现原理 前面介绍了利用第三方虚拟环境来实现 .Net程序脱离框架运行, 并介绍了如何自己编写加载器程序。 今回我们介绍虚拟框架的核心实现原理,感兴趣的朋友可以参考自己实现。 在 让 .Net 程序 脱离 .net framework框架 运行(源代码实现说明)  中我们介绍的脱 离框架运行的方法,仍然需要依赖 rsdeploy.dll 才行。
848 0
|
数据安全/隐私保护
.Net 加密原理,HVM核心的实现原理(八)
目前加密壳将核心转移到Jit层后,内核模式的强度增加空间已经很小了。目前市面上的加密壳至少有一个共同的缺陷,无法防止Jit底层截获IL字节码。 有些壳采用从周边增加强度(如 Anti Hook),由于hook的多样性再加上壳又需要考虑自己的兼容性,所以这个效果不是十分理想。
1204 0
.Net 反射脱壳机核心源代码
using System;using System.Collections.Generic;using System.Text;using System.Reflection;using System.
839 0