temporarily turn off symbol server stuff - switch off spoof for step-over

This commit is contained in:
Ryan Fleury
2026-06-09 09:27:23 -07:00
parent 132751777f
commit 9955c8c1a7
16 changed files with 159 additions and 76 deletions
+2 -2
View File
@@ -5,7 +5,7 @@ target:
{
executable: "build/raddbg.exe"
working_directory: "../raddebugger"
arguments: "--user:C:/devel/raddebugger/build/raddbg_test.user --project:C:/devel/raddebugger/build/raddbg_test.project"
arguments: "--user:C:/devel/raddebugger/build/raddbg_test.user --project:C:/devel/raddebugger/build/raddbg_test.project --capture"
debug_subprocesses: 0
enabled: 1
}
@@ -57,5 +57,5 @@ target:
{
executable: "build/raddbg.exe"
working_directory: build
arguments: "--bin --rdi --thread_count=1 C:/SymbolCache/kernelbase.pdb/53B51385668728BA4297C9C78EEC92DD1/kernelbase.pdb"
arguments: "--bin --rdi --thread_count=1 C:/SymbolCache/kernel32.pdb/E02F64ED8DA50EC6E7691C0AC0BC25781/kernel32.pdb"
}
+6 -6
View File
@@ -1044,12 +1044,12 @@ CV_ThunkOrdinalEnum;
typedef struct CV_SymThunk32 CV_SymThunk32;
struct CV_SymThunk32
{
U32 parent;
U32 end;
U32 next;
U32 off;
U16 sec;
U16 len;
U32 parent;
U32 end;
U32 next;
U32 off;
U16 sec;
U16 len;
CV_ThunkOrdinal ord;
// U8[] name (null terminated)
// U8[] variant (null terminated)
+4 -3
View File
@@ -270,9 +270,10 @@ enum
{
D_TrapFlag_IgnoreStackPointerCheck = (1<<0),
D_TrapFlag_SingleStepAfterHit = (1<<1),
D_TrapFlag_SaveStackPointer = (1<<2),
D_TrapFlag_BeginSpoofMode = (1<<3),
D_TrapFlag_EndStepping = (1<<4),
D_TrapFlag_SaveStackPointerBefore = (1<<2),
D_TrapFlag_SaveStackPointerAfter = (1<<3),
D_TrapFlag_BeginSpoofMode = (1<<4),
D_TrapFlag_EndStepping = (1<<5),
};
typedef struct D_Trap D_Trap;
+57 -48
View File
@@ -2666,10 +2666,12 @@ d_ctrl_thread__module_open(D_Handle process, D_Handle module, U64 base_vaddr, DM
//////////////////////////////
//- rjf: no found debug info path -> try to fall back on symbol server cache path
//
#if 0
if(initial_debug_info_path.size == 0)
{
initial_debug_info_path = smsv_local_path_from_key(arena, str8_skip_last_slash(module_info->debug_info_path), module_info->debug_info_guid, module_info->debug_info_age);
}
#endif
//////////////////////////////
//- rjf: write 1 at attachment marker, to signify attachment
@@ -3086,25 +3088,25 @@ d_ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_ctx, D_Msg *msg, D
{
d_process_write(spoof->process, r1u64(spoof->vaddr, spoof->vaddr+size_of_spoof), &spoof_old_ip_value);
}
}
}
//- rjf: irrespective of what event came back, we should ALWAYS check the
// spoof's thread and see if it hit the spoof address, because we may have
// simply been sent other debug events first
if(spoof != 0)
{
D_Entity *thread = d_entity_from_handle(spoof->thread);
Arch arch = thread->arch;
ARCH_Info *arch_info = arch_info_from_arch(arch);
U64 arch_reg_block_size = arch_info->reg_block_size;
void *regs_block = push_array(scratch.arena, U8, arch_reg_block_size);
d_thread_read_reg_block(spoof->thread, regs_block);
U64 spoof_thread_rip = arch_ip_from_reg_block(arch_info, regs_block);
if(spoof_thread_rip == spoof->new_ip_value)
{
arch_reg_block_write_ip(arch_info, regs_block, spoof_old_ip_value);
d_thread_write_reg_block(spoof->thread, regs_block);
// rjf: irrespective of what event came back, we should ALWAYS check the
// spoof's thread and see if it hit the spoof address, because we may have
// simply been sent other debug events first
if(spoof != 0)
{
D_Entity *thread = d_entity_from_handle(spoof->thread);
Arch arch = thread->arch;
ARCH_Info *arch_info = arch_info_from_arch(arch);
U64 arch_reg_block_size = arch_info->reg_block_size;
void *regs_block = push_array(scratch.arena, U8, arch_reg_block_size);
d_thread_read_reg_block(spoof->thread, regs_block);
U64 spoof_thread_rip = arch_ip_from_reg_block(arch_info, regs_block);
if(spoof_thread_rip == spoof->new_ip_value)
{
arch_reg_block_write_ip(arch_info, regs_block, spoof_old_ip_value);
d_thread_write_reg_block(spoof->thread, regs_block);
}
}
}
}
@@ -5154,22 +5156,38 @@ d_ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, D_Msg *msg)
}
}
//- rjf: trap net on on-target threads trigger trap net logic
B32 use_trap_net_logic = 0;
if(!hard_stop && use_stepping_logic && hit_trap_net_bp)
//- rjf: trap net logic: stack pointer check on target thread
B32 stack_pointer_check_passes = 0;
if(!hard_stop && use_stepping_logic && hit_trap_net_bp && dmn_handle_match(event->thread, d_dmn_from_handle(target_thread)))
{
if(dmn_handle_match(event->thread, d_dmn_from_handle(target_thread)))
U64 sp = d_sp_from_thread(target_thread);
stack_pointer_check_passes = ((hit_trap_flags & D_TrapFlag_IgnoreStackPointerCheck) || (sp == sp_check_value));
}
//- rjf: trap net on on-target threads trigger trap net logic, *if* the stack pointer check passes.
// if it doesn't -> step over trap net & continue
B32 use_trap_net_logic = 0;
if(!hard_stop && use_stepping_logic && hit_trap_net_bp && dmn_handle_match(event->thread, d_dmn_from_handle(target_thread)))
{
if(stack_pointer_check_passes)
{
use_trap_net_logic = 1;
}
else
{
step_past_trap_net = 1;
use_stepping_logic = 0;
}
}
//- rjf: trap net logic: stack pointer check
B32 stack_pointer_matches = 0;
if(use_trap_net_logic)
//- rjf: trap net logic: save stack pointer *before* step-over
if(!hard_stop && use_trap_net_logic)
{
U64 sp = d_sp_from_thread(target_thread);
stack_pointer_matches = (sp == sp_check_value);
if(hit_trap_flags & D_TrapFlag_SaveStackPointerBefore)
{
sp_check_value = d_sp_from_thread(target_thread);
log_infof("sp_check_value = 0x%I64x\n", sp_check_value);
}
}
//- rjf: trap net logic: single step after hit
@@ -5217,6 +5235,16 @@ d_ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, D_Msg *msg)
}
}
//- rjf: trap net logic: save stack pointer *after* step-over
if(!hard_stop && use_trap_net_logic)
{
if(hit_trap_flags & D_TrapFlag_SaveStackPointerAfter)
{
sp_check_value = d_sp_from_thread(target_thread);
log_infof("sp_check_value = 0x%I64x\n", sp_check_value);
}
}
//- rjf: trap net logic: begin spoof mode
B32 begin_spoof_mode = 0;
if(!hard_stop && use_trap_net_logic)
@@ -5234,33 +5262,14 @@ d_ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, D_Msg *msg)
}
}
//- rjf: trap net logic: save stack pointer
B32 save_stack_pointer = 0;
if(!hard_stop && use_trap_net_logic)
{
if(hit_trap_flags & D_TrapFlag_SaveStackPointer)
{
if(stack_pointer_matches) LogInfoNamedBlockF("trap_net__save_sp")
{
save_stack_pointer = 1;
sp_check_value = d_sp_from_thread(target_thread);
log_infof("sp_check_value = 0x%I64x\n", sp_check_value);
}
}
}
//- rjf: trap net logic: end stepping
B32 trap_net_stop = 0;
if(!hard_stop && use_trap_net_logic)
{
if(hit_trap_flags & D_TrapFlag_EndStepping) LogInfoNamedBlockF("trap_net__end_step")
{
if((hit_trap_flags & D_TrapFlag_IgnoreStackPointerCheck) ||
stack_pointer_matches)
{
trap_net_stop = 1;
use_trap_net_logic = 0;
}
trap_net_stop = 1;
use_trap_net_logic = 0;
}
}
+11 -3
View File
@@ -516,16 +516,24 @@ d_trap_net_from_thread__step_over_line(Arena *arena, D_Entity *thread)
}
// rjf: call => save stack pointer before, single-step to go into call; trap on return
else if(point->inst_flags & DASM_InstFlag_Call)
{
flags |= (D_TrapFlag_SaveStackPointerBefore|D_TrapFlag_SingleStepAfterHit);
}
#if 0 // TODO(rjf): @spoof_stepping
// rjf: call => place spoof at return spot in stack, single-step after hitting
else if(point->inst_flags & DASM_InstFlag_Call)
{
flags |= (D_TrapFlag_BeginSpoofMode|D_TrapFlag_SingleStepAfterHit);
}
#endif
// rjf: instruction changes stack pointer => save off the stack pointer, single-step over, keep stepping
// rjf: instruction changes stack pointer => single-step over, save off the stack pointer, keep stepping
else if(point->inst_flags & DASM_InstFlag_ChangesStackPointer)
{
flags |= (D_TrapFlag_SingleStepAfterHit|D_TrapFlag_SaveStackPointer);
flags |= (D_TrapFlag_SingleStepAfterHit|D_TrapFlag_SaveStackPointerAfter);
}
// rjf: add if appropriate
@@ -734,7 +742,7 @@ d_trap_net_from_thread__step_into_line(Arena *arena, D_Entity *thread)
// rjf: instruction changes stack pointer => save off the stack pointer, single-step over, keep stepping
else if(point->inst_flags & DASM_InstFlag_ChangesStackPointer)
{
flags |= (D_TrapFlag_SingleStepAfterHit|D_TrapFlag_SaveStackPointer);
flags |= (D_TrapFlag_SingleStepAfterHit|D_TrapFlag_SaveStackPointerAfter);
}
// rjf: add if appropriate
+1
View File
@@ -682,6 +682,7 @@ di_async_tick(void)
//- rjf: kick off symbol server download, or check to see if we are actively downloading O.G.
B32 og_is_downloading = 0;
if(og_path.size != 0)
{
B32 file_is_present = (properties_from_file_path(og_path).modified != 0);
if(!file_is_present)
+2
View File
@@ -146,6 +146,8 @@ typedef struct HTTP_Response HTTP_Response;
struct HTTP_Response
{
U64 id;
U64 off;
U64 off_opl;
B32 has_more;
HTTP_StatusCode code;
String8 body;
+1
View File
@@ -396,6 +396,7 @@ typedef RDI_U8 RDI_SymbolFlags;
typedef enum RDI_SymbolFlagsEnum
{
RDI_SymbolFlag_IsParam = 0x1,
RDI_SymbolFlag_IsThunk = 0x2,
} RDI_SymbolFlagsEnum;
typedef RDI_U8 RDI_LocationKind;
+1
View File
@@ -849,6 +849,7 @@ typedef struct RDIM_Symbol RDIM_Symbol;
struct RDIM_Symbol
{
struct RDIM_SymbolChunkNode *chunk;
RDI_S32 is_thunk;
RDI_S32 is_extern;
RDI_S32 is_param;
RDIM_String8 name;
+4 -8
View File
@@ -6634,18 +6634,14 @@ rd_window_frame(void)
UI_PermissionFlag_All)
{
B32 has_footer = (is_lister && !is_anchored);
F32 container_corner_top_radius_px = is_lister ? ui_top_font_size()*1.f : ui_top_font_size()*0.15f;
F32 container_corner_bottom_radius_px = has_footer ? ui_top_font_size()*1.f : ui_top_font_size()*0.15f;
F32 container_corner_radius_px = has_footer ? ui_top_font_size()*1.f : ui_top_font_size()*0.15f;
// rjf: build top-level container box
UI_Box *container = &ui_nil_box;
UI_Rect(rect) UI_ChildLayoutAxis(Axis2_Y)
UI_Squish(0.1f-0.1f*open_t)
UI_Transparency(1.f-open_t)
UI_CornerRadius00(container_corner_top_radius_px)
UI_CornerRadius10(container_corner_top_radius_px)
UI_CornerRadius01(container_corner_bottom_radius_px)
UI_CornerRadius11(container_corner_bottom_radius_px)
UI_CornerRadius(container_corner_radius_px)
{
container = ui_build_box_from_stringf(UI_BoxFlag_Clickable|
UI_BoxFlag_DrawBorder|
@@ -11108,7 +11104,7 @@ rd_frame(void)
for(HTTP_Response response = {0}; http_pop_response(rd_state->update_check_arena, rd_state->update_check_http_ring, &response, 0);)
{
str8_list_push(rd_state->update_check_arena, &rd_state->update_check_response_body_pieces, response.body);
if(response.has_more == 0)
if(!response.has_more)
{
done = 1;
}
@@ -12318,7 +12314,7 @@ rd_frame(void)
});
E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, r1u64(0, 0));
expr->type_key = collection_type_key;
expr->space = e_space_make(RD_EvalSpaceKind_MetaCtrlEntity);
expr->space = e_space_make(RD_EvalSpaceKind_MetaQuery);
e_string2expr_map_insert(scratch.arena, macro_map, collection_name, expr);
e_string2typekey_map_insert(rd_frame_arena(), rd_state->meta_name2type_map, collection_name, collection_type_key);
}
+1
View File
@@ -1020,6 +1020,7 @@ RDI_LocationKindTable:
RDI_SymbolFlagTable:
{
{IsParam 0x1}
{IsThunk 0x2}
}
@table(name type desc)
+30
View File
@@ -3194,6 +3194,7 @@ p2r_convert(Arena *arena, P2R_ConvertParams *params)
default:{}break;
case CV_SymKind_LPROC32:
case CV_SymKind_GPROC32:
case CV_SymKind_THUNK32:
{
procedure_record_count += 1;
scope_record_count += 1;
@@ -3600,6 +3601,35 @@ p2r_convert(Arena *arena, P2R_ConvertParams *params)
proc_flags = proc32->flags;
}break;
//- rjf: THUNK32
case CV_SymKind_THUNK32:
{
// rjf: unpack record
CV_SymThunk32 *thunk32 = (CV_SymThunk32 *)iter.struct_base;
String8 name = str8_cstring_capped(thunk32+1, iter.opl);
COFF_SectionHeader *section = (0 < thunk32->sec && thunk32->sec <= coff_sections.count) ? &coff_sections.v[thunk32->sec-1] : 0;
U64 voff_first = 0;
U64 voff_opl = 0;
if(section != 0)
{
voff_first = section->voff + thunk32->off;
voff_opl = voff_first + thunk32->len;
}
// rjf: build symbol / scope
RDIM_Symbol *symbol = rdim_symbol_chunk_list_push(arena, sym_procedures, sym_procedures_chunk_cap);
symbol->name = name;
symbol->is_thunk = 1;
if(voff_first != voff_opl)
{
RDIM_Scope *scope = rdim_scope_chunk_list_push(arena, sym_scopes, sym_scopes_chunk_cap);
RDIM_Rng1U64 range = {voff_first, voff_opl};
rdim_scope_push_voff_range(arena, sym_scopes, scope, range);
scope->symbol = symbol;
symbol->root_scope = scope;
}
}break;
//- rjf: REGREL32
case CV_SymKind_REGREL32:
{
+5 -1
View File
@@ -3353,10 +3353,14 @@ rdim_bake(Arena *arena, RDIM_BakeParams *params)
dst->type_idx = (RDI_U32)rdim_idx_from_type(src->type); // TODO(rjf): @u64_to_u32
dst->root_scope_idx = (RDI_U32)rdim_idx_from_scope(src->root_scope); // TODO(rjf): @u64_to_u32
dst->link_name_string_idx = rdim_bake_idx_from_string(bake_strings, src->link_name);
if (src->is_param)
if(src->is_param)
{
dst->symbol_flags |= RDI_SymbolFlag_IsParam;
}
if(src->is_thunk)
{
dst->symbol_flags |= RDI_SymbolFlag_IsThunk;
}
// rjf: fill container info
if(src->is_extern)
+24 -2
View File
@@ -350,6 +350,18 @@ http_async_tick(void)
req->status_code = status_code;
}
// rjf: figure out total bytes
if(req->total_response_bytes == 0)
{
DWORD buffer_size = sizeof(req->total_response_bytes);
WinHttpQueryHeaders(req->hRequest,
WINHTTP_QUERY_CONTENT_LENGTH|WINHTTP_QUERY_FLAG_NUMBER64,
WINHTTP_HEADER_NAME_BY_INDEX,
&req->total_response_bytes,
&buffer_size,
WINHTTP_NO_HEADER_INDEX);
}
// rjf: join all currently read body contents
String8 body = str8_list_join(scratch.arena, &req->finished_body_pieces, 0);
@@ -359,7 +371,7 @@ http_async_tick(void)
// rjf: compute size per record header
U64 max_record_size = req->out_ring->ring->size;
U64 bytes_per_record_header = sizeof(U64) + sizeof(U64) + sizeof(B32) + sizeof(HTTP_StatusCode);
U64 bytes_per_record_header = sizeof(U64) + sizeof(U64) + sizeof(U64) + sizeof(U64) + sizeof(B32) + sizeof(HTTP_StatusCode);
// rjf: push response records
for(U64 off = 0, next_off = 0; off <= body.size; off = next_off)
@@ -383,6 +395,8 @@ http_async_tick(void)
B32 has_more = !is_last;
str8_list_push(scratch.arena, &pieces, str8_struct(&record_size));
str8_list_push(scratch.arena, &pieces, str8_struct(&req->id));
str8_list_push(scratch.arena, &pieces, str8_struct(&req->total_response_bytes_sent));
str8_list_push(scratch.arena, &pieces, str8_struct(&req->total_response_bytes));
str8_list_push(scratch.arena, &pieces, str8_struct(&has_more));
str8_list_push(scratch.arena, &pieces, str8_struct(&req->status_code));
str8_list_push(scratch.arena, &pieces, str8_substr(body, r1u64(off, next_off)));
@@ -396,12 +410,18 @@ http_async_tick(void)
if(!guarded_ring_write_string_or_wait(&g, record_data, 0))
{
push_failed = 1;
String8 unpushed_body_piece = str8_substr(body, r1u64(off, next_off));
String8 unpushed_body_piece = str8_substr(body, r1u64(off, body.size));
str8_list_push(req->arena, &req->finished_body_pieces, str8_copy(req->arena, unpushed_body_piece));
}
guarded_ring_close(&g);
}
// rjf: advance total bytes sent
if(!push_failed)
{
req->total_response_bytes_sent += (next_off - off);
}
// rjf: cancel on no movement
if(next_off == off || push_failed)
{
@@ -528,6 +548,8 @@ http_pop_response(Arena *arena, GuardedRing *out_ring, HTTP_Response *response_o
guarded_ring_read_or_wait(&g, data.size, data.str, max_U64);
U64 off = 0;
off += str8_deserial_read_struct(data, off, &response_out->id);
off += str8_deserial_read_struct(data, off, &response_out->off);
off += str8_deserial_read_struct(data, off, &response_out->off_opl);
off += str8_deserial_read_struct(data, off, &response_out->has_more);
off += str8_deserial_read_struct(data, off, &response_out->code);
response_out->body.size = (data.size - off);
+2
View File
@@ -35,6 +35,8 @@ struct W32_HTTP_Request
void *optional; // NOTE(rjf): must persist with in-flight requests
U64 optional_size;
HTTP_StatusCode status_code;
U64 total_response_bytes_sent;
U64 total_response_bytes;
U64 arena_start_body_read_pos;
String8List finished_body_pieces;
void *next_body_piece;
@@ -201,7 +201,7 @@ smsv_async_tick(void)
{
str8_list_push(task->arena, &task->file_pieces, str8_copy(task->arena, r.body));
}
if(r.has_more == 0 && task->status != W32_SMSV_TaskStatus_DoneDownloading)
if(!r.has_more && task->status != W32_SMSV_TaskStatus_DoneDownloading)
{
task->status = W32_SMSV_TaskStatus_DoneDownloading;
W32_SMSV_TaskNode *n = push_array(scratch.arena, W32_SMSV_TaskNode, 1);
@@ -329,6 +329,11 @@ smsv_async_tick(void)
}
}
write_data_list_to_file_path(task->local_path, task->file_pieces);
if(task->current_server_url_node != 0)
{
String8 origin_path = str8f(scratch.arena, "%S/origin.txt", str8_chop_last_slash(task->local_path));
write_data_to_file_path(origin_path, task->current_server_url_node->string);
}
}
// rjf: evict task from cache