Skip to content

Full Guide

Zydak edited this page Aug 13, 2026 · 2 revisions

Guide

Usage

Copy Leet.h into your project, then inside one .c/.cpp file include it and define LEET_IMPLEMENTATION, do not define this in multiple modules!

#define LEET_IMPLEMENTATION
#include "Leet.h"

then just compile the source with the built compiler:

./build/bin/clang++ ./test.cpp -o test -fno-exceptions

Configuration

You can tweak the settings of this obfuscator by either messing with the config file or marking functions with annotations in the code.

Config File

When running for the first time compiler will prompt you to create a config file in the current working directory. Inside it you'll be able to change settings globally and per pass.

Parameter Priority

Parameters can be set at three levels, with each level overriding the previous:

  1. Global settings in the config file (apply to all passes)
  2. Per pass settings in the config file (override global for that specific pass)
  3. Per function annotations in the code (override both global and per pass settings)

Available Parameters Per Pass

runtimeSeed is parsed as uint64_t and is the seed for random number generation in all probabilities, compiling twice with the same seed and settings should give you exactly the same file:

~/Dev/LeetObfuscator/build/bin$ ./clang++ ./HelloWorld.cpp -o b.out -O3 -fno-exceptions
RUNTIME SEED: 0
Running AnnotationPass
Running StringEncryptionPass
Running MBAPass
Running BlockSplitterPass
Running AntiAnalysisPass
Running DispatcherPass
Running MBAPass
Running AAMBAPass
Running AntiAliasingPass
Running AntiAnalysisPass
Running NanomitesPass
Running NanomitesMachineFunctionPass
Running AntiAnalysisCodeEmitterPass
~/Dev/LeetObfuscator/build/bin$ ./clang++ ./HelloWorld.cpp -o a.out -O3 -fno-exceptions
RUNTIME SEED: 0
Running AnnotationPass
Running StringEncryptionPass
Running MBAPass
Running BlockSplitterPass
Running AntiAnalysisPass
Running DispatcherPass
Running MBAPass
Running AAMBAPass
Running AntiAliasingPass
Running AntiAnalysisPass
Running NanomitesPass
Running NanomitesMachineFunctionPass
Running AntiAnalysisCodeEmitterPass
~/Dev/LeetObfuscator/build/bin$ md5sum a.out b.out
74a1ac9167470389a778b77e74eb27d6  a.out
74a1ac9167470389a778b77e74eb27d6  b.out

StringEncryptionPass

  • defaultParseMode: Whether to apply the pass by default (all or none).
  • runtimeSeed: Seed for the random number generator.
  • probability: Percentage chance (0-100) to apply string encryption to a string.

MBAPass

  • defaultParseMode: Whether to apply the pass by default (all or none).
  • runtimeSeed: Seed for the random number generator.
  • minFunctionSize: Minimum function size in instructions to be obfuscated.
  • maxFunctionSize: Maximum function size in instructions to be obfuscated.
  • minBlockSize: Minimum basic block size in instructions to be obfuscated.
  • maxBlockSize: Maximum basic block size in instructions to be obfuscated.
  • probability: Percentage chance (0-100) to apply MBA to an operation.
  • expansionCount: Number of MBA expansions to apply.

BlockSplitterPass

  • defaultParseMode: Whether to apply the pass by default (all or none).
  • runtimeSeed: Seed for the random number generator.
  • probability: Percentage chance (0-100) to split a block.
  • blockSplitSize: Target size to split blocks at.

DispatcherPass

  • defaultParseMode: Whether to apply the pass by default (all or none).
  • runtimeSeed: Seed for the random number generator.
  • minFunctionSize: Minimum function size in instructions to be obfuscated.
  • maxFunctionSize: Maximum function size in instructions to be obfuscated.
  • probability: Percentage chance (0-100) to apply control flow flattening.

AntiAnalysisPass

  • defaultParseMode: Whether to apply the pass by default (all or none).
  • runtimeSeed: Seed for the random number generator.
  • minFunctionSize: Minimum function size in instructions to be obfuscated.
  • maxFunctionSize: Maximum function size in instructions to be obfuscated.
  • minBlockSize: Minimum basic block size in instructions to be obfuscated.
  • maxBlockSize: Maximum basic block size in instructions to be obfuscated.
  • probability: Percentage chance (0-100) to apply anti analysis.
  • bogusInsertPosition: Where to insert bogus blocks (start or random).

AAMBAPass

  • defaultParseMode: Whether to apply the pass by default (all or none).
  • runtimeSeed: Seed for the random number generator.
  • minFunctionSize: Minimum function size in instructions to be obfuscated.
  • maxFunctionSize: Maximum function size in instructions to be obfuscated.
  • minBlockSize: Minimum basic block size in instructions to be obfuscated.
  • maxBlockSize: Maximum basic block size in instructions to be obfuscated.
  • probability: Percentage chance (0-100) to apply AAMBA to an operation.

AntiAliasingPass

  • defaultParseMode: Whether to apply the pass by default (all or none).
  • runtimeSeed: Seed for the random number generator.
  • minFunctionSize: Minimum function size in instructions to be obfuscated.
  • maxFunctionSize: Maximum function size in instructions to be obfuscated.
  • probability: Percentage chance (0-100) to apply anti aliasing.

NanomitesPass

  • defaultParseMode: Whether to apply the pass by default (all or none).
  • runtimeSeed: Seed for the random number generator.
  • minFunctionSize: Minimum function size in instructions to be obfuscated.
  • maxFunctionSize: Maximum function size in instructions to be obfuscated.
  • probability: Percentage chance (0-100) to apply nanomites to a call.

Example config file:

# GLOBAL SETTINGS
# These apply to all passes unless overridden in individual pass configurations
#
defaultParseMode=all
runtimeSeed=0
minFunctionSize=20
maxFunctionSize=0
minBlockSize=0
maxBlockSize=0

# PASS CONFIGURATIONS
# Each pass can override global settings or add pass specific parameters
# Parameters not specified here will use the global values above or the default ones
# Btw order matters here, you can reorder and duplicate the passes as much as you want, the only exception is StringEncryptionPass which will always run first
# I'd also advise running NanomitesPass as the last one otherwise stuff will most likely break
passes=
    StringEncryptionPass(),
    MBAPass(expansionCount=2, probability=50),
    BlockSplitterPass(blockSplitSize=50),
    AntiAnalysisPass(probability=25),
    DispatcherPass(),
    MBAPass(expansionCount=1), # This wont re expand previous MBA instructions. Only ones that have been created since the last pass run
    AAMBAPass(probability=35),
    AntiAliasingPass(),
    AntiAnalysisPass(bogusInsertPosition=start,probability=25),
    NanomitesPass(); # remember to end the list with a semicolon. Anything after it will not get parsed

Annotations

You can also mark individual functions and calls in the code with annotations. Inside Leet.h there are macros for every possible setting, you can just slap them on a function and it will be read by the obfuscator.

Annotation Macros Per Pass

StringEncryptionPass

  • LEET_STRING_ENCRYPTION_PROBABILITY(value): Set the probability (0-100) of encrypting a string.

MBAPass

  • LEET_MBA_EXPANSION_COUNT(count): Set the number of MBA expansions to apply.
  • LEET_MBA_PROBABILITY(value): Set the probability (0-100) of applying MBA to an operation.

BlockSplitterPass

  • LEET_BLOCK_SPLITTER_PROBABILITY(value): Set the probability (0-100) of splitting a block.
  • LEET_BLOCK_SPLITTER_SPLIT_SIZE(value): Set the target size to split blocks at.

DispatcherPass

  • LEET_DISPATCHER_PROBABILITY(value): Set the probability (0-100) of applying control flow flattening.

AntiAnalysisPass

  • LEET_ANTI_ANALYSIS_PROBABILITY(value): Set the probability (0-100) of applying anti analysis.
  • LEET_ANTI_ANALYSIS_BOGUS_INSERT_POSITION(value): Set where to insert bogus blocks ("start" or "random").

AntiAliasingPass

  • LEET_ANTI_ALIASING_PROBABILITY(value): Set the probability (0-100) of applying anti aliasing.

AAMBAPass

  • LEET_AAMBA_PROBABILITY(value): Set the probability (0-100) of applying AAMBA to an operation.

NanomitesPass

  • LEET_NANOMITES_PROBABILITY(value): Set the probability (0-100) of applying nanomites to a call.
  • LEET_NANOMITE_CALL(func): Mark a specific call site for nanomite obfuscation.

Generic Pass Control Macros

These work with almost any pass and provide common control options:

  • LEET_SKIP_PASS(pass): Skip the specified pass for this function
  • LEET_FORCE_PASS(pass): Force the specified pass to run on this function
  • LEET_RUNTIME_SEED_PASS(pass, seed): Set the runtime seed for the specified pass
  • LEET_MIN_FUNCTION_SIZE(pass, size): Set the minimum function size for the specified pass
  • LEET_MAX_FUNCTION_SIZE(pass, size): Set the maximum function size for the specified pass
  • LEET_MIN_BLOCK_SIZE(pass, size): Set the minimum block size for the specified pass
  • LEET_MAX_BLOCK_SIZE(pass, size): Set the maximum block size for the specified pass

Apply to All Passes

These macros apply their setting to all passes at once:

  • LEET_SKIP_ALL: Skip all passes for this function
  • LEET_FORCE_ALL: Force all passes to run on this function
  • LEET_RUNTIME_SEED_ALL(seed): Set the runtime seed for all passes
  • LEET_MIN_FUNCTION_SIZE_ALL(size): Set the minimum function size for all passes
  • LEET_MAX_FUNCTION_SIZE_ALL(size): Set the maximum function size for all passes
  • LEET_MIN_BLOCK_SIZE_ALL(size): Set the minimum block size for all passes
  • LEET_MAX_BLOCK_SIZE_ALL(size): Set the maximum block size for all passes

Example usage:

#include "Leet.h"

LEET_FORCE_PASS("DispatcherPass")
LEET_SKIP_PASS("StringEncryptionPass")
LEET_SKIP_PASS("NanomitesPass") // Nanomites are off by default unless overwritten with LEET_NANOMITE_CALL()
LEET_MBA_EXPANSION_COUNT(3)
LEET_MBA_PROBABILITY(80)
void importantFunction()
{
    LEET_NANOMITE_CALL(sensitiveFunction()); // this will get obfuscated with nanomites
    nonSensitiveFunction(); // This won't
}

Logs

If the compilation fails during emitting IR, the code will be dumped into error_log.txt. Additionaly every pass creates a log file inside logs folder in the current working directory.

Clone this wiki locally