Hello is there official vmprotect SDK for rust? Can I use code marker inside rust code? Thank you
use std::os::raw::{c_char, c_void};
#[cfg_attr(
target_os = "macos",
link(name = "VMProtectSDK")
)]
#[cfg_attr(
all(not(target_os = "macos"), target_pointer_width = "64"),
link(name = "VMProtectSDK64")
)]
#[cfg_attr(
all(not(target_os = "macos"), target_pointer_width = "32"),
link(name = "VMProtectSDK32")
)]
unsafe extern "system" {
// protection of whole function (requires debug symbols/MAP/PDB)
pub fn VMProtectFunction();
pub fn VMProtectFunctionVirtualization();
pub fn VMProtectFunctionMutation();
pub fn VMProtectFunctionUltra();
pub fn VMProtectFunctionVirtualizationLockByKey();
pub fn VMProtectFunctionUltraLockByKey();
// protection of function part
pub fn VMProtectBegin(name: *const c_char);
pub fn VMProtectBeginVirtualization(name: *const c_char);
pub fn VMProtectBeginMutation(name: *const c_char);
pub fn VMProtectBeginUltra(name: *const c_char);
pub fn VMProtectBeginVirtualizationLockByKey(name: *const c_char);
pub fn VMProtectBeginUltraLockByKey(name: *const c_char);
pub fn VMProtectEnd();
}
#[inline(always)]
pub fn Function() {
unsafe { VMProtectFunction() };
}
#[inline(always)]
pub fn FunctionMutation() {
unsafe { VMProtectFunctionMutation() };
}
#[inline(always)]
pub fn FunctionVirtualization() {
unsafe { VMProtectFunctionVirtualization() };
}
#[inline(always)]
pub fn FunctionVirtualizationLockByKey() {
unsafe { VMProtectFunctionVirtualizationLockByKey() };
}
#[inline(always)]
pub fn FunctionUltra() {
unsafe { VMProtectFunctionUltra() };
}
#[inline(always)]
pub fn FunctionUltraLockByKey() {
unsafe { VMProtectFunctionUltraLockByKey() };
}
#[allow(clippy::not_unsafe_ptr_arg_deref)]
#[inline(always)]
pub fn Begin(str: *const c_char) {
unsafe { VMProtectBegin(str) };
}
#[allow(clippy::not_unsafe_ptr_arg_deref)]
#[inline(always)]
pub fn BeginMutation(str: *const c_char) {
unsafe { VMProtectBeginMutation(str) };
}
#[allow(clippy::not_unsafe_ptr_arg_deref)]
#[inline(always)]
pub fn BeginVirtualization(str: *const c_char) {
unsafe { VMProtectBeginVirtualization(str) };
}
#[allow(clippy::not_unsafe_ptr_arg_deref)]
#[inline(always)]
pub fn BeginVirtualizationLockByKey(str: *const c_char) {
unsafe { VMProtectBeginVirtualizationLockByKey(str) };
}
#[allow(clippy::not_unsafe_ptr_arg_deref)]
#[inline(always)]
pub fn BeginUltra(str: *const c_char) {
unsafe { VMProtectBeginUltra(str) };
}
#[allow(clippy::not_unsafe_ptr_arg_deref)]
#[inline(always)]
pub fn BeginUltraLockByKey(str: *const c_char) {
unsafe { VMProtectBeginUltraLockByKey(str) };
}
#[inline(always)]
pub fn End() {
unsafe { VMProtectEnd() };
}
Thank you for your help!
Rust is much more strict wrt code reordering, and e.g
VMProtectBegin(...);
// Complicated math where all the external calls would be inlined
VMProtectEnd();
Might end up reordering as
VMProtectBegin(...);
VMProtectEnd();
// Complicated math where all the external calls would be inlined
Because there is no way for VMProtectEnd to observe the result of the computation
Rustc might also duplicate calls to VMProtectEnd in some cases across branches (There is some MIR level optimization that does that)
I do implement some workarounds around that in protected!() macro in GitHub - CertainLach/vmprotect: Unofficial Rust SDK for VMProtect · GitHub ( vmprotect - Rust , cargo add vmprotect)
Furthermore, it is not possible to cleanly call the VMProtectBegin macro with string argument, because Rust way of doing that: VMProtectBegin(c"MarkerName".as_ptr()) would not be visible by vmprotect due to indirection and Rust merging such things too aggressivly, real_c_string - Rust used by vmprotect crate solves that by expanding real_c_string!(" ") into &[32, 0i8,] as *const i8
But even with those workarounds, the easiest way is to either use vmprotect gui to mark functions to protect explicitly, or to use #[vmprotect::protected] proc macro on functions, plus lua script to process the macro output vmprotect/script.lua at master · CertainLach/vmprotect · GitHub as it would also protect you against generic types footguns among other things
Since 3.10.6 VMProtect provides new kind of code markers - VMProtectFunctionXXX, so don’t need to use VMProtectBeginXXX + VMProtectEnd for protection of whole function and/or use external scripts for adding Rust functions into the project anymore.
Here is an example:
mod vmprotect;
fn main() {
vmprotect::Function();
println!("Hello, world!");
}
P.S. Anyway, VMProtectEnd is optional and VMProtect will obfuscation code till the end of a function.
