diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index 1f05114c..ab1c1614 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -606,8 +606,8 @@ ctrl_event_from_serialized_string(Arena *arena, String8 string) read_off += str8_deserial_read_struct(string, read_off, &event.stack_base); read_off += str8_deserial_read_struct(string, read_off, &event.tls_root); read_off += str8_deserial_read_struct(string, read_off, &event.timestamp); - read_off += str8_deserial_read_struct(string, read_off, &event.exception_code); read_off += str8_deserial_read_struct(string, read_off, &event.rgba); + read_off += str8_deserial_read_struct(string, read_off, &event.exception_code); read_off += str8_deserial_read_struct(string, read_off, &event.string.size); event.string.str = push_array_no_zero(arena, U8, event.string.size); read_off += str8_deserial_read(string, read_off, event.string.str, event.string.size, 1); @@ -3603,6 +3603,7 @@ ctrl_thread__module_open(CTRL_Handle process, CTRL_Handle module, Rng1U64 vaddr_ Guid rdi_dbg_guid = {0}; String8 rdi_dbg_path = str8_zero(); String8 raddbg_data = str8_zero(); + Rng1U64 raddbg_section_voff_range = r1u64(0, 0); ProfScope("unpack relevant PE info") { B32 is_valid = 1; @@ -3804,7 +3805,6 @@ ctrl_thread__module_open(CTRL_Handle process, CTRL_Handle module, Rng1U64 vaddr_ U64 sec_count = file_header.section_count; COFF_SectionHeader *sec = push_array(scratch.arena, COFF_SectionHeader, sec_count); dmn_process_read(process.dmn_handle, r1u64(vaddr_range.min + sec_array_off, vaddr_range.min + sec_array_off + sec_count*sizeof(COFF_SectionHeader)), sec); - Rng1U64 raddbg_section_voff_range = r1u64(0, 0); for EachIndex(idx, sec_count) { String8 section_name = str8_cstring(sec[idx].name); @@ -3820,6 +3820,13 @@ ctrl_thread__module_open(CTRL_Handle process, CTRL_Handle module, Rng1U64 vaddr_ vaddr_range.min + raddbg_section_voff_range.max), raddbg_data.str); scratch_end(scratch); } + + // rjf: if we have a raddbg section, mark the first byte as 1, to signify attachment + if(raddbg_section_voff_range.max != raddbg_section_voff_range.min) + { + U8 new_value = 1; + dmn_process_write_struct(process.dmn_handle, vaddr_range.min + raddbg_section_voff_range.min, &new_value); + } } } @@ -3898,6 +3905,7 @@ ctrl_thread__module_open(CTRL_Handle process, CTRL_Handle module, Rng1U64 vaddr_ node->pdatas_count = pdatas_count; node->entry_point_voff = entry_point_voff; node->initial_debug_info_path = initial_debug_info_path; + node->raddbg_section_voff_range = raddbg_section_voff_range; node->raddbg_data = raddbg_data; } } @@ -3905,11 +3913,12 @@ ctrl_thread__module_open(CTRL_Handle process, CTRL_Handle module, Rng1U64 vaddr_ } internal void -ctrl_thread__module_close(CTRL_Handle module) +ctrl_thread__module_close(CTRL_Handle process, CTRL_Handle module, Rng1U64 vaddr_range) { ////////////////////////////// //- rjf: evict module image info from cache // + Rng1U64 raddbg_section_voff_range = {0}; { U64 hash = ctrl_hash_from_handle(module); U64 slot_idx = hash%ctrl_state->module_image_info_cache.slots_count; @@ -3929,11 +3938,21 @@ ctrl_thread__module_close(CTRL_Handle module) } if(node) { + raddbg_section_voff_range = node->raddbg_section_voff_range; DLLRemove(slot->first, slot->last, node); arena_release(node->arena); } } } + + ////////////////////////////// + //- rjf: write 0 into first byte of raddbg data section, to signify detachment + // + if(raddbg_section_voff_range.max != raddbg_section_voff_range.min) + { + U8 new_value = 0; + dmn_process_write_struct(process.dmn_handle, vaddr_range.min + raddbg_section_voff_range.min, &new_value); + } } //- rjf: attached process running/event gathering @@ -4265,13 +4284,14 @@ ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg, { CTRL_Event *out_evt = ctrl_event_list_push(scratch.arena, &evts); CTRL_Handle module_handle = ctrl_handle_make(CTRL_MachineID_Local, event->module); + CTRL_Entity *module_ent = ctrl_entity_from_handle(ctrl_state->ctrl_thread_entity_store, module_handle); + CTRL_Entity *process_ent = ctrl_process_from_entity(module_ent); String8 module_path = event->string; - ctrl_thread__module_close(module_handle); + ctrl_thread__module_close(process_ent->handle, module_handle, module_ent->vaddr_range); out_evt->kind = CTRL_EventKind_EndModule; out_evt->msg_id = msg->msg_id; out_evt->entity = module_handle; out_evt->string = module_path; - CTRL_Entity *module_ent = ctrl_entity_from_handle(ctrl_state->ctrl_thread_entity_store, module_handle); CTRL_Entity *debug_info_path_ent = ctrl_entity_child_from_kind(module_ent, CTRL_EntityKind_DebugInfoPath); if(debug_info_path_ent != &ctrl_entity_nil) { @@ -4302,6 +4322,15 @@ ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg, out_evt->string = event->string; out_evt->entity_id = event->code; }break; + case DMN_EventKind_SetThreadColor: + { + CTRL_Event *out_evt = ctrl_event_list_push(scratch.arena, &evts); + out_evt->kind = CTRL_EventKind_ThreadColor; + out_evt->msg_id = msg->msg_id; + out_evt->entity = ctrl_handle_make(CTRL_MachineID_Local, event->thread); + out_evt->parent = ctrl_handle_make(CTRL_MachineID_Local, event->process); + out_evt->rgba = event->code; + }break; } ctrl_c2u_push_events(&evts); diff --git a/src/ctrl/ctrl_core.h b/src/ctrl/ctrl_core.h index eb74a594..114834fd 100644 --- a/src/ctrl/ctrl_core.h +++ b/src/ctrl/ctrl_core.h @@ -593,6 +593,7 @@ struct CTRL_ModuleImageInfoCacheNode U64 entry_point_voff; Rng1U64 tls_vaddr_range; String8 initial_debug_info_path; + Rng1U64 raddbg_section_voff_range; String8 raddbg_data; }; @@ -953,7 +954,7 @@ internal void ctrl_thread__append_resolved_process_user_bp_traps(Arena *arena, C //- rjf: module lifetime open/close work internal void ctrl_thread__module_open(CTRL_Handle process, CTRL_Handle module, Rng1U64 vaddr_range, String8 path); -internal void ctrl_thread__module_close(CTRL_Handle module); +internal void ctrl_thread__module_close(CTRL_Handle process, CTRL_Handle module, Rng1U64 vaddr_range); //- rjf: attached process running/event gathering internal DMN_Event *ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg, DMN_RunCtrls *run_ctrls, CTRL_Spoof *spoof); diff --git a/src/demon/demon_core.mdesk b/src/demon/demon_core.mdesk index 1ccc3c14..ea3139f6 100644 --- a/src/demon/demon_core.mdesk +++ b/src/demon/demon_core.mdesk @@ -21,6 +21,7 @@ DMN_EventKindTable: {Memory} {DebugString} {SetThreadName} + {SetThreadColor} } @table(name) diff --git a/src/demon/generated/demon.meta.c b/src/demon/generated/demon.meta.c index 69511785..3aa15e72 100644 --- a/src/demon/generated/demon.meta.c +++ b/src/demon/generated/demon.meta.c @@ -4,7 +4,7 @@ //- GENERATED CODE C_LINKAGE_BEGIN -String8 dmn_event_kind_string_table[17] = +String8 dmn_event_kind_string_table[18] = { str8_lit_comp("Null"), str8_lit_comp("Error"), @@ -23,6 +23,7 @@ str8_lit_comp("Halt"), str8_lit_comp("Memory"), str8_lit_comp("DebugString"), str8_lit_comp("SetThreadName"), +str8_lit_comp("SetThreadColor"), }; String8 dmn_exception_kind_string_table[5] = diff --git a/src/demon/generated/demon.meta.h b/src/demon/generated/demon.meta.h index 3b73d40b..f5fdae4c 100644 --- a/src/demon/generated/demon.meta.h +++ b/src/demon/generated/demon.meta.h @@ -25,6 +25,7 @@ DMN_EventKind_Halt, DMN_EventKind_Memory, DMN_EventKind_DebugString, DMN_EventKind_SetThreadName, +DMN_EventKind_SetThreadColor, DMN_EventKind_COUNT, } DMN_EventKind; @@ -58,7 +59,7 @@ DMN_ExceptionKind_COUNT, } DMN_ExceptionKind; C_LINKAGE_BEGIN -extern String8 dmn_event_kind_string_table[17]; +extern String8 dmn_event_kind_string_table[18]; extern String8 dmn_exception_kind_string_table[5]; C_LINKAGE_END diff --git a/src/demon/win32/demon_core_win32.c b/src/demon/win32/demon_core_win32.c index abe2d88d..60573d5b 100644 --- a/src/demon/win32/demon_core_win32.c +++ b/src/demon/win32/demon_core_win32.c @@ -2378,6 +2378,13 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls) } }break; + //- rjf: fill set-thread-color info + case DMN_W32_EXCEPTION_RADDBG_SET_THREAD_COLOR: + { + e->kind = DMN_EventKind_SetThreadColor; + e->code = exception->ExceptionInformation[1]; + }break; + //- rjf: unhandled exception case default: { diff --git a/src/demon/win32/demon_core_win32.h b/src/demon/win32/demon_core_win32.h index c7234571..24f527f2 100644 --- a/src/demon/win32/demon_core_win32.h +++ b/src/demon/win32/demon_core_win32.h @@ -56,6 +56,7 @@ #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 //////////////////////////////// //~ rjf: Win32 Register Codes diff --git a/src/lib_raddbg_markup/raddbg_markup.h b/src/lib_raddbg_markup/raddbg_markup.h index c59d7ade..89ea688c 100644 --- a/src/lib_raddbg_markup/raddbg_markup.h +++ b/src/lib_raddbg_markup/raddbg_markup.h @@ -7,23 +7,37 @@ //////////////////////////////// //~ Implementation Overrides -#if !defined(raddbg_markup_vsnprintf) -# define raddbg_markup_vsnprintf vsnprintf +#if !defined(RADDBG_MARKUP_VSNPRINTF) +# define RADDBG_MARKUP_DEFAULT_VSNPRINTF 1 +# define RADDBG_MARKUP_VSNPRINTF vsnprintf #endif //////////////////////////////// //~ Usage Macros -#define raddbg_is_attached(...) raddbg_is_attached__impl() -#define raddbg_thread_name(fmt, ...) raddbg_thread_name__impl((fmt), __VA_ARGS__) -#define raddbg_thread_color_hex(hexcode) raddbg_thread_color__impl((hexcode)) -#define raddbg_thread_color_rgba(r, g, b, a) raddbg_thread_color__impl((unsigned int)(((r)*255) << 24) | (unsigned int)(((g)*255) << 16) | (unsigned int)(((b)*255) << 8) | (unsigned int)((a)*255)) -#define raddbg_break(...) raddbg_break__impl() -#define raddbg_break_if(expr, ...) ((expr) ? raddbg_break__impl() : (void)0) -#define raddbg_watch(fmt, ...) raddbg_watch__impl((fmt), __VA_ARGS__) -#define raddbg_pin(expr, ...) /* NOTE(rjf): inspected by debugger ui - does not change program execution */ -#define raddbg_log(fmt, ...) raddbg_log__impl((fmt), __VA_ARGS__) -#define raddbg_auto_view_rule(type, ...) raddbg_exe_data static char raddbg_glue(raddbg_auto_view_rule_data__, __COUNTER__)[] = ("auto_view_rule: {type: \"" #type "\", view_rule: \"" #__VA_ARGS__ "\"}") +#if defined(RADDBG_MARKUP_STUBS) +# define raddbg_is_attached(...) (0) +# define raddbg_thread_name(fmt, ...) ((void)0) +# define raddbg_thread_color_hex(hexcode) ((void)0) +# define raddbg_thread_color_rgba(r, g, b, a) ((void)0) +# define raddbg_break(...) ((void)0) +# define raddbg_break_if(expr, ...) ((void)0) +# define raddbg_watch(fmt, ...) ((void)0) +# define raddbg_pin(expr, ...) +# define raddbg_log(fmt, ...) ((void)0) +# define raddbg_auto_view_rule(type, ...) struct raddbg_glue(raddbg_auto_view_rule_stub__, __COUNTER__){int __unused__} +#else +# define raddbg_is_attached(...) raddbg_is_attached__impl() +# define raddbg_thread_name(fmt, ...) raddbg_thread_name__impl((fmt), __VA_ARGS__) +# define raddbg_thread_color_hex(hexcode) raddbg_thread_color__impl((hexcode)) +# define raddbg_thread_color_rgba(r, g, b, a) raddbg_thread_color__impl((unsigned int)(((r)*255) << 24) | (unsigned int)(((g)*255) << 16) | (unsigned int)(((b)*255) << 8) | (unsigned int)((a)*255)) +# define raddbg_break(...) raddbg_break__impl() +# define raddbg_break_if(expr, ...) ((expr) ? raddbg_break__impl() : (void)0) +# define raddbg_watch(fmt, ...) raddbg_watch__impl((fmt), __VA_ARGS__) +# define raddbg_pin(expr, ...) /* NOTE(rjf): inspected by debugger ui - does not change program execution */ +# define raddbg_log(fmt, ...) raddbg_log__impl((fmt), __VA_ARGS__) +# define raddbg_auto_view_rule(type, ...) raddbg_exe_data static char raddbg_glue(raddbg_auto_view_rule_data__, __COUNTER__)[] = ("auto_view_rule: {type: \"" #type "\", view_rule: \"" #__VA_ARGS__ "\"}") +#endif //////////////////////////////// //~ Helpers @@ -34,13 +48,21 @@ //////////////////////////////// //~ Win32 Implementations -#if defined(RADDBG_MARKUP_IMPLEMENTATION) +#if defined(RADDBG_MARKUP_IMPLEMENTATION) && !defined(RADDBG_MARKUP_STUBS) #if defined(_WIN32) +//- default includes +#if RADDBG_MARKUP_DEFAULT_VSNPRINTF +#include +#endif + //- section allocating -#pragma section(".raddbg", read) +#pragma section(".raddbg", read, write) #define raddbg_exe_data __declspec(allocate(".raddbg")) +//- first byte of exe data section -> is attached +raddbg_exe_data unsigned char raddbg_is_attached_byte_marker = 0; + //- types typedef int BOOL; @@ -72,11 +94,12 @@ extern "C" __declspec(dllimport) HANDLE GetCurrentThread(void); __declspec(dllimport) DWORD GetCurrentThreadId(void); __declspec(dllimport) void RaiseException(DWORD dwExceptionCode, DWORD dwExceptionFlags, DWORD nNumberOfArguments, const ULONG_PTR *lpArguments); + __declspec(dllimport) void OutputDebugStringA(LPCSTR buffer); long long _InterlockedCompareExchange64(long long volatile*, long long, long long); long long _InterlockedExchangeAdd64(long long volatile*, long long); #pragma intrinsic(_InterlockedCompareExchange64) #pragma intrinsic(_InterlockedExchangeAdd64) - int raddbg_markup_vsnprintf(char * const, unsigned long long const, const char * const, va_list); + int RADDBG_MARKUP_VSNPRINTF(char * const, unsigned long long const, const char * const, va_list); #if defined(__cplusplus) } #endif @@ -173,8 +196,7 @@ raddbg_encode_utf16(wchar_t *str, unsigned __int32 codepoint) static inline int raddbg_is_attached__impl(void) { - // TODO(rjf) - return 0; + return !!raddbg_is_attached_byte_marker; } static inline void @@ -186,7 +208,7 @@ raddbg_thread_name__impl(char *fmt, ...) { va_list args; va_start(args, fmt); - raddbg_markup_vsnprintf(buffer, sizeof(buffer), fmt, args); + RADDBG_MARKUP_VSNPRINTF(buffer, sizeof(buffer), fmt, args); va_end(args); } @@ -260,7 +282,32 @@ raddbg_thread_name__impl(char *fmt, ...) static inline void raddbg_thread_color__impl(unsigned int hexcode) { - // TODO(rjf) + if(raddbg_is_attached()) + { +#pragma pack(push, 8) + typedef struct RADDBG_ThreadColorInfo RADDBG_ThreadColorInfo; + struct RADDBG_ThreadColorInfo + { + DWORD dwThreadID; + DWORD _pad0_; + DWORD rgba; + DWORD _pad1_; + }; +#pragma pack(pop) + RADDBG_ThreadColorInfo info; + info.dwThreadID = GetCurrentThreadId(); + info.rgba = hexcode; +#pragma warning(push) +#pragma warning(disable: 6320 6322) + __try + { + RaiseException(0x00524144u, 0, sizeof(info) / sizeof(void *), (const ULONG_PTR *)&info); + } + __except(1) + { + } +#pragma warning(pop) + } } #define raddbg_break__impl() (__debugbreak()) @@ -274,7 +321,17 @@ raddbg_watch__impl(char *fmt, ...) static inline void raddbg_log__impl(char *fmt, ...) { - // TODO(rjf) + // rjf: resolve variadic arguments + char buffer[4096]; + { + va_list args; + va_start(args, fmt); + RADDBG_MARKUP_VSNPRINTF(buffer, sizeof(buffer), fmt, args); + va_end(args); + } + + // rjf: output debug string + OutputDebugStringA(buffer); } #endif // defined(_WIN32) diff --git a/src/mule/mule_main.cpp b/src/mule/mule_main.cpp index 23b47f5e..cef09d86 100644 --- a/src/mule/mule_main.cpp +++ b/src/mule/mule_main.cpp @@ -2670,7 +2670,15 @@ dynamic_step_test(void){ //////////////////////////////// int -mule_main(int argc, char** argv){ +mule_main(int argc, char** argv) +{ + raddbg_thread_name("mule_main_thread"); + raddbg_thread_color_rgba(1, 0, 0, 1); + if(raddbg_is_attached()) + { + raddbg_log("raddbg is attached!\n"); + } + mule_init(); // NOTE(allen): Eval Tests @@ -2735,5 +2743,3 @@ mule_main(int argc, char** argv){ return(0); } - - diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 66e29a76..540d3574 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -3114,6 +3114,8 @@ rd_eval_space_write(void *u, E_Space space, void *in, Rng1U64 range) MD_Node *child_schema = md_child_from_string(root_schema, child_key, 0); if(str8_match(child_schema->string, str8_lit("label"), 0)) { + result = 1; + ctrl_entity_equip_string(d_state->ctrl_entity_store, entity, write_string); rd_cmd(D_CmdKind_SetEntityName, .ctrl_entity = entity->handle, .string = write_string); } else if(str8_match(child_schema->string, str8_lit("dbg"), 0))