leanrea: schneller Pfad
Diese Tools kennen Sie bereits. In dieser Datei sind nur der schnellste Befehl für jedes Ziel und die Fallstricke aufgeführt.
Regeln
- Arbeiten Sie an einer Kopie (
cp -cauf APFS ist sofort). Legen Sie jede Extraktion in einem neuen Verzeichnis unter$TMPDIR/re/<name>an. Verwenden Sie eine vorhandene Extraktion wieder, falls vorhanden. - Routen Sie zuerst mit
file -b Tund den magischen Bytes. Führen Sie als nächstes die günstigste Bestandsaufnahme durch. Erst dann dekompilieren oder Code lesen. rgüberspringt versteckte und ignorierte Dateien, und Bundler verstecken Code (Electron:.webpack/,.vite/). Durchsuchen Sie extrahierte Bäume immer mitrg -uu.- Verwenden Sie niemals
catfür eine große oder minimierte Datei. Schneiden Sie sie:rg -o '.{0,200}NEEDLE.{0,200}' F | head. Schreiben Sie eine Disassemblierung einmal in eine Datei, dann durchsuchen Sie diese Datei mit grep. - Bündeln Sie unabhängige Sondierungen in EINEN Shell-Aufruf mit
;undecho '--- name'-Markierungen (in Anführungszeichen: zsh expandiert ein bloßes==x). Begrenzen Sie jede Ausgabe mitheadoder-m. - Antworten Sie mit Beweisen. Markieren Sie in der Antwort jede Behauptung als gesehen (mit Datei:Offset oder einem Symbol/String) oder abgeleitet. Eine Tatsache, die Sie nicht gefunden haben, ist unbekannt, nicht „nicht vorhanden“. Statisches Lesen ist keine beobachtete Ausführung.
- Ein fehlendes Tool ist kein Hindernis. Verwenden Sie den Fallback in derselben Zeile oder
brew install <x>, wenn der Benutzer es erlaubt. - Tool-Aufrufe kosten mehr als Bytes. Zielen Sie auf 2–4 Tool-Aufrufe: einen gebündelten Recon-Aufruf, ein oder zwei gezielte Schnitte, dann antworten. Hören Sie auf, wenn für jedes angefragte Element Beweise vorliegen. Verifizieren Sie nicht erneut, was Sie bereits gesehen haben.
Erster Schritt: ein Aufruf pro Ziel, einfügen und ausführen
Native (Mach-O):
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].*:$' $D/dis.txt | rg -v '^_?_?Z?N?St3' | head -150
Dann lesen Sie eine Funktion: awk '/^FUNC_LABEL:$/{p=1;next} p&&/^[_a-zA-Z].*:$/{exit} p' $D/dis.txt | rg 'bl|b\.|cmp|literal|mov\s+w2'.
Electron:
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
Dann schneiden Sie die Nadel über das Bundle: rg -uu -o --glob '!node_modules' '.{0,250}NEEDLE.{0,250}' $X | head -20.
Go: go version -m T allein beantwortet normalerweise die Frage.
Router
| Ziel (erkennen) | Schnellster Pfad |
|---|---|
Electron-App (*.app/Contents/Resources/app.asar) | npx -y @electron/asar extract app.asar X (auch app.asar.unpacked/ für .node-Addons sehen). Einstiegspunkt: jq .main X/package.json. Oberfläche: `rg -n -o '.{0,120}(ipcMain.(handle |
| Web-Bundle / minifiziertes JS | sourceMappingURL finden. Wenn die Map sourcesContent hat, die Quellen ausgeben: jq -r '.sources[]'. Für webpack: die Modul-IDs durchsuchen, dann um den Treffer herum schneiden. Für Pretty-Print: npx -y prettier --parser babel F > F.pretty.js, dann mit Zeilenbereichen lesen. |
| Hermes / bytenode / V8-Snapshot | Hermes-Magie ist c6 1f bc 03 (index.android.bundle): hermes-dec / hbc-decompiler verwenden. .jsc (bytenode) kann nicht dekompiliert werden: Strings und Laufzeit-Hooks verwenden. |
Mach-O (file: Mach-O) | lipo -info (zuerst thin: lipo -thin arm64 -o T1 T). Dann: otool -L (Bibliotheken); xcrun dyld_info -exports -imports; nm -gU (Exporte) / nm -u (Importe = die Fähigkeitskarte); strings -a -n 6; `otool -l |
| Nativer Code / Logik | otool -tV T > $D/dis.txt (oder llvm-objdump -d --no-show-raw-insn -C). Die Funktion finden: rg -n '^_?.*Name.*:$'. Den Call-/String-Pfad lesen: `awk '/^FUNC:/{p=1} p&&/^[_a-zA-Z].*:$/&&!/FUNC/{exit} p' dis.txt |
| ELF / PE | readelf -hlSW, readelf -dW (NEEDED), nm -D --defined-only, objdump -d -M intel. PE: objdump -x, pefile/wrestool für Ressourcen. checksec: pwn checksec. |
Go (__go_buildinfo, .go.buildinfo) | go version -m T liefert Toolchain, Pfad, Mod, Abhängigkeiten und Build-Flags in einem Aufruf. Ohne Go: `strings -a T |
| Rust | Abhängigkeiten (cargo-auditable): cargo audit bin T, oder .dep-v0 / __DATA,.dep-v0 extrahieren und zlib-inflaten. Compiler: `strings -a T |
.NET (file: Mono/.Net) | ilspycmd -p -o X T.dll (Installation: dotnet tool install -g ilspycmd), dann rg. P/Invoke: rg DllImport X. NativeAOT/IL2CPP sind nativ: die nativen Zeilen verwenden. |
| Android APK | jadx -d X --show-bad-code a.apk dann rg. Nur Ressourcen/Manifest: apktool d --no-src -o X a.apk. Schnellansicht: unzip -l a.apk. lib/*/libflutter.so bedeutet Flutter (Dart AOT: blutter); libhermes.so bedeutet React Native (Hermes-Zeile). |
| Flutter-Snapshot-Hash | In libapp.so die Magie f5 f5 dc dc finden; die 32 Hex-Zeichen bei +20 sind der Snapshot-Hash. Einer Dart-Version zuordnen. |
| WASM | wasm-objdump -x, wasm2wat, wasm-decompile (WABT). |
| SQLite | Die DB kopieren, plus die -wal-Datei falls vorhanden. sqlite3 'file:C?mode=ro' '.schema', dann SELECT * FROM t LIMIT 20. |
| plist / nib / car | plutil -p F. Info.plist enthält die Bundle-ID, URL-Schemata und Datenschutz-Strings. Asset-Kataloge: assetutil --info Assets.car. |
| 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 |
| Firmware | binwalk -e F oder unblob -e X F. Dann jeden extrahierten Binärcode durch diese Tabelle routen. |
| Website | curl -sL URL für das HTML und die Skript-quellen, dann das JS holen und schneiden. Für Laufzeitverhalten einen Headless-Browser mit Netzwerk-Log verwenden (Playwright page.on('request')) oder Chrome --remote-debugging-port. |
| Laufende App / Runtime | macOS: lldb -p PID, dtrace/fs_usage/log stream --predicate 'process=="X"'. Electron main: --inspect (nur wenn die RunAsNode/inspect-Fuses es erlauben). Android: adb logcat, frida -U -f pkg -l hook.js. |
Geschwindigkeitsmuster
- Strings und Importe zuerst. Bei einem kleinen Binary beantworten
nm -u+strings+ die Exportliste normalerweise „was macht es“ ohne Disassemblierung. - Um herauszufinden, wer einen String verwendet: seine Adresse aus den
otool -tV„literal pool for“-Kommentaren holen, oderrg -n 'literal pool for: "X'. Dann die umschließende Funktionsbezeichnung oberhalb dieser Zeile finden. - Ein C++-Name in einem
bl-Ziel verrät bereits das Protokoll (z. B.getpeereid,write,std::hash). Lesen Sie die Aufrufsequenz, nicht jede Anweisung. - Bei JS von der nativen/JS-Grenze nach innen vorgehen: den nativen Aufruf finden, dann seine Aufrufer-Klasse, dann die IPC-Registrierung, dann den Renderer/Preload.
- Versionen vergleichen: die Bestandsaufnahmen differenzieren (
nm, die Modul-Liste,go version -m), bevor Sie Code differenzieren. - Wiederaufbau: die minimale Neuimplementierung schreiben, dann gegen das Original testen (gleiche Eingaben, gleiche Ausgaben).
Installation (nur auf Anfrage)
brew install jadx apktool radare2 binwalk wabt wireshark ghidra · npm i -g @electron/asar · dotnet tool install -g ilspycmd · cargo install cargo-audit.