A Sample .NET DeProtector - whole assembly protection

转载 2006年06月19日 20:47:00
A Sample .NET DeProtector - whole assembly protection
Updated on Feb-13-06

Download (2.0 binaries and full source code)  (4000 downloads since Feb-01-06, let me know whether it works)
Download binaries for .NET Framework 1.1
Browse Source Code    String protection/deprotection article

This is a sample program that dumps out .NET assemblies loaded by a process inside the CLR engine. Whether the assemblies are encrypted or not, by the time CLR executes them, they must be in their original format with no protection, if at this moment, the assemblies are dumped out from memory, protected assemblies are decrypted. This illustrates that whole assembly protection is not a good way to protect intellectual properties.

What is whole assembly protection

Whole assembly protection refers to a technique that encrypts a whole .NET assembly and then gets decrypted at runtime. It usually employs a tool to transform a .NET assembly into an encrypted format, and together with an embedded native loader to create a native image. Since the assembly is now a native image, same as those compiled from visual C++ 6.0, it will not be recognized by any .NET decompilers and disassemblers, and thus achieve protection. On the surface, it appears that a great deal of protection has been done, since all metadata (class, method names, MSIL code, resources, etc) is now hidden, and people can't observe a single details using regular .NET tools. This is why there are vendors that claim that their products protect everything. However, such a protection is unable to overcome this: the .NET Framework runtime only understands assemblies in its specified .NET format. In other words, by the time CLR engine is executing, the protected assembly must somehow recover to its original format with all protection and encryption removed. If at this moment, they are dumped out from the address space, then the original assembly is recovered, and the protection is perfectly defeated. Since .NET Framework is an open standard, they are many ways to get into its runtime address space. Therefore, it's very easy to undo whole assembly protection. Once decrypted, it protects nothing. It's dangerous if you see a product claims that protects everything. In general, security is not an easy one to tackle.

How does the de-protector work

There are many ways to dump out assemblies loaded by the CLR runtime, for example, through DLL redirects, DLL injection, address space scanning, or through .NET specific APIs, such as profiling and debugging interfaces, and other undocumented features. Our sample deprotector right now utilizes two ways to defeat whole assembly protection. The first mechanism is to replace mscoree.dll (the runtime dll loaded by all .NET processes), the deprotector hooks the _CorExeMain() and _CorDllMain() methods and dumps out assemblies inside these two functions. The second way is through the standard profiling APIs, the deprotector implements a simple profiler that monitors assembly/module loading and unloading events, and dumps out modules from memory when modules are just finished loading. The profiling API provides an open mechanism to interact with the CLR.

We tested the deprotector on several protection products on market, and none of them can survive this simple deprotector. Even if anti-debug and anti-trace tricks are usually used by those tools, the original assemblies can be retrieved by simply executing the protected assembly once through the deprotector. Since this is a fundamental flaw, it's impossible to overcome it. Some deprotection mechanisms might be blocked over time, for example, the profiling APIs can be blocked by disabling certain environment variables, but there will be always other mechanisms available to get into the process to undo the protection. There are a few more mechanisms that will be posted over time, such as fusion hooking, delegation hooking, win32 API hooking, etc.

Salamander Protector

Our salamander protector is not a whole assembly protection tool, and thus the deprotector discussed here won't defeat it. The protected assembly by Salamander Protector does not have its MSIL code inside the memory, therefore, any memory dump will not get the MSIL code. Our protector does not prevent people from viewing metadata, and the protected code remains valid .NET format, rather than in native format. After protection, all class/method names are still visible, with only the MSIL code is transformed, which is why we bundle the obfuscator in the protector package.

Potential ways to stop DeProtector

This current version of the DeProtector is not difficult to stop. The following are some tricks that whole assembly protection tools can use to block this sample DeProtector:

  • Disable the Cor_Enable_Profiling and the COR_PROFILER environmental variables in the native loader, so the .NET profiling interface will be prohibited.
  • Once a PE file is loaded, modify the PE header, so this DeProtector does not consider it as an EXE/DLL image, and thus not get dumped. For more info, please check the SaveFile () method of the Dump.cpp source.
  • Examine the time stamp and checksum of those common .NET dlls (e.g., mscoree.dll), don't load if they are modified, which prevents DLL redirects. This has one consequence, that is the protected code may not execute in future versions of .NET Framework.

Future directions

We will continue to release DeProtector versions using other technologies. A professional version of the DeProtector will be included into our free .NET Explorer package (http://www.remotesoft.com/dotexplorer), which will use much more advanced techniques to dump out assemblies from CLR engine. Source code may not be provided in the future. Overall, we truly believe whole assembly protection is not the way to go, and it is IMPOSSIBLE to block all potential places where memory can be dumped. We will show you, stay tuned.

Discussions and Comments

Comments and discussions can be posted through Huihong Luo's blog on the deprotector. We hope the discussion here can help us to better understand .NET source code protection. All deprotection mechanisms mentioned here are not targeting any specific vendor, instead we only discuss generic techniques that ap

.NET 查找程序集路径(CLR关于Assembly的搜索路径的过程) .

最近在回顾.Net应用程序的执行环境,这里做一个很小的总结,方面以后需要的时候进行查找: CLR必须可以找到正确的Assembly,Net提供了Assembly搜索算法,可以根据.conf...

.NET 解释术语:CLR、FCL、IL、Assembly(程序集)

CLR常用简写词语,CLR是公共语言运行时,Common Language Runtime)和Java虚拟机一样也是一个运行时环境,它负责资源管理(内存分配和垃圾收集),并保证应用和底层操作系统之间必...

.NET 查找程序集路径(CLR关于Assembly的搜索路径的过程)

最近在回顾.Net应用程序的执行环境,这里做一个很小的总结,方面以后需要的时候进行查找: CLR必须可以找到正确的Assembly,Net提供了Assembly搜索算法,可以根据.config文...

使用WinSCP .Net Assembly访问FTP with TLS Explicit Encryption

最近有一个任务需要我用.Net实现一个程序来访问FTP。这个FTP使用的加密方式是TLS Explicit Encryption,并且使用Proxy。以前一直使用System.Net.FtpWebRe...

使用.Net下的全局程序集共享缓存(Globe Assembly Cache GAC)详细攻略

使用GAC详细攻略作者:GhostBear在网上搜索了一大堆资料,但都没用。经过自己反复的测试,终于成功了。具体步骤如下: 部署程序集文件到GAC:1.      建一个类库文件,并给它签名。2.  ...

微软一站式示例代码库(中文版)2011-08-08版本, 新添加ASP.NET, Azure, Silverlight, WinForm等15个Sample

2011年的8月8日,立秋,转眼间,秋天悄悄走来; 2011年的8月8日,奥运,转眼间,北京奥运会已过三载; 2011年的8月8日,七夕,转眼间,情人节的幸福或失落尚在心间; 自问:时光飞逝,我...

微软一站式示例代码库(中文版)2011-09-24版本, 新添加ASP.NET, Windows Base, Silverlight, WinForm等20个Sample

让大家久等了,9月份,我们准备了20个中文版Microsoft OneCode Sample,其中包括3个Windows Form Sample,2个Program Language Sample,6...

微软一站式示例代码库(中文版)2011-07-14版本, 新添加ASP.NET, Azure, Silverlight, WinForm等14个Sample

暑假到了,有道是   绿树阴浓夏日长, 楼台倒影入池塘, 水精帘动微风起, 满架蔷薇一院香。 在此盛夏之际,我们发布了新一版本的All-In-One Code Framework 中文版,新增14个...

ASP.NET MVC Sample Applications - Open-Source Examples and Tutorials

http://www.tampadev.org/News/Details/ASPNETMVCSampleApplicationsOpenSourceExamplesTutorials   ASP....

Sample Code on ASP.NET Validation in Depth

Base on my previous post "ASP.NET Validation in Depth" http://blog.csdn.net/riverlau/article/details...
您举报文章:A Sample .NET DeProtector - whole assembly protection