superblaubeere27 / masxinlingvonta

Compiles Java ByteCode to LLVM IR (for obfuscation purposes)

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

masxinlingvonta

Compiles Java ByteCode to LLVM IR and native code (for obfuscation purposes). Contributions are welcome!

Prerequisites

  • LLVM (For compiling the generated LLVM-IR to native code)
  • Maven (For building this project)
  • Java 11 (Download)
  • (For Windows) Windows SDK / Visual Studio with Visual C++ support

Building from source

You can simply build this project with one simple command:

mvn -Djavacpp.platform=<HOST-PLATFORM> clean package

The HOST-PLATFORM is the platform you want to run this tool on, NOT the platform the compile code should run on. Supported host targets: windows-x86_64, linux-x86_64, macosx-x86_64

Features

This project is not production-safe. Please test if the code compiles correctly before publishing!

If you found bugs or missing features, feel free to open an issue.

Supported

  • Automatic generation of Linux and Windows binaries
  • Windows Host platform
  • Most of the latest JVM's instruction set
  • Exception Handling
  • Kotlin

Partially supported

  • Building Windows binaries on non Windows hosts (Requires Windows STLs)
  • Mac OSX (Requires you to build the shared libraries yourself)
  • Floating Point operations (Edge cases like division by zero might cause behaviour that does not match the JVM specification)
  • Lambdas (since they are using invokedynamic)
  • INVOKEDYNAMIC instruction (methods using this instruction will be compiled, but the INVOKEDYNAMIC instruction is extracted to a new method)
  • MULTIANEWARRAY instruction (will be extracted to a new method)

Not supported

  • DUP2_X1 and DUP2_X2 instructions which are generated by get-and-... operations on double- and long-arrays (doubleArray[0]++, doubleArray[0] += 2.0, longArray[0]++)

Planned features

  • Native code obfuscation (String Encryption, Constant obfuscation, Stack Strings)
  • Hiding exported methods via JNI_OnLoad and RegisterNatives
  • Automatic inlining of short methods
  • Integrated obfuscation

Usage

Preparation

Before compiling, you have to add code to your program that loads the generated native libraries. Here is an example for a native loader that assumes that the natives are stored in META-INF/natives. To use it, just add NativeLoader.loadNatives() to the main-method of your program.

Applying NameObfuscation via ProGuard and another bytecode obfuscator for further obfuscation (e.g. ZKM (commercial) , obfuscator, Radon, etc.) is recommended.

Target selection

Before you think about target selection, you should first read about the limitations of this tool and the method it uses (see below).

By default, this tool does not compile every method in your program. You have to specify the methods you want to compile manually using either the annotation api or the config.

Compiling via CLI

If you want to compile shared libraries for your target OSes:

java -jar masxinlingvonta-cli.jar -i input.jar -o obfuscated.jar -compileFor windows,linux -llvmDir "C:\Program Files\LLVM\bin"

If you want to compile the generated IR yourself:

java -jar masxinlingvonta-cli.jar -i input.jar -o obfuscated.jar -ll output.ll

CLI Options:

Optional Option Name Short alias Description
No --inputJar <FILE> -i Input JAR
No --outputJar <FILE> -i Output JAR
Yes --config <FILE> -c Allows you to specify a config (see below)
Yes --irOutput <FILE> -ll Dumps the generated LLVM IR
Yes -compileFor <OS1,OS2,...> Compiles shared libraries for the specified targets
Yes -outputDir Selects a directory where the natives generated by -compileFor will be placed
Yes -llvmDir LLVM's bin folder
Yes -help Prints a help page

Configuration

Here is an example configuration (should be self-explanatory)

{
  "additionalMethodsToCompile": [
    {
      "owner": "net/superblaubeere27/Main",
      "name": "superSophisticatedLicenseCheck",
      "desc": "(Ljava/lang/String;)Z"
    }
  ]
}

Annotations

To use annotations, include the masxinlingvonta-annotations JAR in your class path.

For now there is only one annotation:

Annotation Target Description
@Outsource Methods Methods with this annotation will be compiled to native code

Limitations

Garbage Collection

Local references in a method are only freed when the method returns. For example function with loops like this could cause memory leaks:

@Outsource
private void foo(SocketServer server)throws Exception{
    while (true) {
        Socket sock = server.accept();
        // ...
    
        // The JVM would free the reference to sock which allows it to be garbage collected
    }
} // masxinlingvonta would free the references on return. 

To prevent a memory leak, you should consider extracting the inner part of loops that your program will be stuck in for a while:

@Outsource
private void foo(SocketServer server)throws Exception{
    while (true) {
        bar(server);
    }
}

@Outsource
private void foo(SocketServer server)throws Exception{
    Socket sock = server.accept();
    // ...
    // The local reference to sock will be freed here
  }

Performance

Every JVM-interop is handled via JNI-methods. Only primitive operations like arithmetics, branches etc. are independent.

This dramatically slows down the code, so only a few select methods should be compiled to native code

About

Compiles Java ByteCode to LLVM IR (for obfuscation purposes)

License:GNU General Public License v3.0


Languages

Language:Java 100.0%