Add Ghidra MCP server update workflow instructions and various binary files; enhance segment coverage ledger and mid-project plan with detailed analysis notes
This commit is contained in:
parent
519af09912
commit
8847708d41
10 changed files with 248 additions and 18 deletions
36
.github/instructions/ghidra-mcp-server-updates.instructions.md
vendored
Normal file
36
.github/instructions/ghidra-mcp-server-updates.instructions.md
vendored
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
---
|
||||||
|
description: 'Workflow rules for updating and validating the local Ghidra MCP server used by Crusader reverse-engineering tasks'
|
||||||
|
applyTo: '**'
|
||||||
|
---
|
||||||
|
|
||||||
|
# Ghidra MCP Server Update Workflow
|
||||||
|
|
||||||
|
Use these instructions when making changes in the local Ghidra MCP source at K:/mcp/GhidraMCP from this workspace.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
- Treat K:/mcp/GhidraMCP as the source of truth for server and bridge behavior.
|
||||||
|
- Keep Crusader task notes and MCP implementation aligned.
|
||||||
|
- Prefer small, verifiable batches of MCP changes.
|
||||||
|
|
||||||
|
## Update Rules
|
||||||
|
|
||||||
|
- Read ghidra_mcp_wishlist.md before changing the server.
|
||||||
|
- Implement wishlist items in both layers when applicable:
|
||||||
|
- Java plugin endpoint in src/main/java/com/lauriewired/GhidraMCPPlugin.java.
|
||||||
|
- Python MCP bridge wrapper in bridge_mcp_ghidra.py.
|
||||||
|
- Keep backward compatibility for endpoint naming when practical by adding aliases instead of removing old routes.
|
||||||
|
- Keep xref and analysis outputs machine-friendly and evidence-rich (addresses, ref type, classification, function context).
|
||||||
|
|
||||||
|
## Verification Rules
|
||||||
|
|
||||||
|
- After server edits, run a Maven validation from K:/mcp/GhidraMCP.
|
||||||
|
- Minimum validation command: mvn test.
|
||||||
|
- If packaging changes are involved, also run mvn clean package assembly:single.
|
||||||
|
- Report failures with the exact failing phase and first actionable error.
|
||||||
|
|
||||||
|
## Crusader Workflow Tie-In
|
||||||
|
|
||||||
|
- If a missing MCP operation forced a fallback to PyGhidra, append a concise entry to ghidra_mcp_wishlist.md.
|
||||||
|
- When a wishlist item is completed, update its status note so open gaps remain accurate.
|
||||||
|
- Keep changes minimal and focused on concrete reverse-engineering workflow needs.
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
16
Crusader_Decomp.code-workspace
Normal file
16
Crusader_Decomp.code-workspace
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
{
|
||||||
|
"folders": [
|
||||||
|
{
|
||||||
|
"path": "."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "../../mcp/GhidraMCP"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"settings": {
|
||||||
|
"chat.tools.terminal.autoApprove": {
|
||||||
|
"Set-Content": true
|
||||||
|
},
|
||||||
|
"python-envs.defaultEnvManager": "ms-python.python:pyenv"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -100,6 +100,108 @@ Known call-site classifications (by argument pattern):
|
||||||
- `rng_next_modulo` advances the RNG state and returns the result modulo the requested bound, or `0` when the bound is zero.
|
- `rng_next_modulo` advances the RNG state and returns the result modulo the requested bound, or `0` when the bound is zero.
|
||||||
- Short decompiler comments were added in Ghidra at all five seg091 entries so the current evidence stays attached to the raw database.
|
- Short decompiler comments were added in Ghidra at all five seg091 entries so the current evidence stays attached to the raw database.
|
||||||
|
|
||||||
|
### Raw 0x4588 Runtime Callback Lifecycle Batch (direct MCP analysis)
|
||||||
|
|
||||||
|
- New conservative runtime-callback lifecycle renames (direct analysis):
|
||||||
|
- `000a:4913` = `runtime_callback_object_init_once`
|
||||||
|
- `000a:4a56` = `runtime_callback_object_teardown_once`
|
||||||
|
- `0009:b1c3` = `runtime_callback_object_phase_finalize`
|
||||||
|
- Boundary repair applied with MCP edit-plan API:
|
||||||
|
- Rebuilt `000a:b988` as `sprite_node_get_or_traverse` with full body `000a:b988-000a:bab5`.
|
||||||
|
- This repair absorbs both callback-state sync callsites at `000a:b9e5` and `000a:ba66` that were previously in a no-function gap.
|
||||||
|
- Verified callback-object behavior from this pass:
|
||||||
|
- `runtime_callback_object_init_once` sets one-time guard `0x4594`, snapshots state words (`0x458c`/`0x4590`) via `video_bios_state_snapshot`, installs the object FAR pointer at `0x4588`, and ensures fallback buffer allocation at `0x45a6`.
|
||||||
|
- `runtime_callback_object_teardown_once` sets one-time guard `0x4595`, clears `0x4588`, conditionally emits vtable `+0x0c` callback when current/previous state differ, then calls vtable `+0x04` release path.
|
||||||
|
- `runtime_callback_object_phase_finalize` invokes vtable `+0x08` twice and sweeps table entries via `allocator_head_finalize_sweep`.
|
||||||
|
- Large caller `FUN_000d_9afd` contains both additional vtable `+0x0c` callsites (`000d:9d5e` and `000d:a3b7`) and remains the best next target for concrete subsystem naming.
|
||||||
|
- Short decompiler comments were added at the three renamed lifecycle functions to preserve current evidence.
|
||||||
|
|
||||||
|
### Raw 0x4588 Follow-up Batch (allocator/video helper clarification)
|
||||||
|
|
||||||
|
- New conservative helper renames from direct disassembly/decompile evidence:
|
||||||
|
- `0009:a961` = `allocator_head_finalize_sweep`
|
||||||
|
- `000a:4a1f` = `video_bios_state_snapshot`
|
||||||
|
- Verified behavior anchors:
|
||||||
|
- `allocator_head_finalize_sweep` performs per-head chain compaction/finalize work over allocator table entries used by `runtime_callback_object_phase_finalize`.
|
||||||
|
- `video_bios_state_snapshot` executes BIOS video interrupts (`INT 10h` with `AX=4F03` and `AX=1130,BH=3`) and returns packed state in `DX:AX`; callers store/compare this pair around callback emissions.
|
||||||
|
- Decompiler comments were updated so downstream analysis sees the new helper names directly.
|
||||||
|
|
||||||
|
### Raw 0x4588 Follow-up Batch 2 (cleanup + mode-state wrapper)
|
||||||
|
|
||||||
|
- New conservative structural renames (direct decompile/disassembly evidence):
|
||||||
|
- `000a:4972` = `video_mode_set_and_record_state`
|
||||||
|
- `000d:9afd` = `entity_cleanup_resources_and_dispatch`
|
||||||
|
- Verified behavior anchors:
|
||||||
|
- `video_mode_set_and_record_state` stores requested mode/state to `0x4590`, handles VBE-style mode values (`0x101`/`0x103`/`0x105`) via helper checks, and falls back to `INT 10h` mode path for other values.
|
||||||
|
- `entity_cleanup_resources_and_dispatch` is a large teardown/finalize path for an entity-like object: it clears flags, frees multiple owned buffers/palette handles, performs conditional callback dispatch through `0x4588` vtable `+0x0c`, then destroys object word-list structures.
|
||||||
|
- Decompiler comments were added at both renamed addresses to preserve this provenance.
|
||||||
|
|
||||||
|
### Raw 0x4588 Follow-up Batch 3 (cleanup-callee helper classification)
|
||||||
|
|
||||||
|
- New conservative helper renames from direct MCP decompile evidence:
|
||||||
|
- `0009:7853` = `palette_buffer_alloc_and_init_256`
|
||||||
|
- `0009:1c3a` = `file_handle_alloc_init_and_open`
|
||||||
|
- `0009:1d6a` = `file_handle_open_with_mode`
|
||||||
|
- `0009:8d7b` = `surface_release_internal`
|
||||||
|
- `0009:8e0a` = `surface_release_and_maybe_free`
|
||||||
|
- `000d:9231` = `sprite_redraw_global_if_active`
|
||||||
|
- Verified behavior anchors:
|
||||||
|
- `palette_buffer_alloc_and_init_256` ensures a caller-provided far buffer exists, allocates/initializes a `0x100`-entry palette/work block, and fills it from static table data.
|
||||||
|
- `file_handle_alloc_init_and_open` allocates a handle structure on demand, seeds sentinels, then delegates to `file_handle_open_with_mode`.
|
||||||
|
- `file_handle_open_with_mode` performs path/open initialization with optional pre-delete behavior and stores DOS open result metadata into the handle structure.
|
||||||
|
- `surface_release_and_maybe_free` wraps `surface_release_internal` and conditionally frees memory when `(flags & 1) != 0`.
|
||||||
|
- `sprite_redraw_global_if_active` redraws the global sprite/object pointer at `0x4f38` only when the global gate byte `0x68e5` is enabled.
|
||||||
|
- `entity_cleanup_resources_and_dispatch` now has direct named callees for file/surface/palette cleanup paths, reducing the remaining ambiguity to callback-object role naming and the `000d:7e00` event-dispatch constructor path.
|
||||||
|
- Short decompiler comments were added at all six renamed helpers to preserve evidence provenance in-database.
|
||||||
|
|
||||||
|
### Raw 0x4588 Follow-up Batch 4 (function-object recovery around `000d:7e00`)
|
||||||
|
|
||||||
|
- Missing function objects recovered from direct disassembly boundaries:
|
||||||
|
- `000d:7e00-000d:8077` created and renamed to `entity_dispatch_entry_init_runtime_state`
|
||||||
|
- `000d:8078-000d:819f` renamed to `entity_dispatch_entry_release_runtime_state`
|
||||||
|
- `0003:a880-0003:a896` created as `FUN_0003_a880` (arithmetic helper; decompiler currently simplifies it)
|
||||||
|
- `0003:b8e2-0003:bb39` created and renamed to `far_buffer_alloc_with_mode_flags`
|
||||||
|
- Verified behavior anchors:
|
||||||
|
- `entity_dispatch_entry_init_runtime_state` is a constructor-side helper that initializes runtime fields (`+0x41/+0x42/+0x44`), clears and allocates paired work/palette buffers (`+0x46/+0x48` and `+0x4a/+0x4c`), applies event/setup calls through seg061 helpers, then finalizes activation.
|
||||||
|
- `entity_dispatch_entry_release_runtime_state` is the destructor-side pair: it frees the same paired buffers, propagates active-state changes via global `0x6828`, and destroys embedded word-list members.
|
||||||
|
- `far_buffer_alloc_with_mode_flags` is a low-level far-buffer utility that allocates/reuses a destination pointer and dispatches mode-dependent copy/fill behavior via an internal flag table.
|
||||||
|
- This resolves the previous `000d:7e00` "missing function object" blocker and improves readability for `entity_cleanup_resources_and_dispatch` callback/setup paths.
|
||||||
|
|
||||||
|
### Raw 0x4588 Follow-up Batch 5 (seg061/064/076 helper stabilization)
|
||||||
|
|
||||||
|
- New conservative helper renames:
|
||||||
|
- `0009:6ec7` = `vga_palette_read`
|
||||||
|
- `0008:d3ba` = `timer_entity_enable_wrapper`
|
||||||
|
- Additional evidence-preserving decompiler comments were added (without speculative renames) on:
|
||||||
|
- `0008:eb43`
|
||||||
|
- `0008:ebe7`
|
||||||
|
- `0008:eac8`
|
||||||
|
- `0008:ec23`
|
||||||
|
- Verified behavior anchors:
|
||||||
|
- `vga_palette_read` mirrors `vga_palette_write` and reads DAC entries through ports `0x3c7/0x3c9` into a far palette buffer.
|
||||||
|
- `timer_entity_enable_wrapper` is a thin forwarder to `timer_entity_enable` and is widely used in lifecycle/setup paths.
|
||||||
|
- The seg064 gate helpers (`0008:eb43`/`0008:ebe7`/`0008:ec23`) control one-shot global flag transitions at `0x3b72/0x3b73`, then dispatch via unresolved thunk paths; names remain intentionally conservative pending stronger subsystem identity.
|
||||||
|
- Callback callsite clarification retained:
|
||||||
|
- `entity_cleanup_resources_and_dispatch` vtable `+0x0c` call at `000d:9d5e` passes object fields `+0x12d/+0x12f`.
|
||||||
|
- Matching vtable `+0x0c` call at `000d:a3b7` passes object fields `+0x74f/+0x751`.
|
||||||
|
- These pairs appear to be state/coordinate-like payloads for the runtime callback object at `0x4588`.
|
||||||
|
|
||||||
|
### Raw 0x4588 Follow-up Batch 6 (constructor lane naming + callback globals)
|
||||||
|
|
||||||
|
- New conservative helper renames:
|
||||||
|
- `0008:d27e` = `entity_set_update_period_and_reschedule`
|
||||||
|
- `0009:7905` = `palette_buffer_alloc_copy_from_source`
|
||||||
|
- Verified behavior anchors:
|
||||||
|
- `entity_set_update_period_and_reschedule` stores timing/update-period fields (`+0x36/+0x38/+0x3a`), clears deferred fields (`+0x3c/+0x3e`), then triggers timer recompute/reschedule helpers.
|
||||||
|
- `palette_buffer_alloc_copy_from_source` allocates/replaces destination palette buffer metadata and copies RGB triplets from a source far pointer (`entry_count * 3` bytes).
|
||||||
|
- Disassembly annotations added on both callback emit callsites so payload provenance remains attached in-database:
|
||||||
|
- `000d:9d5e` -> vtable `+0x0c` payload from `+0x12d/+0x12f`
|
||||||
|
- `000d:a3b7` -> vtable `+0x0c` payload from `+0x74f/+0x751`
|
||||||
|
- Global data labels were promoted for the callback lane (where symbolization applies in decompiler views):
|
||||||
|
- `g_active_dispatch_entry_farptr` at `0x6828`
|
||||||
|
- callback-state/object globals at `0x4588/0x458c/0x4590/0x4594/0x4595/0x45a6`
|
||||||
|
- dispatch callback-table pointer at `0x39ca`
|
||||||
|
|
||||||
### Raw 0007 Gameplay Helper Batch (entity/tile aux state)
|
### Raw 0007 Gameplay Helper Batch (entity/tile aux state)
|
||||||
|
|
||||||
- New conservative gameplay-side helper renames (direct analysis from field writes and call structure):
|
- New conservative gameplay-side helper renames (direct analysis from field writes and call structure):
|
||||||
|
|
|
||||||
|
|
@ -59,28 +59,28 @@
|
||||||
"58","code","0x86400","0x44B","None","","","","crusader_ne_segments.csv"
|
"58","code","0x86400","0x44B","None","","","","crusader_ne_segments.csv"
|
||||||
"59","code","0x86A00","0x4288","None","","","","crusader_ne_segments.csv"
|
"59","code","0x86A00","0x4288","None","","","","crusader_ne_segments.csv"
|
||||||
"60","code","0x8B600","0x231","None","","","","crusader_ne_segments.csv"
|
"60","code","0x8B600","0x231","None","","","","crusader_ne_segments.csv"
|
||||||
"61","code","0x8BA00","0x1B6C","None","","","","crusader_ne_segments.csv"
|
"61","code","0x8BA00","0x1B6C","Foothold","Entity/timer dispatch guard and period helpers","timer_entity_enable_wrapper; entity_check_flag_0x4000; entity_set_event_type_checked; entity_set_update_period_and_reschedule","Several wrappers still resolve into thunk-heavy paths and need caller-side semantic naming","crusader_decompilation_notes.md"
|
||||||
"62","code","0x8DA00","0x85F","None","","","","crusader_ne_segments.csv"
|
"62","code","0x8DA00","0x85F","Foothold","Entry word-list lifecycle helpers","entity_word_list_destroy","Caller-side object-role mapping still needed for strong behavioral names","crusader_decompilation_notes.md"
|
||||||
"63","code","0x8E400","0x519","None","","","","crusader_ne_segments.csv"
|
"63","code","0x8E400","0x519","None","","","","crusader_ne_segments.csv"
|
||||||
"64","code","0x8EA00","0x3B1","None","","","","crusader_ne_segments.csv"
|
"64","code","0x8EA00","0x3B1","Foothold","Global one-shot gate/dispatch control","FUN_0008_eb43; FUN_0008_ebe7; FUN_0008_eac8; FUN_0008_ec23","Subsystem identity of the gate path remains unresolved; names intentionally conservative","crusader_decompilation_notes.md"
|
||||||
"65","code","0x8F000","0x5BD","None","","","","crusader_ne_segments.csv"
|
"65","code","0x8F000","0x5BD","None","","","","crusader_ne_segments.csv"
|
||||||
"66","code","0x8F800","0x4A9","None","","","","crusader_ne_segments.csv"
|
"66","code","0x8F800","0x4A9","None","","","","crusader_ne_segments.csv"
|
||||||
"67","code","0x8FE00","0x839","None","","","","crusader_ne_segments.csv"
|
"67","code","0x8FE00","0x839","None","","","","crusader_ne_segments.csv"
|
||||||
"68","code","0x90800","0xB4A","None","","","","crusader_ne_segments.csv"
|
"68","code","0x90800","0xB4A","None","","","","crusader_ne_segments.csv"
|
||||||
"69","code","0x91800","0x2A0","None","","","","crusader_ne_segments.csv"
|
"69","code","0x91800","0x2A0","None","","","","crusader_ne_segments.csv"
|
||||||
"70","code","0x91C00","0xF24","None","","","","crusader_ne_segments.csv"
|
"70","code","0x91C00","0xF24","Foothold","File-handle allocation/open wrappers","file_handle_alloc_init_and_open; file_handle_open_with_mode","Exact DOS open/create flags and mode semantics still need caller-side argument decoding","crusader_decompilation_notes.md"
|
||||||
"71","code","0x92E00","0x6C2","None","","","","crusader_ne_segments.csv"
|
"71","code","0x92E00","0x6C2","None","","","","crusader_ne_segments.csv"
|
||||||
"72","code","0x93600","0xCA1","None","","","","crusader_ne_segments.csv"
|
"72","code","0x93600","0xCA1","None","","","","crusader_ne_segments.csv"
|
||||||
"73","code","0x94600","0x9AA","None","","","","crusader_ne_segments.csv"
|
"73","code","0x94600","0x9AA","None","","","","crusader_ne_segments.csv"
|
||||||
"74","code","0x95200","0x337","None","","","","crusader_ne_segments.csv"
|
"74","code","0x95200","0x337","None","","","","crusader_ne_segments.csv"
|
||||||
"75","code","0x95600","0x1428","None","","","","crusader_ne_segments.csv"
|
"75","code","0x95600","0x1428","None","","","","crusader_ne_segments.csv"
|
||||||
"76","code","0x96E00","0x627","None","","","","crusader_ne_segments.csv"
|
"76","code","0x96E00","0x627","Foothold","VGA palette read/write/free helpers","vga_palette_write; vga_palette_read; palette_free_if_set","Need caller-side analysis to classify higher-level palette transaction semantics","crusader_decompilation_notes.md"
|
||||||
"77","code","0x97600","0x616","None","","","","crusader_ne_segments.csv"
|
"77","code","0x97600","0x616","Foothold","Palette buffer clone/metadata setup","palette_buffer_alloc_copy_from_source","Need caller-side analysis to separate generic palette clone use from callback-specific staging","crusader_decompilation_notes.md"
|
||||||
"78","code","0x97E00","0x634","None","","","","crusader_ne_segments.csv"
|
"78","code","0x97E00","0x634","None","","","","crusader_ne_segments.csv"
|
||||||
"79","code","0x98600","0x421","None","","","","crusader_ne_segments.csv"
|
"79","code","0x98600","0x421","None","","","","crusader_ne_segments.csv"
|
||||||
"80","code","0x98C00","0xF27","Foothold","Conditional render/callback dispatch","entity_conditional_render_dispatch","0x4588 callback object still lacks a concrete subsystem name","crusader_decompilation_notes.md"
|
"80","code","0x98C00","0xF27","Foothold","Conditional render/callback dispatch and surface release","entity_conditional_render_dispatch; surface_release_internal; surface_release_and_maybe_free","0x4588 callback object still lacks a concrete subsystem name","crusader_decompilation_notes.md"
|
||||||
"81","code","0x99E00","0x320","None","","","","crusader_ne_segments.csv"
|
"81","code","0x99E00","0x320","None","","","","crusader_ne_segments.csv"
|
||||||
"82","code","0x9A200","0x1C8A","Partial","Allocator sweep and per-head allocation","allocator_head_try_alloc_block; allocator_head_free_block; public size wrapper","0x4588 object and finalize path still unresolved","crusader_decompilation_notes.md; plan-mid.md"
|
"82","code","0x9A200","0x1C8A","Partial","Allocator sweep and per-head allocation/finalize","allocator_head_try_alloc_block; allocator_head_free_block; allocator_head_finalize_sweep; public size wrapper","0x4588 object subsystem identity still unresolved","crusader_decompilation_notes.md; plan-mid.md"
|
||||||
"83","code","0x9C400","0x31E","Foothold","Allocator node/header helpers","event_queue_push; packed size/header helpers","Mostly structural helper layer","crusader_decompilation_notes.md"
|
"83","code","0x9C400","0x31E","Foothold","Allocator node/header helpers","event_queue_push; packed size/header helpers","Mostly structural helper layer","crusader_decompilation_notes.md"
|
||||||
"84","code","0x9C800","0x1478","None","","","","crusader_ne_segments.csv"
|
"84","code","0x9C800","0x1478","None","","","","crusader_ne_segments.csv"
|
||||||
"85","code","0x9E000","0x404","Foothold","Allocator work token helpers","token reserve/release and commit helpers","Needs clearer subsystem naming","crusader_decompilation_notes.md"
|
"85","code","0x9E000","0x404","Foothold","Allocator work token helpers","token reserve/release and commit helpers","Needs clearer subsystem naming","crusader_decompilation_notes.md"
|
||||||
|
|
@ -89,11 +89,11 @@
|
||||||
"88","code","0xA2E00","0x523","None","","","","crusader_ne_segments.csv"
|
"88","code","0xA2E00","0x523","None","","","","crusader_ne_segments.csv"
|
||||||
"89","code","0xA3400","0x373","None","","","","crusader_ne_segments.csv"
|
"89","code","0xA3400","0x373","None","","","","crusader_ne_segments.csv"
|
||||||
"90","code","0xA3800","0x9C6","None","","","","crusader_ne_segments.csv"
|
"90","code","0xA3800","0x9C6","None","","","","crusader_ne_segments.csv"
|
||||||
"91","code","0xA4400","0x6FA","Partial","Init/context and RNG helpers","seg091_func_00fd; seg091_func_014d; rng_set_seed; rng_next_modulo","00fd and 014d still positional","crusader_decompilation_notes.md; plan-mid.md"
|
"91","code","0xA4400","0x6FA","Partial","Init/context RNG and runtime callback/video-state lifecycle","seg091_func_00fd; seg091_func_014d; rng_set_seed; rng_next_modulo; runtime_callback_object_init_once; runtime_callback_object_teardown_once; video_bios_state_snapshot; video_mode_set_and_record_state","00fd/014d still positional; callback object subsystem identity still unresolved","crusader_decompilation_notes.md; plan-mid.md"
|
||||||
"92","code","0xA4E00","0x59E","None","","","","crusader_ne_segments.csv"
|
"92","code","0xA4E00","0x59E","None","","","","crusader_ne_segments.csv"
|
||||||
"93","code","0xA5600","0x4F1","None","","","","crusader_ne_segments.csv"
|
"93","code","0xA5600","0x4F1","None","","","","crusader_ne_segments.csv"
|
||||||
"94","code","0xA5E00","0x606","Partial","Tracked handle table control","tracked_entity_handle_table_init; tracked_entity_handle_table_shutdown; tracked_entity_handle_table_clear_and_dispatch","Downstream dispatch tail still unresolved","crusader_decompilation_notes.md"
|
"94","code","0xA5E00","0x606","Partial","Tracked handle table control","tracked_entity_handle_table_init; tracked_entity_handle_table_shutdown; tracked_entity_handle_table_clear_and_dispatch","Downstream dispatch tail still unresolved","crusader_decompilation_notes.md"
|
||||||
"95","code","0xA6600","0xC9F","Partial","Cache manager init/reset and 0x4588 runtime callback lifecycle","cache_init; cache_reset_runtime_state; cache_shutdown","Concrete 0x4588 callback object name and nearby no-function callers remain unresolved","crusader_decompilation_notes.md; plan-mid.md"
|
"95","code","0xA6600","0xC9F","Partial","Cache manager init/reset and 0x4588 runtime callback lifecycle","cache_init; cache_reset_runtime_state; cache_shutdown; entity_cleanup_resources_and_dispatch","Concrete 0x4588 callback object name and field-level role mapping remain unresolved","crusader_decompilation_notes.md; plan-mid.md"
|
||||||
"96","code","0xA7600","0x582","None","","","","crusader_ne_segments.csv"
|
"96","code","0xA7600","0x582","None","","","","crusader_ne_segments.csv"
|
||||||
"97","code","0xA7E00","0xDB0","None","","","","crusader_ne_segments.csv"
|
"97","code","0xA7E00","0xDB0","None","","","","crusader_ne_segments.csv"
|
||||||
"98","code","0xA8E00","0x68A","None","","","","crusader_ne_segments.csv"
|
"98","code","0xA8E00","0x68A","None","","","","crusader_ne_segments.csv"
|
||||||
|
|
@ -135,8 +135,8 @@
|
||||||
"134","code","0xD6000","0xEF0","None","","","","crusader_ne_segments.csv"
|
"134","code","0xD6000","0xEF0","None","","","","crusader_ne_segments.csv"
|
||||||
"135","code","0xD7000","0x3B7","None","","","","crusader_ne_segments.csv"
|
"135","code","0xD7000","0x3B7","None","","","","crusader_ne_segments.csv"
|
||||||
"136","code","0xD7600","0x5BD","None","","","","crusader_ne_segments.csv"
|
"136","code","0xD7600","0x5BD","None","","","","crusader_ne_segments.csv"
|
||||||
"137","code","0xD7E00","0xFBB","None","","","","crusader_ne_segments.csv"
|
"137","code","0xD7E00","0xFBB","Foothold","Dispatch-entry runtime state init/release","entity_dispatch_entry_init_runtime_state; entity_dispatch_entry_release_runtime_state","Higher-level callback object role and event semantic naming still unresolved","crusader_decompilation_notes.md; plan-mid.md"
|
||||||
"138","code","0xD9200","0x32E4","None","","","","crusader_ne_segments.csv"
|
"138","code","0xD9200","0x32E4","Foothold","Entity cleanup/finalize with callback and palette/file teardown","entity_cleanup_resources_and_dispatch; sprite_redraw_global_if_active","Callback-object role naming and 000d:7e00 constructor/dispatch path are still unresolved","crusader_decompilation_notes.md; plan-mid.md"
|
||||||
"139","code","0xDCC00","0x984","None","","","","crusader_ne_segments.csv"
|
"139","code","0xDCC00","0x984","None","","","","crusader_ne_segments.csv"
|
||||||
"140","code","0xDD800","0xC6F","None","","","","crusader_ne_segments.csv"
|
"140","code","0xDD800","0xC6F","None","","","","crusader_ne_segments.csv"
|
||||||
"141","code","0xDE600","0x2B","None","","","Short stub-sized segment","crusader_ne_segments.csv"
|
"141","code","0xDE600","0x2B","None","","","Short stub-sized segment","crusader_ne_segments.csv"
|
||||||
|
|
|
||||||
|
17
plan-mid.md
17
plan-mid.md
|
|
@ -20,20 +20,25 @@ The estimates below are intentionally conservative. They measure verified behavi
|
||||||
|
|
||||||
- Priority 0 has started: `crusader_segment_coverage_ledger.csv` exists and contains a first-pass 145-row ledger.
|
- Priority 0 has started: `crusader_segment_coverage_ledger.csv` exists and contains a first-pass 145-row ledger.
|
||||||
- The currently seeded ledger rows are conservative and strongest around seg001, seg004, seg021, seg043, seg080, seg082/083/085, seg091, seg094, and seg095.
|
- The currently seeded ledger rows are conservative and strongest around seg001, seg004, seg021, seg043, seg080, seg082/083/085, seg091, seg094, and seg095.
|
||||||
- Priority 1 has started on the cache/backend cluster: the seg082 allocator mechanics are now materially recovered (`allocator_head_try_alloc_block`, `allocator_head_free_block`, `allocator_free_block_by_ptr`), and the next unresolved clue is that `0x4588` behaves like a runtime-installed callback/dispatch object used by `entity_conditional_render_dispatch` plus a one-shot teardown path.
|
- Priority 1 has started on the cache/backend cluster: the seg082 allocator mechanics are now materially recovered (`allocator_head_try_alloc_block`, `allocator_head_free_block`, `allocator_free_block_by_ptr`), and the `0x4588` path now has named lifecycle helpers (`runtime_callback_object_init_once`, `runtime_callback_object_teardown_once`, `runtime_callback_object_phase_finalize`).
|
||||||
- The `0x4588` blocker is tighter than before: no-function windows now confirm a direct install at `000a:493e`, repeated clear paths in seg004, and additional vtable `+0x0c` callbacks from unresolved `000a:` and `000d:` callers, but the concrete subsystem name is still unresolved.
|
- The `0x4588` blocker is tighter than before: `000a:b988` boundary repair now includes both callback sync callsites (`000a:b9e5` / `000a:ba66`) inside one real function body, `000d:9d5e` / `000d:a3b7` are confirmed inside `entity_cleanup_resources_and_dispatch`, and adjacent helpers are now clarified as `allocator_head_finalize_sweep` (`0009:a961`), `video_bios_state_snapshot` (`000a:4a1f`), and `video_mode_set_and_record_state` (`000a:4972`). Concrete subsystem identity is still unresolved.
|
||||||
|
- A larger MCP rename batch completed for cleanup callees: `palette_buffer_alloc_and_init_256` (`0009:7853`), `file_handle_alloc_init_and_open` (`0009:1c3a`), `file_handle_open_with_mode` (`0009:1d6a`), `surface_release_internal` (`0009:8d7b`), `surface_release_and_maybe_free` (`0009:8e0a`), and `sprite_redraw_global_if_active` (`000d:9231`). This reduces `entity_cleanup_resources_and_dispatch` ambiguity on file/surface/palette teardown paths.
|
||||||
|
- The previously missing `000d:7e00` function object is now recovered and named `entity_dispatch_entry_init_runtime_state`, with paired destructor `entity_dispatch_entry_release_runtime_state` at `000d:8078`. Adjacent missing helpers `0003:a880` and `0003:b8e2` were also recovered, with `0003:b8e2` promoted to `far_buffer_alloc_with_mode_flags`.
|
||||||
|
- Additional helper stabilization now covers seg061/064/076: `vga_palette_read` (`0009:6ec7`) is confirmed alongside existing palette write/free paths, `timer_entity_enable_wrapper` (`0008:d3ba`) is named, and seg064 one-shot gate helpers around `0x3b72/0x3b73` are documented with conservative comments while keeping speculative naming deferred.
|
||||||
|
- Constructor-lane semantics tightened further: `entity_set_update_period_and_reschedule` (`0008:d27e`) and `palette_buffer_alloc_copy_from_source` (`0009:7905`) are now named, and both `0x4588` callback emit callsites (`000d:9d5e`, `000d:a3b7`) now have explicit payload-pair annotations in disassembly.
|
||||||
|
|
||||||
### Current Focus
|
### Current Focus
|
||||||
|
|
||||||
1. Finish Priority 0 refinement by promoting more exact segment rows where notes already support a verified foothold.
|
1. Finish Priority 0 refinement by promoting more exact segment rows where notes already support a verified foothold.
|
||||||
2. Continue the Priority 1 pass by tracing the remaining caller-side `0x4588` / `0009:b1c3` object-role evidence rather than the already-recovered allocator mechanics.
|
2. Continue the Priority 1 pass by tracing remaining caller-side `0x4588` / `0009:b1c3` object-role evidence now that the `000d:7e00` constructor/destructor path is readable.
|
||||||
|
|
||||||
### Next Resume Point
|
### Next Resume Point
|
||||||
|
|
||||||
1. Update the ledger for any additional exact segment anchors found in the reset/cache or render-path notes.
|
1. Update the ledger for any additional exact segment anchors found in the reset/cache or render-path notes.
|
||||||
2. Recover or classify the still-unbounded callback callers around `000a:b9e5` / `000a:ba66` and `000d:9d5e` / `000d:a3b7`; they now look like the best remaining cheap wins on the `0x4588` path.
|
2. Continue caller-role classification inside `entity_cleanup_resources_and_dispatch` (contains both `000d:9d5e` and `000d:a3b7`) and map how it relates to `runtime_callback_object_phase_finalize` + `allocator_head_finalize_sweep`.
|
||||||
3. Revisit the nearby install/lifecycle gap around `000a:493e` / `000a:4a56` only if those caller windows need a stronger object-owner model.
|
3. Promote additional field-level names inside `entity_cleanup_resources_and_dispatch` and `entity_dispatch_entry_init_runtime_state` now that update-period/palette-copy helpers are named.
|
||||||
4. Continue `ASYLUM.24` only after the `0x4588` path has no further cheap wins.
|
4. Classify remaining callback-role semantics for the `0x4588` object (especially vtable `+0x08` vs `+0x0c` intent and phase/event meaning) using the confirmed payload pairs `+0x12d/+0x12f` and `+0x74f/+0x751`.
|
||||||
|
5. Continue `ASYLUM.24` only after the `0x4588` path has no further cheap wins.
|
||||||
|
|
||||||
### Headline Estimate
|
### Headline Estimate
|
||||||
|
|
||||||
|
|
|
||||||
71
smoke_mcp_new_features.py
Normal file
71
smoke_mcp_new_features.py
Normal file
|
|
@ -0,0 +1,71 @@
|
||||||
|
import urllib.parse
|
||||||
|
import urllib.request
|
||||||
|
|
||||||
|
BASE = "http://127.0.0.1:8080"
|
||||||
|
|
||||||
|
|
||||||
|
def excerpt(text, max_len=180):
|
||||||
|
s = (text or "").replace("\r", " ").replace("\n", " ").strip()
|
||||||
|
if len(s) > max_len:
|
||||||
|
return s[: max_len - 3] + "..."
|
||||||
|
return s
|
||||||
|
|
||||||
|
|
||||||
|
def http_get(path, params=None):
|
||||||
|
params = params or {}
|
||||||
|
query = urllib.parse.urlencode(params)
|
||||||
|
url = BASE + path + (("?" + query) if query else "")
|
||||||
|
with urllib.request.urlopen(url, timeout=10) as resp:
|
||||||
|
return resp.read().decode("utf-8", errors="replace")
|
||||||
|
|
||||||
|
|
||||||
|
def http_post(path, data=None):
|
||||||
|
data = data or {}
|
||||||
|
body = urllib.parse.urlencode(data).encode("utf-8")
|
||||||
|
req = urllib.request.Request(BASE + path, data=body, method="POST")
|
||||||
|
with urllib.request.urlopen(req, timeout=10) as resp:
|
||||||
|
return resp.read().decode("utf-8", errors="replace")
|
||||||
|
|
||||||
|
|
||||||
|
def run_test(name, func):
|
||||||
|
try:
|
||||||
|
result = func()
|
||||||
|
print("PASS", name, "::", excerpt(result))
|
||||||
|
except Exception as e:
|
||||||
|
print("FAIL", name, "::", str(e))
|
||||||
|
|
||||||
|
|
||||||
|
readonly_script = "\n".join(
|
||||||
|
[
|
||||||
|
"println('program=' + currentProgram.getName())",
|
||||||
|
"if currentAddress is not None:",
|
||||||
|
" println('addr=' + currentAddress.toString())",
|
||||||
|
"else:",
|
||||||
|
" println('addr=<none>')",
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
run_test("get_project_access_info", lambda: http_get("/get_project_access_info"))
|
||||||
|
run_test("read_region", lambda: http_get("/read_region", {"start": "0007:28ce", "end": "0007:28dd"}))
|
||||||
|
run_test("disassemble_region", lambda: http_get("/disassemble_region", {"start": "0007:28ce", "end": "0007:2900"}))
|
||||||
|
run_test("get_instruction_window", lambda: http_get("/get_instruction_window", {"address": "0007:28ce", "before_count": 2, "after_count": 3}))
|
||||||
|
run_test("search_instructions", lambda: http_get("/search_instructions", {"query": "0007:28ce", "mode": "address", "limit": 5}))
|
||||||
|
run_test("get_data_uses", lambda: http_get("/get_data_uses", {"address": "0007:28ce", "include_operand_scans": "true", "limit": 10}))
|
||||||
|
run_test("analyze_function_boundaries", lambda: http_get("/analyze_function_boundaries", {"start": "0007:28c0", "end": "0007:2910"}))
|
||||||
|
run_test("open_current_program_readonly", lambda: http_post("/open_current_program_readonly", {"version": -1, "make_current": "false"}))
|
||||||
|
run_test("run_readonly_script", lambda: http_post("/run_readonly_script", {"script_text": readonly_script}))
|
||||||
|
run_test("apply_program_edit_plan_dry", lambda: http_post("/apply_program_edit_plan", {"plan": "rename_function_by_address|0007:28ce|tmp_name", "dry_run": "true"}))
|
||||||
|
|
||||||
|
run_test("create_function_by_address_invalid", lambda: http_post("/create_function_by_address", {
|
||||||
|
"entry": "invalid",
|
||||||
|
"name": "tmp",
|
||||||
|
"body_start": "invalid",
|
||||||
|
"body_end": "invalid",
|
||||||
|
"comment": "smoke",
|
||||||
|
}))
|
||||||
|
run_test("delete_function_by_address_invalid", lambda: http_post("/delete_function_by_address", {"entry": "invalid"}))
|
||||||
|
run_test("rename_functions_by_address_invalid_batch", lambda: http_post("/rename_functions_by_address", {"batch": "not_a_valid_batch_line"}))
|
||||||
|
run_test("set_comments_invalid_batch", lambda: http_post("/set_comments", {"batch": "not_a_valid_batch_line"}))
|
||||||
|
run_test("set_decompiler_comments_invalid_batch", lambda: http_post("/set_decompiler_comments", {"batch": "not_a_valid_batch_line"}))
|
||||||
Loading…
Add table
Add a link
Reference in a new issue