leanrea: 高速パス
あなたは既にこれらのツールを知っています。このファイルは、各ターゲットに対する最速のコマンドと落とし穴のみをリストします。
ルール
- コピー上で作業する(APFS では
cp -cは瞬時です)。各抽出結果は$TMPDIR/re/<name>の下に新しいディレクトリに配置します。既存の抽出結果があれば再利用します。 - まず
file -b Tとマジックバイトでルーティングします。次に最も安価なインベントリを実行します。その後でのみデコンパイルまたはコード読み取りを行います。 rgは隠しファイルと無視ファイルをスキップし、バンドラーはコードを隠します(Electron:.webpack/、.vite/)。抽出したツリーは常にrg -uuで検索します。- 大きなファイルや minify されたファイルには決して
catを使わないでください。スライスします:rg -o '.{0,200}NEEDLE.{0,200}' F | head。逆アセンブルは一度ファイルにダンプし、そのファイルを grep します。 - 独立したプローブは、
;とecho '--- name'マーカーを使って1つのシェル呼び出しにまとめます(引用符で囲む: zsh は裸の==xを展開します)。すべての出力はheadまたは-mで制限します。 - 証拠に基づいて回答します。回答では、各主張を 確認済み(ファイル:オフセット、またはシンボル/文字列を引用)または 推測 としてマークします。見つからなかった事実は 不明 であり、「存在しない」ではありません。静的読み取りは実行の観測ではありません。
- ツールが不足していても障害にはなりません。同じ行の代替手段を使用するか、ユーザーが許可すれば
brew install <x>を実行します。 - ターン数はバイト数よりもコストがかかります。2~4回のツール呼び出しを目指します: 1回のバッチ化された偵察呼び出し、1~2回のターゲットスライス、そして回答。依頼されたすべての項目に証拠が揃った時点で停止します。既に見たものを再検証しないでください。
最初の一手: 各1回の呼び出し、貼り付けて実行
ネイティブ (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
次に関数を1つ読む: 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
次にバンドル内のニードルをスライス: rg -uu -o --glob '!node_modules' '.{0,250}NEEDLE.{0,250}' $X | head -20。
Go: go version -m T だけで通常は質問に答えられます。
ルーター
| ターゲット (検出方法) | 最速パス |
|---|---|
Electron アプリ (*.app/Contents/Resources/app.asar) | npx -y @electron/asar extract app.asar X (.node アドオンについては app.asar.unpacked/ も参照)。エントリポイント: jq .main X/package.json。表面: `rg -n -o '.{0,120}(ipcMain.(handle |
| Web バンドル / minified JS | sourceMappingURL を探します。マップに sourcesContent がある場合: jq -r '.sources[]' でソースをダンプします。webpack の場合は、モジュールIDをgrepし、ヒット箇所周辺をスライスします。整形: npx -y prettier --parser babel F > F.pretty.js、その後行範囲で読み取ります。 |
| Hermes / bytenode / V8 スナップショット | Hermes マジックは c6 1f bc 03 (index.android.bundle): hermes-dec / hbc-decompiler を使用。.jsc (bytenode) はデコンパイル不可: 文字列とランタイムフックを使用。 |
Mach-O (file: Mach-O) | lipo -info (最初にthin: lipo -thin arm64 -o T1 T)。次に: otool -L (libs); xcrun dyld_info -exports -imports; nm -gU (exports) / nm -u (imports = 機能マップ); strings -a -n 6; `otool -l | rg -A3 'LC_(RPATH |
| ネイティブコードロジック | otool -tV T > $D/dis.txt (または llvm-objdump -d --no-show-raw-insn -C)。関数を見つける: rg -n '^_?.*Name.*:$'。コール/文字列トレイルを読む: `awk '/^FUNC:/{p=1} p&&/^[_a-zA-Z].*:$/&&!/FUNC/{exit} p' dis.txt | rg 'bl |
| ELF / PE | readelf -hlSW, readelf -dW (NEEDED), nm -D --defined-only, objdump -d -M intel。PE: objdump -x, pefile/wrestool (リソース用)。checksec: pwn checksec。 |
Go (__go_buildinfo, .go.buildinfo) | go version -m T は、ツールチェーン、パス、モッド、依存関係、ビルドフラグを1回の呼び出しで提供します。Go がない場合: strings -a T | rg -m1 -A200 'Go buildinf' 。シンボルはストリッピング後も残ります: go tool nm T | rg main\.。 |
| Rust | 依存関係 (cargo-auditable): cargo audit bin T、または .dep-v0 / __DATA,.dep-v0 を抽出して zlib-inflate。コンパイラ: strings -a T | rg -o '/rustc/[0-9a-f]{40}' | sort -u。パスからクレート: strings -a T | rg -o '[a-z0-9_-]+-[0-9]+\.[0-9]+\.[0-9]+/src' | sort -u。 |
.NET (file: Mono/.Net) | ilspycmd -p -o X T.dll (インストール: dotnet tool install -g ilspycmd)、その後 rg。P/Invoke: rg DllImport X。NativeAOT/IL2CPP はネイティブ: ネイティブの行を使用。 |
| Android APK | jadx -d X --show-bad-code a.apk その後 rg。リソース/マニフェストのみ: apktool d --no-src -o X a.apk。クイックルック: unzip -l a.apk。lib/*/libflutter.so は Flutter (Dart AOT: blutter); libhermes.so は React Native (Hermes 行)。 |
| Flutter スナップショットハッシュ | libapp.so 内で、マジック f5 f5 dc dc を探します。+20 にある32桁の16進文字がスナップショットハッシュです。Dart バージョンにマッピングします。 |
| WASM | wasm-objdump -x, wasm2wat, wasm-decompile (WABT)。 |
| SQLite | データベースをコピーし、-wal ファイルがあればそれもコピーします。sqlite3 'file:C?mode=ro' '.schema'、その後 SELECT * FROM t LIMIT 20。 |
| plist / nib / car | plutil -p F。Info.plist にはバンドルID、URLスキーム、プライバシー文字列が含まれます。アセットカタログ: 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 | sort -u。HAR: jq -r '.log.entries[].request | .method+" "+.url'。 |
| ファームウェア | binwalk -e F または unblob -e X F。その後、抽出された各バイナリをこのテーブルでルーティングします。 |
| Webサイト | HTMLとスクリプトsrcについては curl -sL URL、その後JSをフェッチしてスライスします。ランタイム動作については、ヘッドレスブラウザとネットワークログ(Playwright page.on('request'))またはChrome --remote-debugging-port を使用します。 |
| 実行中のアプリ / ランタイム | macOS: lldb -p PID, dtrace/fs_usage/log stream --predicate 'process=="X"'。Electron main: --inspect (RunAsNode/inspect fuse が許可している場合のみ)。Android: adb logcat, frida -U -f pkg -l hook.js。 |
高速化パターン
- 最初に文字列とインポート。小さなバイナリでは、
nm -u+strings+ エクスポートリストで、逆アセンブリなしで「何をするか」の答えが出ることがよくあります。 - 文字列を使用している場所を見つけるには:
otool -tVの「literal pool for」コメントからアドレスを取得するか、rg -n 'literal pool for: "X'を実行します。次に、その行の上の該当する関数ラベルを見つけます。 blターゲット内のC++名は、すでにプロトコルを教えてくれます(例:getpeereid、write、std::hash)。すべての命令ではなく、コールシーケンスを読みます。- JSの場合、ネイティブ/JS境界から内側に向かって進みます: ネイティブコールを見つけ、次にその呼び出し元クラス、次にIPC登録、次にレンダラー/プリロード。
- バージョン比較: コードをdiffする前に、インベントリ(
nm、モジュールリスト、go version -m)をdiffします。 - 再現: 最小限の再実装を書き、それをオリジナルに対してテストします(同じ入力、同じ出力)。
インストール(リクエストがあった場合のみ)
brew install jadx apktool radare2 binwalk wabt wireshark ghidra · npm i -g @electron/asar · dotnet tool install -g ilspycmd · cargo install cargo-audit。