mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-10-14 04:49:41 -07:00
re-slice linux/win32 backends, top-level folder is backend (demon/win32 -> win32/demon, etc.); os_gfx -> window_manager; fix linux / opengl builds for new apis/types
This commit is contained in:
1 parent
aea4a4ff9d
commit
9a7782de47
50 files changed
+12981
-19517
No files matched your search
@@ -4,9 +4,9 @@
|
||||
#include "demon/demon_core.c"
|
||||
|
||||
#if OS_WINDOWS
|
||||
# include "demon/win32/demon_core_win32.c"
|
||||
# include "win32/demon/win32_demon.c"
|
||||
#elif OS_LINUX
|
||||
# include "demon/linux/demon_core_linux.c"
|
||||
# include "linux/demon/linux_demon.c"
|
||||
#else
|
||||
# error Demon layer backend not defined for this operating system.
|
||||
#endif
|
||||
@@ -7,9 +7,9 @@
|
||||
#include "demon/demon_core.h"
|
||||
|
||||
#if OS_WINDOWS
|
||||
# include "demon/win32/demon_core_win32.h"
|
||||
# include "win32/demon/win32_demon.h"
|
||||
#elif OS_LINUX
|
||||
# include "demon/linux/demon_core_linux.h"
|
||||
# include "linux/demon/linux_demon.h"
|
||||
#else
|
||||
# error Demon layer backend not defined for this operating system.
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,442 +0,0 @@
|
||||
// Copyright (c) Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
#ifndef DEMON_CORE_LINUX_H
|
||||
#define DEMON_CORE_LINUX_H
|
||||
|
||||
////////////////////////////////
|
||||
//~ TLS
|
||||
|
||||
typedef struct DMN_LNX_DbDesc
|
||||
{
|
||||
U32 bit_size;
|
||||
U32 count;
|
||||
U32 offset;
|
||||
} DMN_LNX_DbDesc;
|
||||
|
||||
////////////////////////////////
|
||||
//~ SDT Probes
|
||||
|
||||
typedef struct DMN_LNX_Probe
|
||||
{
|
||||
String8 provider;
|
||||
String8 name;
|
||||
String8 args_string;
|
||||
STAP_ArgArray args;
|
||||
U64 pc;
|
||||
U64 semaphore;
|
||||
} DMN_LNX_Probe;
|
||||
|
||||
typedef struct DMN_LNX_ProbeNode
|
||||
{
|
||||
DMN_LNX_Probe v;
|
||||
struct DMN_LNX_ProbeNode *next;
|
||||
} DMN_LNX_ProbeNode;
|
||||
|
||||
typedef struct DMN_LNX_ProbeList
|
||||
{
|
||||
U64 count;
|
||||
DMN_LNX_ProbeNode *first;
|
||||
DMN_LNX_ProbeNode *last;
|
||||
} DMN_LNX_ProbeList;
|
||||
|
||||
#define DMN_LNX_Probe_XList \
|
||||
X(InitStart, 2, "init_start") \
|
||||
X(InitComplete, 2, "init_complete") \
|
||||
X(RelocStart, 2, "reloc_start") \
|
||||
X(RelocComplete, 3, "reloc_complete") \
|
||||
X(MapStart, 2, "map_start") \
|
||||
X(MapComplete, 3, "map_complete") \
|
||||
X(UnmapStart, 2, "unmap_start") \
|
||||
X(UnmapComplete, 2, "unmap_complete") \
|
||||
X(LongJmp, 3, "longjmp") \
|
||||
X(LongJmpTarget, 3, "longjmp_target") \
|
||||
X(SetJmp, 3, "setjmp")
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DMN_LNX_ProbeType_Null,
|
||||
#define X(_N,...) DMN_LNX_ProbeType_##_N,
|
||||
DMN_LNX_Probe_XList
|
||||
#undef X
|
||||
DMN_LNX_ProbeType_Count,
|
||||
} DMN_LNX_ProbeType;
|
||||
|
||||
////////////////////////////////
|
||||
//~ Process Info
|
||||
|
||||
typedef struct DMN_LNX_Auxv
|
||||
{
|
||||
U64 base;
|
||||
U64 phnum;
|
||||
U64 phent;
|
||||
U64 phdr;
|
||||
U64 execfn;
|
||||
U64 pagesz;
|
||||
} DMN_LNX_Auxv;
|
||||
|
||||
typedef struct DMN_LNX_DynamicInfo
|
||||
{
|
||||
U64 hash_vaddr;
|
||||
U64 gnu_hash_vaddr;
|
||||
U64 strtab_vaddr;
|
||||
U64 strtab_size;
|
||||
U64 symtab_vaddr;
|
||||
U64 symtab_entry_size;
|
||||
} DMN_LNX_DynamicInfo;
|
||||
|
||||
////////////////////////////////
|
||||
//~ Entities
|
||||
|
||||
typedef enum DMN_LNX_EntityKind
|
||||
{
|
||||
DMN_LNX_EntityKind_Null,
|
||||
DMN_LNX_EntityKind_Process,
|
||||
DMN_LNX_EntityKind_ProcessCtx,
|
||||
DMN_LNX_EntityKind_Thread,
|
||||
DMN_LNX_EntityKind_Module,
|
||||
} DMN_LNX_EntityKind;
|
||||
|
||||
typedef enum DMN_LNX_ThreadState
|
||||
{
|
||||
DMN_LNX_ThreadState_Null,
|
||||
DMN_LNX_ThreadState_Running,
|
||||
DMN_LNX_ThreadState_Stopped,
|
||||
DMN_LNX_ThreadState_Exited,
|
||||
DMN_LNX_ThreadState_PendingCreation,
|
||||
} DMN_LNX_ThreadState;
|
||||
|
||||
typedef struct DMN_LNX_Thread
|
||||
{
|
||||
pid_t tid;
|
||||
DMN_LNX_ThreadState state;
|
||||
struct DMN_LNX_Process *process;
|
||||
void *reg_block;
|
||||
B32 is_reg_block_dirty;
|
||||
B32 pass_through_signal;
|
||||
U64 pass_through_signo;
|
||||
U64 orig_rax;
|
||||
|
||||
struct DMN_LNX_Thread *next;
|
||||
struct DMN_LNX_Thread *prev;
|
||||
} DMN_LNX_Thread;
|
||||
|
||||
typedef struct DMN_LNX_ThreadPtrNode
|
||||
{
|
||||
DMN_LNX_Thread *v;
|
||||
struct DMN_LNX_ThreadPtrNode *next;
|
||||
struct DMN_LNX_ThreadPtrNode *prev;
|
||||
} DMN_LNX_ThreadPtrNode;
|
||||
|
||||
typedef struct DMN_LNX_ThreadPtrList
|
||||
{
|
||||
U64 count;
|
||||
DMN_LNX_ThreadPtrNode *first;
|
||||
DMN_LNX_ThreadPtrNode *last;
|
||||
} DMN_LNX_ThreadPtrList;
|
||||
|
||||
typedef struct DMN_LNX_Module
|
||||
{
|
||||
U64 name_vaddr;
|
||||
U64 base_vaddr;
|
||||
U64 name_space_id;
|
||||
U64 size;
|
||||
U64 phvaddr;
|
||||
U64 phentsize;
|
||||
U64 phcount;
|
||||
U64 tls_index;
|
||||
U64 tls_offset;
|
||||
B8 is_live;
|
||||
B8 is_main;
|
||||
|
||||
struct DMN_LNX_Module *next;
|
||||
struct DMN_LNX_Module *prev;
|
||||
} DMN_LNX_Module;
|
||||
|
||||
typedef struct DMN_LNX_ModulePtrNode
|
||||
{
|
||||
DMN_LNX_Module *v;
|
||||
struct DMN_LNX_ModulePtrNode *next;
|
||||
} DMN_LNX_ModulePtrNode;
|
||||
|
||||
typedef struct DMN_LNX_ModulePtrList
|
||||
{
|
||||
U64 count;
|
||||
DMN_LNX_ModulePtrNode *first;
|
||||
DMN_LNX_ModulePtrNode *last;
|
||||
} DMN_LNX_ModulePtrList;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DMN_LNX_ProcessState_Null,
|
||||
DMN_LNX_ProcessState_Launch,
|
||||
DMN_LNX_ProcessState_Attach,
|
||||
DMN_LNX_ProcessState_WaitForExec,
|
||||
DMN_LNX_ProcessState_ExecFailedDoExit,
|
||||
DMN_LNX_ProcessState_Normal,
|
||||
} DMN_LNX_ProcessState;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DMN_LNX_CreateProcessFlag_DebugSubprocesses = (1 << 0),
|
||||
DMN_LNX_CreateProcessFlag_Rebased = (1 << 1),
|
||||
DMN_LNX_CreateProcessFlag_Cow = (1 << 2),
|
||||
DMN_LNX_CreateProcessFlag_ClonedMemory = (1 << 3),
|
||||
} DMN_LNX_CreateProcessFlags;
|
||||
|
||||
typedef struct DMN_LNX_Process
|
||||
{
|
||||
pid_t pid;
|
||||
int fd;
|
||||
DMN_LNX_ProcessState state;
|
||||
B32 debug_subprocesses;
|
||||
B32 is_cow;
|
||||
B32 vfork_with_spoof;
|
||||
U64 thread_count;
|
||||
DMN_LNX_Thread *first_thread;
|
||||
DMN_LNX_Thread *last_thread;
|
||||
U64 main_thread_exit_code;
|
||||
struct DMN_LNX_Process *parent_process;
|
||||
struct DMN_LNX_ProcessCtx *ctx;
|
||||
|
||||
|
||||
struct DMN_LNX_Process *next;
|
||||
struct DMN_LNX_Process *prev;
|
||||
} DMN_LNX_Process;
|
||||
|
||||
typedef struct DMN_LNX_ProcessPtrNode
|
||||
{
|
||||
DMN_LNX_Process *v;
|
||||
struct DMN_LNX_ProcessPtrNode *next;
|
||||
} DMN_LNX_ProcessPtrNode;
|
||||
|
||||
typedef struct DMN_LNX_ProcessPtrList
|
||||
{
|
||||
U64 count;
|
||||
DMN_LNX_ProcessPtrNode *first;
|
||||
DMN_LNX_ProcessPtrNode *last;
|
||||
} DMN_LNX_ProcessPtrList;
|
||||
|
||||
typedef struct DMN_LNX_ProcessCtx
|
||||
{
|
||||
Arena *arena;
|
||||
Arch arch;
|
||||
U64 rdebug_vaddr;
|
||||
ELF_Class dl_class;
|
||||
HashTable *loaded_modules_ht;
|
||||
DMN_LNX_Probe **probes;
|
||||
DMN_ActiveTrap *first_probe_trap;
|
||||
DMN_ActiveTrap *last_probe_trap;
|
||||
DMN_LNX_Module *first_module;
|
||||
DMN_LNX_Module *last_module;
|
||||
U64 module_count;
|
||||
U64 ref_count;
|
||||
|
||||
String8List free_reg_blocks;
|
||||
String8List free_reg_block_nodes;
|
||||
|
||||
// x64
|
||||
U64 xcr0;
|
||||
U64 xsave_size;
|
||||
X64_XSaveLayout xsave_layout;
|
||||
} DMN_LNX_ProcessCtx;
|
||||
|
||||
typedef struct DMN_LNX_Entity
|
||||
{
|
||||
union
|
||||
{
|
||||
DMN_LNX_Process process;
|
||||
DMN_LNX_ProcessCtx process_ctx;
|
||||
DMN_LNX_Thread thread;
|
||||
DMN_LNX_Module module;
|
||||
struct
|
||||
{
|
||||
struct DMN_LNX_Entity *next;
|
||||
};
|
||||
};
|
||||
U32 gen;
|
||||
DMN_LNX_EntityKind kind;
|
||||
} DMN_LNX_Entity;
|
||||
|
||||
typedef struct DMN_LNX_EntityNode
|
||||
{
|
||||
DMN_LNX_Entity *v;
|
||||
struct DMN_LNX_EntityNode *next;
|
||||
} DMN_LNX_EntityNode;
|
||||
|
||||
typedef struct DMN_LNX_EntityList
|
||||
{
|
||||
U64 count;
|
||||
DMN_LNX_EntityNode *first;
|
||||
DMN_LNX_EntityNode *last;
|
||||
} DMN_LNX_EntityList;
|
||||
|
||||
////////////////////////////////
|
||||
//~ Global State
|
||||
|
||||
typedef struct DMN_LNX_State
|
||||
{
|
||||
Arena *arena;
|
||||
|
||||
// rjf: access locking mechanism
|
||||
Mutex access_mutex;
|
||||
B32 access_run_state;
|
||||
|
||||
// rjf: entity storage
|
||||
Arena *entities_arena;
|
||||
DMN_LNX_Entity *entities_base;
|
||||
DMN_LNX_Entity *free_entity;
|
||||
U64 entities_count;
|
||||
|
||||
HashTable *tid_ht; // thread id -> thread entity
|
||||
HashTable *pid_ht; // process id -> process entity
|
||||
|
||||
// process tracking
|
||||
U64 process_count;
|
||||
DMN_LNX_Process *first_process;
|
||||
DMN_LNX_Process *last_process;
|
||||
|
||||
// process/thread creation tracking
|
||||
U64 process_pending_creation;
|
||||
U64 threads_pending_creation;
|
||||
|
||||
// halter
|
||||
Mutex halter_mutex;
|
||||
pid_t halter_tid;
|
||||
U64 halt_code;
|
||||
U64 halt_user_data;
|
||||
B32 is_halting;
|
||||
|
||||
// TLS
|
||||
B32 is_tls_detected;
|
||||
DMN_LNX_DbDesc tls_modid_desc;
|
||||
DMN_LNX_DbDesc tls_offset_desc;
|
||||
} DMN_LNX_State;
|
||||
|
||||
////////////////////////////////
|
||||
//~ Globals
|
||||
|
||||
global B32 dmn_lnx_ctrl_thread;
|
||||
global DMN_LNX_State *dmn_lnx_state;
|
||||
|
||||
////////////////////////////////
|
||||
//~ Memory R/W
|
||||
|
||||
internal U64 dmn_lnx_read(int memory_fd, Rng1U64 range, void *dst);
|
||||
internal B32 dmn_lnx_write(int memory_fd, Rng1U64 range, void *src);
|
||||
internal String8 dmn_lnx_read_string_capped(Arena *arena, int memory_fd, U64 base_vaddr, U64 cap_size);
|
||||
internal String8 dmn_lnx_read_string(Arena *arena, int memory_fd, U64 base_vaddr);
|
||||
#define dmn_lnx_read_struct(fd, vaddr, ptr) dmn_lnx_read((fd), r1u64((vaddr), (vaddr)+sizeof(*(ptr))), (ptr))
|
||||
#define dmn_lnx_write_struct(fd, vaddr, ptr) dmn_lnx_write((fd), r1u64((vaddr), (vaddr)+sizeof(*(ptr))), (ptr))
|
||||
|
||||
////////////////////////////////
|
||||
//~ ELF/GNU info
|
||||
|
||||
internal Rng1U64 dmn_lnx_compute_image_vrange(int memory_fd, ELF_Class elf_class, U64 rebase, U64 e_phaddr, U64 e_phentsize, U64 e_phnum);
|
||||
internal DMN_LNX_DynamicInfo dmn_lnx_dynamic_info_from_memory(int memory_fd, ELF_Class elf_Class, U64 rebase, U64 dynamic_vaddr);
|
||||
internal U64 dmn_lnx_rdebug_vaddr_from_memory(int memory_fd, U64 loader_vaddr, B32 is_rebased);
|
||||
|
||||
////////////////////////////////
|
||||
//~ Process Info
|
||||
|
||||
internal String8 dmn_lnx_exe_path_from_pid(Arena *arena, pid_t pid);
|
||||
internal String8 dmn_lnx_dl_path_from_pid(Arena *arena, pid_t pid, U64 auxv_base);
|
||||
internal ELF_Hdr64 dmn_lnx_ehdr_from_pid(pid_t pid);
|
||||
internal DMN_LNX_Auxv dmn_lnx_auxv_from_pid(pid_t pid, ELF_Class elf_class);
|
||||
internal DMN_LNX_Thread * dmn_lnx_thread_from_pid(pid_t pid);
|
||||
internal DMN_LNX_Process * dmn_lnx_process_from_pid(pid_t pid);
|
||||
|
||||
////////////////////////////////
|
||||
//~ Entity
|
||||
|
||||
// alloc
|
||||
internal DMN_LNX_Entity * dmn_lnx_entity_alloc(DMN_LNX_EntityKind kind);
|
||||
internal DMN_LNX_Process * dmn_lnx_process_alloc(pid_t pid, DMN_LNX_ProcessState state, DMN_LNX_Process *parent_process, B32 debug_subprocess, B32 is_cow);
|
||||
internal DMN_LNX_ProcessCtx * dmn_lnx_process_ctx_alloc(DMN_LNX_Process *process, B32 is_rebased);
|
||||
internal DMN_LNX_Thread * dmn_lnx_thread_alloc(DMN_LNX_Process *process, DMN_LNX_ThreadState thread_state, pid_t tid);
|
||||
internal DMN_LNX_Module * dmn_lnx_module_alloc(DMN_LNX_ProcessCtx *ctx, int memory_fd, U64 base_vaddr, U64 name_vaddr, U64 name_space_id, B32 is_main);
|
||||
|
||||
// release
|
||||
internal void dmn_lnx_entity_release(DMN_LNX_Entity *entity);
|
||||
internal void dmn_lnx_process_release(DMN_LNX_Process *process);
|
||||
internal void dmn_lnx_process_ctx_release(DMN_LNX_ProcessCtx *process_ctx);
|
||||
internal void dmn_lnx_thread_release(DMN_LNX_Thread *thread);
|
||||
internal void dmn_lnx_module_release(DMN_LNX_ProcessCtx *ctx, DMN_LNX_Module *module);
|
||||
|
||||
// clone
|
||||
internal DMN_LNX_ProcessCtx * dmn_lnx_process_ctx_clone(DMN_LNX_Process *process, DMN_LNX_ProcessCtx *ctx);
|
||||
internal DMN_LNX_Module * dmn_lnx_module_clone(DMN_LNX_ProcessCtx *process_ctx, DMN_LNX_Module *module);
|
||||
|
||||
// entity -> handle
|
||||
internal DMN_Handle dmn_lnx_handle_from_entity(DMN_LNX_Entity *entity);
|
||||
internal DMN_Handle dmn_lnx_handle_from_process(DMN_LNX_Process *process);
|
||||
internal DMN_Handle dmn_lnx_handle_from_process_ctx(DMN_LNX_ProcessCtx *process_ctx);
|
||||
internal DMN_Handle dmn_lnx_handle_from_thread(DMN_LNX_Thread *thread);
|
||||
internal DMN_Handle dmn_lnx_handle_from_module(DMN_LNX_Module *module);
|
||||
|
||||
// handle -> entity
|
||||
internal DMN_LNX_Entity * dmn_lnx_entity_from_handle(DMN_Handle handle, DMN_LNX_EntityKind expected_kind);
|
||||
internal DMN_LNX_Process * dmn_lnx_process_from_handle(DMN_Handle process_handle);
|
||||
internal DMN_LNX_ProcessCtx * dmn_lnx_process_ctx_from_handle(DMN_Handle process_ctx_handle);
|
||||
internal DMN_LNX_Thread * dmn_lnx_thread_from_handle(DMN_Handle thread_handle);
|
||||
internal DMN_LNX_Module * dmn_lnx_module_from_handle(DMN_Handle module_handle);
|
||||
|
||||
////////////////////////////////
|
||||
//~ Process Helpers
|
||||
|
||||
internal void dmn_lnx_process_trap_probes(DMN_LNX_Process *process);
|
||||
internal void dmn_lnx_process_untrap_probes(DMN_LNX_Process *process);
|
||||
|
||||
////////////////////////////////
|
||||
//~ Thread Helpers
|
||||
|
||||
internal U64 dmn_lnx_thread_read_ip(DMN_LNX_Thread *thread);
|
||||
internal U64 dmn_lnx_thread_read_sp(DMN_LNX_Thread *thread);
|
||||
internal void dmn_lnx_thread_write_ip(DMN_LNX_Thread *thread, U64 ip);
|
||||
internal void dmn_lnx_thread_write_sp(DMN_LNX_Thread *thread, U64 sp);
|
||||
internal B32 dmn_lnx_thread_read_reg_block(DMN_LNX_Thread *thread);
|
||||
internal B32 dmn_lnx_thread_write_reg_block(DMN_LNX_Thread *thread);
|
||||
internal B32 dmn_lnx_set_single_step_flag(DMN_LNX_Thread *thread, B32 is_on);
|
||||
|
||||
////////////////////////////////
|
||||
//~ List Helpers
|
||||
|
||||
internal void dmn_lnx_thread_ptr_list_push_node(DMN_LNX_ThreadPtrList *list, DMN_LNX_ThreadPtrNode *n);
|
||||
internal DMN_LNX_ThreadPtrNode * dmn_lnx_thread_ptr_list_push(Arena *arena, DMN_LNX_ThreadPtrList *list, DMN_LNX_Thread *v);
|
||||
internal DMN_LNX_ModulePtrNode * dmn_lnx_module_ptr_list_push(Arena *arena, DMN_LNX_ModulePtrList *list, DMN_LNX_Module *v);
|
||||
internal DMN_LNX_ProcessPtrNode * dmn_lnx_process_ptr_list_push(Arena *arena, DMN_LNX_ProcessPtrList *list, DMN_LNX_Process *v);
|
||||
|
||||
////////////////////////////////
|
||||
//~ Debug Event Pushers
|
||||
|
||||
internal void dmn_lnx_push_event_create_process(Arena *arena, DMN_EventList *events, DMN_LNX_Process *process);
|
||||
internal void dmn_lnx_push_event_exit_process(Arena *arena, DMN_EventList *events, DMN_LNX_Process *process);
|
||||
internal void dmn_lnx_push_event_create_thread(Arena *arena, DMN_EventList *events, DMN_LNX_Thread *thread);
|
||||
internal void dmn_lnx_push_event_exit_thread(Arena *arena, DMN_EventList *events, DMN_LNX_Thread *thread, U64 exit_code);
|
||||
internal void dmn_lnx_push_event_load_module(Arena *arena, DMN_EventList *events, DMN_LNX_Thread *thread, DMN_LNX_Module *module);
|
||||
internal void dmn_lnx_push_event_unload_module(Arena *arena, DMN_EventList *events, DMN_LNX_Process *process, DMN_LNX_Module *module);
|
||||
internal void dmn_lnx_push_event_handshake_complete(Arena *arena, DMN_EventList *events, DMN_LNX_Process *process);
|
||||
internal void dmn_lnx_push_event_breakpoint(Arena *arena, DMN_EventList *events, DMN_LNX_Thread *thread, U64 address);
|
||||
internal void dmn_lnx_push_event_single_step(Arena *arena, DMN_EventList *events, DMN_LNX_Thread *thread);
|
||||
internal void dmn_lnx_push_event_exception(Arena *arena, DMN_EventList *events, DMN_LNX_Thread *thread, U64 signo);
|
||||
internal void dmn_lnx_push_event_halt(Arena *arena, DMN_EventList *events);
|
||||
internal void dmn_lnx_push_event_not_attached(Arena *arena, DMN_EventList *events);
|
||||
|
||||
////////////////////////////////
|
||||
//~ Debug Event
|
||||
|
||||
internal DMN_LNX_Thread * dmn_lnx_event_create_thread(Arena *arena, DMN_EventList *events, DMN_LNX_Process *process, pid_t tid);
|
||||
internal void dmn_lnx_event_exit_thread(Arena *arena, DMN_EventList *events, pid_t tid, U64 exit_code);
|
||||
internal DMN_LNX_Process * dmn_lnx_event_create_process(Arena *arena, DMN_EventList *events, pid_t pid, DMN_LNX_Process *parent_process, DMN_LNX_CreateProcessFlags flags);
|
||||
internal void dmn_lnx_event_exit_process(Arena *arena, DMN_EventList *events, pid_t pid);
|
||||
internal void dmn_lnx_event_load_module(Arena *arena, DMN_EventList *events, DMN_LNX_Thread *thread, U64 name_space_id, U64 new_link_map_vaddr);
|
||||
internal void dmn_lnx_event_unload_module(Arena *arena, DMN_EventList *events, DMN_LNX_Process *process, U64 rdebug_vaddr);
|
||||
internal void dmn_lnx_event_breakpoint(Arena *arena, DMN_EventList *events, DMN_ActiveTrap *user_traps, pid_t tid);
|
||||
internal void dmn_lnx_event_data_breakpoint(Arena *arena, DMN_EventList *events, pid_t tid);
|
||||
internal void dmn_lnx_event_halt(Arena *arena, DMN_EventList *events);
|
||||
internal void dmn_lnx_event_single_step(Arena *arena, DMN_EventList *events, pid_t tid);
|
||||
internal void dmn_lnx_event_exception(Arena *arena, DMN_EventList *events, pid_t tid, U64 signo);
|
||||
internal DMN_LNX_Process * dmn_lnx_event_attach(Arena *arena, DMN_EventList *events, pid_t pid);
|
||||
|
||||
#endif // DEMON_CORE_LINUX_H
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,222 +0,0 @@
|
||||
// Copyright (c) Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
#ifndef DEMON_OS_LINUX_H
|
||||
#define DEMON_OS_LINUX_H
|
||||
|
||||
// TODO(allen): Potential Upgrades:
|
||||
//
|
||||
// memory fd upgrade - Right now for each process we hold open a file
|
||||
// descriptor for the process's memory (/proc/%d/mem) for the entire lifetime
|
||||
// of the process; it could be opened and closed with some kind of LRU cache
|
||||
// to put a finite cap on the number of handles the demon holds
|
||||
//
|
||||
|
||||
////////////////////////////////
|
||||
//~ NOTE(allen): Get The Linux Includes
|
||||
|
||||
#include <sys/ptrace.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
#include <elf.h>
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
|
||||
////////////////////////////////
|
||||
//~ NOTE(allen): Linux Demon Types
|
||||
|
||||
//- entities
|
||||
|
||||
// Demon Linux Entity Extensions
|
||||
// Process: ext_u64 set to memory file descriptor
|
||||
// Thread : ext_u64 cast to DEMON_LNX_ThreadExt
|
||||
// Module : ext_u64 set to U64 (address of name)
|
||||
|
||||
struct DEMON_LNX_ThreadExt{
|
||||
B32 expecting_dummy_sigstop;
|
||||
};
|
||||
StaticAssert(sizeof(DEMON_LNX_ThreadExt) <= sizeof(Member(DEMON_Entity, ext_u64)), check_demon_lnx_thread_ext);
|
||||
|
||||
//- helpers
|
||||
|
||||
struct DEMON_LNX_AttachNode{
|
||||
DEMON_LNX_AttachNode *next;
|
||||
pid_t pid;
|
||||
};
|
||||
|
||||
struct DEMON_LNX_ProcessAux{
|
||||
B32 filled;
|
||||
U64 phnum;
|
||||
U64 phent;
|
||||
U64 phdr;
|
||||
U64 execfn;
|
||||
};
|
||||
|
||||
struct DEMON_LNX_PhdrInfo{
|
||||
Rng1U64 range;
|
||||
U64 dynamic;
|
||||
};
|
||||
|
||||
struct DEMON_LNX_ModuleNode{
|
||||
DEMON_LNX_ModuleNode *next;
|
||||
U64 vaddr;
|
||||
U64 size;
|
||||
U64 name;
|
||||
U64 already_known;
|
||||
};
|
||||
|
||||
struct DEMON_LNX_EntityNode{
|
||||
DEMON_LNX_EntityNode *next;
|
||||
DEMON_Entity *entity;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ NOTE(allen): Linux Demon Register Layouts
|
||||
|
||||
// these are defined in <sys/user.h> but only for one architecture at a time
|
||||
// (and we can't really trick it into giving us both in any obvious way)
|
||||
// we define them here so that we have them all "at once"
|
||||
|
||||
struct DEMON_LNX_UserRegsX64{
|
||||
U64 r15;
|
||||
U64 r14;
|
||||
U64 r13;
|
||||
U64 r12;
|
||||
U64 rbp;
|
||||
U64 rbx;
|
||||
U64 r11;
|
||||
U64 r10;
|
||||
U64 r9;
|
||||
U64 r8;
|
||||
U64 rax;
|
||||
U64 rcx;
|
||||
U64 rdx;
|
||||
U64 rsi;
|
||||
U64 rdi;
|
||||
U64 orig_rax;
|
||||
U64 rip;
|
||||
U64 cs;
|
||||
U64 rflags;
|
||||
U64 rsp;
|
||||
U64 ss;
|
||||
U64 fsbase;
|
||||
U64 gsbase;
|
||||
U64 ds;
|
||||
U64 es;
|
||||
U64 fs;
|
||||
U64 gs;
|
||||
};
|
||||
|
||||
struct DEMON_LNX_UserX64{
|
||||
DEMON_LNX_UserRegsX64 regs;
|
||||
S32 u_fpvalid, _pad0;
|
||||
SYMS_XSaveLegacy i387;
|
||||
U64 u_tsize, u_dsize, u_ssize, start_code, start_stack;
|
||||
U64 signal;
|
||||
S32 reserved, _pad1;
|
||||
U64 u_ar0, u_fpstate;
|
||||
U64 magic;
|
||||
U8 u_comm[32];
|
||||
U64 u_debugreg[8];
|
||||
};
|
||||
|
||||
struct DEMON_LNX_UserRegsX86{
|
||||
U32 ebx;
|
||||
U32 ecx;
|
||||
U32 edx;
|
||||
U32 esi;
|
||||
U32 edi;
|
||||
U32 ebp;
|
||||
U32 eax;
|
||||
U32 ds;
|
||||
U32 es;
|
||||
U32 fs;
|
||||
U32 gs;
|
||||
U32 orig_eax;
|
||||
U32 eip;
|
||||
U32 cs;
|
||||
U32 eflags;
|
||||
U32 sp;
|
||||
U32 ss;
|
||||
};
|
||||
|
||||
struct DEMON_LNX_UserX86{
|
||||
DEMON_LNX_UserRegsX86 regs;
|
||||
S32 u_fpvalid;
|
||||
SYMS_FSave i387;
|
||||
U32 u_tsize, u_dsize, u_ssize, start_code, start_stack;
|
||||
S32 signal, reserved;
|
||||
U32 u_ar0, u_fpstate;
|
||||
U32 magic;
|
||||
U8 u_comm[32];
|
||||
U32 u_debugreg[8];
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
enum
|
||||
{
|
||||
DEMON_LNX_PermFlags_Read = (1 << 0),
|
||||
DEMON_LNX_PermFlags_Write = (1 << 1),
|
||||
DEMON_LNX_PermFlags_Exec = (1 << 2),
|
||||
DEMON_LNX_PermFlags_Private = (1 << 3)
|
||||
};
|
||||
typedef int DEMON_LNX_PermFlags;
|
||||
|
||||
enum
|
||||
{
|
||||
DEMON_LNX_MapsEntryType_Null,
|
||||
DEMON_LNX_MapsEntryType_Path,
|
||||
DEMON_LNX_MapsEntryType_Heap,
|
||||
DEMON_LNX_MapsEntryType_Stack,
|
||||
DEMON_LNX_MapsEntryType_VDSO,
|
||||
};
|
||||
typedef int DEMON_LNX_MapsEntryType;
|
||||
|
||||
struct DEMON_LNX_MapsEntry
|
||||
{
|
||||
U64 address_lo;
|
||||
U64 address_hi;
|
||||
DEMON_LNX_PermFlags perms;
|
||||
U64 offset;
|
||||
U32 dev_major;
|
||||
U32 dev_minor;
|
||||
U64 inode;
|
||||
String8 pathname;
|
||||
DEMON_LNX_MapsEntryType type;
|
||||
pid_t stack_tid;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Helpers
|
||||
|
||||
internal DEMON_LNX_ThreadExt* demon_lnx_thread_ext(DEMON_Entity *entity);
|
||||
|
||||
internal B32 demon_lnx_attach_pid(Arena *arena, pid_t pid, DEMON_LNX_AttachNode **new_node);
|
||||
|
||||
internal String8 demon_lnx_executable_path_from_pid(Arena *arena, pid_t pid);
|
||||
internal int demon_lnx_open_memory_fd_for_pid(pid_t pid);
|
||||
|
||||
internal Arch demon_lnx_arch_from_pid(pid_t pid);
|
||||
internal DEMON_LNX_ProcessAux demon_lnx_aux_from_pid(pid_t pid, Arch arch);
|
||||
internal DEMON_LNX_PhdrInfo demon_lnx_phdr_info_from_memory(int memory_fd, B32 is_32bit,
|
||||
U64 phvaddr, U64 phstride, U64 phcount);
|
||||
internal DEMON_LNX_ModuleNode* demon_lnx_module_list_from_process(Arena *arena, DEMON_Entity *process);
|
||||
|
||||
internal U64 demon_lnx_read_memory(int memory_fd, void *dst, U64 src, U64 size);
|
||||
internal B32 demon_lnx_write_memory(int memory_fd, U64 dst, void *src, U64 size);
|
||||
internal String8 demon_lnx_read_memory_str(Arena *arena, int memory_fd, U64 address);
|
||||
|
||||
internal void demon_lnx_regs_x64_from_usr_regs_x64(SYMS_RegX64 *dst, DEMON_LNX_UserRegsX64 *src);
|
||||
internal void demon_lnx_usr_regs_x64_from_regs_x64(DEMON_LNX_UserRegsX64 *dst, SYMS_RegX64 *src);
|
||||
|
||||
internal String8 demon_lnx_read_int_string(int fd);
|
||||
internal B32 demon_lnx_read_expect(int fd, char expect);
|
||||
internal int demon_lnx_read_whitespace(int fd);
|
||||
internal String8 demon_lnx_read_string(Arena *arena, int fd);
|
||||
|
||||
internal int demon_lnx_open_maps(pid_t pid);
|
||||
internal B32 demon_lnx_next_map(Arena *arena, int maps, DEMON_LNX_MapsEntry *entry_out);
|
||||
|
||||
#endif //DEMON_OS_LINUX_H
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,359 +0,0 @@
|
||||
// Copyright (c) Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
#ifndef DEMON_CORE_WIN32_H
|
||||
#define DEMON_CORE_WIN32_H
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Windows Includes
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <psapi.h>
|
||||
#include <tlhelp32.h>
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Win32 Exception Codes
|
||||
|
||||
#define DMN_W32_EXCEPTION_BREAKPOINT 0x80000003u
|
||||
#define DMN_W32_EXCEPTION_SINGLE_STEP 0x80000004u
|
||||
#define DMN_W32_EXCEPTION_LONG_JUMP 0x80000026u
|
||||
#define DMN_W32_EXCEPTION_ACCESS_VIOLATION 0xC0000005u
|
||||
#define DMN_W32_EXCEPTION_ARRAY_BOUNDS_EXCEEDED 0xC000008Cu
|
||||
#define DMN_W32_EXCEPTION_DATA_TYPE_MISALIGNMENT 0x80000002u
|
||||
#define DMN_W32_EXCEPTION_GUARD_PAGE_VIOLATION 0x80000001u
|
||||
#define DMN_W32_EXCEPTION_FLT_DENORMAL_OPERAND 0xC000008Du
|
||||
#define DMN_W32_EXCEPTION_FLT_DEVIDE_BY_ZERO 0xC000008Eu
|
||||
#define DMN_W32_EXCEPTION_FLT_INEXACT_RESULT 0xC000008Fu
|
||||
#define DMN_W32_EXCEPTION_FLT_INVALID_OPERATION 0xC0000090u
|
||||
#define DMN_W32_EXCEPTION_FLT_OVERFLOW 0xC0000091u
|
||||
#define DMN_W32_EXCEPTION_FLT_STACK_CHECK 0xC0000092u
|
||||
#define DMN_W32_EXCEPTION_FLT_UNDERFLOW 0xC0000093u
|
||||
#define DMN_W32_EXCEPTION_INT_DIVIDE_BY_ZERO 0xC0000094u
|
||||
#define DMN_W32_EXCEPTION_INT_OVERFLOW 0xC0000095u
|
||||
#define DMN_W32_EXCEPTION_PRIVILEGED_INSTRUCTION 0xC0000096u
|
||||
#define DMN_W32_EXCEPTION_ILLEGAL_INSTRUCTION 0xC000001Du
|
||||
#define DMN_W32_EXCEPTION_IN_PAGE_ERROR 0xC0000006u
|
||||
#define DMN_W32_EXCEPTION_INVALID_DISPOSITION 0xC0000026u
|
||||
#define DMN_W32_EXCEPTION_NONCONTINUABLE 0xC0000025u
|
||||
#define DMN_W32_EXCEPTION_STACK_OVERFLOW 0xC00000FDu
|
||||
#define DMN_W32_EXCEPTION_INVALID_HANDLE 0xC0000008u
|
||||
#define DMN_W32_EXCEPTION_UNWIND_CONSOLIDATE 0x80000029u
|
||||
#define DMN_W32_EXCEPTION_DLL_NOT_FOUND 0xC0000135u
|
||||
#define DMN_W32_EXCEPTION_ORDINAL_NOT_FOUND 0xC0000138u
|
||||
#define DMN_W32_EXCEPTION_ENTRY_POINT_NOT_FOUND 0xC0000139u
|
||||
#define DMN_W32_EXCEPTION_DLL_INIT_FAILED 0xC0000142u
|
||||
#define DMN_W32_EXCEPTION_CONTROL_C_EXIT 0xC000013Au
|
||||
#define DMN_W32_EXCEPTION_FLT_MULTIPLE_FAULTS 0xC00002B4u
|
||||
#define DMN_W32_EXCEPTION_FLT_MULTIPLE_TRAPS 0xC00002B5u
|
||||
#define DMN_W32_EXCEPTION_NAT_CONSUMPTION 0xC00002C9u
|
||||
#define DMN_W32_EXCEPTION_HEAP_CORRUPTION 0xC0000374u
|
||||
#define DMN_W32_EXCEPTION_STACK_BUFFER_OVERRUN 0xC0000409u
|
||||
#define DMN_W32_EXCEPTION_INVALID_CRUNTIME_PARAM 0xC0000417u
|
||||
#define DMN_W32_EXCEPTION_ASSERT_FAILURE 0xC0000420u
|
||||
#define DMN_W32_EXCEPTION_NO_MEMORY 0xC0000017u
|
||||
#define DMN_W32_EXCEPTION_THROW 0xE06D7363u
|
||||
#define DMN_W32_EXCEPTION_SET_THREAD_NAME 0x406d1388u
|
||||
#define DMN_w32_EXCEPTION_CLRDBG_NOTIFICATION 0x04242420u
|
||||
#define DMN_w32_EXCEPTION_CLR 0xE0434352u
|
||||
#define DMN_W32_EXCEPTION_RADDBG_SET_THREAD_COLOR 0x00524144u
|
||||
#define DMN_W32_EXCEPTION_RADDBG_SET_BREAKPOINT 0x00524145u
|
||||
#define DMN_W32_EXCEPTION_RADDBG_SET_VADDR_RANGE_NOTE 0x00524156u
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Win32 Exception ExceptionInformation Codes
|
||||
//
|
||||
// used as a subcode, apparently in all cases, for DMN_W32_EXCEPTION_STACK_BUFFER_OVERRUN.
|
||||
// need to somehow pipe this through & interpret it correctly in outer layers... @fastfail
|
||||
|
||||
#define DMN_W32_FAST_FAIL_LEGACY_GS_VIOLATION 0
|
||||
#define DMN_W32_FAST_FAIL_VTGUARD_CHECK_FAILURE 1
|
||||
#define DMN_W32_FAST_FAIL_STACK_COOKIE_CHECK_FAILURE 2
|
||||
#define DMN_W32_FAST_FAIL_CORRUPT_LIST_ENTRY 3
|
||||
#define DMN_W32_FAST_FAIL_INCORRECT_STACK 4
|
||||
#define DMN_W32_FAST_FAIL_INVALID_ARG 5
|
||||
#define DMN_W32_FAST_FAIL_GS_COOKIE_INIT 6
|
||||
#define DMN_W32_FAST_FAIL_FATAL_APP_EXIT 7
|
||||
#define DMN_W32_FAST_FAIL_RANGE_CHECK_FAILURE 8
|
||||
#define DMN_W32_FAST_FAIL_UNSAFE_REGISTRY_ACCESS 9
|
||||
#define DMN_W32_FAST_FAIL_GUARD_ICALL_CHECK_FAILURE 10
|
||||
#define DMN_W32_FAST_FAIL_GUARD_WRITE_CHECK_FAILURE 11
|
||||
#define DMN_W32_FAST_FAIL_INVALID_FIBER_SWITCH 12
|
||||
#define DMN_W32_FAST_FAIL_INVALID_SET_OF_CONTEXT 13
|
||||
#define DMN_W32_FAST_FAIL_INVALID_REFERENCE_COUNT 14
|
||||
#define DMN_W32_FAST_FAIL_INVALID_JUMP_BUFFER 18
|
||||
#define DMN_W32_FAST_FAIL_MRDATA_MODIFIED 19
|
||||
#define DMN_W32_FAST_FAIL_CERTIFICATION_FAILURE 20
|
||||
#define DMN_W32_FAST_FAIL_INVALID_EXCEPTION_CHAIN 21
|
||||
#define DMN_W32_FAST_FAIL_CRYPTO_LIBRARY 22
|
||||
#define DMN_W32_FAST_FAIL_INVALID_CALL_IN_DLL_CALLOUT 23
|
||||
#define DMN_W32_FAST_FAIL_INVALID_IMAGE_BASE 24
|
||||
#define DMN_W32_FAST_FAIL_DLOAD_PROTECTION_FAILURE 25
|
||||
#define DMN_W32_FAST_FAIL_UNSAFE_EXTENSION_CALL 26
|
||||
#define DMN_W32_FAST_FAIL_DEPRECATED_SERVICE_INVOKED 27
|
||||
#define DMN_W32_FAST_FAIL_INVALID_BUFFER_ACCESS 28
|
||||
#define DMN_W32_FAST_FAIL_INVALID_BALANCED_TREE 29
|
||||
#define DMN_W32_FAST_FAIL_INVALID_NEXT_THREAD 30
|
||||
#define DMN_W32_FAST_FAIL_GUARD_ICALL_CHECK_SUPPRESSED 31 // Telemetry, nonfatal
|
||||
#define DMN_W32_FAST_FAIL_APCS_DISABLED 32
|
||||
#define DMN_W32_FAST_FAIL_INVALID_IDLE_STATE 33
|
||||
#define DMN_W32_FAST_FAIL_MRDATA_PROTECTION_FAILURE 34
|
||||
#define DMN_W32_FAST_FAIL_UNEXPECTED_HEAP_EXCEPTION 35
|
||||
#define DMN_W32_FAST_FAIL_INVALID_LOCK_STATE 36
|
||||
#define DMN_W32_FAST_FAIL_GUARD_JUMPTABLE 37 // Known to compiler, must retain value 37
|
||||
#define DMN_W32_FAST_FAIL_INVALID_LONGJUMP_TARGET 38
|
||||
#define DMN_W32_FAST_FAIL_INVALID_DISPATCH_CONTEXT 39
|
||||
#define DMN_W32_FAST_FAIL_INVALID_THREAD 40
|
||||
#define DMN_W32_FAST_FAIL_INVALID_SYSCALL_NUMBER 41 // Telemetry, nonfatal
|
||||
#define DMN_W32_FAST_FAIL_INVALID_FILE_OPERATION 42 // Telemetry, nonfatal
|
||||
#define DMN_W32_FAST_FAIL_LPAC_ACCESS_DENIED 43 // Telemetry, nonfatal
|
||||
#define DMN_W32_FAST_FAIL_GUARD_SS_FAILURE 44
|
||||
#define DMN_W32_FAST_FAIL_LOADER_CONTINUITY_FAILURE 45 // Telemetry, nonfatal
|
||||
#define DMN_W32_FAST_FAIL_GUARD_EXPORT_SUPPRESSION_FAILURE 46
|
||||
#define DMN_W32_FAST_FAIL_INVALID_CONTROL_STACK 47
|
||||
#define DMN_W32_FAST_FAIL_SET_CONTEXT_DENIED 48
|
||||
#define DMN_W32_FAST_FAIL_INVALID_IAT 49
|
||||
#define DMN_W32_FAST_FAIL_HEAP_METADATA_CORRUPTION 50
|
||||
#define DMN_W32_FAST_FAIL_PAYLOAD_RESTRICTION_VIOLATION 51
|
||||
#define DMN_W32_FAST_FAIL_LOW_LABEL_ACCESS_DENIED 52 // Telemetry, nonfatal
|
||||
#define DMN_W32_FAST_FAIL_ENCLAVE_CALL_FAILURE 53
|
||||
#define DMN_W32_FAST_FAIL_UNHANDLED_LSS_EXCEPTON 54
|
||||
#define DMN_W32_FAST_FAIL_ADMINLESS_ACCESS_DENIED 55 // Telemetry, nonfatal
|
||||
#define DMN_W32_FAST_FAIL_UNEXPECTED_CALL 56
|
||||
#define DMN_W32_FAST_FAIL_CONTROL_INVALID_RETURN_ADDRESS 57
|
||||
#define DMN_W32_FAST_FAIL_UNEXPECTED_HOST_BEHAVIOR 58
|
||||
#define DMN_W32_FAST_FAIL_FLAGS_CORRUPTION 59
|
||||
#define DMN_W32_FAST_FAIL_VEH_CORRUPTION 60
|
||||
#define DMN_W32_FAST_FAIL_ETW_CORRUPTION 61
|
||||
#define DMN_W32_FAST_FAIL_RIO_ABORT 62
|
||||
#define DMN_W32_FAST_FAIL_INVALID_PFN 63
|
||||
#define DMN_W32_FAST_FAIL_GUARD_ICALL_CHECK_FAILURE_XFG 64
|
||||
#define DMN_W32_FAST_FAIL_CAST_GUARD 65 // Known to compiler, must retain value 65
|
||||
#define DMN_W32_FAST_FAIL_HOST_VISIBILITY_CHANGE 66
|
||||
#define DMN_W32_FAST_FAIL_KERNEL_CET_SHADOW_STACK_ASSIST 67
|
||||
#define DMN_W32_FAST_FAIL_PATCH_CALLBACK_FAILED 68
|
||||
#define DMN_W32_FAST_FAIL_NTDLL_PATCH_FAILED 69
|
||||
#define DMN_W32_FAST_FAIL_INVALID_FLS_DATA 70
|
||||
#define DMN_W32_FAST_FAIL_INVALID_FAST_FAIL_CODE 0xFFFFFFFF
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Win32 Register Codes
|
||||
|
||||
#define DMN_W32_CTX_X86 0x00010000
|
||||
#define DMN_W32_CTX_X64 0x00100000
|
||||
|
||||
#define DMN_W32_CTX_INTEL_CONTROL 0x0001 // segss, rsp, segcs, rip, and rflags
|
||||
#define DMN_W32_CTX_INTEL_INTEGER 0x0002 // rax, rcx, rdx, rbx, rbp, rsi, rdi, and r8-r15
|
||||
#define DMN_W32_CTX_INTEL_SEGMENTS 0x0004 // segds, seges, segfs, and seggs
|
||||
#define DMN_W32_CTX_INTEL_FLOATS 0x0008 // xmm0-xmm15
|
||||
#define DMN_W32_CTX_INTEL_DEBUG 0x0010 // dr0-dr3 and dr6-dr7
|
||||
#define DMN_W32_CTX_INTEL_EXTENDED 0x0020
|
||||
#define DMN_W32_CTX_INTEL_XSTATE 0x0040
|
||||
|
||||
#define DMN_W32_CTX_X86_ALL (DMN_W32_CTX_X86 | \
|
||||
DMN_W32_CTX_INTEL_CONTROL | DMN_W32_CTX_INTEL_INTEGER | \
|
||||
DMN_W32_CTX_INTEL_SEGMENTS | DMN_W32_CTX_INTEL_DEBUG | \
|
||||
DMN_W32_CTX_INTEL_EXTENDED)
|
||||
#define DMN_W32_CTX_X64_ALL (DMN_W32_CTX_X64 | \
|
||||
DMN_W32_CTX_INTEL_CONTROL | DMN_W32_CTX_INTEL_INTEGER | \
|
||||
DMN_W32_CTX_INTEL_SEGMENTS | DMN_W32_CTX_INTEL_FLOATS | \
|
||||
DMN_W32_CTX_INTEL_DEBUG)
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Per-Entity State
|
||||
|
||||
typedef enum DMN_W32_EntityKind
|
||||
{
|
||||
DMN_W32_EntityKind_Null,
|
||||
DMN_W32_EntityKind_Root,
|
||||
DMN_W32_EntityKind_Process,
|
||||
DMN_W32_EntityKind_Thread,
|
||||
DMN_W32_EntityKind_Module,
|
||||
DMN_W32_EntityKind_COUNT
|
||||
}
|
||||
DMN_W32_EntityKind;
|
||||
|
||||
typedef struct DMN_W32_Entity DMN_W32_Entity;
|
||||
struct DMN_W32_Entity
|
||||
{
|
||||
DMN_W32_Entity *first;
|
||||
DMN_W32_Entity *last;
|
||||
DMN_W32_Entity *next;
|
||||
DMN_W32_Entity *prev;
|
||||
DMN_W32_Entity *parent;
|
||||
DMN_W32_EntityKind kind;
|
||||
U32 gen;
|
||||
U64 id;
|
||||
HANDLE handle;
|
||||
Arch arch;
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
U64 injection_address;
|
||||
B32 did_first_bp;
|
||||
}
|
||||
proc;
|
||||
struct
|
||||
{
|
||||
U64 thread_local_base;
|
||||
U64 last_name_hash;
|
||||
U64 name_gather_time_us;
|
||||
}
|
||||
thread;
|
||||
struct
|
||||
{
|
||||
Rng1U64 vaddr_range;
|
||||
U64 address_of_name_pointer;
|
||||
B32 is_main;
|
||||
B32 name_is_unicode;
|
||||
}
|
||||
module;
|
||||
};
|
||||
};
|
||||
|
||||
typedef struct DMN_W32_EntityNode DMN_W32_EntityNode;
|
||||
struct DMN_W32_EntityNode
|
||||
{
|
||||
DMN_W32_EntityNode *next;
|
||||
DMN_W32_Entity *v;
|
||||
};
|
||||
|
||||
typedef struct DMN_W32_EntityIDHashNode DMN_W32_EntityIDHashNode;
|
||||
struct DMN_W32_EntityIDHashNode
|
||||
{
|
||||
DMN_W32_EntityIDHashNode *next;
|
||||
DMN_W32_EntityIDHashNode *prev;
|
||||
U64 id;
|
||||
DMN_W32_Entity *entity;
|
||||
};
|
||||
|
||||
typedef struct DMN_W32_EntityIDHashSlot DMN_W32_EntityIDHashSlot;
|
||||
struct DMN_W32_EntityIDHashSlot
|
||||
{
|
||||
DMN_W32_EntityIDHashNode *first;
|
||||
DMN_W32_EntityIDHashNode *last;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Injection Types
|
||||
|
||||
typedef struct DMN_W32_InjectedBreak DMN_W32_InjectedBreak;
|
||||
struct DMN_W32_InjectedBreak
|
||||
{
|
||||
U64 code;
|
||||
U64 user_data;
|
||||
};
|
||||
|
||||
#define DMN_W32_INJECTED_CODE_SIZE 32
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Image Info Types
|
||||
|
||||
typedef struct DMN_W32_ImageInfo DMN_W32_ImageInfo;
|
||||
struct DMN_W32_ImageInfo
|
||||
{
|
||||
Arch arch;
|
||||
U32 size;
|
||||
U64 tls_index;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Dynamically-Loaded Win32 Function Types
|
||||
|
||||
typedef HRESULT DMN_W32_GetThreadDescriptionFunctionType(HANDLE hThread, WCHAR **ppszThreadDescription);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Shared State Bundle
|
||||
|
||||
typedef struct DMN_W32_Shared DMN_W32_Shared;
|
||||
struct DMN_W32_Shared
|
||||
{
|
||||
// rjf: top-level info
|
||||
Arena *arena;
|
||||
String8List env_strings;
|
||||
|
||||
// rjf: access locking mechanism
|
||||
Mutex access_mutex;
|
||||
B32 access_run_state;
|
||||
|
||||
// rjf: detaching info
|
||||
Arena *detach_arena;
|
||||
DMN_HandleList detach_processes;
|
||||
|
||||
// rjf: entity state
|
||||
Arena *entities_arena;
|
||||
DMN_W32_Entity *entities_base;
|
||||
DMN_W32_Entity *entities_first_free;
|
||||
U64 entities_count;
|
||||
DMN_W32_EntityIDHashSlot *entities_id_hash_slots;
|
||||
U64 entities_id_hash_slots_count;
|
||||
DMN_W32_EntityIDHashNode *entities_id_hash_node_free;
|
||||
|
||||
// rjf: launch state
|
||||
B32 new_process_pending;
|
||||
|
||||
// rjf: run results
|
||||
B32 resume_needed;
|
||||
U32 resume_pid;
|
||||
U32 resume_tid;
|
||||
B32 exception_not_handled;
|
||||
|
||||
// rjf: halting info
|
||||
DMN_Handle halter_process;
|
||||
U32 halter_tid;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Globals
|
||||
|
||||
global DMN_W32_Shared *dmn_w32_shared = 0;
|
||||
global DMN_W32_Entity dmn_w32_entity_nil = {&dmn_w32_entity_nil, &dmn_w32_entity_nil, &dmn_w32_entity_nil, &dmn_w32_entity_nil, &dmn_w32_entity_nil};
|
||||
global DMN_W32_GetThreadDescriptionFunctionType *dmn_w32_GetThreadDescription = 0;
|
||||
thread_static B32 dmn_w32_ctrl_thread = 0;
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Basic Helpers
|
||||
|
||||
internal U64 dmn_w32_hash_from_string(String8 string);
|
||||
internal U64 dmn_w32_hash_from_id(U64 id);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Entity Helpers
|
||||
|
||||
//- rjf: entity <-> handle
|
||||
internal DMN_Handle dmn_w32_handle_from_entity(DMN_W32_Entity *entity);
|
||||
internal DMN_W32_Entity *dmn_w32_entity_from_handle(DMN_Handle handle);
|
||||
|
||||
//- rjf: entity allocation/deallocation
|
||||
internal DMN_W32_Entity *dmn_w32_entity_alloc(DMN_W32_Entity *parent, DMN_W32_EntityKind kind, U64 id);
|
||||
internal void dmn_w32_entity_release(DMN_W32_Entity *entity);
|
||||
|
||||
//- rjf: kind*id -> entity
|
||||
internal DMN_W32_Entity *dmn_w32_entity_from_kind_id(DMN_W32_EntityKind kind, U64 id);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Module Info Extraction
|
||||
|
||||
internal String8 dmn_w32_full_path_from_module(Arena *arena, DMN_W32_Entity *module);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Win32-Level Process/Thread Reads/Writes
|
||||
|
||||
//- rjf: processes
|
||||
internal U64 dmn_w32_process_read(HANDLE process, Rng1U64 range, void *dst);
|
||||
internal B32 dmn_w32_process_write(HANDLE process, Rng1U64 range, void *src);
|
||||
internal String8 dmn_w32_read_memory_str(Arena *arena, HANDLE process_handle, U64 address);
|
||||
internal String16 dmn_w32_read_memory_str16(Arena *arena, HANDLE process_handle, U64 address);
|
||||
#define dmn_w32_process_read_struct(process, vaddr, ptr) dmn_w32_process_read((process), r1u64((vaddr), (vaddr)+(sizeof(*ptr))), ptr)
|
||||
#define dmn_w32_process_write_struct(process, vaddr, ptr) dmn_w32_process_write((process), r1u64((vaddr), (vaddr)+(sizeof(*ptr))), ptr)
|
||||
internal DMN_W32_ImageInfo dmn_w32_image_info_from_process_base_vaddr(HANDLE process, U64 base_vaddr);
|
||||
|
||||
//- rjf: threads
|
||||
internal B32 dmn_w32_thread_read_reg_block(Arch arch, HANDLE thread, void *reg_block);
|
||||
internal B32 dmn_w32_thread_write_reg_block(Arch arch, HANDLE thread, void *reg_block);
|
||||
|
||||
//- rjf: remote thread injection
|
||||
internal DWORD dmn_w32_inject_thread(HANDLE process, U64 start_address);
|
||||
|
||||
#endif // DEMON_CORE_WIN32_H
|
||||
Reference in new issue
Block a user