posts - 4, comments - 116, trackbacks - 0, articles - 0
  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理

初步研究 DNGuard HVM 2007 软件

Posted on 2007-08-28 16:46 Aplo 阅读(2670) 评论(24)  编辑 收藏 所属分类: 破解

我一直很关注瑞克的博客,自从他已开始发布dotnet保护文章开始,因为我也很关注这方面的技术。毕竟是BCG的成员嘛,哈哈哈,看到瑞克终于把 DNGuard HVM 推出,于是就小试一把。看看他把自己的软件说的很棒,到底做到什么保护程度。

不过由于时间有限,我只研究了一个开头,不过我会继续向下深入的分析的。

废话少说,言归正传:

拿到 DNGuard HVM 2007 (可能是使用版,具体给问瑞克了,我是从他bbs上下载的,他说标准版和专业版不提供下载,我也没有办法了)

首先,dotnet实现即时编译是通过mscorjit.dll实现的。其提供一个导出函数getJit,就可以得到FJitCompiler对象的地址,该对象是Singleton模式。无论你调用多少回只会返回一个对象实例。该对象实现了ICorJitCompiler接口,可以进行对dotnet程序即时编译。

DNGuard HVM 的做法是将 mscorjit.dll 中导出函数 getJit 修改,直接跳转他的运行环境 HVMRuntm.dll 0x600085D0 地址,

0x600085D0    mov  eax,0x6001FEE4
                         ret

这样在执行完 getJit 就会返回 0x6001FEE4 地址,这个地址是 DNGuard HVM 实现的一个即时编译对象的地址,当然他也是继承了ICorJitCompiler接口,并实现了compileMethod 虚函数。这样我们就可以通过虚函数表找到这个函数地址。

这里是虚函数表:
0x600188B4   ==>   0x60008AD0
                                 0x60008AE0
                                 0x60008AF0

其中0x60008AD0 就是 compileMethod 虚函数的函数地址。具体内容如下:

0x60008AD0      mov  eax, [0x60021934]
                           mov  ecx, [eax]
                           mov  [esp+04],  eax
                           mov  eax,  [ecx]
                           jmp  eax

这里是什么意思呢?
哈哈哈,我来解释一下:

mov  eax, [0x60021934]          [0x60021934]内存的内容就是 0x790AF70

0x790AF70这个就是微软实现即时编译对象的地址。它将原来 getJit 本该返回的对象地址传给eax,然后

mov  ecx, [eax]

这条语句就可以得到原对象的虚函数表。

mov  eax,  [ecx]

接着获取原对象实现的 compileMethod 虚函数。

jmp  eax

最后执行它。虽然我们有执行回原有对象,可是你别小看它,为什么呢?
DNGuard HVM 2007 将原有对象的虚函数表替换了, compileMethod 虚函数的地址现在变成了 HVMRuntm.dll库中的0x60008B00,这就是HVMRuntm.dll实现的解密函数地址,进行IL解密。

我猜想,可能是瑞克先写的解密函数,然后再写的即时编译对象,否则干什么这么麻烦,跳来跳去的,哈哈哈,(To:瑞克,不知道我说的对不对?)

由于时间关系,我没有跟踪HVMRuntm.dll库中的0x60008B00解密函数,不过下回会继续,也希望给研究 DNGuard HVM 2007 的人有所帮助。

今天就写到这里了。

我的Email是dreamvoice@21cn.com 有机会大家可以切磋一下,BCG万岁~~~~!也祝大家网安啦~~~~!

Feedback

#1楼    回复  引用  查看    

2007-08-28 17:03 by jeffersyuan      
一群反编译的牛人呀,看到汇编就昏了。

#2楼    回复  引用    

2007-08-28 17:10 by 安全人士 [未注册用户]
出来混得迟早要还,软件也是如此,没有哪个厉害,哪个不厉害,只要出来就会有人破解。

所以说做人低调点好,不要指责他人~~~~

#3楼    回复  引用  查看    

2007-08-28 17:30 by 瑞克      
这个只是试用版的,IL字节码没有加密,只是挪了位置,在发布试用版是就明确说过了的。
另外试用版对局部变量签名和异常处理表也没有进行特许保护。

另外你说的那个跳来跳出是为另外一个功能准备的。


#4楼 [楼主]   回复  引用  查看    

2007-08-28 17:39 by Aplo      
to:瑞克

我只是想研究一下 DNGuard HVM 2007 的保护方法(很多方法本身就有缺陷),这和加密不加密IL没有关系。

如果我能有一个正式版研究研究就好了。拿试用版研究没什么意思,但我又不想买,唉~~~~希望过一段时间网上放出正式版能够拿到一份就好了。

哈哈哈,大家一起交流一下嘛 :)

#5楼    回复  引用  查看    

2007-08-28 17:41 by rufus      
@Aplo , 我也看过 DNGuard HVM 2007, 佩服你的分析啊,多写点吧

他在程序里调用了 ISIL 和 GetMethodRID

然后比对后找到真实的 MSIL Address 输出 , 在他最后转入 mscorjit 的时候就已经有了,而且是成堆的明文

呵呵,本人早就注册了,但一直未发贴,今天处女回贴就留在这里了.荣信一下吧.
我也对破解感兴趣啊,有空交流一下

#6楼    回复  引用    

2007-08-28 17:47 by 低调 [未注册用户]
Aplo 哥们:
你的分析太有意思了,我用你的思路测试了一下,谢谢了。大牛,我一直在学这方面的东西。有机会多发表的文章,期待你的文章。
谢谢你给我了这么好的学习机会。

#7楼 [楼主]   回复  引用  查看    

2007-08-28 17:49 by Aplo      
To:rufus

好啊,多谢你的支持,我的MSN是thenickey@gmail.com

我到是没有研究那么多,今天刚看的,我还真不知道

他在程序里调用了 ISIL 和 GetMethodRID

是什么,是在他加密函数里调的吗?有机会给好好研究一下啊

#8楼    回复  引用  查看    

2007-08-28 17:51 by rufus      
@Aplo
应该是它在准备在内存中的结构表吧,我也是看今天发在Rick博客里的回复说的.你可以去看一下,相信会受益的

#9楼    回复  引用  查看    

2007-08-28 17:52 by rufus      
@Aplo , 我把那内容粘过来了,分析思路有点不一样
DNGuard HVM作者一直致力于软件保护研究和开发,一直在分析其它加密产品的技术,并和大家分享。因此我对此产品十分感兴趣,一直视为追崇。最近一直在研究这产品,目的在于和大家交流软件加密技术,让大家更好的保护自己的产品。此文章并不是教学破解,只是分析原理,仅和大家作技术交流。

运行DNGuard HVM以后,感觉与Maxtocode软件有很多相识的地方。

我加密了三个,能运行一个,看来稳定性还有待验证,或者是我程序写得太诡异了?(玩笑)

一夜的分析,原来 DNGuard HVM还是可以还原。

调试工具准备,运行加密软件,分析 Framework 运行流程 (此处省略若干字)

原来 DNGuard HVM 是截获取 Framework JIT mscorwks.dll -> mscorjit.dll 的入口函数,也许是修改 mscorjit.dll 的出口所至,也许是修改 mscorwks.dll 的入口所至,反正就是这函数。
在进入 mscorjit.dll 之前先执行它提供的 HVMRuntime.dll 中的内容进行解密,然后再执行 mscorjit.dll 。
代码原型:
79EED3DD call dword ptr [ecx] <- mscorjit:xxxxxxx (入口)
代码修改后:
修改了 ECX 的值 , 代码改为
79EED3DD call dword ptr [ecx] <- HVMRunti.60004A90

#10楼    回复  引用  查看    

2007-08-28 17:53 by rufus      
1B 30 04 00 4A 00 00 00 02 00 00 11 72 C3 00 00 70 19 73 39 00 00 0A 0A 06 6F 3A 00 00 0A 69 8D 53 00 00 01 0B 06 07 16 06 6F 3A 00 00 0A 69 6F 3B 00 00 0A 26 73 17 00 00 06 0C 08 6F 15 00 00 06 26 08 6F 16 00 00 06 26 DE 0A 06 2C 06 06 6F 23 00 00 0A DC 2A 00 00 01 10 00 00 02 00 0C 00 33 3F 00 0A 00 00 00 00

1B 30 04 00 4A 00 00 00 02 00 00 11 -> 方法头
00 00 01 10 00 00 02 00 0C 00 33 3F 00 0A 00 00 00 00 -> SHE 表
72 C3 00 00 70 19 73 39 00 00 0A 0A 06 6F 3A 00 00 0A 69 8D 53 00 00 01 0B 06 07 16 06 6F 3A 00 00 0A 69 6F 3B 00 00 0A 26 73 17 00 00 06 0C 08 6F 15 00 00 06 26 08 6F 16 00 00 06 26 DE 0A 06 2C 06 06 6F 23 00 00 0A DC 2A -> 方法代码 MSIL

用作者自己提供的 Byte To MSIL 的工具看看是否正确 (注意不支持方法头和 SHE 表的转换 , 听说 MaxtoCode 作者写的转换工具可以支持 MSIL 头和 SHE 表)

#11楼    回复  引用  查看    

2007-08-28 17:53 by rufus      
确认此代码属于可用代码,有些Public Class 没有引用过来,所以翻译得不好。

即然已经确认,DNGuard HVM 截取 mscorwks.dll 飞向 mscorjit.dll 的入口就会解码,而且是往原地址里解,那么要还原就简单的多了。

需要做的就是:
1. Dump 内存
2. 截获DLL通过它提供的结构表找到对应方法的 MethodRID
3. 重构 PE 文件
4. 重构源数据
5. 重新指向新代码地址
如果你只要代码就更简单了。

分析到此结束,大家交流,共同进步,由于本文仅是和大家交流就没有涉及操作中的图片,我的目的不是证明自己有多厉害,而是和大家共同探讨共同进步。以上的分析工具全都是 Internet 上公开的东东。最后怎么重建 PE ,源数据就不说了。

声明:此文以研究的角度出发,里面不涉及任务破解相关的行为。

#12楼 [楼主]   回复  引用  查看    

2007-08-28 17:59 by Aplo      
To:rufus
我也看了那个了,写得有点太简单了,我没有具体跟踪,看不太懂啊,小弟知识浅薄,哈哈哈,研究看看吧

#13楼    回复  引用  查看    

2007-08-28 18:11 by Jason.NET      
写太深了那还不急啊.... 我现在都已经被说是幕后黑手了... 有理没处说去

#14楼    回复  引用    

2007-08-28 18:27 by 低调 [未注册用户]
@Aplo
期待你的文章。都是大牛,学习。。。。。。

#15楼    回复  引用  查看    

2007-08-28 19:51 by 瑞克      
如果要分析脱壳,建议从避开加密壳运行库的方向考虑。如果实现了,那么加密壳的运行库模式就整个报废了,这样要提高加密壳的安全性,就得整个内核模式重新设计了。

如果脱壳不能避开加密壳的运行库的话,本身就是对加密壳实现的一种肯定。这样子,加密壳只要修改运行库的本身的内部实现和加强运行库本身的保护强度就能提供安全性了。

#16楼    回复  引用  查看    

2007-08-28 21:26 by 没剑      
呵呵,看不明白,所以只有努力帮你们顶顶

#17楼 [楼主]   回复  引用  查看    

2007-08-28 21:48 by Aplo      
To:瑞克

看了好几遍我才明白你的意思,在这里我不是针对谁?大家只是讨论技术。
我承认DNGuard HVM 2007比前几款MaxToCode的保护性要强,只限于前几款,因为以后我没有研究过。

但是安全与否其实并不是说“如果脱壳不能避开加密壳的运行库的话,本身就是对加密壳实现的一种肯定。这样子,加密壳只要修改运行库的本身的内部实现和加强运行库本身的保护强度就能提供安全性了。”

首先一点值得肯定,什么叫安全?

其实从理论的角度来讲世界上没有100%安全,因为人是安全的唯一隐患。那什么样我们就能说他安全了,从密码学的角度打个比方:我做了一个保险箱,我把我做的材料、方法、设计图纸和保险箱……什么都给你,就是不给你密码,让你去破解可是你就是破解不出来,这样就算是安全了。(这句话的出处《应用密码学》)

你说我应该避开你的HVMRuntm.dll 那前提条件是你不能对dotnet框架进行修改。但是你不是。你修改了运行框架,使框架执行你的代码,又让我避开你的HVMRuntm.dll运行库。这种说法是不成立的。

如果你真的想要大家承认你,你可以把你的代码公开。这样别人还是破解不了你的加密,那就证明你的加密时成功的。否则就不能说你的加密是绝对安全的。

另外我还想说的一点是,不要像瑞星学习,整天指责这个杀毒软件误杀,那个杀毒软件不行。如果瑞星能把这些扯皮的时间放在研究上,我相信他会做得更好。一款软件是否健全与好坏,还是由使用的人来评判吧,贬低他人并不见得能够抬高自己。

#18楼    回复  引用  查看    

2007-08-29 09:46 by 瑞克      
我在这里没有要贬低别人的意思。
的确,安全在理论上说没有100%的。

"你说我应该避开你的HVMRuntm.dll 那前提条件是你不能对dotnet框架进行修改。但是你不是。你修改了运行框架,使框架执行你的代码,又让我避开你的HVMRuntm.dll运行库。这种说法是不成立的。 "
为了避免误会我这里就不指名,目前市面上的加密壳(包括DNGuard的试用版)也都对框架进行了修改,但是他们的运行库都可以被避开,直接从框架入手进行脱壳,破解者也是可以修改框架的。(避开运行库来脱壳的方法是大同小异的,基本上可以使用同一方法来脱壳)

我这里说避开加密壳运行库,不是说分析时不去分析加密壳运行库对框架的修改和调用。而是分析完后,进行脱壳时完全从框架入手,忽略运行库。

如果加密壳的运行库在脱壳时能被忽略,那么加密壳的核心设计就失败了,就有必要对核心进行重新设计。
我个人很欢迎这方面的研究,这对加密壳的发展以及加密壳核心的更新有很大促进作用。还能避免让我产生盲目自大的个人情绪:)
我一直以为自己对框架内核是十分了解的,看到老外纯win32实现的全系列脱壳机后,真是很佩服。"山外有山,人外有人"这句话说得一点都不假。

加密壳核心如果能做到脱壳时不能被避开,那就完成了万里长征的第一步。
第二步就是从增加运行库自身的复杂度和保护强度来提高安全性了。

#19楼 [楼主]   回复  引用  查看    

2007-08-29 09:53 by Aplo      
哈哈…………

#20楼    回复  引用    

2007-08-29 10:18 by 低调 [未注册用户]
Aplo
十分期待楼主的好文。

#21楼    回复  引用  查看    

2007-08-29 13:14 by winzheng      
呵呵,破解和反破解本身就是一对矛盾的结合体,两者相互促进,才能“Made in China”

#22楼    回复  引用    

2007-08-29 21:55 by 汽车人 [未注册用户]
中国制造也没啥

#23楼    回复  引用    

2007-08-29 21:55 by career [未注册用户]
呵呵,软件很难说

#24楼    回复  引用    

2007-10-10 17:56 by raoyy [未注册用户]
DNGUARD做的很不错,只是我用不起啊,哎...太穷了

标题  
姓名  
主页
Email (只有博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2007-09-07 15:43 编辑过


相关链接: