first pass at demon replacement layer; just trimming out old code & cruft & reading & naming pass

This commit is contained in:
Ryan Fleury
2024-03-05 14:17:41 -08:00
parent 091269b1d8
commit 0c436f0d5b
13 changed files with 3286 additions and 10 deletions
+1 -1
View File
@@ -47,7 +47,7 @@ commands =
{
.rjf_f1 =
{
.win = "build raddbgi_from_pdb telemetry debug",
.win = "build ryan_scratch",
.linux = "",
.out = "*compilation*",
.footer_panel = true,
+1 -1
View File
@@ -13,7 +13,7 @@ global DWORD demon_w32_resume_tid = 0;
global B32 demon_w32_exception_not_handled = 0;
global DEMON_Entity* demon_w32_halter_process = 0;
global DWORD demon_w32_halter_thread_id = 0;
.
global B32 demon_w32_new_process_pending = 0;
global Arena *demon_w32_ext_arena = 0 ;
+118
View File
@@ -0,0 +1,118 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
////////////////////////////////
//~ rjf: Basic Type Functions (Helpers, Implemented Once)
//- rjf: handles
internal DMN_Handle
dmn_handle_zero(void)
{
DMN_Handle h = {0};
return h;
}
internal B32
dmn_handle_match(DMN_Handle a, DMN_Handle b)
{
return a.u32[0] == b.u32[0] && a.u32[1] == b.u32[1];
}
//- rjf: trap chunk lists
internal void
dmn_trap_chunk_list_push(Arena *arena, DMN_TrapChunkList *list, U64 cap, DMN_Trap *trap)
{
DMN_TrapChunkNode *node = list->last;
if(node == 0 || node->count >= node->cap)
{
node = push_array(arena, DMN_TrapChunkNode, 1);
node->cap = cap;
node->v = push_array_no_zero(arena, DMN_Trap, node->cap);
SLLQueuePush(list->first, list->last, node);
list->node_count += 1;
}
MemoryCopyStruct(&node->v[node->count], trap);
node->count += 1;
list->trap_count += 1;
}
internal void
dmn_trap_chunk_list_concat_in_place(DMN_TrapChunkList *dst, DMN_TrapChunkList *to_push)
{
if(dst->last == 0)
{
MemoryCopyStruct(dst, to_push);
}
else if(to_push->first != 0)
{
dst->last->next = to_push->first;
dst->last = to_push->last;
dst->node_count += to_push->node_count;
dst->trap_count += to_push->trap_count;
}
MemoryZeroStruct(to_push);
}
internal void
dmn_trap_chunk_list_concat_shallow_copy(Arena *arena, DMN_TrapChunkList *dst, DMN_TrapChunkList *to_push)
{
for(DMN_TrapChunkNode *src_n = to_push->first; src_n != 0; src_n = src_n->next)
{
DMN_TrapChunkNode *dst_n = push_array(arena, DMN_TrapChunkNode, 1);
dst_n->v = src_n->v;
dst_n->cap = src_n->cap;
dst_n->count = src_n->count;
SLLQueuePush(dst->first, dst->last, dst_n);
dst->node_count += 1;
dst->trap_count += dst_n->count;
}
}
//- rjf: handle lists
internal void
dmn_handle_list_push(Arena *arena, DMN_HandleList *list, DMN_Handle handle)
{
DMN_HandleNode *node = push_array(arena, DMN_HandleNode, 1);
SLLQueuePush(list->first, list->last, node);
node->v = handle;
list->count += 1;
}
internal DMN_HandleArray
dmn_handle_array_from_list(Arena *arena, DMN_HandleList *list)
{
DMN_HandleArray array = {0};
array.count = list->count;
array.handles = push_array_no_zero(arena, DMN_Handle, array.count);
U64 idx = 0;
for(DMN_HandleNode *n = list->first; n != 0; n = n->next, idx += 1)
{
array.handles[idx] = n->v;
}
return array;
}
internal DMN_HandleArray
dmn_handle_array_copy(Arena *arena, DMN_HandleArray *src)
{
DMN_HandleArray dst = {0};
dst.count = src->count;
dst.handles = push_array_no_zero(arena, DMN_Handle, dst.count);
MemoryCopy(dst.handles, src->handles, sizeof(DMN_Handle)*dst.count);
return dst;
}
//- rjf: event list building
internal DMN_Event *
dmn_event_list_push(Arena *arena, DMN_EventList *list)
{
DMN_EventNode *n = push_array(arena, DMN_EventNode, 1);
SLLQueuePush(list->first, list->last, n);
list->count += 1;
DMN_Event *result = &n->v;
return result;
}
+209
View File
@@ -0,0 +1,209 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef DEMON2_CORE_H
#define DEMON2_CORE_H
////////////////////////////////
//~ rjf: Handle Types
typedef struct DMN_Handle DMN_Handle;
struct DMN_Handle
{
U32 u32[2];
};
typedef struct DMN_HandleNode DMN_HandleNode;
struct DMN_HandleNode
{
DMN_HandleNode *next;
DMN_Handle v;
};
typedef struct DMN_HandleList DMN_HandleList;
struct DMN_HandleList
{
DMN_HandleNode *first;
DMN_HandleNode *last;
U64 count;
};
typedef struct DMN_HandleArray DMN_HandleArray;
struct DMN_HandleArray
{
DMN_Handle *handles;
U64 count;
};
////////////////////////////////
//~ rjf: Generated Code
#include "generated/demon2.meta.h"
////////////////////////////////
//~ rjf: Event Types
typedef struct DMN_Event DMN_Event;
struct DMN_Event
{
DMN_EventKind kind;
DMN_ErrorKind error_kind;
DMN_MemoryEventKind memory_kind;
DMN_ExceptionKind exception_kind;
DMN_Handle process;
DMN_Handle thread;
DMN_Handle module;
U64 address;
U64 size;
String8 string;
U32 code; // code gives pid & tid on CreateProcess and CreateThread (respectfully)
U32 flags;
S32 signo;
S32 sigcode;
U64 instruction_pointer;
U64 stack_pointer;
U64 user_data;
B32 exception_repeated;
};
typedef struct DMN_EventNode DMN_EventNode;
struct DMN_EventNode
{
DMN_EventNode *next;
DMN_Event v;
};
typedef struct DMN_EventList DMN_EventList;
struct DMN_EventList
{
DMN_EventNode *first;
DMN_EventNode *last;
U64 count;
};
////////////////////////////////
//~ rjf: Run Control Types
typedef struct DMN_Trap DMN_Trap;
struct DMN_Trap
{
DMN_Handle process;
U64 vaddr;
U64 id;
};
typedef struct DMN_TrapChunkNode DMN_TrapChunkNode;
struct DMN_TrapChunkNode
{
DMN_TrapChunkNode *next;
DMN_Trap *v;
U64 cap;
U64 count;
};
typedef struct DMN_TrapChunkList DMN_TrapChunkList;
struct DMN_TrapChunkList
{
DMN_TrapChunkNode *first;
DMN_TrapChunkNode *last;
U64 node_count;
U64 trap_count;
};
typedef struct DMN_RunCtrls DMN_RunCtrls;
struct DMN_RunCtrls
{
DMN_Handle single_step_thread;
B8 ignore_previous_exception;
B8 run_entities_are_unfrozen;
B8 run_entities_are_processes;
DMN_Handle *run_entities;
U64 run_entity_count;
DMN_TrapChunkList traps;
};
////////////////////////////////
//~ rjf: System Process Listing Types
typedef struct DMN_ProcessIter DMN_ProcessIter;
struct DMN_ProcessIter
{
U64 v[2];
};
typedef struct DMN_ProcessInfo DMN_ProcessInfo;
struct DMN_ProcessInfo
{
String8 name;
U32 pid;
};
////////////////////////////////
//~ rjf: Basic Type Functions (Helpers, Implemented Once)
//- rjf: handles
internal DMN_Handle dmn_handle_zero(void);
internal B32 dmn_handle_match(DMN_Handle a, DMN_Handle b);
//- rjf: trap chunk lists
internal void dmn_trap_chunk_list_push(Arena *arena, DMN_TrapChunkList *list, U64 cap, DMN_Trap *trap);
internal void dmn_trap_chunk_list_concat_in_place(DMN_TrapChunkList *dst, DMN_TrapChunkList *to_push);
internal void dmn_trap_chunk_list_concat_shallow_copy(Arena *arena, DMN_TrapChunkList *dst, DMN_TrapChunkList *to_push);
//- rjf: handle lists
internal void dmn_handle_list_push(Arena *arena, DMN_HandleList *list, DMN_Handle handle);
internal DMN_HandleArray dmn_handle_array_from_list(Arena *arena, DMN_HandleList *list);
internal DMN_HandleArray dmn_handle_array_copy(Arena *arena, DMN_HandleArray *src);
//- rjf: event list building
internal DMN_Event *dmn_event_list_push(Arena *arena, DMN_EventList *list);
////////////////////////////////
//~ rjf: @dmn_os_hooks Main Layer Initialization (Implemented Per-OS)
internal void dmn_init(void);
////////////////////////////////
//~ rjf: @dmn_os_hooks Running/Halting (Implemented Per-OS)
internal DMN_EventList dmn_run(Arena *arena, DMN_RunCtrls *ctrls);
internal void dmn_halt(U64 code, U64 user_data);
////////////////////////////////
//~ rjf: @dmn_os_hooks Process Launching/Attaching/Killing/Detaching (Implemented Per-OS)
internal U32 dmn_launch_process(OS_LaunchOptions *options);
internal B32 dmn_attach_process(U32 pid);
internal B32 dmn_kill_process(DMN_Handle process, U32 exit_code);
internal B32 dmn_detach_process(DMN_Handle process);
////////////////////////////////
//~ rjf: @dmn_os_hooks Entities (Implemented Per-OS)
//- rjf: basic entity info extraction
internal Architecture dmn_arch_from_handle(DMN_Handle handle);
internal String8 dmn_string_from_handle(Arena *arena, DMN_Handle handle);
//- rjf: processes
internal U64 dmn_process_read(DMN_Handle process, Rng1U64 range, void *dst);
internal B32 dmn_process_write(DMN_Handle process, Rng1U64 range, void *src);
#define dmn_process_read_struct(process, vaddr, ptr) dmn_process_read((process), r1u64((vaddr), (vaddr)+(sizeof(*ptr))), ptr)
#define dmn_process_write_struct(process, vaddr, ptr) dmn_process_write((process), r1u64((vaddr), (vaddr)+(sizeof(*ptr))), ptr)
//- rjf: modules
internal Rng1U64 dmn_vaddr_range_from_module(DMN_Handle handle);
//- rjf: threads
internal U64 dmn_stack_base_vaddr_from_thread(DMN_Handle handle);
internal U64 dmn_tls_root_vaddr_from_thread(DMN_Handle handle);
internal B32 dmn_thread_read_reg_block(DMN_Handle handle, void *reg_block);
internal B32 dmn_thread_write_reg_block(DMN_Handle handle, void *reg_block);
////////////////////////////////
//~ rjf: @dmn_os_hooks System Process Listing (Implemented Per-OS)
internal void dmn_process_iter_begin(DMN_ProcessIter *iter);
internal B32 dmn_process_iter_next(Arena *arena, DMN_ProcessIter *iter, DMN_ProcessInfo *info_out);
internal void dmn_process_iter_end(DMN_ProcessIter *iter);
#endif // DEMON2_CORE_H
+80
View File
@@ -0,0 +1,80 @@
////////////////////////////////
//~ rjf: Event Kind Tables
@table(name)
DMN_EventKindTable:
{
{Null}
{Error}
{HandshakeComplete}
{CreateProcess}
{ExitProcess}
{CreateThread}
{ExitThread}
{LoadModule}
{UnloadModule}
{Breakpoint}
{Trap}
{SingleStep}
{Exception}
{Halt}
{Memory}
{DebugString}
{SetThreadName}
}
@table(name)
DMN_ErrorKindTable:
{
{Null}
{NotAttached}
{UnexpectedFailure}
{InvalidHandle}
}
@table(name)
DMN_MemoryEventKindTable:
{
{Null}
{Commit}
{Reserve}
{Decommit}
{Release}
}
@table(name)
DMN_ExceptionKindTable:
{
{Null}
{MemoryRead}
{MemoryWrite}
{MemoryExecute}
{CppThrow}
}
////////////////////////////////
//~ rjf: Generators
@enum DMN_EventKind:
{
@expand(DMN_EventKindTable a) `$(a.name)`,
COUNT
}
@enum DMN_ErrorKind:
{
@expand(DMN_ErrorKindTable a) `$(a.name)`,
COUNT
}
@enum DMN_MemoryEventKind:
{
@expand(DMN_MemoryEventKindTable a) `$(a.name)`,
COUNT
}
@enum DMN_ExceptionKind:
{
@expand(DMN_ExceptionKindTable a) `$(a.name)`,
COUNT
}
+10
View File
@@ -0,0 +1,10 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#include "demon2_core.c"
#if OS_WINDOWS
# include "win32/demon2_core_win32.c"
#else
# error Demon layer backend not defined for this operating system.
#endif
+15
View File
@@ -0,0 +1,15 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef DEMON2_INC_H
#define DEMON2_INC_H
#include "demon2_core.h"
#if OS_WINDOWS
# include "win32/demon2_core_win32.h"
#else
# error Demon layer backend not defined for this operating system.
#endif
#endif // DEMON2_INC_H
+8
View File
@@ -0,0 +1,8 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
//- GENERATED CODE
C_LINKAGE_BEGIN
C_LINKAGE_END
+63
View File
@@ -0,0 +1,63 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
//- GENERATED CODE
#ifndef DEMON2_META_H
#define DEMON2_META_H
typedef enum DMN_EventKind
{
DMN_EventKind_Null,
DMN_EventKind_Error,
DMN_EventKind_HandshakeComplete,
DMN_EventKind_CreateProcess,
DMN_EventKind_ExitProcess,
DMN_EventKind_CreateThread,
DMN_EventKind_ExitThread,
DMN_EventKind_LoadModule,
DMN_EventKind_UnloadModule,
DMN_EventKind_Breakpoint,
DMN_EventKind_Trap,
DMN_EventKind_SingleStep,
DMN_EventKind_Exception,
DMN_EventKind_Halt,
DMN_EventKind_Memory,
DMN_EventKind_DebugString,
DMN_EventKind_SetThreadName,
DMN_EventKind_COUNT,
} DMN_EventKind;
typedef enum DMN_ErrorKind
{
DMN_ErrorKind_Null,
DMN_ErrorKind_NotAttached,
DMN_ErrorKind_UnexpectedFailure,
DMN_ErrorKind_InvalidHandle,
DMN_ErrorKind_COUNT,
} DMN_ErrorKind;
typedef enum DMN_MemoryEventKind
{
DMN_MemoryEventKind_Null,
DMN_MemoryEventKind_Commit,
DMN_MemoryEventKind_Reserve,
DMN_MemoryEventKind_Decommit,
DMN_MemoryEventKind_Release,
DMN_MemoryEventKind_COUNT,
} DMN_MemoryEventKind;
typedef enum DMN_ExceptionKind
{
DMN_ExceptionKind_Null,
DMN_ExceptionKind_MemoryRead,
DMN_ExceptionKind_MemoryWrite,
DMN_ExceptionKind_MemoryExecute,
DMN_ExceptionKind_CppThrow,
DMN_ExceptionKind_COUNT,
} DMN_ExceptionKind;
C_LINKAGE_BEGIN
C_LINKAGE_END
#endif // DEMON2_META_H
File diff suppressed because it is too large Load Diff
+272
View File
@@ -0,0 +1,272 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef DEMON2_CORE_WIN32_H
#define DEMON2_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
////////////////////////////////
//~ rjf: Win32 Register Codes
#define DMN_W32_CTX_X86 0x00010000
#define DMN_W32_CTX_X64 0x00100000
#define DMN_W32_CTX_INTEL_CONTROL 0x0001
#define DMN_W32_CTX_INTEL_INTEGER 0x0002
#define DMN_W32_CTX_INTEL_SEGMENTS 0x0004
#define DMN_W32_CTX_INTEL_FLOATS 0x0008
#define DMN_W32_CTX_INTEL_DEBUG 0x0010
#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;
Architecture 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;
B32 last_run_reported_trap;
U64 last_run_reported_trap_pre_rip;
U64 last_run_reported_trap_post_rip;
}
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
{
Architecture arch;
U32 size;
};
////////////////////////////////
//~ 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: 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;
////////////////////////////////
//~ rjf: Helpers
//- rjf: hashes
internal U64 dmn_w32_hash_from_string(String8 string);
internal U64 dmn_w32_hash_from_id(U64 id);
//- 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: win32-level process reads/writes
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)
//- rjf: win32-level thread register reads/writes
internal U16 dmn_w32_real_tag_word_from_xsave(XSAVE_FORMAT *fxsave);
internal U16 dmn_w32_xsave_tag_word_from_real_tag_word(U16 ftw);
internal B32 dmn_w32_thread_read_reg_block(Architecture arch, HANDLE thread, void *reg_block);
internal B32 dmn_w32_thread_write_reg_block(Architecture arch, HANDLE thread, void *reg_block);
//- rjf: win32-level thread injection
internal DWORD dmn_w32_inject_thread(HANDLE process, U64 start_address);
//- rjf: module image analysis
internal DMN_W32_ImageInfo dmn_w32_image_info_from_process_base_vaddr(HANDLE process, U64 base_vaddr);
//- rjf: module full path extraction
internal String8 dmn_w32_full_path_from_module(Arena *arena, DMN_W32_Entity *module);
#endif // DEMON2_CORE_WIN32_H
+2
View File
@@ -9,6 +9,8 @@
// [x] CRT asserts - stepping over int 29 should work just like stepping over
// an int3
// [ ] committing needs to happen when navigating focus away for any reason
// [ ] better discoverability for view rules - have better help hover tooltip,
// info on arguments, and better autocomplete lister
//
// [ ] source view -> floating margin/line-nums
// [ ] theme colors -> more explicit about e.g. opaque backgrounds vs. floating
+34 -8
View File
@@ -1,14 +1,40 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#include "lib_raddbgi_format/raddbgi_format.h"
#include "lib_raddbgi_format/raddbgi_format.c"
#include "lib_raddbgi_format/raddbgi_format_parse.h"
#include "lib_raddbgi_format/raddbgi_format_parse.c"
#include "lib_raddbgi_make/raddbgi_make.h"
#include "lib_raddbgi_make/raddbgi_make.c"
////////////////////////////////
//~ rjf: Build Options
int main(int argument_count, char **arguments)
#define BUILD_VERSION_MAJOR 0
#define BUILD_VERSION_MINOR 9
#define BUILD_VERSION_PATCH 8
#define BUILD_RELEASE_PHASE_STRING_LITERAL "ALPHA"
#define BUILD_TITLE "ryan_scratch"
#define BUILD_CONSOLE_INTERFACE 1
////////////////////////////////
//~ rjf: Includes
//- rjf: [h]
#include "base/base_inc.h"
#include "os/os_inc.h"
#include "regs/regs.h"
#include "coff/coff.h"
#include "pe/pe.h"
#include "demon2/demon2_inc.h"
//- rjf: [c]
#include "base/base_inc.c"
#include "os/os_inc.c"
#include "regs/regs.c"
#include "coff/coff.c"
#include "pe/pe.c"
#include "demon2/demon2_inc.c"
////////////////////////////////
//~ rjf: Entry Point
internal void
entry_point(CmdLine *cmdline)
{
return 0;
}