leanrea: fast path You already know these tools. This file only lists the fastest command for each target, and the traps. Rules - Work on a copy ( on APFS is instant). Put each extraction in a new dir under . Reuse an extraction if one exists. - Route by and the magic bytes first. Run the cheapest inventory next. Only then decompile or read code. - skips hidden and ignored files, and bundlers hide code (Electron: , ). Always search extracted trees with . - Never a big or minified file. Slice it: . Dump a disassembly once to a file, then grep that file. - Batch independent probes into ONE shel…

$D/dis.txt | rg -v '^_?_?Z?N?St3' | head -150\n```\nThen read one function: `awk '/^FUNC_LABEL:$/{p=1;next} p&&/^[_a-zA-Z].*:$/{exit} p' $D/dis.txt | rg 'bl|b\\.|cmp|literal|mov\\s+w2'`.\n\nElectron:\n```sh\nA=./app.asar; X=$TMPDIR/re/asar; rm -rf $X; npx -y @electron/asar extract $A $X && jq '{name,version,main}' $X/package.json; find $X -path '*/node_modules' -prune -o -type f \\( -name '*.js' -o -name '*.node' \\) -print | head -60; ls ${A}.unpacked/node_modules 2>/dev/null; rg -uu -l --glob '!node_modules' 'exposeInMainWorld' $X\n```\nThen slice the needle across the bundle: `rg -uu -o --glob '!node_modules' '.{0,250}NEEDLE.{0,250}' $X | head -20`.\n\nGo: `go version -m T` alone usually answers the question.\n\n## Router\n| Target (detect) | Fastest path |\n|---|---|\n| Electron app (`*.app/Contents/Resources/app.asar`) | `npx -y @electron/asar extract app.asar X` (also see `app.asar.unpacked/` for `.node` addons). Entry point: `jq .main X/package.json`. Surface: `rg -n -o '.{0,120}(ipcMain\\.(handle|handleOnce|on|once)|ipcRenderer\\.(invoke|send|sendSync|on)|contextBridge\\.exposeIn(Main|Isolated)World|webPreferences|preload:|nodeIntegration|contextIsolation|sandbox|\\.node\\b).{0,160}' -uu X --glob '!node_modules'`. App-specific IPC wrappers often hide the channels, so also run `rg -uu -o '\"[a-z]+:[a-z0-9:-]+\"' X/\u003cmain> \\| sort -u`. Fuses: `npx -y @electron/fuses read --app A.app`. |\n| Web bundle / minified JS | Find `sourceMappingURL`. If the map has `sourcesContent`, dump the sources: `jq -r '.sources[]'`. For webpack, grep the module ids, then slice around the hit. For pretty-print: `npx -y prettier --parser babel F > F.pretty.js`, then read with line ranges. |\n| Hermes / bytenode / V8 snapshot | Hermes magic is `c6 1f bc 03` (`index.android.bundle`): use `hermes-dec` / `hbc-decompiler`. `.jsc` (bytenode) cannot be decompiled: use strings and runtime hooks. |\n| Mach-O (`file`: Mach-O) | `lipo -info` (thin first: `lipo -thin arm64 -o T1 T`). Then: `otool -L` (libs); `xcrun dyld_info -exports -imports`; `nm -gU` (exports) / `nm -u` (imports = the capability map); `strings -a -n 6`; `otool -l \\| rg -A3 'LC_(RPATH\\|BUILD_VERSION)'`; `codesign -d --entitlements :- T`; `otool -ov` (ObjC classes/methods); `xcrun swift-demangle --compact`. |\n| Native code logic | `otool -tV T > $D/dis.txt` (or `llvm-objdump -d --no-show-raw-insn -C`). Find the function: `rg -n '^_?.*Name.*:

leanrea: fast path You already know these tools. This file only lists the fastest command for each target, and the traps. Rules - Work on a copy ( on APFS is instant). Put each extraction in a new dir under . Reuse an extraction if one exists. - Route by and the magic bytes first. Run the cheapest inventory next. Only then decompile or read code. - skips hidden and ignored files, and bundlers hide code (Electron: , ). Always search extracted trees with . - Never a big or minified file. Slice it: . Dump a disassembly once to a file, then grep that file. - Batch independent probes into ONE shel…

`. Read the call/string trail: `awk '/^FUNC:/{p=1} p&&/^[_a-zA-Z].*:$/&&!/FUNC/{exit} p' dis.txt \\| rg 'bl\\|call\\|literal\\|cmp'`. otool labels string literals and stubs inline, which is often enough. Only for real pseudocode: Ghidra `analyzeHeadless $D p -import T -postScript DecompileAll.java -deleteProject` or `r2 -qc 'aaa; pdc @ sym.X' T`. |\n| ELF / PE | `readelf -hlSW`, `readelf -dW` (NEEDED), `nm -D --defined-only`, `objdump -d -M intel`. PE: `objdump -x`, `pefile`/`wrestool` for resources. checksec: `pwn checksec`. |\n| Go (`__go_buildinfo`, `.go.buildinfo`) | `go version -m T` gives the toolchain, path, mod, deps and build flags in one call. Without Go: `strings -a T \\| rg -m1 -A200 'Go buildinf' `. Symbols survive stripping: `go tool nm T \\| rg main\\.`. |\n| Rust | Deps (cargo-auditable): `cargo audit bin T`, or extract `.dep-v0` / `__DATA,.dep-v0` and zlib-inflate it. Compiler: `strings -a T \\| rg -o '/rustc/[0-9a-f]{40}' \\| sort -u`. Crates from paths: `strings -a T \\| rg -o '[a-z0-9_-]+-[0-9]+\\.[0-9]+\\.[0-9]+/src' \\| sort -u`. |\n| .NET (`file`: Mono/.Net) | `ilspycmd -p -o X T.dll` (install: `dotnet tool install -g ilspycmd`), then `rg`. P/Invoke: `rg DllImport X`. NativeAOT/IL2CPP are native: use the native rows. |\n| Android APK | `jadx -d X --show-bad-code a.apk` then `rg`. Resources/manifest only: `apktool d --no-src -o X a.apk`. Quick look: `unzip -l a.apk`. `lib/*/libflutter.so` means Flutter (Dart AOT: `blutter`); `libhermes.so` means React Native (Hermes row). |\n| Flutter snapshot hash | In `libapp.so`, find magic `f5 f5 dc dc`; the 32 hex chars at +20 are the snapshot hash. Map it to a Dart version. |\n| WASM | `wasm-objdump -x`, `wasm2wat`, `wasm-decompile` (WABT). |\n| SQLite | Copy the db, plus the `-wal` file if present. `sqlite3 'file:C?mode=ro' '.schema'`, then `SELECT * FROM t LIMIT 20`. |\n| plist / nib / car | `plutil -p F`. Info.plist holds the bundle id, URL schemes and privacy strings. Asset catalogs: `assetutil --info Assets.car`. |\n| pcap / HAR | `tshark -r C -q -z conv,tcp`; `tshark -r C -T fields -e dns.qry.name -e tls.handshake.extensions_server_name -e http.request.full_uri \\| sort -u`. HAR: `jq -r '.log.entries[].request \\| .method+\" \"+.url'`. |\n| Firmware | `binwalk -e F` or `unblob -e X F`. Then route each extracted binary through this table. |\n| Website | `curl -sL URL` for the HTML and script srcs, then fetch the JS and slice it. For runtime behavior, use a headless browser with a network log (Playwright `page.on('request')`) or Chrome `--remote-debugging-port`. |\n| Running app / runtime | macOS: `lldb -p PID`, `dtrace`/`fs_usage`/`log stream --predicate 'process==\"X\"'`. Electron main: `--inspect` (only if the RunAsNode/inspect fuses allow it). Android: `adb logcat`, `frida -U -f pkg -l hook.js`. |\n\n## Speed patterns\n- Strings and imports first. On a small binary, `nm -u` + `strings` + the export list usually answer \"what does it do\" with no disassembly.\n- To find who uses a string: get its address from `otool -tV` \"literal pool for\" comments, or `rg -n 'literal pool for: \"X'`. Then find the enclosing function label above that line.\n- A C++ name in a `bl` target already tells you the protocol (for example `getpeereid`, `write`, `std::hash`). Read the call sequence, not every instruction.\n- For JS, go from the native/JS boundary inward: find the native call, then its caller class, then the IPC registration, then the renderer/preload.\n- Comparing versions: diff the inventories (`nm`, the module list, `go version -m`) before you diff any code.\n- Rebuilding: write the minimal reimplementation, then test it against the original (same inputs, same outputs).\n\n## Install (only on request)\n`brew install jadx apktool radare2 binwalk wabt wireshark ghidra` · `npm i -g @electron/asar` · `dotnet tool install -g ilspycmd` · `cargo install cargo-audit`.","attachment_filenames":[],"attachments":[],"content_json":{"type":"doc","content":[{"type":"heading","attrs":{"level":1},"content":[{"text":"leanrea: fast path","type":"text"}]},{"type":"paragraph","content":[{"text":"You already know these tools. This file only lists the fastest command for each target, and the traps.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Rules","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Work on a copy (","type":"text"},{"text":"cp -c","type":"text","marks":[{"type":"code_inline"}]},{"text":" on APFS is instant). Put each extraction in a new dir under ","type":"text"},{"text":"$TMPDIR/re/\u003cname>","type":"text","marks":[{"type":"code_inline"}]},{"text":". Reuse an extraction if one exists.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Route by ","type":"text"},{"text":"file -b T","type":"text","marks":[{"type":"code_inline"}]},{"text":" and the magic bytes first. Run the cheapest inventory next. Only then decompile or read code.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"rg","type":"text","marks":[{"type":"code_inline"}]},{"text":" skips hidden and ignored files, and bundlers hide code (Electron: ","type":"text"},{"text":".webpack/","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":".vite/","type":"text","marks":[{"type":"code_inline"}]},{"text":"). Always search extracted trees with ","type":"text"},{"text":"rg -uu","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Never ","type":"text"},{"text":"cat","type":"text","marks":[{"type":"code_inline"}]},{"text":" a big or minified file. Slice it: ","type":"text"},{"text":"rg -o '.{0,200}NEEDLE.{0,200}' F | head","type":"text","marks":[{"type":"code_inline"}]},{"text":". Dump a disassembly once to a file, then grep that file.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Batch independent probes into ONE shell call with ","type":"text"},{"text":";","type":"text","marks":[{"type":"code_inline"}]},{"text":" and ","type":"text"},{"text":"echo '--- name'","type":"text","marks":[{"type":"code_inline"}]},{"text":" markers (quoted: zsh expands a bare ","type":"text"},{"text":"==x","type":"text","marks":[{"type":"code_inline"}]},{"text":"). Cap every output with ","type":"text"},{"text":"head","type":"text","marks":[{"type":"code_inline"}]},{"text":" or ","type":"text"},{"text":"-m","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Answer from evidence. In the answer, mark each claim as ","type":"text"},{"text":"seen","type":"text","marks":[{"type":"strong"}]},{"text":" (cite file:offset, or a symbol/string) or ","type":"text"},{"text":"inferred","type":"text","marks":[{"type":"strong"}]},{"text":". A fact you did not find is ","type":"text"},{"text":"unknown","type":"text","marks":[{"type":"strong"}]},{"text":", not \"absent\". Static reading is not observed execution.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"A missing tool is not a blocker. Use the fallback in the same row, or ","type":"text"},{"text":"brew install \u003cx>","type":"text","marks":[{"type":"code_inline"}]},{"text":" if the user allows it.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Turns cost more than bytes. Aim for 2–4 tool calls: one batched recon call, one or two targeted slices, then answer. Stop when every item you were asked has evidence. Do not re-verify what you already saw.","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"First move: one call each, paste and run","type":"text"}]},{"type":"paragraph","content":[{"text":"Native (Mach-O):","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"sh"},"content":[{"text":"T=./bin; D=$TMPDIR/re/$(basename $T); mkdir -p $D; file $T; lipo -info $T; otool -L $T; echo '--- EXPORTS'; nm -gU $T | head -150; echo '--- IMPORTS'; nm -u $T | rg -v '^__Z|napi_' | tr '\\n' ' '; echo; echo '--- STRINGS'; strings -a -n 6 $T | rg -v '^[_$.]' | head -400; otool -tV $T > $D/dis.txt; echo '--- FUNCS'; rg '^[_a-zA-Z].*:

leanrea: fast path You already know these tools. This file only lists the fastest command for each target, and the traps. Rules - Work on a copy ( on APFS is instant). Put each extraction in a new dir under . Reuse an extraction if one exists. - Route by and the magic bytes first. Run the cheapest inventory next. Only then decompile or read code. - skips hidden and ignored files, and bundlers hide code (Electron: , ). Always search extracted trees with . - Never a big or minified file. Slice it: . Dump a disassembly once to a file, then grep that file. - Batch independent probes into ONE shel…

$D/dis.txt | rg -v '^_?_?Z?N?St3' | head -150","type":"text"}]},{"type":"paragraph","content":[{"text":"Then read one function: ","type":"text"},{"text":"awk '/^FUNC_LABEL:$/{p=1;next} p&&/^[_a-zA-Z].*:$/{exit} p' $D/dis.txt | rg 'bl|b\\.|cmp|literal|mov\\s+w2'","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]},{"type":"paragraph","content":[{"text":"Electron:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"sh"},"content":[{"text":"A=./app.asar; X=$TMPDIR/re/asar; rm -rf $X; npx -y @electron/asar extract $A $X && jq '{name,version,main}' $X/package.json; find $X -path '*/node_modules' -prune -o -type f \\( -name '*.js' -o -name '*.node' \\) -print | head -60; ls ${A}.unpacked/node_modules 2>/dev/null; rg -uu -l --glob '!node_modules' 'exposeInMainWorld' $X","type":"text"}]},{"type":"paragraph","content":[{"text":"Then slice the needle across the bundle: ","type":"text"},{"text":"rg -uu -o --glob '!node_modules' '.{0,250}NEEDLE.{0,250}' $X | head -20","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]},{"type":"paragraph","content":[{"text":"Go: ","type":"text"},{"text":"go version -m T","type":"text","marks":[{"type":"code_inline"}]},{"text":" alone usually answers the question.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Router","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Target (detect)","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Fastest path","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Electron app (","type":"text"},{"text":"*.app/Contents/Resources/app.asar","type":"text","marks":[{"type":"code_inline"}]},{"text":")","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"npx -y @electron/asar extract app.asar X","type":"text","marks":[{"type":"code_inline"}]},{"text":" (also see ","type":"text"},{"text":"app.asar.unpacked/","type":"text","marks":[{"type":"code_inline"}]},{"text":" for ","type":"text"},{"text":".node","type":"text","marks":[{"type":"code_inline"}]},{"text":" addons). Entry point: ","type":"text"},{"text":"jq .main X/package.json","type":"text","marks":[{"type":"code_inline"}]},{"text":". Surface: `rg -n -o '.{0,120}(ipcMain.(handle","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Web bundle / minified JS","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Find ","type":"text"},{"text":"sourceMappingURL","type":"text","marks":[{"type":"code_inline"}]},{"text":". If the map has ","type":"text"},{"text":"sourcesContent","type":"text","marks":[{"type":"code_inline"}]},{"text":", dump the sources: ","type":"text"},{"text":"jq -r '.sources[]'","type":"text","marks":[{"type":"code_inline"}]},{"text":". For webpack, grep the module ids, then slice around the hit. For pretty-print: ","type":"text"},{"text":"npx -y prettier --parser babel F > F.pretty.js","type":"text","marks":[{"type":"code_inline"}]},{"text":", then read with line ranges.","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Hermes / bytenode / V8 snapshot","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Hermes magic is ","type":"text"},{"text":"c6 1f bc 03","type":"text","marks":[{"type":"code_inline"}]},{"text":" (","type":"text"},{"text":"index.android.bundle","type":"text","marks":[{"type":"code_inline"}]},{"text":"): use ","type":"text"},{"text":"hermes-dec","type":"text","marks":[{"type":"code_inline"}]},{"text":" / ","type":"text"},{"text":"hbc-decompiler","type":"text","marks":[{"type":"code_inline"}]},{"text":". ","type":"text"},{"text":".jsc","type":"text","marks":[{"type":"code_inline"}]},{"text":" (bytenode) cannot be decompiled: use strings and runtime hooks.","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Mach-O (","type":"text"},{"text":"file","type":"text","marks":[{"type":"code_inline"}]},{"text":": Mach-O)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"lipo -info","type":"text","marks":[{"type":"code_inline"}]},{"text":" (thin first: ","type":"text"},{"text":"lipo -thin arm64 -o T1 T","type":"text","marks":[{"type":"code_inline"}]},{"text":"). Then: ","type":"text"},{"text":"otool -L","type":"text","marks":[{"type":"code_inline"}]},{"text":" (libs); ","type":"text"},{"text":"xcrun dyld_info -exports -imports","type":"text","marks":[{"type":"code_inline"}]},{"text":"; ","type":"text"},{"text":"nm -gU","type":"text","marks":[{"type":"code_inline"}]},{"text":" (exports) / ","type":"text"},{"text":"nm -u","type":"text","marks":[{"type":"code_inline"}]},{"text":" (imports = the capability map); ","type":"text"},{"text":"strings -a -n 6","type":"text","marks":[{"type":"code_inline"}]},{"text":"; ","type":"text"},{"text":"otool -l | rg -A3 'LC_(RPATH|BUILD_VERSION)'","type":"text","marks":[{"type":"code_inline"}]},{"text":"; ","type":"text"},{"text":"codesign -d --entitlements :- T","type":"text","marks":[{"type":"code_inline"}]},{"text":"; ","type":"text"},{"text":"otool -ov","type":"text","marks":[{"type":"code_inline"}]},{"text":" (ObjC classes/methods); ","type":"text"},{"text":"xcrun swift-demangle --compact","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Native code logic","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"otool -tV T > $D/dis.txt","type":"text","marks":[{"type":"code_inline"}]},{"text":" (or ","type":"text"},{"text":"llvm-objdump -d --no-show-raw-insn -C","type":"text","marks":[{"type":"code_inline"}]},{"text":"). Find the function: ","type":"text"},{"text":"rg -n '^_?.*Name.*:

leanrea: fast path You already know these tools. This file only lists the fastest command for each target, and the traps. Rules - Work on a copy ( on APFS is instant). Put each extraction in a new dir under . Reuse an extraction if one exists. - Route by and the magic bytes first. Run the cheapest inventory next. Only then decompile or read code. - skips hidden and ignored files, and bundlers hide code (Electron: , ). Always search extracted trees with . - Never a big or minified file. Slice it: . Dump a disassembly once to a file, then grep that file. - Batch independent probes into ONE shel…

","type":"text","marks":[{"type":"code_inline"}]},{"text":". Read the call/string trail: ","type":"text"},{"text":"awk '/^FUNC:/{p=1} p&&/^[_a-zA-Z].*:$/&&!/FUNC/{exit} p' dis.txt | rg 'bl|call|literal|cmp'","type":"text","marks":[{"type":"code_inline"}]},{"text":". otool labels string literals and stubs inline, which is often enough. Only for real pseudocode: Ghidra ","type":"text"},{"text":"analyzeHeadless $D p -import T -postScript DecompileAll.java -deleteProject","type":"text","marks":[{"type":"code_inline"}]},{"text":" or ","type":"text"},{"text":"r2 -qc 'aaa; pdc @ sym.X' T","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"ELF / PE","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"readelf -hlSW","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"readelf -dW","type":"text","marks":[{"type":"code_inline"}]},{"text":" (NEEDED), ","type":"text"},{"text":"nm -D --defined-only","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"objdump -d -M intel","type":"text","marks":[{"type":"code_inline"}]},{"text":". PE: ","type":"text"},{"text":"objdump -x","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"pefile","type":"text","marks":[{"type":"code_inline"}]},{"text":"/","type":"text"},{"text":"wrestool","type":"text","marks":[{"type":"code_inline"}]},{"text":" for resources. checksec: ","type":"text"},{"text":"pwn checksec","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Go (","type":"text"},{"text":"__go_buildinfo","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":".go.buildinfo","type":"text","marks":[{"type":"code_inline"}]},{"text":")","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"go version -m T","type":"text","marks":[{"type":"code_inline"}]},{"text":" gives the toolchain, path, mod, deps and build flags in one call. Without Go: ","type":"text"},{"text":"strings -a T | rg -m1 -A200 'Go buildinf' ","type":"text","marks":[{"type":"code_inline"}]},{"text":". Symbols survive stripping: ","type":"text"},{"text":"go tool nm T | rg main\\.","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Rust","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Deps (cargo-auditable): ","type":"text"},{"text":"cargo audit bin T","type":"text","marks":[{"type":"code_inline"}]},{"text":", or extract ","type":"text"},{"text":".dep-v0","type":"text","marks":[{"type":"code_inline"}]},{"text":" / ","type":"text"},{"text":"__DATA,.dep-v0","type":"text","marks":[{"type":"code_inline"}]},{"text":" and zlib-inflate it. Compiler: ","type":"text"},{"text":"strings -a T | rg -o '/rustc/[0-9a-f]{40}' | sort -u","type":"text","marks":[{"type":"code_inline"}]},{"text":". Crates from paths: ","type":"text"},{"text":"strings -a T | rg -o '[a-z0-9_-]+-[0-9]+\\.[0-9]+\\.[0-9]+/src' | sort -u","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":".NET (","type":"text"},{"text":"file","type":"text","marks":[{"type":"code_inline"}]},{"text":": Mono/.Net)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"ilspycmd -p -o X T.dll","type":"text","marks":[{"type":"code_inline"}]},{"text":" (install: ","type":"text"},{"text":"dotnet tool install -g ilspycmd","type":"text","marks":[{"type":"code_inline"}]},{"text":"), then ","type":"text"},{"text":"rg","type":"text","marks":[{"type":"code_inline"}]},{"text":". P/Invoke: ","type":"text"},{"text":"rg DllImport X","type":"text","marks":[{"type":"code_inline"}]},{"text":". NativeAOT/IL2CPP are native: use the native rows.","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Android APK","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"jadx -d X --show-bad-code a.apk","type":"text","marks":[{"type":"code_inline"}]},{"text":" then ","type":"text"},{"text":"rg","type":"text","marks":[{"type":"code_inline"}]},{"text":". Resources/manifest only: ","type":"text"},{"text":"apktool d --no-src -o X a.apk","type":"text","marks":[{"type":"code_inline"}]},{"text":". Quick look: ","type":"text"},{"text":"unzip -l a.apk","type":"text","marks":[{"type":"code_inline"}]},{"text":". ","type":"text"},{"text":"lib/*/libflutter.so","type":"text","marks":[{"type":"code_inline"}]},{"text":" means Flutter (Dart AOT: ","type":"text"},{"text":"blutter","type":"text","marks":[{"type":"code_inline"}]},{"text":"); ","type":"text"},{"text":"libhermes.so","type":"text","marks":[{"type":"code_inline"}]},{"text":" means React Native (Hermes row).","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Flutter snapshot hash","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"In ","type":"text"},{"text":"libapp.so","type":"text","marks":[{"type":"code_inline"}]},{"text":", find magic ","type":"text"},{"text":"f5 f5 dc dc","type":"text","marks":[{"type":"code_inline"}]},{"text":"; the 32 hex chars at +20 are the snapshot hash. Map it to a Dart version.","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"WASM","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"wasm-objdump -x","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"wasm2wat","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"wasm-decompile","type":"text","marks":[{"type":"code_inline"}]},{"text":" (WABT).","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"SQLite","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Copy the db, plus the ","type":"text"},{"text":"-wal","type":"text","marks":[{"type":"code_inline"}]},{"text":" file if present. ","type":"text"},{"text":"sqlite3 'file:C?mode=ro' '.schema'","type":"text","marks":[{"type":"code_inline"}]},{"text":", then ","type":"text"},{"text":"SELECT * FROM t LIMIT 20","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"plist / nib / car","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"plutil -p F","type":"text","marks":[{"type":"code_inline"}]},{"text":". Info.plist holds the bundle id, URL schemes and privacy strings. Asset catalogs: ","type":"text"},{"text":"assetutil --info Assets.car","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"pcap / HAR","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"tshark -r C -q -z conv,tcp","type":"text","marks":[{"type":"code_inline"}]},{"text":"; ","type":"text"},{"text":"tshark -r C -T fields -e dns.qry.name -e tls.handshake.extensions_server_name -e http.request.full_uri | sort -u","type":"text","marks":[{"type":"code_inline"}]},{"text":". HAR: ","type":"text"},{"text":"jq -r '.log.entries[].request | .method+\" \"+.url'","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Firmware","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"binwalk -e F","type":"text","marks":[{"type":"code_inline"}]},{"text":" or ","type":"text"},{"text":"unblob -e X F","type":"text","marks":[{"type":"code_inline"}]},{"text":". Then route each extracted binary through this table.","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Website","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"curl -sL URL","type":"text","marks":[{"type":"code_inline"}]},{"text":" for the HTML and script srcs, then fetch the JS and slice it. For runtime behavior, use a headless browser with a network log (Playwright ","type":"text"},{"text":"page.on('request')","type":"text","marks":[{"type":"code_inline"}]},{"text":") or Chrome ","type":"text"},{"text":"--remote-debugging-port","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Running app / runtime","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"macOS: ","type":"text"},{"text":"lldb -p PID","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"dtrace","type":"text","marks":[{"type":"code_inline"}]},{"text":"/","type":"text"},{"text":"fs_usage","type":"text","marks":[{"type":"code_inline"}]},{"text":"/","type":"text"},{"text":"log stream --predicate 'process==\"X\"'","type":"text","marks":[{"type":"code_inline"}]},{"text":". Electron main: ","type":"text"},{"text":"--inspect","type":"text","marks":[{"type":"code_inline"}]},{"text":" (only if the RunAsNode/inspect fuses allow it). Android: ","type":"text"},{"text":"adb logcat","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"frida -U -f pkg -l hook.js","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Speed patterns","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Strings and imports first. On a small binary, ","type":"text"},{"text":"nm -u","type":"text","marks":[{"type":"code_inline"}]},{"text":" + ","type":"text"},{"text":"strings","type":"text","marks":[{"type":"code_inline"}]},{"text":" + the export list usually answer \"what does it do\" with no disassembly.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"To find who uses a string: get its address from ","type":"text"},{"text":"otool -tV","type":"text","marks":[{"type":"code_inline"}]},{"text":" \"literal pool for\" comments, or ","type":"text"},{"text":"rg -n 'literal pool for: \"X'","type":"text","marks":[{"type":"code_inline"}]},{"text":". Then find the enclosing function label above that line.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"A C++ name in a ","type":"text"},{"text":"bl","type":"text","marks":[{"type":"code_inline"}]},{"text":" target already tells you the protocol (for example ","type":"text"},{"text":"getpeereid","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"write","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"std::hash","type":"text","marks":[{"type":"code_inline"}]},{"text":"). Read the call sequence, not every instruction.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"For JS, go from the native/JS boundary inward: find the native call, then its caller class, then the IPC registration, then the renderer/preload.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Comparing versions: diff the inventories (","type":"text"},{"text":"nm","type":"text","marks":[{"type":"code_inline"}]},{"text":", the module list, ","type":"text"},{"text":"go version -m","type":"text","marks":[{"type":"code_inline"}]},{"text":") before you diff any code.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Rebuilding: write the minimal reimplementation, then test it against the original (same inputs, same outputs).","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Install (only on request)","type":"text"}]},{"type":"paragraph","content":[{"text":"brew install jadx apktool radare2 binwalk wabt wireshark ghidra","type":"text","marks":[{"type":"code_inline"}]},{"text":" · ","type":"text"},{"text":"npm i -g @electron/asar","type":"text","marks":[{"type":"code_inline"}]},{"text":" · ","type":"text"},{"text":"dotnet tool install -g ilspycmd","type":"text","marks":[{"type":"code_inline"}]},{"text":" · ","type":"text"},{"text":"cargo install cargo-audit","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]}]},"metadata":{"date":"2026-11-02","name":"leanrea","author":"@skillopedia","source":{"stars":3916,"repo_name":"leanrea","origin_url":"https://github.com/aicodeking/leanrea/blob/HEAD/leanrea/SKILL.md","repo_owner":"aicodeking","body_sha256":"53581bd7fb1fae4352ab43252e67b84667b68895a68e372b99d302b58d9c782d","cluster_key":"852eb9aff3bc867720b127fb9ac51f9062e5d7afc95eeb309e0e12e6e0747286","clean_bundle":{"format":"clean-skill-bundle-v1","source":"aicodeking/leanrea/leanrea/SKILL.md","text_bytes":0,"source_commit":"09ba4aa0217f82cd880f855a60b877f59f39b22b","skills_sh_rank":7560,"attachment_count":0,"text_attachments":0,"attachment_storage":"skill_attachments","binary_attachments":0},"cluster_size":1,"skill_md_path":"leanrea/SKILL.md","import_metadata":{"date":"2026-11-02","author":"@skillopedia","version":"v1","category":"security","category_label":"Security"},"exact_dupes_collapsed_into_this":0},"version":"v1","category":"security","import_tag":"skills-sh-top20k-2026-11","description":"Reverse engineer shipped software with plain local CLI tools, no MCP needed. Covers Electron/JS bundles, native Mach-O/ELF/PE, Go/Rust/.NET/Flutter/WASM binaries, APKs, SQLite, pcaps, firmware and websites. Use to explain how a feature works, extract versions/deps, compare builds, or rebuild a feature."}},"renderedAt":1793661387413}

leanrea: fast path You already know these tools. This file only lists the fastest command for each target, and the traps. Rules - Work on a copy ( on APFS is instant). Put each extraction in a new dir under . Reuse an extraction if one exists. - Route by and the magic bytes first. Run the cheapest inventory next. Only then decompile or read code. - skips hidden and ignored files, and bundlers hide code (Electron: , ). Always search extracted trees with . - Never a big or minified file. Slice it: . Dump a disassembly once to a file, then grep that file. - Batch independent probes into ONE shel…