masxinlingvonta
主要用来将Java字节码
编译为LLVM-IR
或者是底层代码
。
如今对Java桌面端程序的保护主要为基于字节码的代码混淆和今天我们要介绍的这种保护方案,masxinlingvonta (下称MLV)
正实现了这种方案。
通过这种保护方案,可以将Java字节码
编译为二进制文件,而使用各种壳
对程序进行强力保护。
但这种方案在带来极大的代码保护强度下,也会带来十分严重的性能问题,因为这种方案主要是使用JNI
实现的。
其中,大部分对JVM指令
的实现都是通过了JNI,只有少数算术运算
是独立实现的。
所以,这种方案将只会针对某些特殊的方法
进行保护。
请注意:本项目仍不成熟,不适合用于生产环境,请自行测试。
特性
- 自动生成
Linux
和Windows
二进制文件。
- 大多数最新的
JVM虚拟机指令集
。
- Java 异常处理。
- Kotlin.
还有部分未支持或未完全支持的内容,请前往Github项目页
查看。
使用
环境
- LLVM: 将生成的
LLVM-IR
编译成二进制文件。
- Maven: 用于构建本项目。
- Java 11
Windows SDK
和VS C++ Support
准备
要调用native
修饰的方法,需要先加载二进制文件。所以,我们要在程序入口处使用已经提前写好了的NativeLoader
:
public void main(String... args) {
NativeLoader.loadNatives();
}
注
在我的分支中,我对这一过程实现了自动化。所以,如果您使用本文章提供的成品,则不需要这一步。
指定函数 (Include)
1. 声明
通过声明,我们可以简单的对函数进行指定。
@Outsource
public static void helloNative() {
System.out.println("This method is heavily protected!");
}
2. 配置文件
项目同样提供了另一个方案,我们可以通过配置文件对函数进行指定。
{
"additionalMethodsToCompile": [
{
"owner": "me/ultrapanda/Main",
"name": "helloNative",
"desc": "()V"
}
]
}
CLI 选项
必需 |
选项用法 |
简短用法 |
解释 |
是 |
--inputJar <文件> |
-i |
输入 JAR 文件 |
是 |
--outputJar <文件> |
-i |
输出 JAR 文件 |
否 |
--config <文件> |
-c |
加载配置文件来指定函数 |
否 |
--irOutput <文件> |
-ll |
保存LLVM-IR 代码 |
否 |
-compileFor <OS1,OS2,...> |
|
编译目标平台 |
否 |
-outputDir |
|
编译生成的文件将会被保存在这个文件夹 |
否 |
-llvmDir |
|
LLVM bin 文件夹 |
否 |
-help |
|
输出帮助信息 |
运行
编译到特定平台:
java -jar masxinlingvonta-cli.jar -i input.jar -o obfuscated.jar -compileFor windows,linux -llvmDir "C:\Program Files\LLVM\bin"
编译到LLVM-IR
:
java -jar masxinlingvonta-cli.jar -i input.jar -o obfuscated.jar -ll output.ll
打包
若您使用了NativeLoader
, 您需要将编译出的文件添加到输出JAR文件
中的META-INF/natives
目录下。
生成样本
值得注意的
垃圾回收
本地引用只有在方法返回之后才会被回收,下面的例子会导致潜在的内存泄露。
@Outsource
private void foo(SocketServer server)throws Exception{
while (true) {
Socket sock = server.accept();
// ...
// 正常情况下,JVM虚拟机会在此时进行垃圾回收。
}
} // 但现在,只有在方法返回后,masxinlingvonta 将会进行垃圾回收。
所以,要排除这种潜在的内存泄露问题,你需要将内部循环展开到一个函数中。
@Outsource
private void foo(SocketServer server)throws Exception{
while (true) {
bar(server);
}
}
@Outsource
private void foo(SocketServer server)throws Exception{
Socket sock = server.accept();
// ...
// 将会在这里进行垃圾回收
}
原项目地址
https://github.com/superblaubeere27/masxinlingvonta
我的分支
https://github.com/DotRacel/masxinlingvonta
(已向原项目提交了PR)
项目成品下载 (分支编译)
https://www.aliyundrive.com/s/zqtmeCZe8mn
保护样本下载
https://www.aliyundrive.com/s/XTJrjzJFJpx