aboutsummaryrefslogtreecommitdiffstats
path: root/fw/pseudo/gcp_command_surface.c (follow)
Commit message (Collapse)AuthorAge
* fw: command-surface dumps for all twelve TAs, with honest handler attributionuser2026-09-29
| | | | | | | | | | | | | | | | | | | | | | | | | | | GCP had a decompiled command-surface artifact and the other eleven did not, though the command surface is what an analyst reads first. fw/ta_surface.py emits one per TA into fw/pseudo/<ta>_command_surface.c. Two corrections were needed for these to be honest rather than merely present. First, prefer the address-keyed map: cmdmaps record handlers by name, captured before the renames, and the first run used the name map for GCP as well, resolving only 4 of its 17 handlers and silently replacing a good artifact with a worse one. The tool now prefers <ta>_ea.json where it exists. Second, separate function entries from labels inside functions: rap's cmd 1 points into start, two of auc's land inside another handler, and five of OPM's nine dispatch into the middle of larger functions, so printing the containing function as the handler would assert that start is rap's cmd 1 handler. Exact entries and internal labels are now separate sections, with the containing function reproduced in full under a warning that the command's code begins at the stated offset. IDA refuses to split those internal entries out, and undefining the owning function to force a split was not worth the risk so soon after repairing a corrupt database. OPM cmd 8 at 0x401320 is reported as entering opm_asd301_path+0x60 rather than asserted as a separate function, despite earlier notes calling it a merged handler. 62 exact handlers across the twelve, all decompiling, plus 9 internal-label entries each shipped with its containing code. TMZ has no command map, which is correct for a stub that answers every command id identically.
* fw: regenerate the GCP command-surface dump after the arity passuser2026-09-29
| | | | | | The committed surface predated the inferred-arity work, so its call sites still rendered with IDA's guessed argument counts. Regenerated from the final databases so the artifact matches the verified state: 17 handlers, no decompilation failures.
* fw: recover helper arity by dataflow, validated first -- 632/632 functions ↵user2026-09-29
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | now typed 179 prototypes came from an established role, leaving ~450 helpers with none. Guessing their argument count would repeat the lvar mistake, producing output that reads well and says something false. Arity is recoverable instead: on AAPCS a register read before it is written on any path is an incoming parameter, so fw/ta_arity.py walks basic blocks from the entry and derives it. The validation is the point. The control is the set of handlers the dispatch table points at, which the dispatcher calls as mov r0,r5; mov r1,r4; bl handler, so their arity of two is proven rather than assumed, plus zero_fill and memcmp. Two attempts failed the control before one passed: push {r3,r4,r5,lr} is the alignment idiom and reads r3, making every such function look like it took four arguments; excluding push and pop then over-corrected by also excluding stm, which for the ASD RPC thunks is the argument-passing idiom, so those reported zero arguments. With push and pop excluded, stm and ldm treated as real dataflow, and the control restricted to proven arities, it agrees 19 of 19. That last correction disproved four prototypes already applied: gcp_asd_rpc_304 takes none since it zero-fills its own buffer, _107 takes two because movs r2,#0 writes r2 before the stm reads it, _202 takes four, and only _305 was the single argument all four had been declared with. Coverage is now 632 of 632 functions carrying a prototype across all twelve TAs, with 554 named and 78 documented. Measured against a pristine database, raw pointer-arithmetic casts fall from 81 to 8 and anonymous parameters from 113 to 0.
* fw: readable GCP command-surface dump + sharpen FE0F's in-database commentuser2026-09-29
Generates fw/pseudo/gcp_command_surface.c, the full GCP command surface decompiled with restored names, prototypes and structure types, with each handler's finding notes inline. This is the artifact the objective actually asks for: pseudocode plausible enough to analyse. Also corrects FE0F's comment, which predated the hardware work. It framed the issue as destroy-side only. The sharper and now proven statement is that FE0C never writes slot+0x18 at all, which is the field this search compares against, so that field is permanently zero for every session and an all-zero query matches the first slot whatever its state. Records the full hardware chain and the explicit finding that this is not a use-after-free, since the handle is a monotonic counter rebound on slot reuse and a stale handle is correctly rejected. Adds an explicit save_database plus lease release to fw/ta_ida.py: save_database is a client method rather than a remote_ops op, so the earlier call raised and was swallowed, leaving work only in the unpacked scratch files where an unclean worker exit would lose it. All twelve databases are now saved and released.