.Net中的泛型和C++中的模版很相似,但在编译行为上有些不同。
之前做DNGuard HVM 时就遇到了加密泛型的麻烦问题,最近又发现了泛型在 ngen 加强保护模式下也有问题,在。Net解密中它同样也是一个麻烦。
C++中的模版在编译时就生成了实例代码,出现代码膨胀。
.Net的泛型,在编译时只会生成一份MSIL代码,然后在运行时才会出现实例代码。
泛型方法的编译过程和普通方法相比,多了泛型参数的构造和传递以及使用泛型参数构造父类型。
加密处理过程中不能忽略泛型参数,必须把泛型参数也纳入处理范围才行。
处理泛型参数还需要注意参数个数,之前因为没有考虑这个问题,引入了一个隐患。
不过如果你能确定泛型参数不会超过126个那也可以不用考虑。
ni 加强保护模式下泛型的问题,因为泛型代码是在运行时生成实例代码的,
如果对泛型使用反射的话,就有可能导致 Jit 请求的发生,这时就会出现问题。
泛型在解密脱壳中也有一些麻烦。
昨天晚上 tankaiha 告诉我,tracky 找到 一dotNet加密壳 的 vm unpacker。
在国外网站 http://www.tuts4you.com/download.php?list.55 上面有一些 UnpackMe (.NET) 的例程。
我就拿这里的例程测试这个 unpcaker的效果。怎么形容呢?有点像段誉的一阳指。
分析了一下实现原理,它是通过在Jit安装钩子拦截代码的方式做的,拦截的函数是
JitNativeCode 函数。分析了一下它方法体重构的代码,使用的是偷懒的方式(目前加密壳Jit层的一个漏洞)。
从它拦截的位置来看,对maxtocode企业版无害,位置靠前了。
从它方法体重构的代码看,对DNGuard HVM 标准版无害,构造不出正确的方法体。
我比较感兴趣的是它实现主动Jit请求的方法,我在它里面注入了一个Dll,拦截在Jit底层,用来记录哪些方法进入了Jit编译过程。
在测试了几个样例后发现一个问题,记录的的方法中没有一个是泛型的方法,样例中有几个里面是使用了泛型的。
跟踪它的主程序,发现有一处好像是调用了判断是否泛型方法的,然后就jmp跳过了。
把它nop掉后再试,还是没有记录到 泛型方法。
跟踪进去发现是出现了 初始化类型 的异常。看来泛型在脱壳中也是一个麻烦。
曾经有朋友跟我抱怨之前因为 泛型无法加密,他把所有使用泛型的地方都改成不用泛型了。现在用DNGuard能加密泛型了,他又想要再改回去。
其实写代码该怎么用就怎么用,没有必要因为加密的问题影响程序设计。
就像现在,也没有必要因为泛型的脱壳中还存在麻烦,就乱用泛型。
现在技术基本上是透明的,泛型的问题也应该只是早和晚的区别了。