- Implement complete cross-process injection engine via snd_inj_ctx_t - Track explicit remote_entry_point for safe thread hijacking and PE execution - Refactor standalone syscall resolvers into a unified pipeline (scan/sort) - Perfect status code system by purging generic fallbacks in favor of highly-specific, domain-aware error codes - Fix minor pointer validation and parsing bugs in the reflective loader
8.2 KiB
Common: API Reference
Public API under include/sindri/common/. Include sindri/common.h for the full surface.
Implementation sources: src/common/ (buffer.c, hash.c, status.c, disk.c, debug.c, crt_manifest.c).
Macros (sindri/common/macros.h)
| Macro | Description |
|---|---|
SND_BEGIN_EXTERN_C / SND_END_EXTERN_C |
C++ extern "C" linkage wrappers |
SND_FORCE_INLINE |
static __forceinline (MSVC) or always_inline (GCC/Clang) |
Memory (sindri/common/memory.h)
Header-only CRT replacements and bounds helpers.
SND_PTR_ADD(base, offset)
Adds a byte offset to a base pointer (casts through unsigned char *).
snd_memory_bounds_check
SND_FORCE_INLINE int snd_memory_bounds_check(size_t total_size, size_t offset, size_t size);
Returns 1 if [offset, offset+size) fits within [0, total_size).
snd_memory_ptr_bounds_check
SND_FORCE_INLINE int snd_memory_ptr_bounds_check(
const void *base, size_t total_size, const void *ptr, size_t size);
Validates that [ptr, ptr+size) lies within [base, base+total_size). Returns 0 if base or ptr is NULL, or if ptr < base.
snd_memzero
Zeroes size bytes at dest using a volatile loop (prevents compiler elision). Replaces memset.
snd_memcpy
Copies count bytes from src to dest. Replaces memcpy.
String (sindri/common/string.h)
Header-only bounded string operations.
ASCII
| Function | Replaces | Notes |
|---|---|---|
snd_strnlen(str, max_len) |
strnlen |
|
snd_strncpy(dest, dest_size, src, max_src_len) |
strncpy |
Always null-terminates |
snd_strncat(dest, dest_size, src, max_src_len) |
strncat |
Bounded append |
snd_strnchr(str, c, max_len) |
strchr |
Bounded search |
snd_strncmp(s1, s2, max_len) |
strncmp |
Returns <0 / 0 / >0 |
Wide (UTF-16)
| Function | Replaces | Notes |
|---|---|---|
snd_wcsnlen(str, max_len) |
wcsnlen |
|
snd_wcsnicmp(s1, s2, n) |
wcsnicmp |
Case-insensitive |
snd_wcsncpy(dest, dest_size, src, max_src_len) |
wcsncpy |
|
snd_wcsncat(dest, dest_size, src, max_src_len) |
wcsncat |
|
snd_ascii_to_wide(dest, dest_size, src, max_src_len) |
mbstowcs |
Latin ASCII → wide |
Used by PEB walking, export forwarders, and LdrLoadDll path construction.
Buffer (sindri/common/buffer.h)
snd_buffer_t
typedef struct snd_buffer_s {
void *data;
size_t size;
snd_free_cb free_routine;
} snd_buffer_t;
snd_free_cb
typedef void (*snd_free_cb)(snd_buffer_t *buf);
snd_buffer_init
Initializes tracking metadata without allocating memory.
void snd_buffer_init(snd_buffer_t *buf, void *data, size_t size, snd_free_cb free_routine);
snd_buffer_free
Invokes free_routine if set, then zeroes the struct.
void snd_buffer_free(snd_buffer_t *buf);
Source: src/common/buffer.c
snd_buffer_bounds_check
SND_FORCE_INLINE int snd_buffer_bounds_check(const snd_buffer_t *buf, size_t offset, size_t size);
Returns 0 if buf is NULL, buf->data is NULL, or buf->size is zero.
Pre-built free routines
| Function | Backend |
|---|---|
snd_buffer_free_heap |
HeapFree(GetProcessHeap(), …) |
snd_buffer_free_virtual |
VirtualFree(…, MEM_RELEASE) |
snd_buffer_free_mapped |
UnmapViewOfFile |
Hashing (sindri/common/hash.h)
Runtime hashing uses the algorithm selected at CMake configure time.
snd_hash
uint32_t snd_hash(const char *str);
Case-sensitive. Export names from the EAT.
snd_hash_lower
uint32_t snd_hash_lower(const char *str);
Lowercases ASCII before hashing. Import DLL names.
snd_hash_wide_lower
uint32_t snd_hash_wide_lower(const wchar_t *str);
Lowercases wide string before hashing. PEB module names.
Source: src/common/hash.c
Status (sindri/common/status.h)
snd_status_t
| Field | Debug (SND_DEBUG=1) |
Release |
|---|---|---|
code |
snd_status_code_t |
same |
os_error |
int |
same |
file |
source file | (omitted) |
line |
line number | (omitted) |
context |
128-byte formatted string | (omitted) |
Convenience macros
| Macro | Description |
|---|---|
SND_SUCCEEDED(x) |
(x.code == SND_SUCCESS) |
SND_FAILED(x) |
(x.code != SND_SUCCESS) |
SND_OK |
Success status |
SND_ERR(code) |
Framework error |
SND_ERR_CTX(code, fmt, …) |
Error with formatted context (debug only) |
SND_ERR_W32(code) |
Error + GetLastError() |
SND_ERR_W32_CTX(code, fmt, …) |
W32 + context |
SND_ERR_NT(code, nt_status) |
Error + NTSTATUS |
SND_ERR_NT_CTX(code, nt_status, fmt, …) |
NT + context |
SND_MAX_CTX_LEN
Value: 128 — max formatted context string length.
Status code ranges (selected)
| Range | Domain |
|---|---|
0x100 |
Command-line errors |
0x200 |
File / I/O |
0x300 |
PE parsing |
0x400 |
Reflective loading |
0x500 |
Syscall resolution |
0x600 |
PEB |
0x800 |
OS / mapping |
0x900 |
Access denied |
Full enum: include/sindri/common/status.h.
snd_status_to_string
const char *snd_status_to_string(snd_status_t status);
Human-readable description. Returns empty string when SND_DEBUG=0.
snd_status_print
void snd_status_print(snd_status_t status);
Prints code, context, OS error, and file/line via SND_DEBUG_PRINT. No-op body when SND_DEBUG=0.
Source: src/common/status.c
Debug (sindri/common/debug.h)
Controlled by CMake SND_ENABLE_DEBUG → SND_DEBUG.
SND_DEBUG_PRINT(fmt, …)
Formatted debug output. No-op when SND_DEBUG=0.
SND_FDEBUG_PRINT(stream, fmt, …)
Stream-targeted output when SND_USE_PRINTF=1; otherwise same as SND_DEBUG_PRINT.
SND_FALLBACK_STR(debug_str)
Returns debug_str when SND_DEBUG=1, "" when SND_DEBUG=0. Used for stage name strings in state machines.
snd_dump_hex
void snd_dump_hex(const void *dat, size_t len_dat, uintptr_t base_off);
Hex + ASCII dump. Only emits when SND_DEBUG=1.
Source: src/common/debug.c
SND_DEBUG_MAX_LEN
Value: 1024 — internal format buffer when using OutputDebugStringA path.
Disk I/O (sindri/common/disk.h)
snd_disk_buffer_load
snd_status_t snd_disk_buffer_load(const char *path, snd_buffer_t *out_buf);
Reads entire file into heap memory. Sets free_routine = snd_buffer_free_heap.
Returns: SND_OK, SND_STATUS_INVALID_PATH, SND_STATUS_FILE_CREATE_FAILED, SND_STATUS_FILE_READ_FAILED, etc.
Source: src/common/disk.c
CRT manifest (src/common/crt_manifest.c)
Global linker symbols (not for direct use):
void *memcpy(void *dest, const void *src, size_t count);
void *memset(void *dest, int c, size_t count);
Compiled when building CRT-less targets. Satisfies MSVC implicit codegen under /NODEFAULTLIB.
Internal NT layouts (include/sindri/internal/nt/)
Not part of sindri/common.h, but replaces the former internal/nt_defs.h monolith.
types.h
| Symbol | Description |
|---|---|
SND_NT_SUCCESS(s) |
((NTSTATUS)(s)) >= 0 |
SND_PAGE_SIZE |
0x1000 |
SND_OBJ_CASE_INSENSITIVE |
0x00000040L |
SND_InitializeObjectAttributes(p, n, a, r, s) |
Init object attributes macro |
SND_UNICODE_STRING |
NT counted wide string |
SND_OBJECT_ATTRIBUTES |
Object Manager attributes |
SND_CLIENT_ID |
Process/thread identifier |
snd_init_unicode_string(us, buf, char_count) |
Inline unicode string init |
api.h
Function pointer typedefs: SND_LdrLoadDll_t, SND_NtOpenSection_t, SND_NtMapViewOfSection_t, SND_NtClose_t, SND_NtAllocateVirtualMemory_t, SND_NtProtectVirtualMemory_t, SND_NtFreeVirtualMemory_t, SND_NtOpenProcess_t, SND_NtWriteVirtualMemory_t, SND_NtCreateThreadEx_t.
peb.h
Layouts: SND_PEB, SND_PEB_LDR_DATA, SND_LDR_DATA_TABLE_ENTRY, SND_RTL_USER_PROCESS_PARAMETERS, SND_CURDIR.
Include via sindri/internal/nt.h.