| name | RE-SKILLS.md |
|---|---|
| description | Use whenever the user says "reverse engineer", "ida", or "ghidra"; also use for generic reverse-engineering workflows involving IDA Pro, Ghidra, emulation, Frida, USB/libusb, ADB, reporting, and durable note-taking. Keep guidance target-agnostic and avoid vendor-, platform-, subsystem-, or device-family-specific assumptions. |
Generic reverse-engineering workflow guidance for future sessions. This skill is target-agnostic: do not encode vendor-, platform-, subsystem-, or device-family-specific assumptions here.
- For all IDA Pro work, use
ida-rpc. Do not rely on manual UI-only analysis when an RPC query or database edit is needed. - For all Ghidra work, use
ghidra-rpc. Use it for decompiler inspection, symbol work, comments, memory maps, and function metadata when available. - For all emulation tasks, use
emu-rpc. Use emulation to test specific hypotheses, not as a substitute for static analysis. - For USB/libusb and ADB device access, run commands outside the sandbox when required and serialize access to each device.
- Write all durable notes in structured form under
/home/$USER/basic-memory/. Prefer topic directories and stable titles over ad hoc local text files. - For all android and ios app reverse engineering tasks, prefer using
frida.
- Start by recovering state: read existing notes, reports, scripts, loader/import settings, and prior command logs before making new changes.
- Separate verified facts from hypotheses. Mark hypotheses clearly and update them when evidence changes.
- Prefer primary evidence: disassembly, decompiler output, traces, protocol captures, source code, hardware logs, and reproducible test output.
- Keep experiments narrow. Change one variable at a time and record what changed.
- Do not repeat a failed path unless a concrete new variable or new evidence changes the expected outcome.
- Preserve enough detail for replay: tool version, input file hash/path, base address, architecture, endian mode, command, options, device mode, and output.
- Write findings promptly in
/home/$USER/basic-memory/and, when the task calls for it, in anRE/*.mdreport. - After each testing or verification task completes, use basic memory to take notes what was successful and what failed with the aim to prevent any mistakes in the future.
- Store durable notes under
/home/$USER/basic-memory/, grouped by domain or project, for examplereverse/<topic>/orreverse/meta/. - Include these fields when practical: goal, target artifact, environment, tools, exact commands, observations, conclusion, failed paths, and next action.
- Record both successes and dead ends. A failed experiment is useful only if the exact setup and reason for failure are captured.
- Keep secrets, credentials, private tokens, and unrelated personal metadata out of notes.
- Use
ida-rpcto inspect decompiler output, disassembly, functions, symbols, xrefs, strings, memory segments, and type information. - Confirm loader settings before analysis: architecture, bitness, endian mode, image base, segment permissions, entrypoints, and processor mode.
- Create meaningful segments for code, data, register windows, stacks, heaps, shared memory, firmware tables, and manually mapped blobs when known.
- Do not trust the first auto-analysis result. Check function boundaries, mode switches, literal pools, jump tables, veneers, and exception vectors manually.
- Rename functions only when behavior is understood. Prefer action-oriented names such as
parse_command,copy_from_fifo, ordispatch_request. - Rename variables and arguments to describe role, not guessed type. Correct pointer, array, struct, and integer widths when the decompiler is misleading.
- Add comments at decision points: command dispatch, trust boundaries, hardware access, crypto calls, memory copies, validation checks, and error handling.
- Use cross-references aggressively. A single string, constant, or callsite is weak evidence; corroborate with multiple references.
- When matching source to binary, compare call structure, constants, register access order, error strings, and side effects, not just symbol names.
- Keep IDA loader and helper scripts deterministic and rerunnable. Validate with a small known sample.
- Use
ghidra-rpcfor decompiler inspection, program metadata, symbol updates, comments, function boundaries, and memory-map work. - Verify language/compiler selection and image base before relying on decompiler output.
- Create memory blocks with explicit permissions and names. Map peripheral/register areas as separate blocks when they are referenced by code.
- Re-run analysis selectively after correcting memory maps, function starts, or processor mode; do not rely on stale decompilation.
- Use data types early for repeated structures: command blocks, descriptors, headers, tables, contexts, queues, and register layouts.
- Rename functions and variables in the database as conclusions mature. Keep comments concise and evidence-backed.
- Use function graph, references, and symbol trees to validate dispatch paths and initialization order.
- When importing raw firmware, preserve the original file offset to runtime address relationship in
/home/$USER/basic-memory/notes.
- Use
emu-rpcfor emulation setup, execution, memory/register inspection, tracing, and hooks. - Emulate to test a specific hypothesis, not to replace static analysis.
- Define the minimum environment needed: architecture, mode, base address, mapped ranges, stack, input buffers, hooks, and expected stop condition.
- Stub hardware reads/writes explicitly. Log unmapped accesses and decide whether each one is a required peripheral, a mapping bug, or unreachable code.
- Keep emulation deterministic: fixed inputs, fixed memory snapshots, bounded instruction counts, and reproducible traces.
- Compare emulator behavior against static control flow and real-device logs when available.
- Do not brute force secrets or opaque values. Use emulation to understand data flow, validation logic, and state transitions.
- Save short traces around important branches, indirect calls, and memory/register accesses.
- Confirm process state first: spawn vs attach, architecture, package/process name, library load timing, and whether the runtime is available.
- Separate hook installation from hook effectiveness. A hook install log is not proof; require an observed event or changed behavior.
- For Java targets, wait for the Java runtime before Java hooks. For native targets, wait for the library/module before attaching exports or offsets.
- Use small probes before large hook bundles. Validate one known method/function, then expand.
- Log structured events with enough context: thread, timestamp, function, arguments, return value, exception, and relevant buffers.
- Guard hooks against null pointers, invalid Java objects, unavailable classes, overloaded signatures, and repeated installation.
- Keep generated scripts syntax-checkable and split reusable helpers from target-specific hooks.
- When hooks fail, distinguish runtime unavailable, symbol not found, wrong overload, wrong process, timing issue, and event-delivery failure.
- Serialize USB/libusb access. Do not run parallel tools against the same device.
- Run USB/libusb and ADB device access outside the sandbox when required by the environment.
- Before a hardware command, record device identity and state: bus/address, VID:PID, product strings, interfaces, endpoints, mode, permissions, and power-cycle state.
- Claim only the needed interface and release/close handles on exit. Handle disconnects and re-enumeration as normal events.
- Treat timeouts, stalls, short reads, and disconnects as distinct observations. Do not collapse them into a generic failure.
- Use conservative timeouts first, then tune based on observed device behavior.
- For write-capable commands, state read/write direction, target, expected size, and failure impact before running the command.
- With ADB, check server/device state first:
adb devices, authorization, transport ID, root state, SELinux state when relevant, and whether another server instance owns the device. - If ADB or libusb reports permission or daemon errors, fix the host access path before changing target logic.
- Power cycling is a state change. Record it, wait for stable re-enumeration, and re-identify the device before continuing.
- Every report should include scope, inputs, environment, method, findings, failed paths, remaining unknowns, and exact reproduction steps.
- Include file hashes or stable paths for binaries and dumps when practical.
- Use short evidence excerpts instead of long raw logs. Keep full logs in files when they matter.
- End with next actions that are falsifiable: what to test, why, what output would confirm it, and what output would reject it.
- For each new session, if a
.gitfolder exists in the current directory, create a new branch usinggitwith an appropriate name and commit after each successful step so that any future failures can be reverted to a working state. NEVER push, keep the commits local.