Documentation

Target Version: 1.6.1.1
This page provides instructions on how to use VxLang.

Generating a Project JSON

VxLang supports JSON files to adjust protection options at the binary level. To obtain the latest version of the JSON file, use the CMD options. Below is an example command:

:\> vxlang.exe ${PE-Binary}

This will create a temp.json file.

{ "input": "test.exe", "output": "", "backup": false, "use-data-section": false, "base-section-name": "", "map-file-path": "", "virtualizer": { "entry-point": false, "virtualization-by-map": [] }, "obfuscator": { "entry-point": false, "obfuscation-by-map": [], "flattening-by-map": [] }, "protector": { "compress": true, "symbol-data": false, "mutate-import-table": true, "vxlang-link-event": false, "anti-tamper": { "enable": true, "hide-unused-memory": true, "pause-protection": true, "message": "" }, "extension": [], "raw-data" : [], "reflection": { "enable": false, "ldr-update": true } } }

The generated JSON can be used as shown below.

:\> vxlang.exe temp.json

JSON Description

input   :   The input file.
output   :   The output file.
backup   :   Decide whether to back up the original file.
use-data-section   :   This flag recycles the data section instead of creating a VxLang section.
base-section-name   :   Sets the default section name for VxLang data or code. If empty, generate a random name.
map-file-path   :   Use a MAP file to map binary information.

virtualizer:

entry-point   :   Virtualizes the program entry point.
virtualization-by-map   :   Based on the function name written in the MAP file, virtualizes the entire function.

obfuscator:

entry-point   :   Flattening the program entry point.
obfuscation-by-map   :   Based on the function name written in the MAP file, obfuscation the entire function.
flattening-by-map   :   Based on the function name written in the MAP file, flattening the entire function.

protector:

compress   :   Compress the binary. If this flag is not set, only the VxLang core is added.
symbol-data   :   Decide if you want to keep the debug symbols.
mutate-import-table   :   Obfuscate the import table.
vxlang-link-event   :   SDK to route obfuscated or virtualized blocks through the VxLang core. This is freely controllable via VxLang extension modules.
anti-tamper:enable   :   Enable the anti-tamper feature included with VxLang.
anti-tamper:hide-unused-memory   :   Delete memory that is not referenced by the protected memory.
anti-tamper:pause-protection   :   Detect thread pauses.
anti-tamper:message   :   The message that is output when detected by the anti-tamper. If it is empty, the program will exit.
extension   :   VxLang extension modules developed by users.
raw-data   :   Enclose (compress) RAW data, such as other binaries (DLL/SYS), in the target binary. This can be freely controlled by the extension module.
reflection:enable   :   Reflex load the target binary.
reflection:ldr-update   :   Determines whether to update the target binaries in the PEB!LDR.

How to protect user code

Precautions

  When using code obfuscation and virtualization, be mindful of the following situations:

  1. Compiler Optimization Considerations:
  If you're using the VxLang SDK to obfuscate or virtualize your code, ensure that you check the compiler optimization settings. When compiler optimization is enabled, your code might be merged in ways that differ from how you originally wrote it. If VxLang SDK functions are referenced within this merged code, the Begin/End positions might change, resulting in less obfuscation than intended.

  Here's how to fix the problem:

1. Turn off compiler optimization.
2. Disable code optimization for specific functions or pages at the code level.
3. Use MAP/PDB-based obfuscation/virtualization.

  2. Potential Code Generation:
  Be aware of the following code pattern that may occur during the obfuscation and virtualization process:

...
call _VXLANG_BEGIN
jmp L1

L0:
jmp EXIT

L1:
lea rax, $L0
jmp rax

EXIT:
call _VXLANG_END
...

  In this example, the jmp rax instruction causes a jump from the VxLang region back to the original code. This type of code can occur when table-based operations are used in a switch-case statement.

  3. Exception Handling:
  VxLang currently only supports SEH (Structured Exception Handling). Therefore, be cautious when using it in conjunction with try-catch blocks.

Protecting user code with the SDK

  Let's check out the VxLang SDK functions.
  - Link: vxlib.h
  - Link: vxlib.cpp

// Code Obfuscation Macros
#define VL_OBFUSCATION_BEGIN
#define VL_OBFUSCATION_END
// Code Flattening Macros
#define VL_CODE_FLATTENING_BEGIN
#define VL_CODE_FLATTENING_END
// Code Virtualization Macros
#define VL_VIRTUALIZATION_BEGIN
#define VL_VIRTUALIZATION_END

  To protect specific code sections, you can insert these macros as follows:
  Link: sample.cpp

void func() {
   VL_OBFUSCATION_BEGIN;
   // Your code to be obfuscated
   VL_OBFUSCATION_END;
   return;
}

Protecting user code with the MAP-File

  VxLang can perform function-level obfuscation by utilizing the binary's MAP-file.
  The MAP file looks something like this:

map64

Timestamp is 66d39ebe (Sun Sep 1 07:52:46 2024)

Preferred load address is 0000000140000000

Start Length Name Class
...
0001:00000000     __local_stdio_printf_options   0000000140001000 f i sample.obj
0001:00000010     _vfprintf_l                               0000000140001010 f i sample.obj
0001:00000060     printf                                      0000000140001060 f i sample.obj
...

In the MAP file, the function is represented by f, as shown in the example above.
Find the function you need to obfuscate in the list above and enter it into your project JSON, and it will be obfuscated per function.

"virtualization-by-map": [
    "__local_stdio_printf_options",
    "_vfprintf_l",
    "printf"
]
"obfuscation-by-map": [
    "__local_stdio_printf_options",
    "_vfprintf_l",
    "printf"
]
"flattening-by-map": [
    "__local_stdio_printf_options",
    "_vfprintf_l",
    "printf"
]

Protecting user code with the PDB-File

...

Disable the VxLang-Core

  VxLang performs additional binary protection behavior through VxLang-Core. However, sometimes users only need code protection without additional protection behavior. In this case, you can enter a command like the one below to exclude the core.

:\> vxlang.exe ${PE-Binary} --disable-core
:\> vxlang.exe temp.json --disable-core