静态库和目标文件保护指引
静态库和目标文件介绍#
目标文件是指源代码编译后生成的中间文件,包含了汇编或机器代码、符号表以及其他一些用于链接的信息,其中目标文件通常以 .o(在UNIX系统中)或.obj(在Windows系统中)为扩展名;
静态库文件是由一组预编译的目标文件打包而成,以便于在链接时使用,程序被编译链接时,静态库中的目标文件会被复制到可执行行文件中,其中静态库通常以 .a(在UNIX系统中)或.lib(在Windows系统中)为扩展名。
安全性问题#
由于经过编译的目标文件包含汇编指令和符号表等信息,使用反编译工具对其进行解析,依然可以反编译为类C伪代码。针对一些只需交付静态库和目标文件的用户场景,为了保证程序不被逆向破解,则对静态库和目标文件的保护变得尤为重要。
Virbox Protector
对静态库和目标文件程序的保护,包含了名称混淆和函数级别的保护(包括代码混淆和代码虚拟化)。
1)测试举例(以Linux x64架构程序为例子),原程序反编译截图:
2)保护后程序反编译截图:
支持范围#
特点#
1.保护后的程序,基本不会影响编译时将库链接到应用程序的运行加载时间和内存消耗;
2.保护后的程序,在编译时基本不会出现兼容性问题;
3.保护时函数选择合适的保护方式,则程序启动时间和内存占用基本上不会有影响。
性能问题
静态库和目标文件的性能影响主要是函数的代码混淆和虚拟化部分,性能开销虚拟化最大,混淆较轻,但性能损失与具体的代码逻辑有关;
1.比如对于循环调用的代码,函数进行代码虚拟化和混淆,就会影响程序运行,若代码只有逻辑运算,函数全部虚拟化后影响也不是很大。
2.所以在保护上,建议是只保护核心代码,着重流程和逻辑运算,尽量不要保护大循环,也不要全部勾选。
支持架构#
静态库和目标文件支持范围如下:
系统 | 是否支持 |
---|---|
windows(x86和x64架构) | 支持 |
Linux(x86和x64架构) | 支持 |
Arm Linux(arm32和arm64架构) | 支持 |
macOS(x64和arm64架构) | 暂不支持 |
功能介绍#
基础功能#
名称混淆#
使用nm <your_file>
命令去查看程序符号,其中打印的信息中符号的标识符表示的含义如下:
- r:表示该符号为只读数据。
- b:表示该符号为BSS段,通常用于未初始化的全局变量。
- t/T:表示该符号为代码段(text),包含可执行代码。
- U:表示该符号未定义,需要在链接时解析。
- W:表示该符号为弱符号,允许多个符号具有相同的名称。
注意:其中未定义的符号U
和弱符号W
默认均不混淆。
仅混淆本地符号
静态库和目标文件都包含本地符号,本地符号一般用于描述函数名和地址信息,这些符号用于链接器在构建可执行文件时解析符号引用,保护程序时选择仅混淆本地符号
,可以混淆本地符号。
效果图如下所示:
保留自定义符号
静态库和目标文件的自定义符号一般是指在文件中定义的可以被其他文件访问的符号,可以包含全局符号和静态符号,通常使用特定的关键字或修饰符来指定其属性和作用域。
效果图如下所示:
注意:选择保留自定义符号
选项,名称列表需要添加自定义的导出符号,否则编译链接时会报错,提示找不到符号。
合并目标文件#
静态库文件支持合并目标文件功能;
功能描述:由于静态库文件是多个目标文件预编译而成,所以当静态库里有多个.o或.obj时,勾选合并目标文件
选项后的静态库文件里合成一个.o或.obj。
目的:当静态库文件里面有多个.o或.obj文件时,且目标文件之间存在符号调用,若使用名称混淆功能,则符号被混淆,程序加载很容易出问题,所以勾选该选项后,可以避免这种问题。
效果图如下所示:
函数功能#
代码混淆#
代码混淆是将函数中原始的指令,通过等价变换、立即数加密、间接跳转、虚假分支、花指令加扰、指令切片等手段,将原始指令转换为难以阅读的随机的指令片段。
原程序反编译:
保护后反编译:
代码虚拟化#
代码虚拟化,是保护过程中将函数中原始的汇编指令,转换为自定义的虚拟指令,运行时在自定义的虚拟机中执行,模拟了汇编指令中的内存访问、条件判断、寄存器状态等。
原程序反编译:
保护后反编译:
自动化集成#
自动化集成可以使用命令行的方式对文件进行保护,Virbox Protector
支持命令行选项,可以指定基础保护选项和函数选项,方便自动化集成。
命令行工具 virboxprotector_con
的默认路径位于:
Windows:C:\Program Files\senseshield\Virbox Protector 3\binLinux:/usr/share/virboxprotector/binmacOS:/Applications/Virbox Protector 3.app/Contents/MacOS/bin
目标文件
命令行执行virboxprotector_con --help=obj
可查看所有功能的参数。
静态库文件
命令行执行virboxprotector_con --help=archive
可查看所有功能的参数。
只合并但不保护文件
一般适用静态库文件的合并,命令行执行virboxprotector_con --help=objmerge
可查看所有功能的参数。
virboxprotector_con -objmerge <archive1> <archive2> ... <options ...> [-o <output_path>]命令参考如下:virboxprotector_con -objmerge lib1.a lib2.a lib3.a -o libtest.a
加密选项#
选项 | 命令行 | 通配符 |
---|---|---|
名称混淆 | --rename=<value> | 0 |
函数名称列表 | --keep-rules=<rules> | 2 |
函数名称列表文件的路径 | --keep-file=<file_path> | N/A |
合并目标文件(仅静态库) | --obj-merge=<value> | 0 |
名称混淆选项
--rename=0
关闭。
--rename=1
仅混淆本地符号。
--rename=2
保留自定义名称。
举例
1. 对静态库文件进行保护,并开启合并目标文件和仅混淆本地符号,命令参考如下:virboxprotector_con libhello.a --obj-merge=1 --rename=1 -o protected/libhello.a2. 对静态库文件进行保护,并开启合并目标文件和保留自定义名称,命令参考如下:virboxprotector_con libhello.a --obj-merge=1 --rename=2 --keep-rules="main;array" -o protected/libhello.a
若保留的函数名称过长,可以将函数名称保存到文本文件中(比如symbol.txt),并且命令行指定--keep-file=symbol.txt
,然后进行保护。
命令参考:virboxprotector_con libhello.a --obj-merge=1 --rename=2 --keep-file=symbol.txt -o protected/libhello.a
其中symbol.txt
文件内容要保留的函数名称的书写格式如下图所示:
函数选项#
支持指定函数名称或规则保护,使用 ;
号隔开, 支持通配符 *
。
选项 | 命令行 | 通配符 |
---|---|---|
忽略不支持的函数 | --ignore-unsupported=<value> | N/A |
代码混淆 | -m | 支持 * |
代码虚拟化 | -v | 支持 * |
举例
-m "function1;function2" -v "function3;function4" -e "test*" --ignore-unsupported=1
--ignore-unsupported=
选项用于忽略不支持的函数,不支持则跳过,对 Jar/aar/war/apk/aab 格式的程序默认开启。
命令参考如下:
1. 对静态库文件进行保护,设置函数进行虚拟化,并开启合并目标文件和仅混淆本地符号,virboxprotector_con libhello.a -v "main;array" --obj-merge=1 --rename=1 -o protected/libhello.a
保护指引#
名称混淆使用#
1.以Linux x64程序的静态库和目标文件为例
1)选择保留自定义符号
选项,名称列表为空 ,然后保护选中项目;
2)使用编译器链接目标文件时,报错提示“undefined reference to xxx”;
3)根据报错提示的符号名称,在名称列表里输入名称,比如main
,设置完成后保护选中项目;
4)再使用编译器链接目标文件时就可以编译成功了。
2.以Windows x64程序的静态库和目标文件为例
1)选择保留自定义符号
选项,名称列表为空 ,然后保护选中项目;
2)使用编译器链接目标文件时,报错提示“undefined reference to xxx”;
3)根据报错提示的符号名称,在名称列表里输入名称,比如someLibFunc;feiboLib;arrayLib
,设置完成后保护选中项目;
4)再使用编译器链接目标文件时就可以编译成功了。
函数选项的使用#
1.将目标文件或静态库文件拖入到Virbox Protector
工具的界面;
2.点击函数选项->添加函数->选中函数->右键->选择保护方式->确定,如下图所示:
3.设置完成后,点击保护选中项目即可保护成功。
常见问题#
不识别的OBJ文件#
1.使用vs工具编译release版的lib文件时,加壳工具解析提示"文件格式错误",如何修改;
1)项目的配置属性->高级->全程序优化,"使用链接时间代码生成"选项不支持,改成其他选项,如图所示。
2)项目的配置属性->C/C++->优化,全程序优化改成否,如图所示。
3)设置好支持保存并重新编译,则编译后的lib库即可识别。