masxinlingvonta —— Java so加固混淆保护器
## masxinlingvonta主要用来将`Java字节码`编译为`LLVM-IR`或者是`底层代码`。
如今对Java桌面端程序的保护主要为基于字节码的代码混淆和今天我们要介绍的这种保护方案,`masxinlingvonta (下称MLV)`正实现了这种方案。
通过这种保护方案,可以将`Java字节码`编译为二进制文件,而使用各种`壳`对程序进行强力保护。
但这种方案在带来极大的代码保护强度下,也会带来十分严重的性能问题,因为这种方案主要是使用`JNI`实现的。
其中,大部分对`JVM指令`的实现都是通过了JNI,只有少数`算术运算`是独立实现的。
所以,这种方案将只会针对某些特殊的`方法`进行保护。
请注意:本项目仍不成熟,不适合用于生产环境,请自行测试。
## 特性
1. 自动生成`Linux`和`Windows`二进制文件。
2. 大多数最新的 `JVM虚拟机指令集`。
3. Java 异常处理。
4. Kotlin.
还有部分未支持或未完全支持的内容,请前往`Github项目页`查看。
## 使用
### 环境
1. LLVM: 将生成的`LLVM-IR`编译成二进制文件。
2. Maven: 用于构建本项目。
3. Java 11
4. `Windows SDK`和`VS C++ Support`
### 准备
要调用`native`修饰的方法,需要先加载二进制文件。所以,我们要在程序入口处使用已经提前写好了的`NativeLoader`:
```java
public void main(String... args) {
NativeLoader.loadNatives();
}
```
#### 注
在我的分支中,我对这一过程实现了自动化。所以,如果您使用本文章提供的成品,则不需要这一步。
### 指定函数 (Include)
#### 1. 声明
通过声明,我们可以简单的对函数进行指定。
```java
@Outsource
public static void helloNative() {
System.out.println("This method is heavily protected!");
}
```
#### 2. 配置文件
项目同样提供了另一个方案,我们可以通过配置文件对函数进行指定。
```json
{
"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`目录下。
### 生成样本
![样本](https://note.ultrapanda.me/upload/2021/10/image-7676ccee248f4b7e8b02de9c60ed8937.png)
## 值得注意的
### 垃圾回收
本地引用只有在方法返回之后才会被回收,下面的例子会导致潜在的内存泄露。
```java
@Outsource
private void foo(SocketServer server)throws Exception{
while (true) {
Socket sock = server.accept();
// ...
// 正常情况下,JVM虚拟机会在此时进行垃圾回收。
}
} // 但现在,只有在方法返回后,masxinlingvonta 将会进行垃圾回收。
```
所以,要排除这种潜在的内存泄露问题,你需要将内部循环展开到一个函数中。
```java
@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 正好需要 不咋地可不可以套深思虚拟化? 感谢分享
页:
[1]