obsidian community edition - universal pe packer
advanced, open-source obfuscation
obsidian is a custom universal pe packer / executable protector written in C. it is designed to be paired with a loader stub that decrypts and executes the packed payload.
a compiled stub example is available in the stubs folder that uses rolling xor obfuscation with shifts and does not contain any anti-debugging mechanisms.
this packer/stub has been tested to work on putty.exe, strings.exe, and can even pack itself, and then pack other executables from the packed state.
every pe stub/loader gets burned the moment its source becomes public. the only way to stay ahead of this is to write your own custom one. there is an included a template for you to fill out with your own code.
community edition-v1.3:
- ARM64 support now added
- improved xor algorithm
- hash-based import lookups
- compiled xorshift64+ stub (stubs/stub.bin)
- high entropy ASLR support
- stub template (BYOS - bring your own stub)
- extensive debug output (-DDEBUG & --debug flags)
- randomized config marker
- zeroed out optional headers
- secure key generation
- checksum recalculation
- pe section manipulation
- progress bar and colors
obsidian pro is an upgraded version of obsidian community edition with SPECK encryption, aPlib compression, and anti-debugging syscalls. it is licensed using open-source obsidian keykeeper which sits behind a clearnet-to-tor proxy, enabling anonymous license management.
where to find:
pro edition features:
- SPECK 128/128 CTR encryption
- aPlib compression (--compress)
- resource encryption
- extensive syscall anti-debug (--ultra)
- anti-sandbox
- hmac integrity checks
- ollvm-22 obfuscated
community and pro edition:
- pyinstaller support
- remain updated to keep ahead of av detection
commercial edition(future):
- gui
- anti-dump protection
- license support/hardware binding
- online key provisioning
- DRM-like protections
.\obsidian.ce.universal.exe program.exe packed.exe
void obfuscate_data(uint8_t* data, size_t size, uint64_t key) {
uint8_t key_xor_aa = (uint8_t)(key ^ 0xAA);
uint8_t key_xor_aa_shr8 = (uint8_t)((key ^ 0xAA) >> 8);
for (size_t i = 0; i < size; i++) {
uint64_t subkey = key ^ (i * 0x9E3779B97F4A7C15ULL);
subkey = (subkey ^ (subkey >> 30)) * 0xBF58476D1CE4E5B9ULL;
subkey = (subkey ^ (subkey >> 27)) * 0x94D049BB133111EBULL;
subkey = subkey ^ (subkey >> 31);
uint8_t shift1 = (uint8_t)((i * 8) & 0x3F);
uint8_t shift2 = (uint8_t)((24 + i * 8) & 0x3F);
uint8_t shift3 = (uint8_t)((56 + i * 8) & 0x3F);
uint8_t mask = (uint8_t)(subkey >> shift1)
^ (uint8_t)(subkey >> shift2)
^ (uint8_t)(subkey >> shift3);
data[i] ^= mask;
data[i] += key_xor_aa;
data[i] -= key_xor_aa_shr8;
}
}obfuscation process:
- use constants to derive values for add and sub operations
- mix in 'golden ratio' constants into a subkey to increase entropy
- generate shifts and final mask variable
- apply transformation to data
| stub.bin | stub.Oz.bin | stub.obfuscated.bin | stub.full.obf.bin | stub-arm64.bin | |
|---|---|---|---|---|---|
| description: | no optimization | aggressive size optimization | control flow flattening + instruction substitution | fully obfuscated (bogus control flow, splitting, flattening, substitution) | arm64 variant, -O1 optimized |
| size: | 17kb | 13kb | 17kb | 57kb | 5kb |
| tools: | clang/llvm | clang/llvm + Oz | clang/llvm + Oz + ollvm-22 | clang/llvm + Oz + ollvm-22 | clang/llvm + O1 |
| note: | basic | smallest/fastest | balanced | largest/slowest | now available in stubs/ folder |
requirements:
gcc:
- mingw64 tool suite available at
https://winlibs.com/ - windbg or other debugger
- python interpreter for
clean.py
llvm/clang:
- llvm 22 toolchain
- mingw64 tool suite
step 1: build stub object file
gcc:
.\gcc.exe stub.c -o stub.o -fno-asynchronous-unwind-tables -fno-ident -fno-stack-protector
llvm/clang:
clang --target=x86_64-pc-windows-gnu \
-I/llvm-mingw-20260311-ucrt-macos-universal/generic-w64-mingw32/include \
-masm=intel \
-fno-asynchronous-unwind-tables -fno-ident -fno-stack-protector -Oz \
-c stub.c -o stub.o
step 2: link and strip stub binary
both:
.\ld.exe stub.o -o stub.exe -nostdlib --build-id=none -s --entry=_start
.\objcopy.exe -O binary stub.exe stub.bin
.\windres.exe resource.rc -o resource.o
step 3: build obsidian ce
gcc:
.\gcc.exe obsidian.c resource.o -o obsidian.exe -lbcrypt
llvm/clang:
x86_64-w64-mingw32-clang \
-I/llvm-mingw-20260311-ucrt-macos-universal/generic-w64-mingw32/include -O1 \
obsidian.c resource.o -o obsidian.exe -lbcrypt




