https://github.com/sub1to/ctninja
Compile-time string encryption and import obfuscation for Windows PE32(+) binaries
https://github.com/sub1to/ctninja
compile compile-time cplusplus encryption imports joaat joaat64 ninja obfuscation pe32 pe32plus peb peb-walking security stealth string time windows xorstr
Last synced: 8 days ago
JSON representation
Compile-time string encryption and import obfuscation for Windows PE32(+) binaries
- Host: GitHub
- URL: https://github.com/sub1to/ctninja
- Owner: sub1to
- License: mit
- Created: 2025-02-02T11:23:40.000Z (3 months ago)
- Default Branch: public
- Last Pushed: 2025-02-25T15:59:44.000Z (2 months ago)
- Last Synced: 2025-03-29T06:45:04.198Z (29 days ago)
- Topics: compile, compile-time, cplusplus, encryption, imports, joaat, joaat64, ninja, obfuscation, pe32, pe32plus, peb, peb-walking, security, stealth, string, time, windows, xorstr
- Language: C++
- Homepage:
- Size: 89.8 KB
- Stars: 8
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.MD
- Contributing: CONTRIBUTING.MD
- License: LICENSE.MD
Awesome Lists containing this project
README
# CTNinja: Compile-Time Ninja
**Compile-time string encryption and import obfuscation for Windows PE32(+) binaries**
---
## Features
- 🔒 **Compile-Time String Encryption**
Obfuscate strings at compile-time using the `_X` operator to avoid plaintext exposure in binaries.
```cpp
auto str = "SensitiveData"_X; // Encrypted at compile-time
printf(str.c_str());
```
- 🎯 **JOAAT Hashing**
Generate Jenkins One-At-A-Time (JOAAT) hashes at compile-time (`_JOAAT`/`_JOAAT64`) or runtime (`joaat`/`wjoaat`/`joaat64`/`wjoaat64`).
```cpp
constexpr auto hash32 = "Kernel32.dll"_JOAAT; // Compile-time hash
constexpr auto hash64 = "Kernel32.dll"_JOAAT64; // Compile-time hash
```- 🕵️ **PEB Walking & Stealthy Imports**
Resolve modules and exports without `GetProcAddress` or static imports:
```cpp
auto hModule = ctninja::xport::get_module("Kernel32.dll"_JOAAT);
auto pFunc = ctninja::xport::get_export(hModule, "CloseHandle"_JOAAT);
```- 💻 **Operator-Driven Function Calls**
Call obfuscated imports directly via the `$$` syntax:
```cpp
// Predefined in def.h: fpCreateThread, fpLoadLibraryA, fpCloseHandle, etc.
$$(Kernel32.dll, CloseHandle, m_hPipeThread); // Resolves and calls at runtime
```
- 🛡️ **Secure Runtime Value Obfuscation**
Protect in-memory values with XOR + bit rotation using `SecureValue32`/`SecureValue64`. Keys are re-rolled on every access.
Most operators are implemented, and it will implicitly cast to it's template type, allowing you to use SecureValue as if
it is a built-in type.
- **PE32+ Focus**
Built for modern Windows binaries, with minimal overhead.---
## Installation
CTNinja is built using **Premake5**. Follow these steps:1. **Generate Project Files**
Run `build.bat` (Visual Studio 2022) or `premake5 vs2022`.2. **Build the Library**
Compile the generated project to produce `ctninja.lib`.3. **Link in Your Project**
Add `ctninja.lib` and include the `ctninja.h` header.---
## Usage
### 1. Obfuscate Strings
```cpp
#includeprintf("Hello, Malware Analyst"_X.c_str());
```⚠️ **Critical**:
Do not call `c_str()` multiple times on the same object!The data is decrypted on the stack when you call `c_str()`. Calling it again will re-encrypt the data.
- ❌
```cpp
auto str = "SensitiveData"_X; // Encrypted at compile-time
printf(str.c_str());
printf(str.c_str());
```
- ✅
```cpp
auto secstr = "SensitiveData"_X; // Encrypted at compile-time
auto str = secstr.c_str();
printf(str);
printf(str);
```
- ✅
```cpp
printf("SensitiveData"_X.c_str());
printf("SensitiveData"_X.c_str());
```### 2. Resolve Modules/Exports via PEB
```cpp
#includeHMODULE hKernel32 = ctninja::xport::get_module("Kernel32.dll"_JOAAT);
FARPROC pCreateFile = ctninja::xport::get_export(hKernel32, "CreateFileW"_JOAAT);
```### 3. Call Functions Stealthily
```cpp
#define CTNINJA_MAGIC_IMPORT
#define CTNINJA_MAGIC_IMPORT_THROW_ON_FAILURE
#includetry{
HANDLE hFile = $$(Kernel32.dll, CreateFileW, L"file.txt", GENERIC_READ, ...);
}
catch(CallException const& e)
{
ctninja::$printf("%s\n"_X.c_str(), e.what());
}
```- `CTNINJA_MAGIC_IMPORT` enables the `$` and `$$` macros
- `CTNINJA_MAGIC_IMPORT_THROW_ON_FAILURE` enables exceptions in `$$` if the function is not found#### 3.1 Defining Function Signatures
For `$$()` to work, **you must define the function signature** as `fp` in your code.
Predefined signatures for common Windows APIs (e.g., `fpCreateThread`, `fpLoadLibraryA`) are in [`ctninja/include/def.h`](include/def.h).For custom functions, define the typedef **before using `$$()`**:
```cpp
// Example for a custom function
typedef BOOL (WINAPI* fpSomeObscureFunction)(DWORD param1, LPCSTR param2);
// Now call it via:
$$(SomeDll.dll, SomeObscureFunction, 123, "param");
```⚠️ **Critical**:
- The typedef **must** match the exact function signature.
- The naming convention **must** be `fp` (case-sensitive).### 4. JOAAT Hashing
#### 4.1 Compile-Time JOAAT Hashing
```cpp
#includeu32 ulHash32 = "hash_me"_JOAAT; // Compile-Time JOAAT for static strings
u64 ulHash64 = "hash_me"_JOAAT64; // Compile-Time JOAAT64 for static strings
```#### 4.2 Runtime JOAAT Hashing
```cpp
#includeu32 ulHash32 = ctninja::joaat("hash_me"); // Runtime JOAAT for dynamic strings
u64 ulHash64 = ctninja::wjoaat64(L"hash_me"); // Runtime JOAAT64 for dynamic strings
```### 5. Protect Sensitive Values in Memory
#### 5.1 float
```cpp
#includetypedef ctninja::SecureValue32 SV_Float;
SV_Float secretFloat = 123.45f; // Stored encrypted in memory
// Use like a normal value (automatically encrypts/decrypts):
secretFloat += 10.0f;
printf("%f", (float)secretFloat);
```#### 5.2 BYTE*
```cpp
#include// Architecture-agnostic definition (auto-chooses 32/64-bit)
#ifdef _M_X64
typedef ctninja::SecureValue64 SVP_BYTE;
#else
typedef ctninja::SecureValue32 SVP_BYTE;
#endifSVP_BYTE pSec;
pSec = pArray;
*pSec = 0x1f;
pSec[1] = 0x2e;
```---
## Notes
- **Windows Only**: Designed for PE32(+) binaries (x86/x64).
- **C++20 Required**: Relies on `constexpr`/`consteval` for compile-time magic.
- **Antivirus Warnings**: Obfuscation may trigger heuristic detections. Test thoroughly.---
## Authors
- **sub1to** - *Initial work* - [sub1to](https://github.com/sub1to)
See also the list of [contributors](https://github.com/sub1to/ctninja/contributors) who participated in this project.## License
MIT License. See [LICENSE.MD](LICENSE.MD)## Contributing
PRs and issues welcome! See [CONTRIBUTING.MD](CONTRIBUTING.MD) for guidelines.