mirror of
https://github.com/youssefnoob003/SindriKit
synced 2026-07-07 21:57:09 +00:00
Refactor: Encapsulate NTDLL state within syscall subsystem
This commit is contained in:
@@ -91,7 +91,6 @@ add_library(sindri_engine STATIC
|
||||
src/primitives/modules/win.c
|
||||
src/primitives/modules/native.c
|
||||
src/primitives/modules/peb.c
|
||||
src/primitives/modules/ntdll.c
|
||||
# Syscall resolvers
|
||||
src/primitives/syscalls/syscalls.c
|
||||
src/primitives/syscalls/hellsgate.c
|
||||
|
||||
@@ -57,7 +57,7 @@ When operating in native mode, SindriKit needs a clean `ntdll.dll` to extract SS
|
||||
|
||||
At boot, the Session Manager (`smss.exe`) creates pre-mapped, read-only section objects for core system DLLs under the `\KnownDlls` Object Manager directory. These sections are snapshots taken before any userland security software is initialized. Opening `\KnownDlls\ntdll.dll` via `NtOpenSection` and mapping it into the current process with `NtMapViewOfSection` yields a pristine image whose text section has never been touched by EDR hooks.
|
||||
|
||||
The base address of this clean mapping is then fed directly to `snd_set_ntdll()` (from `sindri/primitives/ntdll.h`), ensuring that all subsequent SSN resolution operate on unmodified stubs.
|
||||
The base address of this clean mapping is then fed directly to `snd_set_ntdll()`, ensuring that all subsequent SSN resolution operate on unmodified stubs.
|
||||
|
||||
```c
|
||||
PVOID clean_ntdll = NULL;
|
||||
|
||||
@@ -14,17 +14,3 @@ The primitives domain forms the absolute foundation of SindriKit. Everything bui
|
||||
Techniques for interacting with loaded DLLs and extracting function addresses via PEB traversal.
|
||||
- [syscalls/](syscalls/)
|
||||
The framework's advanced system for bypassing userland EDR hooks via a cascading fallback mechanism.
|
||||
|
||||
---
|
||||
|
||||
## Global Primitives (`sindri/primitives/ntdll.h`)
|
||||
|
||||
SindriKit maintains global state for the `ntdll.dll` base address. This address is used ubiquitously by native components (like the syscall resolver and the native module API) to extract clean stubs or parse export tables without relying on repetitive PEB lookups or the potentially hooked PEB-resident image.
|
||||
|
||||
### `snd_set_ntdll`
|
||||
Sets the globally cached base address of `ntdll.dll`.
|
||||
- **`ntdll_base`**: Base address to cache. Typically obtained via KnownDlls mapping or PEB walking.
|
||||
|
||||
### `snd_get_ntdll`
|
||||
Retrieves the globally cached base address.
|
||||
- **Returns:** `PVOID` The base address, or `NULL` if not set.
|
||||
|
||||
@@ -27,4 +27,4 @@ The `snd_mem_native` implementation bypasses `kernel32.dll` and `ntdll.dll` enti
|
||||
By executing the `syscall` instruction directly, the implant cleanly bypasses userland EDR hooks placed inside the `ntdll.dll` stubs. The kernel receives the memory request without userland telemetry sensors ever recording the event.
|
||||
|
||||
> [!WARNING]
|
||||
> `snd_mem_native` requires the operator to manually configure the syscall pipeline (via `snd_set_syscall_strategy` and `sindri/primitives/ntdll.h`'s `snd_set_ntdll`) prior to invocation. If the pipeline is not bootstrapped, the native memory calls will immediately fail.
|
||||
> `snd_mem_native` requires the operator to manually configure the syscall pipeline (via `snd_set_syscall_strategy` and `snd_set_ntdll`) prior to invocation. If the pipeline is not bootstrapped, the native memory calls will immediately fail.
|
||||
|
||||
@@ -56,9 +56,3 @@ Hash-based variant. Eliminates the plaintext module name string from the binary
|
||||
| `out_base` | `PVOID*` | Receives the base address of the located module |
|
||||
|
||||
**Returns:** `snd_status_t` — `SND_OK` on success.
|
||||
|
||||
---
|
||||
|
||||
## Global NTDLL State (`sindri/primitives/ntdll.h`)
|
||||
|
||||
SindriKit maintains global state for the `ntdll.dll` base address. This address is used ubiquitously by native components to extract clean stubs or parse export tables without relying on repetitive PEB lookups or the potentially hooked PEB-resident image.
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
This directory details SindriKit's advanced system for extracting System Service Numbers (SSNs) and bypassing inline userland EDR hooks.
|
||||
|
||||
> [!WARNING]
|
||||
> **Initialization Constraint:** The syscall pipeline requires setting up the NTDLL base address. `snd_set_ntdll()` (from `sindri/primitives/ntdll.h`) must be called prior to invoking any resolution function.
|
||||
> **Initialization Constraint:** The syscall pipeline requires setting up the NTDLL base address. `snd_set_ntdll()` must be called prior to invoking any resolution function.
|
||||
|
||||
## Table of Contents
|
||||
- [pipeline.md](pipeline.md)
|
||||
|
||||
@@ -65,7 +65,7 @@ Appends a fallback strategy to the resolution pipeline. The pipeline is evaluate
|
||||
### NTDLL Base Address
|
||||
|
||||
> [!NOTE]
|
||||
> The `ntdll.dll` base address is managed globally via `snd_set_ntdll` and `snd_get_ntdll` from `sindri/primitives/ntdll.h`. You MUST set the global base before attempting to resolve syscalls.
|
||||
> The `ntdll.dll` base address is managed globally via `snd_set_ntdll` and `snd_get_ntdll`. You MUST set the global base before attempting to resolve syscalls.
|
||||
|
||||
---
|
||||
|
||||
@@ -91,3 +91,19 @@ ASM stub that performs the actual `syscall` instruction. Architecture-specific i
|
||||
| `args` | `snd_syscall_args_t*` | Pointer to a populated arguments structure |
|
||||
|
||||
**Returns:** `NTSTATUS` — the raw kernel return value.
|
||||
|
||||
### `snd_set_ntdll`
|
||||
Sets the global `ntdll.dll` base address.
|
||||
|
||||
| Parameter | Type | Description |
|
||||
|---|---|---|
|
||||
| `base` | `PVOID` | The base address of the `ntdll.dll` image |
|
||||
|
||||
**Returns:** `void`
|
||||
|
||||
---
|
||||
|
||||
### `snd_get_ntdll`
|
||||
Returns the global `ntdll.dll` base address.
|
||||
|
||||
**Returns:** `PVOID` — the base address of the `ntdll.dll` image, or `NULL` if not set.
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
#include <sindri/primitives/heavens_gate.h>
|
||||
#include <sindri/primitives/memory.h>
|
||||
#include <sindri/primitives/modules.h>
|
||||
#include <sindri/primitives/ntdll.h>
|
||||
#include <sindri/primitives/os_api.h>
|
||||
#include <sindri/primitives/peb.h>
|
||||
#include <sindri/primitives/syscalls.h>
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
#ifndef SND_PRIMITIVES_NTDLL_H
|
||||
#define SND_PRIMITIVES_NTDLL_H
|
||||
|
||||
#include <sindri/common/helpers.h>
|
||||
#include <windows.h>
|
||||
|
||||
SND_BEGIN_EXTERN_C
|
||||
|
||||
/**
|
||||
* @brief Sets the global base address of the ntdll.dll module.
|
||||
* @param ntdll_base The base address of the ntdll module.
|
||||
*/
|
||||
void snd_set_ntdll(PVOID ntdll_base);
|
||||
|
||||
/**
|
||||
* @brief Retrieves the global base address of the ntdll.dll module.
|
||||
* @return The base address of the ntdll module, or NULL if not set.
|
||||
*/
|
||||
PVOID snd_get_ntdll(void);
|
||||
|
||||
SND_END_EXTERN_C
|
||||
|
||||
#endif // SND_PRIMITIVES_NTDLL_H
|
||||
@@ -59,6 +59,18 @@ void snd_set_syscall_strategy(snd_syscall_resolver_t resolver);
|
||||
*/
|
||||
snd_status_t snd_add_syscall_strategy(snd_syscall_resolver_t resolver);
|
||||
|
||||
/**
|
||||
* @brief Sets the global base address of the ntdll.dll module.
|
||||
* @param ntdll_base The base address of the ntdll module.
|
||||
*/
|
||||
void snd_set_ntdll(PVOID ntdll_base);
|
||||
|
||||
/**
|
||||
* @brief Retrieves the global base address of the ntdll.dll module.
|
||||
* @return The base address of the ntdll module, or NULL if not set.
|
||||
*/
|
||||
PVOID snd_get_ntdll(void);
|
||||
|
||||
/**
|
||||
* @brief Core resolution entrypoint (evaluates the internal fallback chain
|
||||
* automatically).
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
#include <sindri/primitives/ntdll.h>
|
||||
|
||||
static PVOID g_PristineNtdll = NULL;
|
||||
|
||||
void snd_set_ntdll(PVOID ntdll_base) {
|
||||
if (ntdll_base == NULL) {
|
||||
return;
|
||||
}
|
||||
g_PristineNtdll = ntdll_base;
|
||||
}
|
||||
|
||||
PVOID snd_get_ntdll(void) {
|
||||
return g_PristineNtdll;
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
#include <sindri/common/status.h>
|
||||
#include <sindri/primitives/ntdll.h>
|
||||
#include <sindri/primitives/peb.h>
|
||||
#include <sindri/primitives/syscalls.h>
|
||||
#include <windows.h>
|
||||
@@ -9,6 +8,18 @@
|
||||
// State management for the resolution pipeline
|
||||
static snd_syscall_resolver_t g_strategy_chain[SND_MAX_INTERNAL_STRATEGIES] = {0};
|
||||
static int g_strategy_count = 0;
|
||||
static PVOID g_syscall_ntdll_target = NULL;
|
||||
|
||||
void snd_set_ntdll(PVOID ntdll_base) {
|
||||
if (ntdll_base == NULL) {
|
||||
return;
|
||||
}
|
||||
g_syscall_ntdll_target = ntdll_base;
|
||||
}
|
||||
|
||||
PVOID snd_get_ntdll(void) {
|
||||
return g_syscall_ntdll_target;
|
||||
}
|
||||
|
||||
void snd_set_syscall_strategy(snd_syscall_resolver_t resolver) {
|
||||
if (!resolver)
|
||||
|
||||
Reference in New Issue
Block a user