mirror of
https://github.com/youssefnoob003/SindriKit
synced 2026-07-07 21:57:09 +00:00
Release v1.1.0: Process Injection & Architecture Hardening
- 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
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
#define SINDRI_H
|
||||
|
||||
#include <sindri/common.h>
|
||||
#include <sindri/injection.h>
|
||||
#include <sindri/loaders.h>
|
||||
#include <sindri/parsers.h>
|
||||
#include <sindri/primitives.h>
|
||||
|
||||
@@ -2,9 +2,12 @@
|
||||
#define SND_COMMON_H
|
||||
|
||||
#include <sindri/common/buffer.h>
|
||||
#include <sindri/common/debug.h>
|
||||
#include <sindri/common/disk.h>
|
||||
#include <sindri/common/hash.h>
|
||||
#include <sindri/common/helpers.h>
|
||||
#include <sindri/common/macros.h>
|
||||
#include <sindri/common/memory.h>
|
||||
#include <sindri/common/status.h>
|
||||
#include <sindri/common/string.h>
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
#ifndef SND_COMMON_BUFFER_H
|
||||
#define SND_COMMON_BUFFER_H
|
||||
|
||||
#include <sindri/common/helpers.h>
|
||||
#include <sindri/common/macros.h>
|
||||
#include <sindri/common/memory.h>
|
||||
#include <stddef.h>
|
||||
#include <windows.h>
|
||||
|
||||
SND_BEGIN_EXTERN_C
|
||||
@@ -11,7 +13,6 @@ typedef struct snd_buffer_s snd_buffer_t;
|
||||
|
||||
/**
|
||||
* @brief Function signature for the custom buffer deallocator callback.
|
||||
* @param buf Pointer to the buffer structure being freed.
|
||||
*/
|
||||
typedef void (*snd_free_cb)(snd_buffer_t *buf);
|
||||
|
||||
@@ -19,8 +20,8 @@ typedef void (*snd_free_cb)(snd_buffer_t *buf);
|
||||
* @brief Represents a tracked, bounds-checked memory buffer.
|
||||
*/
|
||||
struct snd_buffer_s {
|
||||
LPVOID data;
|
||||
SIZE_T size;
|
||||
void *data;
|
||||
size_t size;
|
||||
snd_free_cb free_routine;
|
||||
};
|
||||
|
||||
@@ -31,32 +32,25 @@ struct snd_buffer_s {
|
||||
* @param size Size of the memory block.
|
||||
* @param free_routine Optional callback used to safely deallocate this memory.
|
||||
*/
|
||||
void snd_buffer_init(snd_buffer_t *buf, LPVOID data, SIZE_T size, snd_free_cb free_routine);
|
||||
void snd_buffer_init(snd_buffer_t *buf, void *data, size_t size, snd_free_cb free_routine);
|
||||
|
||||
/**
|
||||
* @brief Frees a tracked buffer using its assigned cleanup routine and zeroes
|
||||
* the structure.
|
||||
* @param buf Pointer to the buffer structure to free.
|
||||
* @brief Frees a tracked buffer using its assigned cleanup routine and zeroes the structure.
|
||||
*/
|
||||
void snd_buffer_free(snd_buffer_t *buf);
|
||||
|
||||
/**
|
||||
* @brief Checks if a given offset and size are within the bounds of a buffer.
|
||||
*
|
||||
* @param buf The buffer context to check against.
|
||||
* @param offset The offset from the start of the buffer.
|
||||
* @param size The size of the region to check.
|
||||
* @return TRUE if within bounds, FALSE otherwise.
|
||||
* @return 1 if within bounds, 0 otherwise.
|
||||
*/
|
||||
SND_FORCE_INLINE BOOL snd_buffer_bounds_check(const snd_buffer_t *buf, SIZE_T offset, SIZE_T size) {
|
||||
SND_FORCE_INLINE int snd_buffer_bounds_check(const snd_buffer_t *buf, size_t offset, size_t size) {
|
||||
if (buf == NULL || buf->data == NULL || buf->size == 0)
|
||||
return FALSE;
|
||||
return snd_bounds_check(buf->size, offset, size);
|
||||
return 0;
|
||||
return snd_memory_bounds_check(buf->size, offset, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Default routine for buffers allocated via HeapAlloc on the process
|
||||
* heap.
|
||||
* @brief Default routine for buffers allocated via HeapAlloc on the process heap.
|
||||
*/
|
||||
SND_FORCE_INLINE void snd_buffer_free_heap(snd_buffer_t *buf) {
|
||||
if (buf && buf->data) {
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
#ifndef SND_COMMON_DEBUG_H
|
||||
#define SND_COMMON_DEBUG_H
|
||||
|
||||
#include <sindri/common/macros.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* @def SND_DEBUG
|
||||
* @brief Global toggle for debug output.
|
||||
*/
|
||||
#ifndef SND_DEBUG
|
||||
#define SND_DEBUG 0
|
||||
#endif
|
||||
|
||||
/* * Macro block to strip diagnostic error string literals out of the .rdata
|
||||
* section entirely when compiling for the production/SILENT tier.
|
||||
*/
|
||||
#if SND_DEBUG
|
||||
#define SND_FALLBACK_STR(debug_str) debug_str
|
||||
#else
|
||||
#define SND_FALLBACK_STR(debug_str) ""
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def SND_USE_PRINTF
|
||||
* @brief Toggles debug output destination (1 for stdout, 0 for OutputDebugStringA).
|
||||
*/
|
||||
#ifndef SND_USE_PRINTF
|
||||
#define SND_USE_PRINTF 0
|
||||
#endif
|
||||
|
||||
SND_BEGIN_EXTERN_C
|
||||
|
||||
#if SND_DEBUG
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
|
||||
#if SND_USE_PRINTF
|
||||
|
||||
#define SND_FDEBUG_PRINT(stream, fmt, ...) \
|
||||
do { \
|
||||
FILE *_s = (stream) ? (FILE *)(stream) : stdout; \
|
||||
fprintf(_s, fmt, ##__VA_ARGS__); \
|
||||
fflush(_s); \
|
||||
} while (0)
|
||||
|
||||
#define SND_DEBUG_PRINT(fmt, ...) SND_FDEBUG_PRINT(stdout, fmt, ##__VA_ARGS__)
|
||||
|
||||
#else
|
||||
|
||||
#define SND_DEBUG_MAX_LEN 1024
|
||||
|
||||
static inline void debug_print(const char *fmt, ...) {
|
||||
char buf[SND_DEBUG_MAX_LEN];
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
vsnprintf(buf, sizeof(buf), fmt, args);
|
||||
va_end(args);
|
||||
|
||||
OutputDebugStringA(buf);
|
||||
}
|
||||
|
||||
#define SND_FDEBUG_PRINT(stream, fmt, ...) debug_print(fmt, ##__VA_ARGS__)
|
||||
#define SND_DEBUG_PRINT(fmt, ...) debug_print(fmt, ##__VA_ARGS__)
|
||||
|
||||
#endif // SND_USE_PRINTF
|
||||
|
||||
#else
|
||||
|
||||
#define SND_FDEBUG_PRINT(stream, fmt, ...) \
|
||||
do { \
|
||||
(void)(stream); \
|
||||
} while (0)
|
||||
|
||||
#define SND_DEBUG_PRINT(fmt, ...) \
|
||||
do { \
|
||||
(void)0; \
|
||||
} while (0)
|
||||
|
||||
#endif // SND_DEBUG
|
||||
|
||||
/**
|
||||
* @brief Prints a combined hexadecimal and ASCII view of a byte buffer.
|
||||
*/
|
||||
void snd_dump_hex(const void *dat, size_t len_dat, uintptr_t base_off);
|
||||
|
||||
SND_END_EXTERN_C
|
||||
|
||||
#endif // SND_COMMON_DEBUG_H
|
||||
@@ -2,7 +2,7 @@
|
||||
#define SND_COMMON_DISK_H
|
||||
|
||||
#include <sindri/common/buffer.h>
|
||||
#include <sindri/common/helpers.h>
|
||||
#include <sindri/common/macros.h>
|
||||
#include <sindri/common/status.h>
|
||||
|
||||
SND_BEGIN_EXTERN_C
|
||||
@@ -16,7 +16,7 @@ SND_BEGIN_EXTERN_C
|
||||
* @note The caller is responsible for freeing the buffer using
|
||||
* snd_buffer_free(out_buf).
|
||||
*/
|
||||
snd_status_t snd_buffer_load_from_disk(const char *path, snd_buffer_t *out_buf);
|
||||
snd_status_t snd_disk_buffer_load(const char *path, snd_buffer_t *out_buf);
|
||||
|
||||
SND_END_EXTERN_C
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#ifndef SND_COMMON_HASH_H
|
||||
#define SND_COMMON_HASH_H
|
||||
|
||||
#include <sindri/common/helpers.h>
|
||||
#include <windows.h>
|
||||
#include <sindri/common/macros.h>
|
||||
#include <stdint.h>
|
||||
|
||||
SND_BEGIN_EXTERN_C
|
||||
|
||||
@@ -11,21 +11,21 @@ SND_BEGIN_EXTERN_C
|
||||
* (Case-Sensitive).
|
||||
* @note Use this for API names from the Export Directory.
|
||||
*/
|
||||
DWORD snd_hash(const char *str);
|
||||
uint32_t snd_hash(const char *str);
|
||||
|
||||
/**
|
||||
* @brief Computes the configured hash of a standard ASCII string, converting to
|
||||
* lowercase.
|
||||
* @note Use this for DLL names found in the PE Import Directory.
|
||||
*/
|
||||
DWORD snd_hash_lower(const char *str);
|
||||
uint32_t snd_hash_lower(const char *str);
|
||||
|
||||
/**
|
||||
* @brief Computes the configured hash of a wide string, converting to lowercase
|
||||
* (Case-Insensitive).
|
||||
* @note Use this for finding DLL module names in the PEB.
|
||||
*/
|
||||
DWORD snd_hash_wide_lower(const wchar_t *str);
|
||||
uint32_t snd_hash_wide_lower(const wchar_t *str);
|
||||
|
||||
SND_END_EXTERN_C
|
||||
|
||||
|
||||
@@ -1,305 +0,0 @@
|
||||
#ifndef SND_COMMON_HELPERS_H
|
||||
#define SND_COMMON_HELPERS_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <windows.h>
|
||||
|
||||
/**
|
||||
* @def SND_DEBUG
|
||||
* @brief Global toggle for debug output.
|
||||
* Set to 1 to enable logging macros, or 0 to compile them out entirely for
|
||||
* Release builds.
|
||||
*/
|
||||
#ifndef SND_DEBUG
|
||||
#define SND_DEBUG 0
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def SND_USE_PRINTF
|
||||
* @brief Toggles the debug output destination.
|
||||
* If 1, debug macros route to standard stdout via `printf`.
|
||||
* If 0, debug macros route to the Windows kernel debugger via
|
||||
* `OutputDebugStringA`.
|
||||
*/
|
||||
#ifndef SND_USE_PRINTF
|
||||
#define SND_USE_PRINTF 0
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def SND_BEGIN_EXTERN_C
|
||||
* @brief Opens an `extern "C"` linkage block for C++ compatibility.
|
||||
*/
|
||||
/**
|
||||
* @def SND_END_EXTERN_C
|
||||
* @brief Closes an `extern "C"` linkage block.
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
#define SND_BEGIN_EXTERN_C extern "C" {
|
||||
#define SND_END_EXTERN_C }
|
||||
#else
|
||||
#define SND_BEGIN_EXTERN_C
|
||||
#define SND_END_EXTERN_C
|
||||
#endif
|
||||
|
||||
SND_BEGIN_EXTERN_C
|
||||
|
||||
/**
|
||||
* @def SND_FORCE_INLINE
|
||||
* @brief Compiler-agnostic macro to force function inlining.
|
||||
* Useful for embedding bounds checks and offset calculations directly into the
|
||||
* caller's assembly.
|
||||
*/
|
||||
#if defined(_MSC_VER)
|
||||
#define SND_FORCE_INLINE static __forceinline
|
||||
#else
|
||||
#define SND_FORCE_INLINE static inline __attribute__((always_inline))
|
||||
#endif
|
||||
|
||||
#if SND_DEBUG
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#if SND_USE_PRINTF
|
||||
/**
|
||||
* @def SND_FDEBUG_PRINT
|
||||
* @brief Formats and prints a debug message to a specific file stream (e.g.,
|
||||
* stderr, stdout).
|
||||
*/
|
||||
#define SND_FDEBUG_PRINT(stream, fmt, ...) \
|
||||
do { \
|
||||
FILE *_s = (stream) ? (FILE *)(stream) : stdout; \
|
||||
fprintf(_s, fmt, ##__VA_ARGS__); \
|
||||
fflush(_s); \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* @def SND_DEBUG_PRINT
|
||||
* @brief Formats and prints a debug message to standard output.
|
||||
*/
|
||||
#define SND_DEBUG_PRINT(fmt, ...) SND_FDEBUG_PRINT(stdout, fmt, ##__VA_ARGS__)
|
||||
|
||||
#else
|
||||
/**
|
||||
* @def SND_DEBUG_MAX_LEN
|
||||
* @brief Maximum string length for the internal debug formatting buffer.
|
||||
*/
|
||||
#define SND_DEBUG_MAX_LEN 1024
|
||||
|
||||
/**
|
||||
* @brief Internal variadic wrapper to format strings for the Windows Debugger.
|
||||
* @note This is completely stripped out of Release builds.
|
||||
*/
|
||||
static inline void snd_debug_print_internal(const char *fmt, ...) {
|
||||
char buf[SND_DEBUG_MAX_LEN];
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
// Safely format the string into our local buffer (requires CRT in debug mode)
|
||||
vsnprintf(buf, sizeof(buf), fmt, args);
|
||||
va_end(args);
|
||||
|
||||
// Send the formatted string to the Windows kernel debug buffer
|
||||
OutputDebugStringA(buf);
|
||||
}
|
||||
|
||||
// Map both macros to the new OutputDebugString wrapper
|
||||
#define SND_FDEBUG_PRINT(stream, fmt, ...) snd_debug_print_internal(fmt, ##__VA_ARGS__)
|
||||
|
||||
#define SND_DEBUG_PRINT(fmt, ...) snd_debug_print_internal(fmt, ##__VA_ARGS__)
|
||||
|
||||
#endif // SND_USE_PRINTF
|
||||
|
||||
#else
|
||||
// When SND_DEBUG is 0, these macros compile to empty no-ops to strip strings
|
||||
// from the binary.
|
||||
#define SND_FDEBUG_PRINT(stream, fmt, ...) \
|
||||
do { \
|
||||
(void)(stream); \
|
||||
} while (0)
|
||||
|
||||
#define SND_DEBUG_PRINT(fmt, ...) \
|
||||
do { \
|
||||
(void)0; \
|
||||
} while (0)
|
||||
#endif // SND_DEBUG
|
||||
|
||||
/**
|
||||
* @def SND_PTR_ADD
|
||||
* @brief Safely adds a byte offset to a base pointer by casting to a BYTE
|
||||
* pointer first.
|
||||
*/
|
||||
#define SND_PTR_ADD(base, offset) ((BYTE *)(base) + (offset))
|
||||
|
||||
/**
|
||||
* @brief Prints a combined hexadecimal and ASCII view of a byte buffer.
|
||||
* @param dat Pointer to the first byte to print.
|
||||
* @param len_dat Number of bytes to dump from @p dat.
|
||||
* @param base_off Base address used to compute printed relative offsets.
|
||||
*
|
||||
* @note Output is gated by `SND_DEBUG` through debug print macros.
|
||||
*/
|
||||
void snd_dump_hex(const void *dat, size_t len_dat, ULONG_PTR base_off);
|
||||
|
||||
/**
|
||||
* @brief Checks if a given size and offset are within the bounds of a total
|
||||
* size.
|
||||
* @param total_size The total size of the buffer.
|
||||
* @param offset The offset from the start.
|
||||
* @param size The size of the region to check.
|
||||
* @return TRUE if within bounds, FALSE otherwise.
|
||||
*/
|
||||
SND_FORCE_INLINE BOOL snd_bounds_check(SIZE_T total_size, SIZE_T offset, SIZE_T size) {
|
||||
if (offset > total_size)
|
||||
return FALSE;
|
||||
if (size > total_size - offset)
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Checks if a pointer and size are within the bounds of a base pointer
|
||||
* and total size.
|
||||
* @param base The base pointer.
|
||||
* @param total_size The total size of the base buffer.
|
||||
* @param ptr The target pointer to check.
|
||||
* @param size The size of the region at the target pointer.
|
||||
* @return TRUE if within bounds, FALSE otherwise.
|
||||
*/
|
||||
SND_FORCE_INLINE BOOL snd_ptr_bounds_check(const void *base, SIZE_T total_size, const void *ptr, SIZE_T size) {
|
||||
if (base == NULL || ptr == NULL)
|
||||
return FALSE;
|
||||
ULONG_PTR ubase = (ULONG_PTR)base;
|
||||
ULONG_PTR utarget = (ULONG_PTR)ptr;
|
||||
if (utarget < ubase)
|
||||
return FALSE;
|
||||
SIZE_T offset = (SIZE_T)(utarget - ubase);
|
||||
return snd_bounds_check(total_size, offset, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Bounded, CRT-independent memory zeroing routine.
|
||||
* Replaces memset.
|
||||
*/
|
||||
SND_FORCE_INLINE void snd_memzero(void *dest, size_t size) {
|
||||
if (!dest)
|
||||
return;
|
||||
volatile BYTE *p = (volatile BYTE *)dest;
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
p[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Raw byte copy routine.
|
||||
* Replaces memcpy.
|
||||
*/
|
||||
SND_FORCE_INLINE void snd_memcpy(void *dest, const void *src, size_t count) {
|
||||
if (!dest || !src)
|
||||
return;
|
||||
BYTE *d = (BYTE *)dest;
|
||||
const BYTE *s = (const BYTE *)src;
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
d[i] = s[i];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Bounded, CRT-independent string length evaluation.
|
||||
* Replaces strnlen.
|
||||
*/
|
||||
SND_FORCE_INLINE size_t snd_strnlen(const char *str, size_t max_len) {
|
||||
if (!str)
|
||||
return 0;
|
||||
size_t len = 0;
|
||||
while (len < max_len && str[len] != '\0') {
|
||||
len++;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Bounded, truncation-safe string copying.
|
||||
* Replaces strncpy / strncpy_s.
|
||||
*/
|
||||
SND_FORCE_INLINE void snd_strncpy(char *dest, size_t dest_size, const char *src, size_t max_src_len) {
|
||||
if (!dest || dest_size == 0 || !src)
|
||||
return;
|
||||
|
||||
size_t i = 0;
|
||||
while (i < (dest_size - 1) && i < max_src_len && src[i] != '\0') {
|
||||
dest[i] = src[i];
|
||||
i++;
|
||||
}
|
||||
dest[i] = '\0';
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Bounded, CRT-independent string concatenation.
|
||||
* Replaces strcat / strcat_s.
|
||||
*/
|
||||
static inline void snd_strncat(char *dest, SIZE_T dest_size, const char *src, SIZE_T max_src_len) {
|
||||
if (!dest || dest_size == 0 || !src)
|
||||
return;
|
||||
|
||||
SIZE_T dest_len = 0;
|
||||
while (dest_len < dest_size && dest[dest_len] != '\0') {
|
||||
dest_len++;
|
||||
}
|
||||
|
||||
if (dest_len >= dest_size - 1) {
|
||||
dest[dest_size - 1] = '\0';
|
||||
return;
|
||||
}
|
||||
|
||||
SIZE_T i = 0;
|
||||
while (i < max_src_len && src[i] != '\0' && (dest_len + i) < (dest_size - 1)) {
|
||||
dest[dest_len + i] = src[i];
|
||||
i++;
|
||||
}
|
||||
|
||||
dest[dest_len + i] = '\0';
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Bounded, CRT-independent character search.
|
||||
* Replaces strchr.
|
||||
*/
|
||||
static inline const char *snd_strnchr(const char *str, char c, SIZE_T max_len) {
|
||||
if (!str)
|
||||
return NULL;
|
||||
|
||||
for (SIZE_T i = 0; i < max_len; i++) {
|
||||
if (str[i] == c) {
|
||||
return &str[i];
|
||||
}
|
||||
if (str[i] == '\0') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Bounded, CRT-independent string comparison.
|
||||
* Replaces strcmp / strncmp.
|
||||
*/
|
||||
static inline int snd_strncmp(const char *s1, const char *s2, SIZE_T max_len) {
|
||||
if (!s1 || !s2)
|
||||
return (s1 == s2) ? 0 : ((s1 < s2) ? -1 : 1);
|
||||
|
||||
for (SIZE_T i = 0; i < max_len; i++) {
|
||||
if (s1[i] != s2[i]) {
|
||||
return (int)((unsigned char)s1[i] - (unsigned char)s2[i]);
|
||||
}
|
||||
if (s1[i] == '\0') {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
SND_END_EXTERN_C
|
||||
|
||||
#endif // SND_COMMON_HELPERS_H
|
||||
@@ -0,0 +1,32 @@
|
||||
#ifndef SND_COMMON_MACROS_H
|
||||
#define SND_COMMON_MACROS_H
|
||||
|
||||
/**
|
||||
* @def SND_BEGIN_EXTERN_C
|
||||
* @brief Opens an `extern "C"` linkage block for C++ compatibility.
|
||||
*/
|
||||
/**
|
||||
* @def SND_END_EXTERN_C
|
||||
* @brief Closes an `extern "C"` linkage block.
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
#define SND_BEGIN_EXTERN_C extern "C" {
|
||||
#define SND_END_EXTERN_C }
|
||||
#else
|
||||
#define SND_BEGIN_EXTERN_C
|
||||
#define SND_END_EXTERN_C
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def SND_FORCE_INLINE
|
||||
* @brief Compiler-agnostic macro to force function inlining.
|
||||
* Useful for embedding bounds checks and offset calculations directly into the
|
||||
* caller's assembly.
|
||||
*/
|
||||
#if defined(_MSC_VER)
|
||||
#define SND_FORCE_INLINE static __forceinline
|
||||
#else
|
||||
#define SND_FORCE_INLINE static inline __attribute__((always_inline))
|
||||
#endif
|
||||
|
||||
#endif // SND_COMMON_MACROS_H
|
||||
@@ -0,0 +1,70 @@
|
||||
#ifndef SND_COMMON_MEMORY_H
|
||||
#define SND_COMMON_MEMORY_H
|
||||
|
||||
#include <sindri/common/macros.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
SND_BEGIN_EXTERN_C
|
||||
|
||||
/**
|
||||
* @def SND_PTR_ADD
|
||||
* @brief Safely adds a byte offset to a base pointer.
|
||||
*/
|
||||
#define SND_PTR_ADD(base, offset) ((unsigned char *)(base) + (offset))
|
||||
|
||||
/**
|
||||
* @brief Checks if a given size and offset are within the bounds of a total size.
|
||||
* @return 1 if within bounds, 0 otherwise.
|
||||
*/
|
||||
SND_FORCE_INLINE int snd_memory_bounds_check(size_t total_size, size_t offset, size_t size) {
|
||||
if (offset > total_size)
|
||||
return 0;
|
||||
if (size > total_size - offset)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Checks if a pointer and size are within the bounds of a base pointer and total size.
|
||||
* @return 1 if within bounds, 0 otherwise.
|
||||
*/
|
||||
SND_FORCE_INLINE int snd_memory_ptr_bounds_check(const void *base, size_t total_size, const void *ptr, size_t size) {
|
||||
if (base == NULL || ptr == NULL)
|
||||
return 0;
|
||||
uintptr_t ubase = (uintptr_t)base;
|
||||
uintptr_t utarget = (uintptr_t)ptr;
|
||||
if (utarget < ubase)
|
||||
return 0;
|
||||
size_t offset = (size_t)(utarget - ubase);
|
||||
return snd_memory_bounds_check(total_size, offset, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Bounded, CRT-independent memory zeroing routine. Replaces memset.
|
||||
*/
|
||||
SND_FORCE_INLINE void snd_memzero(void *dest, size_t size) {
|
||||
if (!dest)
|
||||
return;
|
||||
volatile unsigned char *p = (volatile unsigned char *)dest;
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
p[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Raw byte copy routine. Replaces memcpy.
|
||||
*/
|
||||
SND_FORCE_INLINE void snd_memcpy(void *dest, const void *src, size_t count) {
|
||||
if (!dest || !src)
|
||||
return;
|
||||
unsigned char *d = (unsigned char *)dest;
|
||||
const unsigned char *s = (const unsigned char *)src;
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
d[i] = s[i];
|
||||
}
|
||||
}
|
||||
|
||||
SND_END_EXTERN_C
|
||||
|
||||
#endif // SND_COMMON_MEMORY_H
|
||||
@@ -1,27 +1,35 @@
|
||||
#ifndef SND_COMMON_STATUS_H
|
||||
#define SND_COMMON_STATUS_H
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#if SND_DEBUG
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#include <sindri/common/helpers.h>
|
||||
#include <sindri/common/macros.h>
|
||||
|
||||
SND_BEGIN_EXTERN_C
|
||||
|
||||
// Maximum length for error context strings (including null terminator)
|
||||
#define SND_MAX_CTX_LEN 128
|
||||
#define SND_MAX_CTX_LEN 128
|
||||
#define SND_FAILED(x) (x.code != SND_SUCCESS)
|
||||
#define SND_SUCCEEDED(x) (x.code == SND_SUCCESS)
|
||||
|
||||
typedef enum _SND_STATUS_CODE {
|
||||
SND_SUCCESS = 0,
|
||||
SND_ERROR_GENERIC = -1,
|
||||
SND_STATUS_INVALID_PARAMETER = -2,
|
||||
SND_STATUS_INTEGER_OVERFLOW = -3,
|
||||
SND_STATUS_UNSUPPORTED = -4,
|
||||
SND_STATUS_NOT_INITIALIZED = -5,
|
||||
SND_SUCCESS = 0,
|
||||
SND_ERROR_GENERIC = -1,
|
||||
SND_STATUS_NULL_POINTER = -2,
|
||||
SND_STATUS_INTEGER_OVERFLOW = -3,
|
||||
SND_STATUS_UNSUPPORTED = -4,
|
||||
SND_STATUS_NOT_INITIALIZED = -5,
|
||||
SND_STATUS_BUFFER_TOO_SMALL = -6,
|
||||
|
||||
// Core Engine Execution Errors
|
||||
SND_STATUS_TOO_MANY_ARGUMENTS = 0x50,
|
||||
SND_STATUS_NTDLL_NOT_INITIALIZED,
|
||||
SND_STATUS_RESOLVER_NOT_INITIALIZED,
|
||||
SND_STATUS_OM_NOT_INITIALIZED,
|
||||
SND_STATUS_PIPELINE_EXHAUSTED,
|
||||
|
||||
// Command-line argument errors
|
||||
SND_STATUS_MISSING_COMMAND_LINE_ARGS = 0x100,
|
||||
@@ -51,6 +59,8 @@ typedef enum _SND_STATUS_CODE {
|
||||
SND_STATUS_INVALID_IMPORT_TABLE_SIZE,
|
||||
SND_STATUS_INVALID_FILE_OFFSET,
|
||||
SND_STATUS_DIRECTORY_NOT_FOUND,
|
||||
SND_STATUS_CORRUPTED_STATE,
|
||||
SND_STATUS_IMAGE_NOT_MAPPED,
|
||||
|
||||
// Reflective loading errors
|
||||
SND_STATUS_SECTION_COPY_FAILED = 0x400,
|
||||
@@ -68,15 +78,32 @@ typedef enum _SND_STATUS_CODE {
|
||||
SND_STATUS_EXPORT_FORWARDER_UNSUPPORTED,
|
||||
SND_STATUS_MISSING_DLL_EXPORT_NAME,
|
||||
SND_STATUS_INVALID_STAGE_SEQUENCE,
|
||||
SND_STATUS_CORRUPTED_STATE,
|
||||
SND_FAILED_TO_EXECUTE,
|
||||
SND_STATUS_LOCAL_EXECUTION_BLOCKED,
|
||||
|
||||
// Syscall resolution errors
|
||||
SND_STATUS_SSN_NOT_FOUND,
|
||||
SND_STATUS_SSN_BUFFER_TOO_SMALL,
|
||||
SND_STATUS_SSN_NOT_FOUND = 0x500,
|
||||
|
||||
// PEB
|
||||
SND_STATUS_PEB_MODULE_NOT_FOUND,
|
||||
SND_STATUS_PEB_MODULE_NOT_FOUND = 0x600,
|
||||
SND_STATUS_PEB_PROCESS_PARAMETERS_NOT_FOUND,
|
||||
|
||||
// OS errors
|
||||
SND_STATUS_MODULE_NOT_FOUND = 0x800,
|
||||
SND_STATUS_SECTION_OPEN_FAILED,
|
||||
SND_STATUS_SECTION_MAP_FAILED,
|
||||
SND_STATUS_HANDLE_CLOSE_FAILED,
|
||||
SND_STATUS_PROCESS_OPEN_FAILED,
|
||||
SND_STATUS_VIRTUAL_ALLOC_FAILED,
|
||||
SND_STATUS_VIRTUAL_WRITE_FAILED,
|
||||
SND_STATUS_VIRTUAL_PROTECT_FAILED,
|
||||
SND_STATUS_THREAD_CREATE_FAILED,
|
||||
SND_STATUS_VIRTUAL_FREE_FAILED,
|
||||
|
||||
// Remote process errors
|
||||
SND_STATUS_ACCESS_DENIED = 0x900,
|
||||
SND_STATUS_INVALID_PAYLOAD,
|
||||
SND_STATUS_INVALID_INJECTION_TARGET,
|
||||
} snd_status_code_t;
|
||||
|
||||
typedef struct _SND_STATUS {
|
||||
@@ -113,11 +140,13 @@ static inline snd_status_t _snd_make_success() {
|
||||
return status;
|
||||
}
|
||||
|
||||
#define SND_OK _snd_make_success()
|
||||
#define SND_ERR(c) _snd_make_err(c, 0, __FILE__, __LINE__, NULL)
|
||||
#define SND_ERR_CTX(c, ...) _snd_make_err(c, 0, __FILE__, __LINE__, __VA_ARGS__)
|
||||
#define SND_ERR_W32(code) _snd_make_err(code, GetLastError(), __FILE__, __LINE__, NULL)
|
||||
#define SND_ERR_W32_CTX(code, ...) _snd_make_err(code, GetLastError(), __FILE__, __LINE__, __VA_ARGS__)
|
||||
#define SND_OK _snd_make_success()
|
||||
#define SND_ERR(c) _snd_make_err(c, 0, __FILE__, __LINE__, NULL)
|
||||
#define SND_ERR_CTX(c, ...) _snd_make_err(c, 0, __FILE__, __LINE__, __VA_ARGS__)
|
||||
#define SND_ERR_W32(code) _snd_make_err(code, GetLastError(), __FILE__, __LINE__, NULL)
|
||||
#define SND_ERR_W32_CTX(code, ...) _snd_make_err(code, GetLastError(), __FILE__, __LINE__, __VA_ARGS__)
|
||||
#define SND_ERR_NT(code, nt_status) _snd_make_err(code, nt_status, __FILE__, __LINE__, NULL)
|
||||
#define SND_ERR_NT_CTX(code, nt_status, ...) _snd_make_err(code, nt_status, __FILE__, __LINE__, __VA_ARGS__)
|
||||
|
||||
#else
|
||||
|
||||
@@ -133,11 +162,13 @@ static inline snd_status_t _snd_make_err(snd_status_code_t code, int os_error) {
|
||||
return status;
|
||||
}
|
||||
|
||||
#define SND_OK _snd_make_success()
|
||||
#define SND_ERR(code) _snd_make_err(code, 0)
|
||||
#define SND_ERR_CTX(code, ...) _snd_make_err(code, 0)
|
||||
#define SND_ERR_W32(code) _snd_make_err(code, GetLastError())
|
||||
#define SND_ERR_W32_CTX(code, ...) _snd_make_err(code, GetLastError())
|
||||
#define SND_OK _snd_make_success()
|
||||
#define SND_ERR(code) _snd_make_err(code, 0)
|
||||
#define SND_ERR_CTX(code, ...) _snd_make_err(code, 0)
|
||||
#define SND_ERR_W32(code) _snd_make_err(code, GetLastError())
|
||||
#define SND_ERR_W32_CTX(code, ...) _snd_make_err(code, GetLastError())
|
||||
#define SND_ERR_NT(code, nt_status) _snd_make_err(code, nt_status)
|
||||
#define SND_ERR_NT_CTX(code, nt_status, ...) _snd_make_err(code, nt_status)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,174 @@
|
||||
#ifndef SND_COMMON_STRING_H
|
||||
#define SND_COMMON_STRING_H
|
||||
|
||||
#include <sindri/common/macros.h>
|
||||
#include <stddef.h>
|
||||
|
||||
SND_BEGIN_EXTERN_C
|
||||
|
||||
/**
|
||||
* @brief Bounded, CRT-independent string length evaluation. Replaces strnlen.
|
||||
*/
|
||||
SND_FORCE_INLINE size_t snd_strnlen(const char *str, size_t max_len) {
|
||||
if (!str)
|
||||
return 0;
|
||||
size_t len = 0;
|
||||
while (len < max_len && str[len] != '\0') {
|
||||
len++;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Bounded, truncation-safe string copying. Replaces strncpy.
|
||||
*/
|
||||
SND_FORCE_INLINE void snd_strncpy(char *dest, size_t dest_size, const char *src, size_t max_src_len) {
|
||||
if (!dest || dest_size == 0 || !src)
|
||||
return;
|
||||
size_t i = 0;
|
||||
while (i < (dest_size - 1) && i < max_src_len && src[i] != '\0') {
|
||||
dest[i] = src[i];
|
||||
i++;
|
||||
}
|
||||
dest[i] = '\0';
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Bounded, CRT-independent string concatenation. Replaces strncat.
|
||||
*/
|
||||
SND_FORCE_INLINE void snd_strncat(char *dest, size_t dest_size, const char *src, size_t max_src_len) {
|
||||
if (!dest || dest_size == 0 || !src)
|
||||
return;
|
||||
size_t dest_len = 0;
|
||||
while (dest_len < dest_size && dest[dest_len] != '\0') {
|
||||
dest_len++;
|
||||
}
|
||||
if (dest_len >= dest_size - 1) {
|
||||
dest[dest_size - 1] = '\0';
|
||||
return;
|
||||
}
|
||||
size_t i = 0;
|
||||
while (i < max_src_len && src[i] != '\0' && (dest_len + i) < (dest_size - 1)) {
|
||||
dest[dest_len + i] = src[i];
|
||||
i++;
|
||||
}
|
||||
dest[dest_len + i] = '\0';
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Bounded, CRT-independent character search. Replaces strchr.
|
||||
*/
|
||||
SND_FORCE_INLINE const char *snd_strnchr(const char *str, char c, size_t max_len) {
|
||||
if (!str)
|
||||
return NULL;
|
||||
for (size_t i = 0; i < max_len; i++) {
|
||||
if (str[i] == c)
|
||||
return &str[i];
|
||||
if (str[i] == '\0')
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Bounded, CRT-independent string comparison. Replaces strncmp.
|
||||
*/
|
||||
SND_FORCE_INLINE int snd_strncmp(const char *s1, const char *s2, size_t max_len) {
|
||||
if (!s1 || !s2)
|
||||
return (s1 == s2) ? 0 : ((s1 < s2) ? -1 : 1);
|
||||
for (size_t i = 0; i < max_len; i++) {
|
||||
if (s1[i] != s2[i])
|
||||
return (int)((unsigned char)s1[i] - (unsigned char)s2[i]);
|
||||
if (s1[i] == '\0')
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Bounded, CRT-independent wide string length evaluation. Replaces wcsnlen.
|
||||
*/
|
||||
SND_FORCE_INLINE size_t snd_wcsnlen(const wchar_t *str, size_t max_len) {
|
||||
if (!str)
|
||||
return 0;
|
||||
size_t len = 0;
|
||||
while (len < max_len && str[len] != L'\0') {
|
||||
len++;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Bounded, case-insensitive wide string comparison. Replaces wcsnicmp.
|
||||
*/
|
||||
SND_FORCE_INLINE int snd_wcsnicmp(const wchar_t *s1, const wchar_t *s2, size_t n) {
|
||||
if (n == 0)
|
||||
return 0;
|
||||
do {
|
||||
wchar_t c1 = *s1++;
|
||||
wchar_t c2 = *s2++;
|
||||
if (c1 >= L'A' && c1 <= L'Z')
|
||||
c1 += (L'a' - L'A');
|
||||
if (c2 >= L'A' && c2 <= L'Z')
|
||||
c2 += (L'a' - L'A');
|
||||
if (c1 != c2)
|
||||
return (int)(c1 - c2);
|
||||
if (c1 == L'\0')
|
||||
break;
|
||||
} while (--n);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Bounded, truncation-safe wide string copying. Replaces wcsncpy.
|
||||
*/
|
||||
SND_FORCE_INLINE void snd_wcsncpy(wchar_t *dest, size_t dest_size, const wchar_t *src, size_t max_src_len) {
|
||||
if (!dest || dest_size == 0 || !src)
|
||||
return;
|
||||
size_t i = 0;
|
||||
while (i < (dest_size - 1) && i < max_src_len && src[i] != L'\0') {
|
||||
dest[i] = src[i];
|
||||
i++;
|
||||
}
|
||||
dest[i] = L'\0';
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Bounded, CRT-independent wide string concatenation. Replaces wcsncat.
|
||||
*/
|
||||
SND_FORCE_INLINE void snd_wcsncat(wchar_t *dest, size_t dest_size, const wchar_t *src, size_t max_src_len) {
|
||||
if (!dest || dest_size == 0 || !src)
|
||||
return;
|
||||
size_t dest_len = 0;
|
||||
while (dest_len < dest_size && dest[dest_len] != L'\0') {
|
||||
dest_len++;
|
||||
}
|
||||
if (dest_len >= dest_size - 1) {
|
||||
dest[dest_size - 1] = L'\0';
|
||||
return;
|
||||
}
|
||||
size_t i = 0;
|
||||
while (i < max_src_len && src[i] != L'\0' && (dest_len + i) < (dest_size - 1)) {
|
||||
dest[dest_len + i] = src[i];
|
||||
i++;
|
||||
}
|
||||
dest[dest_len + i] = L'\0';
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Bounded ASCII to Wide string conversion. Replaces mbstowcs.
|
||||
*/
|
||||
SND_FORCE_INLINE void snd_ascii_to_wide(wchar_t *dest, size_t dest_size, const char *src, size_t max_src_len) {
|
||||
if (!dest || dest_size == 0 || !src)
|
||||
return;
|
||||
size_t i = 0;
|
||||
while (i < (dest_size - 1) && i < max_src_len && src[i] != '\0') {
|
||||
dest[i] = (wchar_t)(unsigned char)src[i];
|
||||
i++;
|
||||
}
|
||||
dest[i] = L'\0';
|
||||
}
|
||||
|
||||
SND_END_EXTERN_C
|
||||
|
||||
#endif // SND_COMMON_STRING_H
|
||||
@@ -0,0 +1,8 @@
|
||||
#ifndef SND_INJECTION_H
|
||||
#define SND_INJECTION_H
|
||||
|
||||
#include <sindri/injection/classic/chain.h>
|
||||
#include <sindri/injection/classic/engine.h>
|
||||
#include <sindri/injection/context.h>
|
||||
|
||||
#endif // SND_INJECTION_H
|
||||
@@ -0,0 +1,7 @@
|
||||
#ifndef SND_INJECTION_CLASSIC_H
|
||||
#define SND_INJECTION_CLASSIC_H
|
||||
|
||||
#include <sindri/injection/classic/chain.h>
|
||||
#include <sindri/injection/classic/engine.h>
|
||||
|
||||
#endif // SND_INJECTION_CLASSIC_H
|
||||
@@ -0,0 +1,37 @@
|
||||
#ifndef SND_INJECTION_CLASSIC_CHAIN_H
|
||||
#define SND_INJECTION_CLASSIC_CHAIN_H
|
||||
|
||||
#include <sindri/common/macros.h>
|
||||
#include <sindri/injection/classic/engine.h>
|
||||
#include <sindri/injection/context.h>
|
||||
|
||||
SND_BEGIN_EXTERN_C
|
||||
|
||||
// Forward declare the loader context so we don't have to include the loader module
|
||||
typedef struct _snd_ldr_pe_ctx snd_ldr_pe_ctx_t;
|
||||
|
||||
/**
|
||||
* @brief Executes the full classic injection pipeline.
|
||||
*
|
||||
* Runs: open_target -> alloc_remote -> write_payload -> set_protections -> execute.
|
||||
*
|
||||
* @param ctx Initialized injection context with target_pid, payload, and proc_api set.
|
||||
* @return SND_OK on success, otherwise the failing stage status.
|
||||
*/
|
||||
snd_status_t snd_inj_classic_shell(snd_inj_ctx_t *ctx);
|
||||
|
||||
/**
|
||||
* @brief High-level orchestrator that links a loader context and an injection context.
|
||||
*
|
||||
* The user initializes both contexts with their desired API backends, and this
|
||||
* chain handles the inter-context data marshaling and execution flow.
|
||||
*
|
||||
* @param ldr_ctx Initialized PE loader context with raw_source, mem_api, and mod_api set.
|
||||
* @param inj_ctx Initialized injection context with target_pid, and proc_api set.
|
||||
* @return SND_OK on success, otherwise the failing stage status.
|
||||
*/
|
||||
snd_status_t snd_inj_classic_pe(snd_ldr_pe_ctx_t *ldr_ctx, snd_inj_ctx_t *inj_ctx);
|
||||
|
||||
SND_END_EXTERN_C
|
||||
|
||||
#endif // SND_INJECTION_CLASSIC_CHAIN_H
|
||||
@@ -0,0 +1,47 @@
|
||||
#ifndef SND_INJECTION_CLASSIC_ENGINE_H
|
||||
#define SND_INJECTION_CLASSIC_ENGINE_H
|
||||
|
||||
#include <sindri/common/macros.h>
|
||||
#include <sindri/common/status.h>
|
||||
#include <sindri/injection/context.h>
|
||||
|
||||
SND_BEGIN_EXTERN_C
|
||||
|
||||
/**
|
||||
* @brief Opens a handle to the target process.
|
||||
* @param ctx Initialized injection context with target_pid and proc_api set.
|
||||
* @return SND_OK on success, otherwise SND_STATUS_PROCESS_OPEN_FAILED.
|
||||
*/
|
||||
snd_status_t snd_inj_classic_open_target(snd_inj_ctx_t *ctx);
|
||||
|
||||
/**
|
||||
* @brief Allocates memory in the remote process for the payload.
|
||||
* @param ctx Context after SND_INJ_STAGE_TARGET_ACQUIRED.
|
||||
* @return SND_OK on success, otherwise SND_STATUS_REMOTE_ALLOC_FAILED.
|
||||
*/
|
||||
snd_status_t snd_inj_classic_alloc_remote(snd_inj_ctx_t *ctx);
|
||||
|
||||
/**
|
||||
* @brief Writes the payload buffer into the allocated remote memory.
|
||||
* @param ctx Context after SND_INJ_STAGE_MEMORY_ALLOCATED.
|
||||
* @return SND_OK on success, otherwise SND_STATUS_REMOTE_WRITE_FAILED.
|
||||
*/
|
||||
snd_status_t snd_inj_classic_write_payload(snd_inj_ctx_t *ctx);
|
||||
|
||||
/**
|
||||
* @brief Transitions remote memory protections from RW to RX.
|
||||
* @param ctx Context after SND_INJ_STAGE_PAYLOAD_WRITTEN.
|
||||
* @return SND_OK on success, otherwise SND_STATUS_REMOTE_PROTECT_FAILED.
|
||||
*/
|
||||
snd_status_t snd_inj_classic_set_protections(snd_inj_ctx_t *ctx);
|
||||
|
||||
/**
|
||||
* @brief Creates a remote thread at the payload base to execute the shellcode.
|
||||
* @param ctx Context after SND_INJ_STAGE_PROTECTIONS_SET.
|
||||
* @return SND_OK on success, otherwise SND_STATUS_THREAD_CREATE_FAILED.
|
||||
*/
|
||||
snd_status_t snd_inj_classic_execute(snd_inj_ctx_t *ctx);
|
||||
|
||||
SND_END_EXTERN_C
|
||||
|
||||
#endif // SND_INJECTION_CLASSIC_ENGINE_H
|
||||
@@ -0,0 +1,47 @@
|
||||
#ifndef SND_INJECTION_CONTEXT_H
|
||||
#define SND_INJECTION_CONTEXT_H
|
||||
|
||||
#include <sindri/common/buffer.h>
|
||||
#include <sindri/common/debug.h>
|
||||
#include <sindri/common/macros.h>
|
||||
#include <sindri/primitives/os_api.h>
|
||||
#include <windows.h>
|
||||
|
||||
SND_BEGIN_EXTERN_C
|
||||
|
||||
typedef enum {
|
||||
SND_INJ_STAGE_UNINITIALIZED = 0,
|
||||
SND_INJ_STAGE_TARGET_ACQUIRED,
|
||||
SND_INJ_STAGE_MEMORY_ALLOCATED,
|
||||
SND_INJ_STAGE_PAYLOAD_WRITTEN,
|
||||
SND_INJ_STAGE_PROTECTIONS_SET,
|
||||
SND_INJ_STAGE_EXECUTED,
|
||||
} snd_inj_stage_t;
|
||||
|
||||
typedef struct _snd_inj_ctx_t {
|
||||
DWORD target_pid;
|
||||
HANDLE target_process;
|
||||
PVOID remote_base;
|
||||
PVOID remote_entry_point;
|
||||
SIZE_T remote_size;
|
||||
HANDLE remote_thread;
|
||||
|
||||
snd_inj_stage_t stage;
|
||||
|
||||
const snd_buffer_t *payload;
|
||||
const snd_process_api_t *proc_api;
|
||||
} snd_inj_ctx_t;
|
||||
|
||||
/**
|
||||
* @brief Converts an injection stage enum to a human-readable string.
|
||||
*/
|
||||
const char *snd_inj_stage_to_string(snd_inj_stage_t stage);
|
||||
|
||||
/**
|
||||
* @brief Cleans up injection context: closes handles, resets state.
|
||||
*/
|
||||
void snd_inj_cleanup(snd_inj_ctx_t *ctx);
|
||||
|
||||
SND_END_EXTERN_C
|
||||
|
||||
#endif // SND_INJECTION_CONTEXT_H
|
||||
@@ -0,0 +1,8 @@
|
||||
#ifndef SINDRI_INTERNAL_NT_H
|
||||
#define SINDRI_INTERNAL_NT_H
|
||||
|
||||
#include <sindri/internal/nt/api.h>
|
||||
#include <sindri/internal/nt/peb.h>
|
||||
#include <sindri/internal/nt/types.h>
|
||||
|
||||
#endif // SINDRI_INTERNAL_NT_H
|
||||
@@ -0,0 +1,75 @@
|
||||
#ifndef SND_INTERNAL_NT_API_H
|
||||
#define SND_INTERNAL_NT_API_H
|
||||
|
||||
#include <sindri/common/macros.h>
|
||||
#include <sindri/internal/nt/types.h>
|
||||
#include <windows.h>
|
||||
|
||||
SND_BEGIN_EXTERN_C
|
||||
|
||||
/**
|
||||
* @brief Type definition for LdrLoadDll function.
|
||||
*/
|
||||
typedef NTSTATUS(NTAPI *SND_LdrLoadDll_t)(PWSTR PathToFile, PULONG Flags, PSND_UNICODE_STRING ModuleFileName,
|
||||
PHANDLE ModuleHandle);
|
||||
|
||||
/*
|
||||
* @brief Type definition for NtOpenSection function.
|
||||
*/
|
||||
typedef NTSTATUS(NTAPI *SND_NtOpenSection_t)(PHANDLE SectionHandle, ACCESS_MASK DesiredAccess,
|
||||
PSND_OBJECT_ATTRIBUTES ObjectAttributes);
|
||||
|
||||
/*
|
||||
* @brief Type definition for NtMapViewOfSection function.
|
||||
*/
|
||||
typedef NTSTATUS(NTAPI *SND_NtMapViewOfSection_t)(HANDLE SectionHandle, HANDLE ProcessHandle, PVOID *BaseAddress,
|
||||
ULONG_PTR ZeroBits, SIZE_T CommitSize, PLARGE_INTEGER SectionOffset,
|
||||
PSIZE_T ViewSize, DWORD InheritDisposition, ULONG AllocationType,
|
||||
ULONG Win32Protect);
|
||||
|
||||
/*
|
||||
* @brief Type definition for NtClose function.
|
||||
*/
|
||||
typedef NTSTATUS(NTAPI *SND_NtClose_t)(HANDLE Handle);
|
||||
|
||||
/*
|
||||
* @brief Type definition for NtAllocateVirtualMemory function.
|
||||
*/
|
||||
typedef NTSTATUS(NTAPI *SND_NtAllocateVirtualMemory_t)(HANDLE ProcessHandle, PVOID *BaseAddress, ULONG_PTR ZeroBits,
|
||||
SIZE_T *Size, ULONG AllocationType, ULONG Win32Protect);
|
||||
|
||||
/*
|
||||
* @brief Type definition for NtProtectVirtualMemory function.
|
||||
*/
|
||||
typedef NTSTATUS(NTAPI *SND_NtProtectVirtualMemory_t)(HANDLE ProcessHandle, PVOID *BaseAddress, PSIZE_T RegionSize,
|
||||
ULONG NewProtect, PULONG OldProtect);
|
||||
|
||||
/*
|
||||
* @brief Type definition for NtFreeVirtualMemory function.
|
||||
*/
|
||||
typedef NTSTATUS(NTAPI *SND_NtFreeVirtualMemory_t)(HANDLE ProcessHandle, PVOID *BaseAddress, PSIZE_T RegionSize,
|
||||
ULONG FreeType);
|
||||
|
||||
/*
|
||||
* @brief Type definition for NtOpenProcess function.
|
||||
*/
|
||||
typedef NTSTATUS(NTAPI *SND_NtOpenProcess_t)(HANDLE *ProcessHandle, ACCESS_MASK DesiredAccess, PVOID ObjectAttributes,
|
||||
PVOID ClientId);
|
||||
|
||||
/*
|
||||
* @brief Type definition for NtWriteVirtualMemory function.
|
||||
*/
|
||||
typedef NTSTATUS(NTAPI *SND_NtWriteVirtualMemory_t)(HANDLE ProcessHandle, PVOID BaseAddress, PVOID Buffer, SIZE_T Size,
|
||||
SIZE_T *NumberOfBytesWritten);
|
||||
|
||||
/*
|
||||
* @brief Type definition for NtCreateThreadEx function.
|
||||
*/
|
||||
typedef NTSTATUS(NTAPI *SND_NtCreateThreadEx_t)(HANDLE *ThreadHandle, ACCESS_MASK DesiredAccess, PVOID ObjectAttributes,
|
||||
HANDLE ProcessHandle, PVOID StartRoutine, PVOID Argument,
|
||||
ULONG CreateFlags, SIZE_T ZeroBits, SIZE_T StackSize,
|
||||
SIZE_T MaximumStackSize, PVOID AttributeList);
|
||||
|
||||
SND_END_EXTERN_C
|
||||
|
||||
#endif // SND_INTERNAL_NT_API_H
|
||||
@@ -0,0 +1,77 @@
|
||||
#ifndef SND_INTERNAL_NT_DEFS_H
|
||||
#define SND_INTERNAL_NT_DEFS_H
|
||||
|
||||
#include <sindri/common/macros.h>
|
||||
#include <sindri/internal/nt/types.h>
|
||||
#include <windows.h>
|
||||
|
||||
SND_BEGIN_EXTERN_C
|
||||
|
||||
/**
|
||||
* @brief A basic representation of the current directory struct to align memory block layouts.
|
||||
*/
|
||||
typedef struct _SND_CURDIR {
|
||||
SND_UNICODE_STRING DosPath;
|
||||
HANDLE Handle;
|
||||
} SND_CURDIR, *PSND_CURDIR;
|
||||
|
||||
/**
|
||||
* @brief Process parameters structure containing environment configuration details.
|
||||
*/
|
||||
typedef struct _SND_RTL_USER_PROCESS_PARAMETERS {
|
||||
ULONG MaximumLength;
|
||||
ULONG Length;
|
||||
ULONG Flags;
|
||||
ULONG DebugFlags;
|
||||
HANDLE ConsoleHandle;
|
||||
ULONG ConsoleFlags;
|
||||
HANDLE StandardInput;
|
||||
HANDLE StandardOutput;
|
||||
HANDLE StandardError;
|
||||
SND_CURDIR CurrentDirectory;
|
||||
SND_UNICODE_STRING DllPath;
|
||||
SND_UNICODE_STRING ImagePathName;
|
||||
SND_UNICODE_STRING CommandLine;
|
||||
PVOID Environment;
|
||||
} SND_RTL_USER_PROCESS_PARAMETERS, *PSND_RTL_USER_PROCESS_PARAMETERS;
|
||||
|
||||
/**
|
||||
* @brief PEB loader data structure.
|
||||
*/
|
||||
typedef struct _SND_PEB_LDR_DATA {
|
||||
ULONG Length;
|
||||
BYTE Reserved[8];
|
||||
LIST_ENTRY InLoadOrderModuleList;
|
||||
LIST_ENTRY InMemoryOrderModuleList;
|
||||
LIST_ENTRY InInitializationOrderModuleList;
|
||||
} SND_PEB_LDR_DATA, *PSND_PEB_LDR_DATA;
|
||||
|
||||
/**
|
||||
* @brief Loader data table entry for module tracking.
|
||||
*/
|
||||
typedef struct _SND_LDR_DATA_TABLE_ENTRY {
|
||||
LIST_ENTRY InLoadOrderLinks;
|
||||
LIST_ENTRY InMemoryOrderLinks;
|
||||
LIST_ENTRY InInitializationOrderLinks;
|
||||
PVOID DllBase;
|
||||
PVOID EntryPoint;
|
||||
ULONG SizeOfImage;
|
||||
SND_UNICODE_STRING FullDllName;
|
||||
SND_UNICODE_STRING BaseDllName;
|
||||
} SND_LDR_DATA_TABLE_ENTRY, *PSND_LDR_DATA_TABLE_ENTRY;
|
||||
|
||||
/**
|
||||
* @brief Process Environment Block (PEB) definition.
|
||||
*/
|
||||
typedef struct _SND_PEB {
|
||||
BYTE Reserved1[2];
|
||||
BYTE BeingDebugged;
|
||||
BYTE Reserved2[1];
|
||||
PVOID Reserved3[2];
|
||||
PSND_PEB_LDR_DATA Ldr;
|
||||
PSND_RTL_USER_PROCESS_PARAMETERS ProcessParameters;
|
||||
} SND_PEB, *PSND_PEB;
|
||||
|
||||
SND_END_EXTERN_C
|
||||
|
||||
#endif // SND_INTERNAL_NT_DEFS_H
|
||||
@@ -0,0 +1,77 @@
|
||||
#ifndef SND_INTERN_NT_TYPES_H
|
||||
#define SND_INTERN_NT_TYPES_H
|
||||
|
||||
#include <sindri/common/macros.h>
|
||||
#include <windows.h>
|
||||
|
||||
SND_BEGIN_EXTERN_C
|
||||
|
||||
/**
|
||||
* @brief Macro to check if an NTSTATUS indicates success.
|
||||
*/
|
||||
#define SND_NT_SUCCESS(s) (((NTSTATUS)(s)) >= 0)
|
||||
|
||||
/**
|
||||
* @brief Object attribute flag indicating case-insensitive object names.
|
||||
*/
|
||||
#define SND_OBJ_CASE_INSENSITIVE 0x00000040L
|
||||
|
||||
/**
|
||||
* @brief Page size used in memory allocations.
|
||||
*/
|
||||
#define SND_PAGE_SIZE ((SIZE_T)0x1000)
|
||||
|
||||
/**
|
||||
* @brief Initializes an SND_OBJECT_ATTRIBUTES structure.
|
||||
*/
|
||||
#define SND_InitializeObjectAttributes(p, n, a, r, s) \
|
||||
{ \
|
||||
(p)->Length = sizeof(SND_OBJECT_ATTRIBUTES); \
|
||||
(p)->RootDirectory = r; \
|
||||
(p)->Attributes = a; \
|
||||
(p)->ObjectName = n; \
|
||||
(p)->SecurityDescriptor = s; \
|
||||
(p)->SecurityQualityOfService = NULL; \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Represents a Unicode string in the NT environment.
|
||||
*/
|
||||
typedef struct _SND_UNICODE_STRING {
|
||||
USHORT Length;
|
||||
USHORT MaximumLength;
|
||||
PWSTR Buffer;
|
||||
} SND_UNICODE_STRING, *PSND_UNICODE_STRING;
|
||||
|
||||
typedef struct _SND_OBJECT_ATTRIBUTES {
|
||||
ULONG Length;
|
||||
HANDLE RootDirectory;
|
||||
PSND_UNICODE_STRING ObjectName;
|
||||
ULONG Attributes;
|
||||
PVOID SecurityDescriptor;
|
||||
PVOID SecurityQualityOfService;
|
||||
} SND_OBJECT_ATTRIBUTES, *PSND_OBJECT_ATTRIBUTES;
|
||||
|
||||
/**
|
||||
* @brief Client ID structure.
|
||||
*/
|
||||
typedef struct _SND_CLIENT_ID {
|
||||
HANDLE UniqueProcess;
|
||||
HANDLE UniqueThread;
|
||||
} SND_CLIENT_ID, *PSND_CLIENT_ID;
|
||||
|
||||
/**
|
||||
* @brief Initializes a UNICODE_STRING structure from a wide string buffer and length.
|
||||
* Replaces RtlInitUnicodeString.
|
||||
*/
|
||||
SND_FORCE_INLINE void snd_init_unicode_string(SND_UNICODE_STRING *us, const wchar_t *buf, size_t char_count) {
|
||||
if (us) {
|
||||
us->Buffer = (wchar_t *)buf;
|
||||
us->Length = (USHORT)(char_count * sizeof(wchar_t));
|
||||
us->MaximumLength = us->Length + sizeof(wchar_t);
|
||||
}
|
||||
}
|
||||
|
||||
SND_END_EXTERN_C
|
||||
|
||||
#endif // SND_INTERNAL_NT_TYPES_H
|
||||
@@ -1,92 +0,0 @@
|
||||
#ifndef SND_INTERNAL_NT_DEFS_H
|
||||
#define SND_INTERNAL_NT_DEFS_H
|
||||
#include <sindri/common/helpers.h>
|
||||
#include <windows.h>
|
||||
|
||||
SND_BEGIN_EXTERN_C
|
||||
|
||||
/**
|
||||
* @brief Macro to check if an NTSTATUS indicates success.
|
||||
*/
|
||||
#ifndef NT_SUCCESS
|
||||
#define NT_SUCCESS(s) (((NTSTATUS)(s)) >= 0)
|
||||
#endif
|
||||
|
||||
#define SND_OBJ_CASE_INSENSITIVE 0x00000040L
|
||||
#define SND_PAGE_SIZE ((SIZE_T)0x1000)
|
||||
|
||||
/**
|
||||
* @brief Represents a Unicode string in the NT environment.
|
||||
*/
|
||||
typedef struct _SND_UNICODE_STRING {
|
||||
USHORT Length; // In BYTES
|
||||
USHORT MaximumLength; // In BYTES
|
||||
PWSTR Buffer;
|
||||
} SND_UNICODE_STRING, *PSND_UNICODE_STRING;
|
||||
|
||||
/**
|
||||
* @brief PEB loader data structure.
|
||||
*/
|
||||
typedef struct _SND_PEB_LDR_DATA {
|
||||
ULONG Length;
|
||||
BYTE Reserved[8];
|
||||
LIST_ENTRY InLoadOrderModuleList;
|
||||
LIST_ENTRY InMemoryOrderModuleList;
|
||||
LIST_ENTRY InInitializationOrderModuleList;
|
||||
} SND_PEB_LDR_DATA, *PSND_PEB_LDR_DATA;
|
||||
|
||||
/**
|
||||
* @brief Process Environment Block (PEB) definition.
|
||||
*/
|
||||
typedef struct _SND_PEB {
|
||||
BYTE Reserved1[2];
|
||||
BYTE BeingDebugged;
|
||||
BYTE Reserved2[1];
|
||||
PVOID Reserved3[2];
|
||||
PSND_PEB_LDR_DATA Ldr;
|
||||
} SND_PEB, *PSND_PEB;
|
||||
|
||||
/**
|
||||
* @brief Loader data table entry for module tracking.
|
||||
*/
|
||||
typedef struct _SND_LDR_DATA_TABLE_ENTRY {
|
||||
LIST_ENTRY InLoadOrderLinks;
|
||||
LIST_ENTRY InMemoryOrderLinks;
|
||||
LIST_ENTRY InInitializationOrderLinks;
|
||||
PVOID DllBase;
|
||||
PVOID EntryPoint;
|
||||
ULONG SizeOfImage;
|
||||
SND_UNICODE_STRING FullDllName;
|
||||
SND_UNICODE_STRING BaseDllName;
|
||||
} SND_LDR_DATA_TABLE_ENTRY, *PSND_LDR_DATA_TABLE_ENTRY;
|
||||
|
||||
/**
|
||||
* @brief Type definition for LdrLoadDll function (ntdll native loader, no
|
||||
* kernel32 required).
|
||||
*/
|
||||
typedef NTSTATUS(NTAPI *LdrLoadDll_t)(PWSTR PathToFile, // optional search path (NULL = default)
|
||||
PULONG Flags, // optional flags (NULL = 0)
|
||||
PSND_UNICODE_STRING ModuleFileName, PHANDLE ModuleHandle);
|
||||
|
||||
typedef struct _SND_OBJECT_ATTRIBUTES {
|
||||
ULONG Length;
|
||||
HANDLE RootDirectory;
|
||||
PSND_UNICODE_STRING ObjectName;
|
||||
ULONG Attributes;
|
||||
PVOID SecurityDescriptor;
|
||||
PVOID SecurityQualityOfService;
|
||||
} SND_OBJECT_ATTRIBUTES, *PSND_OBJECT_ATTRIBUTES;
|
||||
|
||||
#define SND_InitializeObjectAttributes(p, n, a, r, s) \
|
||||
{ \
|
||||
(p)->Length = sizeof(SND_OBJECT_ATTRIBUTES); \
|
||||
(p)->RootDirectory = r; \
|
||||
(p)->Attributes = a; \
|
||||
(p)->ObjectName = n; \
|
||||
(p)->SecurityDescriptor = s; \
|
||||
(p)->SecurityQualityOfService = NULL; \
|
||||
}
|
||||
|
||||
SND_END_EXTERN_C
|
||||
|
||||
#endif // SND_INTERNAL_NT_DEFS_H
|
||||
@@ -1,7 +1,6 @@
|
||||
#ifndef SND_LOADERS_H
|
||||
#define SND_LOADERS_H
|
||||
|
||||
#include <sindri/loaders/knowndlls/knowndlls.h>
|
||||
#include <sindri/loaders/reflective/chain.h>
|
||||
#include <sindri/loaders/reflective/engine.h>
|
||||
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
#ifndef SND_LOADERS_KNOWNDLLS_H
|
||||
#define SND_LOADERS_KNOWNDLLS_H
|
||||
|
||||
#include <sindri/common/helpers.h>
|
||||
#include <sindri/common/status.h>
|
||||
#include <sindri/internal/nt_defs.h>
|
||||
#include <windows.h>
|
||||
|
||||
SND_BEGIN_EXTERN_C
|
||||
|
||||
#if defined(_WIN64)
|
||||
#define SND_TARGET_KNOWNDLLS_DIR L"\\KnownDlls\\"
|
||||
#elif defined(_WIN32)
|
||||
#define SND_TARGET_KNOWNDLLS_DIR L"\\KnownDlls32\\"
|
||||
#else
|
||||
#error "Unsupported architecture: SindriKit requires _WIN32 or _WIN64"
|
||||
#endif
|
||||
|
||||
typedef snd_status_t(WINAPI *snd_knowndlls_open_section_cb)(PHANDLE SectionHandle, ACCESS_MASK DesiredAccess,
|
||||
PSND_OBJECT_ATTRIBUTES ObjectAttributes);
|
||||
|
||||
typedef snd_status_t(WINAPI *snd_knowndlls_map_view_cb)(HANDLE SectionHandle, HANDLE ProcessHandle, PVOID *BaseAddress,
|
||||
ULONG_PTR ZeroBits, SIZE_T CommitSize,
|
||||
PLARGE_INTEGER SectionOffset, PSIZE_T ViewSize,
|
||||
DWORD InheritDisposition, ULONG AllocationType,
|
||||
ULONG Win32Protect);
|
||||
|
||||
typedef snd_status_t(WINAPI *snd_knowndlls_close_cb)(HANDLE Handle);
|
||||
|
||||
/**
|
||||
* @brief Configuration structure for the KnownDlls loader mapping technique.
|
||||
*/
|
||||
typedef struct {
|
||||
snd_knowndlls_open_section_cb open_section;
|
||||
snd_knowndlls_map_view_cb map_view_of_section;
|
||||
snd_knowndlls_close_cb close_handle;
|
||||
} snd_knowndlls_config_t;
|
||||
|
||||
// Expose the available configurations to the caller
|
||||
extern const snd_knowndlls_config_t snd_knowndlls_win;
|
||||
extern const snd_knowndlls_config_t snd_knowndlls_native;
|
||||
|
||||
/**
|
||||
* @brief Maps a module from the \KnownDlls object directory into memory.
|
||||
*
|
||||
* @param config Pointer to the injected API configuration (Win32 or Native).
|
||||
* @param dll_name The exact name of the DLL in the KnownDlls directory (e.g.,
|
||||
* L"ntdll.dll").
|
||||
* @param out_base_address Pointer to receive the base address of the mapped
|
||||
* section.
|
||||
* @return SND_OK on success, or an error code on failure.
|
||||
*/
|
||||
snd_status_t snd_map_knowndll(const snd_knowndlls_config_t *config, const wchar_t *dll_name, PVOID *out_base_address);
|
||||
|
||||
SND_END_EXTERN_C
|
||||
|
||||
#endif // SND_LOADERS_KNOWNDLLS_H
|
||||
@@ -0,0 +1,7 @@
|
||||
#ifndef SND_LOADERS_REFLECTIVE_H
|
||||
#define SND_LOADERS_REFLECTIVE_H
|
||||
|
||||
#include <sindri/loaders/reflective/chain.h>
|
||||
#include <sindri/loaders/reflective/engine.h>
|
||||
|
||||
#endif // SND_LOADERS_REFLECTIVE_H
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef SND_LOADERS_REFLECTIVE_CHAIN_H
|
||||
#define SND_LOADERS_REFLECTIVE_CHAIN_H
|
||||
|
||||
#include <sindri/common/helpers.h>
|
||||
#include <sindri/common/macros.h>
|
||||
#include <sindri/loaders/reflective/engine.h>
|
||||
|
||||
SND_BEGIN_EXTERN_C
|
||||
@@ -14,7 +14,7 @@ SND_BEGIN_EXTERN_C
|
||||
* @note Wraps compatibility check, copy, relocation, imports, protections, and
|
||||
* TLS.
|
||||
*/
|
||||
snd_status_t snd_prepare_reflective_image(snd_loader_ctx_t *ctx);
|
||||
snd_status_t snd_ldr_pe_prepare_image(snd_ldr_pe_ctx_t *ctx);
|
||||
|
||||
/**
|
||||
* @brief Executes the loaded image entry point.
|
||||
@@ -22,14 +22,14 @@ snd_status_t snd_prepare_reflective_image(snd_loader_ctx_t *ctx);
|
||||
* @param ctx Prepared loader context.
|
||||
* @return SND_OK on success, otherwise execution error.
|
||||
*/
|
||||
snd_status_t snd_execute_reflective_image(snd_loader_ctx_t *ctx);
|
||||
snd_status_t snd_ldr_pe_execute_image(snd_ldr_pe_ctx_t *ctx);
|
||||
|
||||
/**
|
||||
* @brief Cleans up and detaches the reflective image state.
|
||||
*
|
||||
* @param ctx Reflective loader context.
|
||||
*/
|
||||
void snd_detach_reflective_image(snd_loader_ctx_t *ctx);
|
||||
void snd_ldr_pe_detach_image(snd_ldr_pe_ctx_t *ctx);
|
||||
|
||||
SND_END_EXTERN_C
|
||||
|
||||
|
||||
@@ -2,16 +2,17 @@
|
||||
#define SND_LOADERS_REFLECTIVE_ENGINE_H
|
||||
|
||||
#include <sindri/common/buffer.h>
|
||||
#include <sindri/common/helpers.h>
|
||||
#include <sindri/common/macros.h>
|
||||
#include <sindri/common/status.h>
|
||||
#include <sindri/parsers/pe/pe_parser.h>
|
||||
#include <sindri/parsers/pe/parser.h>
|
||||
#include <sindri/primitives/os_api.h>
|
||||
#include <windows.h>
|
||||
|
||||
SND_BEGIN_EXTERN_C
|
||||
|
||||
typedef struct {
|
||||
LPVOID virtual_base;
|
||||
LPVOID local_base;
|
||||
LPVOID execution_base;
|
||||
LONG_PTR delta_offset;
|
||||
LPVOID entry_point;
|
||||
SIZE_T allocated_size;
|
||||
@@ -26,18 +27,18 @@ typedef enum {
|
||||
SND_STAGE_IMPORTS_RESOLVED,
|
||||
SND_STAGE_READY_FOR_EXECUTION,
|
||||
SND_STAGE_EXECUTED,
|
||||
} snd_loader_stage_t;
|
||||
} snd_ldr_pe_stage_t;
|
||||
|
||||
typedef struct {
|
||||
typedef struct _snd_ldr_pe_ctx {
|
||||
const snd_buffer_t *raw_source;
|
||||
snd_pe_parser_t pe;
|
||||
snd_pe_target_t target;
|
||||
snd_loader_stage_t stage;
|
||||
snd_ldr_pe_stage_t stage;
|
||||
|
||||
const snd_memory_api_t *mem_api;
|
||||
const snd_module_api_t *mod_api;
|
||||
|
||||
} snd_loader_ctx_t;
|
||||
} snd_ldr_pe_ctx_t;
|
||||
|
||||
/**
|
||||
* @brief Portable macro to resolve and call a reflectively loaded DLL export
|
||||
@@ -53,7 +54,7 @@ typedef struct {
|
||||
#define SND_CALL_EXPORT(ctx, name, signature, status_out, ...) \
|
||||
do { \
|
||||
FARPROC _proc = NULL; \
|
||||
(status_out) = snd_get_proc_address((ctx), (name), &_proc); \
|
||||
(status_out) = snd_ldr_pe_get_proc_address((ctx), (name), &_proc); \
|
||||
if ((status_out).code == SND_SUCCESS && _proc != NULL) { \
|
||||
((signature)_proc)(__VA_ARGS__); \
|
||||
} \
|
||||
@@ -74,7 +75,7 @@ typedef struct {
|
||||
#define SND_CALL_EXPORT_RET(ctx, name, signature, status_out, ret_out, ...) \
|
||||
do { \
|
||||
FARPROC _proc = NULL; \
|
||||
(status_out) = snd_get_proc_address((ctx), (name), &_proc); \
|
||||
(status_out) = snd_ldr_pe_get_proc_address((ctx), (name), &_proc); \
|
||||
if ((status_out).code == SND_SUCCESS && _proc != NULL) { \
|
||||
(ret_out) = ((signature)_proc)(__VA_ARGS__); \
|
||||
} \
|
||||
@@ -85,7 +86,7 @@ typedef struct {
|
||||
* @param ctx The loader context with parsed PE.
|
||||
* @return SND_OK on match, otherwise SND_STATUS_ARCH_MISMATCH.
|
||||
*/
|
||||
snd_status_t snd_compatibility_check(snd_loader_ctx_t *ctx);
|
||||
snd_status_t snd_ldr_pe_compatibility_check(snd_ldr_pe_ctx_t *ctx);
|
||||
|
||||
/**
|
||||
* @brief Allocates memory and copies sections.
|
||||
@@ -93,42 +94,42 @@ snd_status_t snd_compatibility_check(snd_loader_ctx_t *ctx);
|
||||
* success.
|
||||
* @return SND_OK on success, otherwise an allocation error.
|
||||
*/
|
||||
snd_status_t snd_allocate_and_copy_image(snd_loader_ctx_t *ctx);
|
||||
snd_status_t snd_ldr_pe_allocate_and_copy_image(snd_ldr_pe_ctx_t *ctx);
|
||||
|
||||
/**
|
||||
* @brief Applies base relocation fixups.
|
||||
* @param ctx The loader context containing the mapped virtual base.
|
||||
* @return SND_OK on success, otherwise a relocation error.
|
||||
*/
|
||||
snd_status_t snd_apply_relocations(snd_loader_ctx_t *ctx);
|
||||
snd_status_t snd_ldr_pe_apply_relocations(snd_ldr_pe_ctx_t *ctx);
|
||||
|
||||
/**
|
||||
* @brief Resolves imports and patches IAT.
|
||||
* @param ctx The loader context.
|
||||
* @return SND_OK on success, otherwise a resolution error.
|
||||
*/
|
||||
snd_status_t snd_resolve_imports(snd_loader_ctx_t *ctx);
|
||||
snd_status_t snd_ldr_pe_resolve_imports(snd_ldr_pe_ctx_t *ctx);
|
||||
|
||||
/**
|
||||
* @brief Applies final section page protections.
|
||||
* @param ctx The loader context.
|
||||
* @return SND_OK on success, otherwise a protection error.
|
||||
*/
|
||||
snd_status_t snd_apply_memory_protections(snd_loader_ctx_t *ctx);
|
||||
snd_status_t snd_ldr_pe_apply_memory_protections(snd_ldr_pe_ctx_t *ctx);
|
||||
|
||||
/**
|
||||
* @brief Executes TLS callbacks from a loaded image.
|
||||
* @param ctx The loader context.
|
||||
* @param reason The reason for the call (e.g., DLL_PROCESS_ATTACH).
|
||||
*/
|
||||
void snd_execute_tls_callbacks(snd_loader_ctx_t *ctx, DWORD reason);
|
||||
void snd_ldr_pe_execute_tls_callbacks(snd_ldr_pe_ctx_t *ctx, DWORD reason);
|
||||
|
||||
/**
|
||||
* @brief Resolves the entry point pointer.
|
||||
* @param ctx The loader context.
|
||||
* @return SND_OK on success, error code on failure.
|
||||
*/
|
||||
snd_status_t snd_get_entry_point(snd_loader_ctx_t *ctx);
|
||||
snd_status_t snd_ldr_pe_get_entry_point(snd_ldr_pe_ctx_t *ctx);
|
||||
|
||||
/**
|
||||
* @brief Resolves an exported symbol address.
|
||||
@@ -137,13 +138,13 @@ snd_status_t snd_get_entry_point(snd_loader_ctx_t *ctx);
|
||||
* @param func_addr_out Receives resolved export pointer.
|
||||
* @return SND_OK on success, error code on failure.
|
||||
*/
|
||||
snd_status_t snd_get_proc_address(snd_loader_ctx_t *ctx, const char *func_name, FARPROC *func_addr_out);
|
||||
snd_status_t snd_ldr_pe_get_proc_address(snd_ldr_pe_ctx_t *ctx, const char *func_name, FARPROC *func_addr_out);
|
||||
|
||||
/**
|
||||
* @brief Frees memory associated with the mapped reflective image.
|
||||
* @param ctx The loader context.
|
||||
*/
|
||||
void snd_free_mapped_image(snd_loader_ctx_t *ctx);
|
||||
void snd_ldr_pe_free_mapped_image(snd_ldr_pe_ctx_t *ctx);
|
||||
|
||||
SND_END_EXTERN_C
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifndef SND_PARSERS_H
|
||||
#define SND_PARSERS_H
|
||||
|
||||
#include <sindri/parsers/env.h>
|
||||
#include <sindri/parsers/pe.h>
|
||||
|
||||
#endif // SND_PARSERS_H
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
#ifndef SND_PARSERS_ENV_H
|
||||
#define SND_PARSERS_ENV_H
|
||||
|
||||
#include <sindri/parsers/env/peb.h>
|
||||
|
||||
#endif // SND_PARSERS_ENV_H
|
||||
Vendored
+50
@@ -0,0 +1,50 @@
|
||||
#ifndef SND_PARSERS_ENV_PEB_H
|
||||
#define SND_PARSERS_ENV_PEB_H
|
||||
|
||||
#include <sindri/common/macros.h>
|
||||
#include <sindri/common/status.h>
|
||||
#include <sindri/internal/nt/peb.h>
|
||||
#include <sindri_hashes.h>
|
||||
#include <windows.h>
|
||||
|
||||
SND_BEGIN_EXTERN_C
|
||||
|
||||
/**
|
||||
* @brief Safely locates the base address of a loaded module by walking the PEB.
|
||||
* @param module_name Case-insensitive target name (e.g., L"ntdll.dll")
|
||||
* @return Base pointer to the module, or NULL if not found.
|
||||
*/
|
||||
snd_status_t WINAPI snd_peb_get_module_base(const wchar_t *module_name, PVOID *out_base);
|
||||
|
||||
/**
|
||||
* @brief Safely locates the base address of a loaded module by walking the PEB
|
||||
* and comparing hashes.
|
||||
* @param module_hash The hash of the target name.
|
||||
* @return Base pointer to the module, or NULL if not found.
|
||||
*/
|
||||
snd_status_t WINAPI snd_peb_get_module_base_hash(DWORD module_hash, PVOID *out_base);
|
||||
|
||||
/**
|
||||
* @brief Dynamically retrieves the current local process Environment Block (PEB).
|
||||
*/
|
||||
SND_FORCE_INLINE PSND_PEB snd_peb_get_local(void) {
|
||||
#if defined(_M_X64) || defined(__x86_64__)
|
||||
// 64-bit Intel/AMD Windows
|
||||
return (PSND_PEB)__readgsqword(0x60);
|
||||
|
||||
#elif defined(_M_IX86) || defined(__i386__)
|
||||
// 32-bit Intel/AMD Windows
|
||||
return (PSND_PEB)__readfsdword(0x30);
|
||||
|
||||
#elif defined(_M_ARM64) || defined(__aarch64__)
|
||||
// 64-bit ARM Windows
|
||||
return (PSND_PEB)__readx18qword(0x60);
|
||||
|
||||
#else
|
||||
#error "Unsupported CPU architecture for local PEB resolution."
|
||||
#endif
|
||||
}
|
||||
|
||||
SND_END_EXTERN_C
|
||||
|
||||
#endif // SND_PARSERS_ENV_PEB_H
|
||||
@@ -1,10 +1,11 @@
|
||||
#ifndef SND_PARSERS_PE_H
|
||||
#define SND_PARSERS_PE_H
|
||||
|
||||
#include <sindri/parsers/pe/pe_exports.h>
|
||||
#include <sindri/parsers/pe/pe_imports.h>
|
||||
#include <sindri/parsers/pe/pe_parser.h>
|
||||
#include <sindri/parsers/pe/pe_relocations.h>
|
||||
#include <sindri/parsers/pe/pe_utils.h>
|
||||
#include <sindri/parsers/pe/exports.h>
|
||||
#include <sindri/parsers/pe/imports.h>
|
||||
#include <sindri/parsers/pe/parser.h>
|
||||
#include <sindri/parsers/pe/relocations.h>
|
||||
#include <sindri/parsers/pe/section_utils.h>
|
||||
#include <sindri/parsers/pe/utils.h>
|
||||
|
||||
#endif
|
||||
#endif // SND_PARSERS_PE_H
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
#ifndef SND_PARSERS_PE_EXPORTS_H
|
||||
#define SND_PARSERS_PE_EXPORTS_H
|
||||
|
||||
#include "sindri_hashes.h"
|
||||
|
||||
#include <sindri/common/helpers.h>
|
||||
#include <sindri/common/macros.h>
|
||||
#include <sindri/common/status.h>
|
||||
#include <sindri/primitives/os_api.h>
|
||||
#include <sindri_hashes.h>
|
||||
#include <windows.h>
|
||||
|
||||
SND_BEGIN_EXTERN_C
|
||||
@@ -51,12 +50,12 @@ snd_status_t snd_pe_get_export_address(PVOID base_address, SIZE_T size, const ch
|
||||
* @param func_hash The custom hash of the exported function name.
|
||||
* @param func_addr_out Pointer that receives the resolved memory address on
|
||||
* success.
|
||||
* @param resolver Callback function used to resolve external dependencies via
|
||||
* hash if the requested export is a forwarder. If NULL, forwarders fail.
|
||||
* @param resolver Callback function used to load external dependencies if the
|
||||
* requested export is a forwarder. If NULL, forwarder resolution will fail.
|
||||
* @returns SND_OK on success, or an error status.
|
||||
*/
|
||||
snd_status_t snd_pe_get_export_address_by_hash(PVOID base_address, SIZE_T size, DWORD func_hash, FARPROC *func_addr_out,
|
||||
snd_module_resolver_hash_cb resolver);
|
||||
snd_status_t snd_pe_get_export_address_hash(PVOID base_address, SIZE_T size, DWORD func_hash, FARPROC *func_addr_out,
|
||||
snd_module_resolver_cb resolver);
|
||||
|
||||
SND_END_EXTERN_C
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
#ifndef SND_PARSERS_PE_IMPORTS_H
|
||||
#define SND_PARSERS_PE_IMPORTS_H
|
||||
|
||||
#include <sindri/common/helpers.h>
|
||||
#include <sindri/common/macros.h>
|
||||
#include <sindri/common/status.h>
|
||||
#include <sindri/parsers/pe/pe_parser.h>
|
||||
#include <sindri/parsers/pe/parser.h>
|
||||
#include <sindri/primitives/os_api.h>
|
||||
#include <windows.h>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#define SND_PARSERS_PE_PARSER_H
|
||||
|
||||
#include <sindri/common/buffer.h>
|
||||
#include <sindri/common/helpers.h>
|
||||
#include <sindri/common/macros.h>
|
||||
#include <sindri/common/status.h>
|
||||
#include <windows.h>
|
||||
|
||||
+2
-2
@@ -1,9 +1,9 @@
|
||||
#ifndef SND_PARSERS_PE_RELOCATIONS_H
|
||||
#define SND_PARSERS_PE_RELOCATIONS_H
|
||||
|
||||
#include <sindri/common/helpers.h>
|
||||
#include <sindri/common/macros.h>
|
||||
#include <sindri/common/status.h>
|
||||
#include <sindri/parsers/pe/pe_parser.h>
|
||||
#include <sindri/parsers/pe/parser.h>
|
||||
#include <windows.h>
|
||||
|
||||
SND_BEGIN_EXTERN_C
|
||||
@@ -0,0 +1,35 @@
|
||||
#ifndef SND_PE_SECTION_UTILS_H
|
||||
#define SND_PE_SECTION_UTILS_H
|
||||
|
||||
#include <sindri/parsers/pe/parser.h>
|
||||
#include <stddef.h>
|
||||
#include <windows.h>
|
||||
|
||||
/**
|
||||
* @brief Retrieves the name of a PE section safely, resolving COFF string
|
||||
* tables if needed.
|
||||
* @note Internal engine use only.
|
||||
*/
|
||||
void snd_pe_section_name(const snd_pe_parser_t *parser, const IMAGE_SECTION_HEADER *section, char *name_buffer,
|
||||
size_t buffer_size);
|
||||
|
||||
/**
|
||||
* @brief Calculates the exact size to copy from raw file to virtual memory.
|
||||
* @note Internal engine use only.
|
||||
*/
|
||||
SND_FORCE_INLINE DWORD snd_pe_section_copy_size(const IMAGE_SECTION_HEADER *s) {
|
||||
if (s->Misc.VirtualSize == 0) {
|
||||
return s->SizeOfRawData;
|
||||
}
|
||||
return s->SizeOfRawData < s->Misc.VirtualSize ? s->SizeOfRawData : s->Misc.VirtualSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Calculates the final allocated size of a section in virtual memory.
|
||||
* @note Internal engine use only.
|
||||
*/
|
||||
SND_FORCE_INLINE DWORD snd_pe_section_loaded_size(const IMAGE_SECTION_HEADER *s) {
|
||||
return s->Misc.VirtualSize != 0 ? s->Misc.VirtualSize : s->SizeOfRawData;
|
||||
}
|
||||
|
||||
#endif // SND_PE_SECTION_UTILS_H
|
||||
@@ -1,9 +1,9 @@
|
||||
#ifndef SND_PARSERS_PE_UTILS_H
|
||||
#define SND_PARSERS_PE_UTILS_H
|
||||
|
||||
#include <sindri/common/helpers.h>
|
||||
#include <sindri/common/macros.h>
|
||||
#include <sindri/common/status.h>
|
||||
#include <sindri/parsers/pe/pe_parser.h>
|
||||
#include <sindri/parsers/pe/parser.h>
|
||||
#include <windows.h>
|
||||
|
||||
SND_BEGIN_EXTERN_C
|
||||
@@ -3,10 +3,12 @@
|
||||
|
||||
#include <sindri/primitives/ffi.h>
|
||||
#include <sindri/primitives/heavens_gate.h>
|
||||
#include <sindri/primitives/mapping.h>
|
||||
#include <sindri/primitives/memory.h>
|
||||
#include <sindri/primitives/modules.h>
|
||||
#include <sindri/primitives/object_manager.h>
|
||||
#include <sindri/primitives/os_api.h>
|
||||
#include <sindri/primitives/peb.h>
|
||||
#include <sindri/primitives/process.h>
|
||||
#include <sindri/primitives/syscalls.h>
|
||||
|
||||
#endif // SND_PRIMITIVES_H
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef SND_PRIMITIVES_FFI_H
|
||||
#define SND_PRIMITIVES_FFI_H
|
||||
|
||||
#include <sindri/common/helpers.h>
|
||||
#include <sindri/common/macros.h>
|
||||
#include <windows.h>
|
||||
|
||||
SND_BEGIN_EXTERN_C
|
||||
@@ -24,7 +24,7 @@ SND_BEGIN_EXTERN_C
|
||||
* by the assembly bridge. The caller is responsible for ensuring that
|
||||
* the argument types and count are compatible with the target function.
|
||||
*/
|
||||
UINT_PTR snd_execute_dynamic(PVOID pFunctionAddress, DWORD dwArgCount, const UINT_PTR *pArgs);
|
||||
UINT_PTR snd_ffi_execute(PVOID pFunctionAddress, DWORD dwArgCount, const UINT_PTR *pArgs);
|
||||
|
||||
SND_END_EXTERN_C
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef SND_PRIMITIVES_HEAVENS_GATE_H
|
||||
#define SND_PRIMITIVES_HEAVENS_GATE_H
|
||||
|
||||
#include <sindri/common/helpers.h>
|
||||
#include <sindri/common/macros.h>
|
||||
#include <sindri/common/status.h>
|
||||
#include <windows.h>
|
||||
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
#ifndef SND_PRIMITIVES_MAPPING_H
|
||||
#define SND_PRIMITIVES_MAPPING_H
|
||||
|
||||
#include <sindri/common/macros.h>
|
||||
#include <sindri/primitives/os_api.h>
|
||||
|
||||
SND_BEGIN_EXTERN_C
|
||||
|
||||
// Expose globally available, ready-to-use WinAPI capabilities
|
||||
extern const snd_mapping_api_t snd_map_win;
|
||||
extern const snd_mapping_api_t snd_map_nt;
|
||||
extern const snd_mapping_api_t snd_map_sys;
|
||||
|
||||
SND_END_EXTERN_C
|
||||
|
||||
#endif // SND_PRIMITIVES_MAPPING_H
|
||||
@@ -1,14 +1,15 @@
|
||||
#ifndef SND_PRIMITIVES_MEMORY_H
|
||||
#define SND_PRIMITIVES_MEMORY_H
|
||||
|
||||
#include <sindri/common/helpers.h>
|
||||
#include <sindri/common/macros.h>
|
||||
#include <sindri/primitives/os_api.h>
|
||||
|
||||
SND_BEGIN_EXTERN_C
|
||||
|
||||
// Expose globally available, ready-to-use WinAPI capabilities
|
||||
extern const snd_memory_api_t snd_mem_win;
|
||||
extern const snd_memory_api_t snd_mem_native;
|
||||
extern const snd_memory_api_t snd_mem_nt;
|
||||
extern const snd_memory_api_t snd_mem_sys;
|
||||
|
||||
SND_END_EXTERN_C
|
||||
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
#ifndef SND_PRIMITIVES_MODULES_H
|
||||
#define SND_PRIMITIVES_MODULES_H
|
||||
|
||||
#include <sindri/common/helpers.h>
|
||||
#include <sindri/common/macros.h>
|
||||
#include <sindri/primitives/os_api.h>
|
||||
|
||||
SND_BEGIN_EXTERN_C
|
||||
|
||||
// Expose globally available, ready-to-use WinAPI capabilities
|
||||
extern const snd_module_api_t snd_mod_win;
|
||||
extern const snd_module_api_t snd_mod_native;
|
||||
extern const snd_module_api_t snd_mod_nt;
|
||||
|
||||
SND_END_EXTERN_C
|
||||
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
#ifndef SND_PRIMITIVES_OBJECT_MANAGER_H
|
||||
#define SND_PRIMITIVES_OBJECT_MANAGER_H
|
||||
|
||||
#include <sindri/common/macros.h>
|
||||
#include <sindri/common/status.h>
|
||||
#include <sindri/primitives/os_api.h>
|
||||
#include <windows.h>
|
||||
|
||||
SND_BEGIN_EXTERN_C
|
||||
|
||||
#if defined(_WIN64)
|
||||
#define SND_TARGET_KNOWNDLLS_DIR L"\\KnownDlls\\"
|
||||
#elif defined(_WIN32)
|
||||
#define SND_TARGET_KNOWNDLLS_DIR L"\\KnownDlls32\\"
|
||||
#else
|
||||
#error "Unsupported architecture: SindriKit requires _WIN32 or _WIN64"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Maps a module from the \KnownDlls object directory into memory.
|
||||
*
|
||||
* @param config Pointer to the injected API configuration (Win32 or Native).
|
||||
* @param dll_name The exact name of the DLL in the KnownDlls directory (e.g.,
|
||||
* L"ntdll.dll").
|
||||
* @param out_base_address Pointer to receive the base address of the mapped
|
||||
* section.
|
||||
* @return SND_OK on success, or an error code on failure.
|
||||
*/
|
||||
snd_status_t snd_om_knowndll_map(const snd_mapping_api_t *config, const wchar_t *dll_name, PVOID *out_base_address);
|
||||
|
||||
SND_END_EXTERN_C
|
||||
|
||||
#endif // SND_PRIMITIVES_OBJECT_MANAGER_H
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef SND_PRIMITIVES_OS_API_H
|
||||
#define SND_PRIMITIVES_OS_API_H
|
||||
|
||||
#include <sindri/common/helpers.h>
|
||||
#include <sindri/common/macros.h>
|
||||
#include <sindri/common/status.h>
|
||||
#include <windows.h>
|
||||
|
||||
@@ -19,10 +19,26 @@ typedef snd_status_t(WINAPI *snd_module_get_proc_cb)(HMODULE hModule, const char
|
||||
typedef snd_status_t(WINAPI *snd_module_resolver_cb)(const wchar_t *module_name, PVOID *out_base);
|
||||
|
||||
// Module Capabilities (Hashes)
|
||||
typedef snd_status_t(WINAPI *snd_module_load_hash_cb)(DWORD module_hash, HMODULE *out_module);
|
||||
typedef snd_status_t(WINAPI *snd_module_get_proc_hash_cb)(HMODULE hModule, DWORD proc_hash, FARPROC *out_proc);
|
||||
typedef snd_status_t(WINAPI *snd_module_resolver_hash_cb)(DWORD module_hash, PVOID *out_base);
|
||||
|
||||
// Mapping Capabilities
|
||||
typedef snd_status_t(WINAPI *snd_mapping_open_cb)(const wchar_t *section_name, HANDLE *out_handle);
|
||||
typedef snd_status_t(WINAPI *snd_mapping_view_cb)(HANDLE section_handle, PVOID *out_base, SIZE_T *out_size);
|
||||
typedef snd_status_t(WINAPI *snd_mapping_close_cb)(HANDLE handle);
|
||||
|
||||
// Process Capabilities
|
||||
typedef snd_status_t(WINAPI *snd_process_open_cb)(DWORD pid, DWORD desired_access, HANDLE *out_process);
|
||||
typedef snd_status_t(WINAPI *snd_process_alloc_remote_cb)(HANDLE process, SIZE_T size, DWORD allocation_type,
|
||||
DWORD protect, PVOID *out_address);
|
||||
typedef snd_status_t(WINAPI *snd_process_write_remote_cb)(HANDLE process, PVOID base_address, const void *buffer,
|
||||
SIZE_T size, SIZE_T *bytes_written);
|
||||
typedef snd_status_t(WINAPI *snd_process_protect_remote_cb)(HANDLE process, PVOID base_address, SIZE_T size,
|
||||
DWORD new_protect, DWORD *old_protect);
|
||||
typedef snd_status_t(WINAPI *snd_process_create_thread_cb)(HANDLE process, PVOID start_address, PVOID parameter,
|
||||
HANDLE *out_thread);
|
||||
typedef snd_status_t(WINAPI *snd_process_close_cb)(HANDLE handle);
|
||||
|
||||
/**
|
||||
* @brief Local Memory Management API table.
|
||||
*/
|
||||
@@ -42,11 +58,31 @@ typedef struct {
|
||||
snd_module_resolver_cb get_module_base;
|
||||
|
||||
// Hash-based resolution
|
||||
snd_module_load_hash_cb load_library_hash;
|
||||
snd_module_get_proc_hash_cb get_proc_address_hash;
|
||||
snd_module_resolver_hash_cb get_module_base_hash;
|
||||
} snd_module_api_t;
|
||||
|
||||
/**
|
||||
* @brief Mapping API table.
|
||||
*/
|
||||
typedef struct {
|
||||
snd_mapping_open_cb open;
|
||||
snd_mapping_view_cb view;
|
||||
snd_mapping_close_cb close;
|
||||
} snd_mapping_api_t;
|
||||
|
||||
/**
|
||||
* @brief Remote Process Operations API table.
|
||||
*/
|
||||
typedef struct {
|
||||
snd_process_open_cb open_process;
|
||||
snd_process_alloc_remote_cb alloc_remote;
|
||||
snd_process_write_remote_cb write_remote;
|
||||
snd_process_protect_remote_cb protect_remote;
|
||||
snd_process_create_thread_cb create_remote_thread;
|
||||
snd_process_close_cb close_handle;
|
||||
} snd_process_api_t;
|
||||
|
||||
SND_END_EXTERN_C
|
||||
|
||||
#endif // SND_PRIMITIVES_OS_API_H
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
#ifndef SND_PEB_H
|
||||
#define SND_PEB_H
|
||||
|
||||
#include "sindri_hashes.h"
|
||||
|
||||
#include <sindri/common/helpers.h>
|
||||
#include <sindri/common/status.h>
|
||||
#include <windows.h>
|
||||
|
||||
SND_BEGIN_EXTERN_C
|
||||
|
||||
/**
|
||||
* @brief Safely locates the base address of a loaded module by walking the PEB.
|
||||
* @param module_name Case-insensitive target name (e.g., L"ntdll.dll")
|
||||
* @return Base pointer to the module, or NULL if not found.
|
||||
*/
|
||||
snd_status_t WINAPI snd_peb_get_module_base(const wchar_t *module_name, PVOID *out_base);
|
||||
|
||||
/**
|
||||
* @brief Safely locates the base address of a loaded module by walking the PEB
|
||||
* and comparing hashes.
|
||||
* @param module_hash The hash of the target name.
|
||||
* @return Base pointer to the module, or NULL if not found.
|
||||
*/
|
||||
snd_status_t WINAPI snd_peb_get_module_base_by_hash(DWORD module_hash, PVOID *out_base);
|
||||
|
||||
SND_END_EXTERN_C
|
||||
|
||||
#endif // SND_PEB_H
|
||||
@@ -0,0 +1,18 @@
|
||||
#ifndef SND_PRIMITIVES_PROCESS_H
|
||||
#define SND_PRIMITIVES_PROCESS_H
|
||||
|
||||
#include <sindri/common/macros.h>
|
||||
#include <sindri/common/status.h>
|
||||
#include <sindri/primitives/os_api.h>
|
||||
#include <windows.h>
|
||||
|
||||
SND_BEGIN_EXTERN_C
|
||||
|
||||
// Expose globally available, ready-to-use WinAPI capabilities
|
||||
extern const snd_process_api_t snd_proc_win;
|
||||
extern const snd_process_api_t snd_proc_nt;
|
||||
extern const snd_process_api_t snd_proc_sys;
|
||||
|
||||
SND_END_EXTERN_C
|
||||
|
||||
#endif // SND_PRIMITIVES_PROCESS_H
|
||||
@@ -1,14 +1,16 @@
|
||||
#ifndef SND_PRIMITIVES_SYSCALLS_COMMON_H
|
||||
#define SND_PRIMITIVES_SYSCALLS_COMMON_H
|
||||
|
||||
#include <sindri/common/helpers.h>
|
||||
#include <sindri/common/macros.h>
|
||||
#include <sindri/common/status.h>
|
||||
#include <sindri/internal/nt_defs.h>
|
||||
#include <sindri/primitives/os_api.h>
|
||||
#include <windows.h>
|
||||
|
||||
SND_BEGIN_EXTERN_C
|
||||
|
||||
#define SND_MAX_SYSCALLS 500
|
||||
#define SND_MAX_SYS_NAME_LEN 256
|
||||
|
||||
/**
|
||||
* @brief Syscall entry structure holding the address, hash, and syscall number.
|
||||
*/
|
||||
@@ -33,6 +35,7 @@ typedef struct {
|
||||
PVOID arg8;
|
||||
PVOID arg9;
|
||||
PVOID arg10;
|
||||
PVOID arg11;
|
||||
} snd_syscall_args_t;
|
||||
|
||||
/**
|
||||
@@ -41,35 +44,27 @@ typedef struct {
|
||||
*/
|
||||
typedef snd_status_t (*snd_syscall_resolver_t)(PVOID ntdll_base, DWORD func_hash, snd_syscall_entry_t *entry_out);
|
||||
|
||||
snd_status_t snd_hell_extract_syscall(PVOID ntdll_base, DWORD func_hash, snd_syscall_entry_t *entry_out);
|
||||
snd_status_t snd_halo_extract_syscall(PVOID ntdll_base, DWORD func_hash, snd_syscall_entry_t *entry_out);
|
||||
snd_status_t snd_tartarus_extract_syscall(PVOID ntdll_base, DWORD func_hash, snd_syscall_entry_t *entry_out);
|
||||
snd_status_t snd_veles_extract_syscall(PVOID ntdll_base, DWORD func_hash, snd_syscall_entry_t *entry_out);
|
||||
snd_status_t snd_syscall_resolve_ssn_scan(PVOID ntdll, DWORD func_hash, snd_syscall_entry_t *entry_out);
|
||||
snd_status_t snd_syscall_resolve_ssn_sort(PVOID ntdll, DWORD func_hash, snd_syscall_entry_t *entry_out);
|
||||
|
||||
/**
|
||||
* @brief Sets the primary syscall resolution strategy using a function pointer.
|
||||
* @param resolver The resolver function to use as the primary strategy.
|
||||
*/
|
||||
void snd_set_syscall_strategy(snd_syscall_resolver_t resolver);
|
||||
void snd_syscall_strategy_set(snd_syscall_resolver_t resolver);
|
||||
|
||||
/**
|
||||
* @brief Adds a fallback syscall resolution strategy to the pipeline.
|
||||
* @param resolver The fallback resolver function to add.
|
||||
* @return SND_OK on success, or an error if the pipeline is full.
|
||||
*/
|
||||
snd_status_t snd_add_syscall_strategy(snd_syscall_resolver_t resolver);
|
||||
snd_status_t snd_syscall_strategy_add(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);
|
||||
void snd_syscall_set_ntdll(PVOID ntdll_base);
|
||||
|
||||
/**
|
||||
* @brief Core resolution entrypoint (evaluates the internal fallback chain
|
||||
@@ -79,14 +74,14 @@ PVOID snd_get_ntdll(void);
|
||||
* @param entry_out Pointer to the entry structure to populate.
|
||||
* @return SND_OK on success, or an error code if resolution fails.
|
||||
*/
|
||||
snd_status_t snd_resolve_syscall(DWORD func_hash, snd_syscall_entry_t *entry_out);
|
||||
snd_status_t snd_syscall_resolve(DWORD func_hash, snd_syscall_entry_t *entry_out);
|
||||
|
||||
/**
|
||||
* @brief ASM stub for invoking syscalls.
|
||||
* @param args Pointer to the syscall arguments structure.
|
||||
* @return The NTSTATUS returned by the syscall.
|
||||
*/
|
||||
extern NTSTATUS snd_invoke_syscall_asm(snd_syscall_args_t *args);
|
||||
extern NTSTATUS snd_syscall_invoke_asm(snd_syscall_args_t *args);
|
||||
|
||||
SND_END_EXTERN_C
|
||||
|
||||
|
||||
Reference in New Issue
Block a user