Skip to main content

Virbox Protector用户指引(.NET )

.NET程序是由C#、Visual Basic 等语言开发的基于公共语言运行时(CLR)的应用程序。.NET程序的源代码通常会被编译成中间语言(IL)或字节码(Bytecode),然后在运行时由CLR解释执行。这样的设计有利于跨平台和语言互操作,但也带来了一些安全风险,因为IL或字节码相对于源代码更容易被反编译或反汇编,从而暴露出程序的逻辑和数据。

.NET程序的安全性一直是开发者主要的关注点之一,Virbox Protector 对 .NET 程序的保护,包含了整体的加密、运行时反调试、名称混淆、函数级别的保护(包括代码加密,代码混淆,以及高强度的代码虚拟化等技术)。

对程序做好保护,并不是一件简单的事,需要结合具体的场景和安全需求,尤其是高强度的保护选项,往往伴随着使用限制或者性能问题,没有哪种加密策略可以保证安全性高又不影响性能,本文档将对保护的场景、流程(包括集成构建)以及加密选项进行指引。

支持范围#

.NET 程序最早只在由微软实现的 .NET Framework 环境下环境,随着 Mono 运行时的出现(尤其是 Unity 引擎的推广),以及 .NET Core 的推出和 .NET 5 及以上的推出,运行环境变得更复杂。

由于不同运行时环境对 .NET 标准和底层库的支持不同,而代码保护技术往往依赖一些底层技术,在不同环境下会存在兼容性差异。

运行环境#

运行环境是否支持说明
.NET Framework 2.x ~ 4.x完整支持
.NET Core 2✔️已废弃版本,部分功能不兼容
.NET Core 3✔️非Windows系统部分功能不支持
.NET 5 以上✔️非Windows系统部分功能不支持
Mono Runtime✖️如果是Unity引擎,可以使用 Unity 加密方案

功能与兼容性#

保护选项兼容性备注
导入表保护支持Windows(x86/x64/arm32/arm64)、Linux(x64)
压缩仅支持 Windows 系统;不支持In Memory Module,比如使用Assembly.Load 加载的 dll
JIT加密支持 Windows(x86/x64)、Linux(x64)
字符串加密完整支持
资源加密完整支持
附加数据加密仅支持Windows部分打包工具会生成附加数据
调试器检测完整支持
名称混淆完整支持
[E] 代码加密完整支持
[M] 代码混淆完整支持
[V] 代码虚拟化完整支持

功能介绍#

基础保护#

压缩#

压缩 .NET 程序中的 .text 节中的信息,也可以起到静态防反编译的功能。

该功能不支持Assembly.Load 等内存加载 DLL的调用方式。

保护前

保护后

JIT加密#

加密 .NET 程序中的所有方法的IL字节码,防止程序被静态反编译,仅在特定的函数 JIT 编译时解密一次,不会在内存中驻留明文,可以防止从内存中整体 dump 出 IL字节码。

JIT加密对程序性能影响小,是较为普遍的一种加密方式。

保护前

保护后

导入表保护#

将系统模块的函数调用转换为桩函数调用,降低代码可读性。

保护前

imp_protect_before

保护后

imp_protect_after

资源加密#

加密.NET 程序绑定的资源。

保护前

res_before

保护后

res_after

调试器检测#

运行时检测到被调试则退出进程。

附加数据加密#

某些播放器类程序包含附加数据,该功能可以加密 .NET 程序的附加数据。

函数级保护#

代码混淆#

对指定函数进程控制流混淆。

代码加密#

基于 .NET 动态方法技术,运行时动态生成方法。

代码虚拟化#

一种高安全性的保护方式,将 IL 字节法转换为自定义的虚拟机字节码,在自定义虚拟机中解释执行。

安全性高,但对性能影响较大,仅适合对核心的函数保护。

名称混淆#

将代码中的命名空间、类、方法、属性等修改为无意义的名称。

不能混淆被其它模块引用的类和方法,否则可能导致程序无法运行。

运行平台#

指定运行时系统架构。

.NET 的保护选项中,JIT 加密 功能使用了 Native 层的保护技术,对运行平台有影响,勾选需要的运行平台可以兼容指定的运行环境。

注:指定非 Windows平台请勿勾选 压缩

platforms

程序集合并#

将多个.NET程序集合并为一个,消除模块间的引用,合并后可以提升名称混淆的效果。

注:请勿合并保护后的程序集,可以先合并再保护。

使用界面合并程序集

打开 ”工具“ --> “程序集合并” ,设置要合并的程序集:

使用命令行合并程序集

virboxprotector_con -ilmerge <main_assembly> <other_assemblies ...> -o <output_file>

SDK标签#

Virbox Protector 还提供了类/方法标签的方式控制保护方式,C# 使用示例见Virbox Protector安装目录下<install_dir>/example/sdk/C#

SDK标签使用了微软提供了标准 Obfuscation 描述,使用时需要引入 System.Reflection

using System.Reflection;

以下函数级标签可以对 class 和 method 标记,如果对class标记则会标记该class下的所有方法。

代码混淆#

[Obfuscation(Feature = "Mutation", Exclude = false)]

代码加密#

[Obfuscation(Feature = "Encryption", Exclude = false)]

代码虚拟化#

[Obfuscation(Feature = "Virtualization", Exclude = false)]

名称混淆#

名称混淆白名单,保留该名称,不对其进行名称混淆。

[Obfuscation(Feature = "Renaming")]

保护指引#

普通的保护方式#

如果对安全性没有较高的要求,不需要函数级别的保护,只需要调整基础保护选项即可实现防反编译和防整体内存Dump。

保护选项保护建议说明
压缩如无特别需要不要勾选
JIT加密Windows/Linux系统下勾选
字符串加密有敏感字符串则勾选
资源加密需要加密.NET资源则勾选
附加数据加密有附加数据则勾选部分打包工具会生成附加数据
调试器检测每个进程只需要保护一个模块(如主程序exe);如果模块做为SDK发布供第三方调用,则不勾选
名称混淆对主程序exe,选择"保留自定义名称";对dll,选择"只混淆私有成员"
[E] 代码加密Windows 平台使用默认选项(仅加密入口函数);非Windows平台由于不支持JIT加密,建议对必要的函数勾选
[M] 代码混淆无需选择
[V] 代码虚拟化无需选择

高安全性保护#

如果对安全性有较高要求,可以在 名称混淆上加强,并对关键的函数进行代码虚拟化

自定义名称混淆可以对命名空间、类、方法等名称进行混淆,由于模块间一般存在互相调用,对public属性的名称混淆会导致调用出错找不到方法,需要由开发者自定义配置。

对于模块间调用问题,也可以通过程序集合并功能将多个模块合并为一个再进行保护。Virbox Protector 提供了免费工具 程序集合并功能,可以在菜单栏 工具--.NET程序集合并中找到。virboxprotector_con 支持命令行选项 -ilmerge 进行合并,实现自动化。

举例:

# 将 test.exe 和其依赖的 test.dll 合并为一个 test.exevirboxprotector_con -ilmerge test.exe test.dll -o merged/test.exe

对关键的函数逻辑(如授权验证,关键的加密解密代码逻辑),推荐使用代码虚拟化进行保护,代码虚拟化对运行性能有一定影响,不适合大面积使用。如需诊断性能问题,可以在函数选项-添加函数-性能分析中运行程序查看函数的调用次数。

自动化集成#

命令行工具#

Virbox Protector 的命令行工具 virboxprotector_con 的默认路径位于:

Windows:C:\Program Files\senseshield\Virbox Protector 3\bin
Linux:/usr/share/virboxprotector/bin
macOS:/Applications/Virbox Protector 3.app/Contents/MacOS/bin

使用配置文件保护#

使用工具界面进行保护,在被保护的程序旁边会生成 .ssp 文件,然后调用virboxprotector_con

virboxprotector_con <input_file> -o <output_file>

virboxprotector_con 会自动查找 <input_file>.ssp 作为配置文件开始保护。

使用SDK标签保护#

使用界面工具虽然可以简单自由生成配置文件进行保护,但在开发过程中如果修改被保护的代码,配置文件就会失效。

SDK标签

命令行选项#

保护选项#

选项命令行默认选项
压缩--pack=0
JIT 加密--jit-enc=1
导入表保护--imp-protect=0
字符串加密--str-enc=0
资源加密--res-enc=0
附加数据加密--overlay-enc=1
调试器检测--detect-dbg=0
名称混淆--rename=exe 混淆所有名称2;dll 只混淆私有名称1
名称混淆保留规则--keep-rules=""

函数选项#

选项命令行
忽略不支持的函数--ignore-unsupported=<value>(默认关闭:0)
代码加密-e
代码混淆-m
代码虚拟化-v

支持指定函数名称或规则保护,使用 ;号隔开, 支持通配符 *,举例:

-m "function1;function2" -v "function3;function4" -e "test*" --ignore-unsupported=1

建议使用SDK标签,更便于维护和自动化。

运行平台#

指定运行平台可以用 --platforms= 选项,举例如下:

指定Windows平台:

--platforms="windows-x86"

指定Windows和Linux 双平台:

--platforms="windows-x86;linux-x86"

命令行保护场景举例#

对主程序保护(混淆所有名称,开启反调试):

virboxprotector_con test.exe --pack=0 --jit-enc=1 --str-enc=1 --rename=2 --keep-rules="" -detect-dbg=1 -o protected/test.exe

对dll保护(混淆私有名称):

virboxprotector_con test.dll --pack=0 --jit-enc=1 --str-enc=1 --rename=1 

对dll保护(保留自定义的名称):

virboxprotector_con test.dll --pack=0 --jit-enc=1 --str-enc=1 --rename=2 --keep-rules="MyNamespace.MyClass1.*;MyNamespace.MyClass2.*"

对需要在Linux平台dll保护:

virboxprotector_con test.dll --pack=0 --jit-enc=1 --detect-dbg=1 --str-enc=1 --rename=1 --platforms=windows-x86;linux-x86 -o protected/test.dll

注:根据自己的需求添加命令参数。