This repo contains a POC for runtime function decryption done natively with Rust.
The function encryption uses a streaming cipher, in this case ChaCha20 but it is trivial to modify the POC to use any streaming cipher. Block ciphers can also be used, although they require more set up.
This method aims to minimally modify the source code of a program, mainly relying on post-build scripts to encrypt the functions.
Encryption keys are created with build.rs.
The encryption happens in the build/post_build build script. The build script relies on debug symbols to parse function names and lengths.
In order to call encrypted functions, you use the encrypted_call! macro. Provide a function pointer and the necessary arguments.
If you want to make your own functions, add them to the encrypted_functions.rs file, add the necessary #[inline(never)] and #[export_name = "${FUNCTION_NAME}"] and prepend them with the necessary stub: jmp 2f int3 int3 int3 int3.
If you want to use another file, please change the ENCRYPTED_FUNCTIONS environmental variable in the Makefile.toml.
The maximum length of a single function is 4,294,967,295 bytes. This can be changed by increasing the number of padding bytes.
Install cargo make: cargo install cargo-make
To run compile and run the debug build: cargo make debug
To run compile and run the release build: cargo make release