@eyeauras/insight-cli 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.cli-package-build.json +1 -1
- package/README.md +25 -0
- package/SKILL.md +38 -54
- package/dist/src/binary.d.ts +3 -0
- package/dist/src/binary.js +74 -0
- package/dist/src/capture.d.ts +3 -0
- package/dist/src/capture.js +220 -0
- package/dist/src/cli.js +57 -12
- package/dist/src/contexts.d.ts +5 -0
- package/dist/src/contexts.js +42 -16
- package/dist/src/debugger-caller.d.ts +17 -0
- package/dist/src/debugger-caller.js +129 -0
- package/dist/src/debugger-launch.d.ts +2 -0
- package/dist/src/debugger-launch.js +17 -0
- package/dist/src/debugger-results.d.ts +1 -0
- package/dist/src/debugger-results.js +8 -0
- package/dist/src/debugger-supervisor.js +56 -13
- package/dist/src/debugger.js +16 -7
- package/dist/src/die.d.ts +12 -0
- package/dist/src/die.js +127 -0
- package/dist/src/dnspy-runtime.d.ts +8 -0
- package/dist/src/dnspy-runtime.js +46 -0
- package/dist/src/dnspy.d.ts +22 -0
- package/dist/src/dnspy.js +160 -0
- package/dist/src/dotnet-diagnostics.d.ts +13 -0
- package/dist/src/dotnet-diagnostics.js +101 -0
- package/dist/src/frida-worker.d.ts +1 -0
- package/dist/src/frida-worker.js +125 -0
- package/dist/src/frida.d.ts +16 -0
- package/dist/src/frida.js +125 -0
- package/dist/src/ghidra-debugger-runtime.d.ts +7 -0
- package/dist/src/ghidra-debugger-runtime.js +31 -0
- package/dist/src/ghidra-processes.d.ts +6 -0
- package/dist/src/ghidra-processes.js +121 -0
- package/dist/src/ghidra.js +6 -6
- package/dist/src/ilspy.d.ts +7 -0
- package/dist/src/ilspy.js +122 -0
- package/dist/src/lldb.d.ts +10 -0
- package/dist/src/lldb.js +99 -0
- package/dist/src/llvm.d.ts +6 -0
- package/dist/src/llvm.js +133 -0
- package/dist/src/managed-heap.d.ts +4 -0
- package/dist/src/managed-heap.js +73 -0
- package/dist/src/managed-metadata.d.ts +11 -0
- package/dist/src/managed-metadata.js +66 -0
- package/dist/src/mitmproxy.d.ts +55 -0
- package/dist/src/mitmproxy.js +172 -0
- package/dist/src/native-inputs.d.ts +3 -2
- package/dist/src/native-inputs.js +9 -4
- package/dist/src/package-version.d.ts +1 -0
- package/dist/src/package-version.js +3 -0
- package/dist/src/procmon-config.d.ts +2 -0
- package/dist/src/procmon-config.js +15 -0
- package/dist/src/procmon-events.d.ts +13 -0
- package/dist/src/procmon-events.js +82 -0
- package/dist/src/procmon.d.ts +4 -0
- package/dist/src/procmon.js +107 -0
- package/dist/src/research.d.ts +11 -2
- package/dist/src/research.js +5 -3
- package/dist/src/runtime-catalog.d.ts +5 -10
- package/dist/src/runtime-catalog.js +4 -5
- package/dist/src/runtime-manager.d.ts +27 -3
- package/dist/src/runtime-manager.js +100 -159
- package/dist/src/runtime-selection.js +21 -4
- package/dist/src/server.d.ts +13 -0
- package/dist/src/server.js +21 -45
- package/dist/src/sevenzip.d.ts +15 -0
- package/dist/src/sevenzip.js +119 -0
- package/dist/src/strace.d.ts +10 -0
- package/dist/src/strace.js +71 -0
- package/dist/src/text-window.d.ts +11 -0
- package/dist/src/text-window.js +6 -0
- package/dist/src/tool-runtime/archives.d.ts +10 -0
- package/dist/src/{runtime-archives.js → tool-runtime/archives.js} +91 -24
- package/dist/src/tool-runtime/catalog.d.ts +3 -0
- package/dist/src/tool-runtime/catalog.js +13 -0
- package/dist/src/tool-runtime/commands.d.ts +9 -0
- package/dist/src/tool-runtime/commands.js +39 -0
- package/dist/src/tool-runtime/deadline.d.ts +11 -0
- package/dist/src/tool-runtime/deadline.js +32 -0
- package/dist/src/tool-runtime/definition.d.ts +73 -0
- package/dist/src/tool-runtime/definition.js +49 -0
- package/dist/src/tool-runtime/dotnet.d.ts +4 -0
- package/dist/src/tool-runtime/dotnet.js +22 -0
- package/dist/src/tool-runtime/identity.d.ts +6 -0
- package/dist/src/tool-runtime/identity.js +50 -0
- package/dist/src/tool-runtime/installer.d.ts +101 -0
- package/dist/src/tool-runtime/installer.js +180 -0
- package/dist/src/tool-runtime/launch-worker.d.ts +1 -0
- package/dist/src/tool-runtime/launch-worker.js +58 -0
- package/dist/src/tool-runtime/run.d.ts +51 -0
- package/dist/src/tool-runtime/run.js +159 -0
- package/dist/src/tool-runtime/store.d.ts +15 -0
- package/dist/src/tool-runtime/store.js +219 -0
- package/dist/src/tool-runtime/supervisor.d.ts +57 -0
- package/dist/src/tool-runtime/supervisor.js +266 -0
- package/dist/src/tool-runtime/windows-job.d.ts +22 -0
- package/dist/src/tool-runtime/windows-job.js +43 -0
- package/dist/src/toolbox.d.ts +84 -0
- package/dist/src/toolbox.js +35 -0
- package/dist/src/tshark.d.ts +23 -0
- package/dist/src/tshark.js +174 -0
- package/dist/src/windbg.d.ts +14 -0
- package/dist/src/windbg.js +119 -0
- package/dist/src/workspace.d.ts +1 -0
- package/dist/src/workspace.js +6 -0
- package/package.json +5 -4
- package/references/agent-execution.md +36 -0
- package/references/agent-setup.md +61 -0
- package/references/artifacts.md +5 -0
- package/references/debugger.md +22 -0
- package/references/ilspy.md +33 -0
- package/references/managed-runtime.md +48 -7
- package/references/native/InsightPythonWheels.java +283 -2
- package/references/native/InsightTraceState.java +28 -13
- package/references/setup.md +2 -1
- package/runtime/managed/insight-heap/Azure.Core.dll +0 -0
- package/runtime/managed/insight-heap/Azure.Identity.dll +0 -0
- package/runtime/managed/insight-heap/Insight.Heap.csproj +1 -0
- package/runtime/managed/insight-heap/Insight.Heap.deps.json +391 -0
- package/runtime/managed/insight-heap/Insight.Heap.dll +0 -0
- package/runtime/managed/insight-heap/Insight.Heap.runtimeconfig.json +13 -0
- package/runtime/managed/insight-heap/Microsoft.Bcl.AsyncInterfaces.dll +0 -0
- package/runtime/managed/insight-heap/Microsoft.Diagnostics.NETCore.Client.dll +0 -0
- package/runtime/managed/insight-heap/Microsoft.Diagnostics.Runtime.dll +0 -0
- package/runtime/managed/insight-heap/Microsoft.Extensions.Configuration.Abstractions.dll +0 -0
- package/runtime/managed/insight-heap/Microsoft.Extensions.DependencyInjection.Abstractions.dll +0 -0
- package/runtime/managed/insight-heap/Microsoft.Extensions.Diagnostics.Abstractions.dll +0 -0
- package/runtime/managed/insight-heap/Microsoft.Extensions.FileProviders.Abstractions.dll +0 -0
- package/runtime/managed/insight-heap/Microsoft.Extensions.Hosting.Abstractions.dll +0 -0
- package/runtime/managed/insight-heap/Microsoft.Extensions.Logging.Abstractions.dll +0 -0
- package/runtime/managed/insight-heap/Microsoft.Extensions.Options.dll +0 -0
- package/runtime/managed/insight-heap/Microsoft.Extensions.Primitives.dll +0 -0
- package/runtime/managed/insight-heap/Microsoft.Identity.Client.Extensions.Msal.dll +0 -0
- package/runtime/managed/insight-heap/Microsoft.Identity.Client.dll +0 -0
- package/runtime/managed/insight-heap/Microsoft.IdentityModel.Abstractions.dll +0 -0
- package/runtime/managed/insight-heap/Microsoft.Security.AntiSSRF.dll +0 -0
- package/runtime/managed/insight-heap/NuGet.Config +1 -0
- package/runtime/managed/insight-heap/Program.cs +20 -0
- package/runtime/managed/insight-heap/README.md +16 -0
- package/runtime/managed/insight-heap/System.ClientModel.dll +0 -0
- package/runtime/managed/insight-heap/System.Memory.Data.dll +0 -0
- package/runtime/managed/insight-heap/System.Security.Cryptography.ProtectedData.dll +0 -0
- package/runtime/managed/insight-heap/dependencies.json +436 -0
- package/runtime/managed/insight-heap/notices/Azure.Core-LICENSE.txt +21 -0
- package/runtime/managed/insight-heap/notices/Azure.Identity-LICENSE.txt +21 -0
- package/runtime/managed/insight-heap/notices/Microsoft.Bcl.AsyncInterfaces-LICENSE.txt +23 -0
- package/runtime/managed/insight-heap/notices/Microsoft.Bcl.AsyncInterfaces-THIRD-PARTY-NOTICES.TXT +1418 -0
- package/runtime/managed/insight-heap/notices/Microsoft.Diagnostics.NETCore.Client-LICENSE.txt +23 -0
- package/runtime/managed/insight-heap/notices/Microsoft.Diagnostics.Runtime-LICENSE.txt +23 -0
- package/runtime/managed/insight-heap/notices/Microsoft.Extensions.Configuration.Abstractions-LICENSE.txt +23 -0
- package/runtime/managed/insight-heap/notices/Microsoft.Extensions.Configuration.Abstractions-THIRD-PARTY-NOTICES.TXT +1418 -0
- package/runtime/managed/insight-heap/notices/Microsoft.Extensions.DependencyInjection.Abstractions-LICENSE.txt +23 -0
- package/runtime/managed/insight-heap/notices/Microsoft.Extensions.DependencyInjection.Abstractions-THIRD-PARTY-NOTICES.TXT +1418 -0
- package/runtime/managed/insight-heap/notices/Microsoft.Extensions.Diagnostics.Abstractions-LICENSE.txt +23 -0
- package/runtime/managed/insight-heap/notices/Microsoft.Extensions.Diagnostics.Abstractions-THIRD-PARTY-NOTICES.TXT +1418 -0
- package/runtime/managed/insight-heap/notices/Microsoft.Extensions.FileProviders.Abstractions-LICENSE.txt +23 -0
- package/runtime/managed/insight-heap/notices/Microsoft.Extensions.FileProviders.Abstractions-THIRD-PARTY-NOTICES.TXT +1418 -0
- package/runtime/managed/insight-heap/notices/Microsoft.Extensions.Hosting.Abstractions-LICENSE.txt +23 -0
- package/runtime/managed/insight-heap/notices/Microsoft.Extensions.Hosting.Abstractions-THIRD-PARTY-NOTICES.TXT +1418 -0
- package/runtime/managed/insight-heap/notices/Microsoft.Extensions.Logging.Abstractions-LICENSE.txt +23 -0
- package/runtime/managed/insight-heap/notices/Microsoft.Extensions.Logging.Abstractions-THIRD-PARTY-NOTICES.TXT +1418 -0
- package/runtime/managed/insight-heap/notices/Microsoft.Extensions.Options-LICENSE.txt +23 -0
- package/runtime/managed/insight-heap/notices/Microsoft.Extensions.Options-THIRD-PARTY-NOTICES.TXT +1418 -0
- package/runtime/managed/insight-heap/notices/Microsoft.Extensions.Primitives-LICENSE.txt +23 -0
- package/runtime/managed/insight-heap/notices/Microsoft.Extensions.Primitives-THIRD-PARTY-NOTICES.TXT +1418 -0
- package/runtime/managed/insight-heap/notices/Microsoft.Identity.Client-LICENSE.txt +21 -0
- package/runtime/managed/insight-heap/notices/Microsoft.Identity.Client.Extensions.Msal-LICENSE.txt +21 -0
- package/runtime/managed/insight-heap/notices/Microsoft.IdentityModel.Abstractions-LICENSE.txt +21 -0
- package/runtime/managed/insight-heap/notices/Microsoft.Security.AntiSSRF-LICENSE.txt +21 -0
- package/runtime/managed/insight-heap/notices/System.ClientModel-LICENSE.txt +21 -0
- package/runtime/managed/insight-heap/notices/System.Memory.Data-LICENSE.txt +23 -0
- package/runtime/managed/insight-heap/notices/System.Memory.Data-THIRD-PARTY-NOTICES.TXT +1418 -0
- package/runtime/managed/insight-heap/notices/System.Security.Cryptography.ProtectedData-LICENSE.TXT +23 -0
- package/runtime/managed/insight-heap/notices/System.Security.Cryptography.ProtectedData-THIRD-PARTY-NOTICES.TXT +309 -0
- package/runtime/managed/insight-heap/packages.lock.json +165 -0
- package/runtime/managed/insight-heap/provenance.json +146 -0
- package/runtime/managed/insight-heap/runtimes/win/lib/netstandard2.0/System.Security.Cryptography.ProtectedData.dll +0 -0
- package/runtime/managed/insight-managed/Insight.Managed.csproj +4 -0
- package/runtime/managed/insight-managed/Insight.Managed.deps.json +41 -0
- package/runtime/managed/insight-managed/Insight.Managed.dll +0 -0
- package/runtime/managed/insight-managed/Insight.Managed.runtimeconfig.json +13 -0
- package/runtime/managed/insight-managed/LICENSE.dnlib.txt +20 -0
- package/runtime/managed/insight-managed/NuGet.Config +1 -0
- package/runtime/managed/insight-managed/Program.cs +31 -0
- package/runtime/managed/insight-managed/README.md +16 -0
- package/runtime/managed/insight-managed/dnlib.dll +0 -0
- package/runtime/managed/insight-managed/packages.lock.json +13 -0
- package/runtime/managed/insight-managed/provenance.json +40 -0
- package/runtime/native/binary/README.md +22 -0
- package/runtime/native/binary/dependencies.json +166 -0
- package/runtime/native/binary/helper.cpp +44 -0
- package/runtime/native/binary/insight-binary-darwin-arm64 +0 -0
- package/runtime/native/binary/notices/Catch2-3.12.0--Catch2-3.12.0__LICENSE.txt +23 -0
- package/runtime/native/binary/notices/LIEF-LICENSE.txt +202 -0
- package/runtime/native/binary/notices/LIEF-attribution.txt +37 -0
- package/runtime/native/binary/notices/Melkor_ELF_Fuzzer-ac2495b--elf_fuzzer-master__LICENSE.txt +674 -0
- package/runtime/native/binary/notices/expected-1.3.1--expected-1.3.1__COPYING +121 -0
- package/runtime/native/binary/notices/frozen-61dce5a--frozen-61dce5ae18ca59931e27675c468e64118aba8744__AUTHORS +3 -0
- package/runtime/native/binary/notices/frozen-61dce5a--frozen-61dce5ae18ca59931e27675c468e64118aba8744__LICENSE +202 -0
- package/runtime/native/binary/notices/json-LICENSE.MIT +21 -0
- package/runtime/native/binary/notices/mbedtls-4.0.0.r0.gec4044008d--LICENSE +553 -0
- package/runtime/native/binary/notices/mbedtls-4.0.0.r0.gec4044008d--framework__LICENSE +553 -0
- package/runtime/native/binary/notices/mbedtls-4.0.0.r0.gec4044008d--tf-psa-crypto__LICENSE +552 -0
- package/runtime/native/binary/notices/mbedtls-4.0.0.r0.gec4044008d--tf-psa-crypto__framework__LICENSE +553 -0
- package/runtime/native/binary/notices/nanobind-2.13.0.r18.g4db9ed3f--LICENSE +26 -0
- package/runtime/native/binary/notices/nanobind-2.13.0.r18.g4db9ed3f--ext__robin_map__LICENSE +21 -0
- package/runtime/native/binary/notices/span-LICENSE_1_0.txt +23 -0
- package/runtime/native/binary/notices/span-attribution.txt +11 -0
- package/runtime/native/binary/notices/spdlog-1.17.0--spdlog-1.17.0__LICENSE +25 -0
- package/runtime/native/binary/notices/utfcpp-4.0.9--utfcpp-4.0.9__LICENSE +23 -0
- package/runtime/native/binary/provenance.json +48 -0
- package/runtime/native/child-deadline-linux-x64 +0 -0
- package/runtime/native/child-deadline-linux.c +24 -0
- package/runtime/native/child-deadline-linux.provenance.json +17 -0
- package/runtime/native/deadline-alarm-darwin-universal.dylib +0 -0
- package/runtime/native/deadline-alarm.c +33 -0
- package/runtime/native/deadline-alarm.provenance.json +22 -0
- package/runtime/native/deadline-exec-darwin-arm64 +0 -0
- package/runtime/native/deadline-exec.c +24 -0
- package/runtime/native/deadline-exec.provenance.json +17 -0
- package/runtime/native/dnspy-extension/Bridge.cs +58 -0
- package/runtime/native/dnspy-extension/Insight.DnSpy.csproj +13 -0
- package/runtime/native/dnspy-extension/Insight.DnSpy.x.dll +0 -0
- package/runtime/native/dnspy-extension/NuGet.Config +1 -0
- package/runtime/native/dnspy-extension/UNICODE-LOADER.md +26 -0
- package/runtime/native/dnspy-extension/packages.lock.json +6 -0
- package/runtime/native/dnspy-extension/provenance.json +27 -0
- package/runtime/native/dnspy-extension/upstream-public-build.snk +0 -0
- package/runtime/native/dnspy-extension/vendor-files.json +4341 -0
- package/runtime/native/file-version.ps1 +7 -0
- package/runtime/native/insight-registry-win-x64.dll +0 -0
- package/runtime/native/mitmproxy/bridge.py +180 -0
- package/runtime/native/mitmproxy/notices.json +476 -0
- package/runtime/native/sources/detours-LICENSE.md +23 -0
- package/runtime/native/sources/detours-e4bfd6b.tar.gz +0 -0
- package/runtime/native/sources/detours-provenance.json +10 -0
- package/runtime/native/tshark-layout.json +2247 -0
- package/runtime/native/windows-job/DirectoryAlias.cs +24 -0
- package/runtime/native/windows-job/Insight.WindowsJob.csproj +1 -0
- package/runtime/native/windows-job/Insight.WindowsJob.dll +0 -0
- package/runtime/native/windows-job/NuGet.Config +1 -0
- package/runtime/native/windows-job/OwnedJob.cs +79 -0
- package/runtime/native/windows-job/RegistryRedirect.cs +45 -0
- package/runtime/native/windows-job/packages.lock.json +21 -0
- package/runtime/native/windows-job/provenance.json +16 -0
- package/runtime/native/windows-job/windows-job.ps1 +8 -0
- package/runtime/native/windows-registry.c +21 -0
- package/runtime/native/windows-registry.def +3 -0
- package/runtime/native/windows-registry.provenance.json +14 -0
- package/runtime/notices/diagnostics-10.0.750501.txt +23 -0
- package/runtime/tool-catalog.json +290 -0
- package/runtime/toolbox.json +1401 -0
- package/skill-bundle/insight-artifacts/SKILL.md +30 -0
- package/skill-bundle/insight-artifacts/references/agent-execution.md +36 -0
- package/skill-bundle/insight-artifacts/references/artifacts.md +52 -0
- package/skill-bundle/insight-binary/SKILL.md +46 -0
- package/skill-bundle/insight-binary/references/agent-execution.md +36 -0
- package/skill-bundle/insight-capture/SKILL.md +56 -0
- package/skill-bundle/insight-capture/references/agent-execution.md +36 -0
- package/skill-bundle/insight-cli/SKILL.md +42 -0
- package/skill-bundle/insight-cli/references/agent-execution.md +36 -0
- package/skill-bundle/insight-cli/references/agent-setup.md +61 -0
- package/skill-bundle/insight-die/SKILL.md +49 -0
- package/skill-bundle/insight-die/references/agent-execution.md +36 -0
- package/skill-bundle/insight-dnspy/SKILL.md +65 -0
- package/skill-bundle/insight-dnspy/references/agent-execution.md +36 -0
- package/skill-bundle/insight-dotnet-dump/SKILL.md +46 -0
- package/skill-bundle/insight-dotnet-dump/references/agent-execution.md +36 -0
- package/skill-bundle/insight-dotnet-stack/SKILL.md +39 -0
- package/skill-bundle/insight-dotnet-stack/references/agent-execution.md +36 -0
- package/skill-bundle/insight-dotnet-trace/SKILL.md +45 -0
- package/skill-bundle/insight-dotnet-trace/references/agent-execution.md +36 -0
- package/skill-bundle/insight-frida/SKILL.md +67 -0
- package/skill-bundle/insight-frida/references/agent-execution.md +36 -0
- package/skill-bundle/insight-ghidra/SKILL.md +91 -0
- package/skill-bundle/insight-ghidra/references/administration.md +34 -0
- package/skill-bundle/insight-ghidra/references/agent-execution.md +36 -0
- package/skill-bundle/insight-ghidra/references/archive.md +32 -0
- package/skill-bundle/insight-ghidra/references/artifacts.md +52 -0
- package/skill-bundle/insight-ghidra/references/debugger.md +62 -0
- package/skill-bundle/insight-ghidra/references/extensions-and-sync.md +124 -0
- package/skill-bundle/insight-ghidra/references/managed-runtime.md +157 -0
- package/skill-bundle/insight-ghidra/references/native-workflows.md +112 -0
- package/skill-bundle/insight-ghidra/references/query-semantics.md +96 -0
- package/skill-bundle/insight-ghidra/references/recovery.md +53 -0
- package/skill-bundle/insight-ghidra/references/research.md +101 -0
- package/skill-bundle/insight-ghidra/references/setup.md +50 -0
- package/skill-bundle/insight-ilspy/SKILL.md +45 -0
- package/skill-bundle/insight-ilspy/references/agent-execution.md +36 -0
- package/skill-bundle/insight-ilspy/references/ilspy.md +33 -0
- package/skill-bundle/insight-interop/SKILL.md +54 -0
- package/skill-bundle/insight-interop/references/agent-execution.md +36 -0
- package/skill-bundle/insight-lldb/SKILL.md +54 -0
- package/skill-bundle/insight-lldb/references/agent-execution.md +36 -0
- package/skill-bundle/insight-llvm/SKILL.md +56 -0
- package/skill-bundle/insight-llvm/references/agent-execution.md +36 -0
- package/skill-bundle/insight-managed-heap/SKILL.md +43 -0
- package/skill-bundle/insight-managed-heap/references/agent-execution.md +36 -0
- package/skill-bundle/insight-managed-metadata/SKILL.md +52 -0
- package/skill-bundle/insight-managed-metadata/references/agent-execution.md +36 -0
- package/skill-bundle/insight-mitmproxy/SKILL.md +62 -0
- package/skill-bundle/insight-mitmproxy/references/agent-execution.md +36 -0
- package/skill-bundle/insight-overview/SKILL.md +79 -0
- package/skill-bundle/insight-overview/references/agent-execution.md +36 -0
- package/skill-bundle/insight-procmon/SKILL.md +49 -0
- package/skill-bundle/insight-procmon/references/agent-execution.md +36 -0
- package/skill-bundle/insight-re/SKILL.md +121 -0
- package/skill-bundle/insight-re/references/agent-execution.md +36 -0
- package/skill-bundle/insight-re/references/artifacts.md +52 -0
- package/skill-bundle/insight-re/references/recovery.md +53 -0
- package/skill-bundle/insight-sevenzip/SKILL.md +42 -0
- package/skill-bundle/insight-sevenzip/references/agent-execution.md +36 -0
- package/skill-bundle/insight-strace/SKILL.md +46 -0
- package/skill-bundle/insight-strace/references/agent-execution.md +36 -0
- package/skill-bundle/insight-tshark/SKILL.md +49 -0
- package/skill-bundle/insight-tshark/references/agent-execution.md +36 -0
- package/skill-bundle/insight-windbg/SKILL.md +46 -0
- package/skill-bundle/insight-windbg/references/agent-execution.md +36 -0
- package/skill-bundle/manifest.json +32 -0
- package/skills/insight-artifacts/SKILL.md +30 -0
- package/skills/insight-artifacts/references/agent-execution.md +36 -0
- package/skills/insight-artifacts/references/artifacts.md +52 -0
- package/skills/insight-binary/SKILL.md +46 -0
- package/skills/insight-binary/references/agent-execution.md +36 -0
- package/skills/insight-capture/SKILL.md +56 -0
- package/skills/insight-capture/references/agent-execution.md +36 -0
- package/skills/insight-die/SKILL.md +49 -0
- package/skills/insight-die/references/agent-execution.md +36 -0
- package/skills/insight-dnspy/SKILL.md +65 -0
- package/skills/insight-dnspy/references/agent-execution.md +36 -0
- package/skills/insight-dotnet-dump/SKILL.md +46 -0
- package/skills/insight-dotnet-dump/references/agent-execution.md +36 -0
- package/skills/insight-dotnet-stack/SKILL.md +39 -0
- package/skills/insight-dotnet-stack/references/agent-execution.md +36 -0
- package/skills/insight-dotnet-trace/SKILL.md +45 -0
- package/skills/insight-dotnet-trace/references/agent-execution.md +36 -0
- package/skills/insight-frida/SKILL.md +67 -0
- package/skills/insight-frida/references/agent-execution.md +36 -0
- package/skills/insight-ghidra/SKILL.md +91 -0
- package/skills/insight-ghidra/references/administration.md +34 -0
- package/skills/insight-ghidra/references/agent-execution.md +36 -0
- package/skills/insight-ghidra/references/archive.md +32 -0
- package/skills/insight-ghidra/references/artifacts.md +52 -0
- package/skills/insight-ghidra/references/debugger.md +62 -0
- package/skills/insight-ghidra/references/extensions-and-sync.md +124 -0
- package/skills/insight-ghidra/references/managed-runtime.md +157 -0
- package/skills/insight-ghidra/references/native-workflows.md +112 -0
- package/skills/insight-ghidra/references/query-semantics.md +96 -0
- package/skills/insight-ghidra/references/recovery.md +53 -0
- package/skills/insight-ghidra/references/research.md +101 -0
- package/skills/insight-ghidra/references/setup.md +50 -0
- package/skills/insight-ilspy/SKILL.md +45 -0
- package/skills/insight-ilspy/references/agent-execution.md +36 -0
- package/skills/insight-ilspy/references/ilspy.md +33 -0
- package/skills/insight-interop/SKILL.md +54 -0
- package/skills/insight-interop/references/agent-execution.md +36 -0
- package/skills/insight-lldb/SKILL.md +54 -0
- package/skills/insight-lldb/references/agent-execution.md +36 -0
- package/skills/insight-llvm/SKILL.md +56 -0
- package/skills/insight-llvm/references/agent-execution.md +36 -0
- package/skills/insight-managed-heap/SKILL.md +43 -0
- package/skills/insight-managed-heap/references/agent-execution.md +36 -0
- package/skills/insight-managed-metadata/SKILL.md +52 -0
- package/skills/insight-managed-metadata/references/agent-execution.md +36 -0
- package/skills/insight-mitmproxy/SKILL.md +62 -0
- package/skills/insight-mitmproxy/references/agent-execution.md +36 -0
- package/skills/insight-overview/SKILL.md +79 -0
- package/skills/insight-overview/references/agent-execution.md +36 -0
- package/skills/insight-procmon/SKILL.md +49 -0
- package/skills/insight-procmon/references/agent-execution.md +36 -0
- package/skills/insight-re/SKILL.md +22 -9
- package/skills/insight-re/references/agent-execution.md +36 -0
- package/skills/insight-re/references/artifacts.md +52 -0
- package/skills/insight-re/references/recovery.md +53 -0
- package/skills/insight-sevenzip/SKILL.md +42 -0
- package/skills/insight-sevenzip/references/agent-execution.md +36 -0
- package/skills/insight-strace/SKILL.md +46 -0
- package/skills/insight-strace/references/agent-execution.md +36 -0
- package/skills/insight-tshark/SKILL.md +49 -0
- package/skills/insight-tshark/references/agent-execution.md +36 -0
- package/skills/insight-windbg/SKILL.md +46 -0
- package/skills/insight-windbg/references/agent-execution.md +36 -0
- package/dist/src/runtime-archives.d.ts +0 -5
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
// Internal bounded collector process, never a second public CLI or persistent service.
|
|
2
|
+
import { pathToFileURL } from 'node:url';
|
|
3
|
+
import { processIdentity } from './tool-runtime/identity.js';
|
|
4
|
+
import { inheritedDeadlineEnvironment } from './tool-runtime/deadline.js';
|
|
5
|
+
import { mkdir } from 'node:fs/promises';
|
|
6
|
+
import { join } from 'node:path';
|
|
7
|
+
async function main() {
|
|
8
|
+
let input = '';
|
|
9
|
+
for await (const chunk of process.stdin) {
|
|
10
|
+
input += chunk;
|
|
11
|
+
if (Buffer.byteLength(input) > 2 * 1024 ** 2)
|
|
12
|
+
throw Error('Collector request exceeds two MiB');
|
|
13
|
+
}
|
|
14
|
+
const config = JSON.parse(input);
|
|
15
|
+
// Set this after Node starts: only SDK helper execs load the constructor, not the target.
|
|
16
|
+
const receipts = join(process.env.HOME, 'native-deadlines');
|
|
17
|
+
await mkdir(receipts, { mode: 0o700 });
|
|
18
|
+
Object.assign(process.env, await inheritedDeadlineEnvironment(config.deadlineUnixSeconds, receipts));
|
|
19
|
+
// This import is intentionally isolated in an owned child; native addon faults cannot crash the owner.
|
|
20
|
+
const frida = await import(pathToFileURL(config.module).href);
|
|
21
|
+
const emit = (value) => process.stdout.write(JSON.stringify(value) + '\n');
|
|
22
|
+
if (config.mode === 'probe') {
|
|
23
|
+
const version = await frida.getLocalDevice();
|
|
24
|
+
emit({ kind: 'probe', protocol: 1, version: '17.24.0', device: version.type });
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
const cancellable = new frida.Cancellable();
|
|
28
|
+
let session, script, detached = false, finished = false, error = false, unloaded = false, sessionDetached = false, loaded = false, interrupted = false, count = 0;
|
|
29
|
+
const duration = config.durationMs ?? 1000, deadline = setTimeout(() => cancellable.cancel(), duration + 5000);
|
|
30
|
+
let resolveDone;
|
|
31
|
+
const done = new Promise(ok => resolveDone = ok);
|
|
32
|
+
let observation;
|
|
33
|
+
const stop = () => { interrupted = true; error = true; emit({ kind: 'interrupted', signal: 'SIGTERM' }); resolveDone(); if (!loaded)
|
|
34
|
+
cancellable.cancel(); };
|
|
35
|
+
process.once('SIGTERM', stop);
|
|
36
|
+
try {
|
|
37
|
+
if (!config.pid || (await processIdentity(config.pid))?.birth !== config.expectedBirth)
|
|
38
|
+
throw Error('Target birth identity changed before attach');
|
|
39
|
+
session = await frida.attach(config.pid, {}, cancellable);
|
|
40
|
+
session.detached.connect((reason, crash) => { detached = true; if (!finished) {
|
|
41
|
+
error = true;
|
|
42
|
+
emit({ kind: 'detached', reason, crash: Boolean(crash) });
|
|
43
|
+
resolveDone();
|
|
44
|
+
} });
|
|
45
|
+
let source = config.source;
|
|
46
|
+
if (config.mode === 'modules')
|
|
47
|
+
source = 'send({kind:"modules",items:Process.enumerateModules().map(m=>({name:m.name,path:m.path,base:m.base.toString(),size:m.size}))});';
|
|
48
|
+
if (config.mode === 'exports')
|
|
49
|
+
source = 'send({kind:"exports",module:' + JSON.stringify(config.moduleName) + ',items:Process.getModuleByName(' + JSON.stringify(config.moduleName) + ').enumerateExports()});';
|
|
50
|
+
// Keep user source untouched (strict directives and source line numbers matter).
|
|
51
|
+
const bootstrap = await session.createScript('send(Frida.version);', {}, cancellable);
|
|
52
|
+
let versionTimer;
|
|
53
|
+
const version = new Promise((ok, bad) => { bootstrap.message.connect((message) => message.type === 'send' ? ok(message.payload) : bad(new Error('Frida runtime version probe failed'))); versionTimer = setTimeout(() => bad(new Error('Frida runtime version probe timed out')), 5000); });
|
|
54
|
+
void version.catch(() => { });
|
|
55
|
+
try {
|
|
56
|
+
await bootstrap.load(cancellable);
|
|
57
|
+
const actual = await version;
|
|
58
|
+
emit({ kind: 'runtime', version: actual });
|
|
59
|
+
if (actual !== '17.24.0')
|
|
60
|
+
throw Error('Frida runtime version differs from 17.24.0');
|
|
61
|
+
}
|
|
62
|
+
finally {
|
|
63
|
+
if (versionTimer)
|
|
64
|
+
clearTimeout(versionTimer);
|
|
65
|
+
await bootstrap.unload(cancellable);
|
|
66
|
+
}
|
|
67
|
+
script = await session.createScript(source, {}, cancellable);
|
|
68
|
+
script.message.connect((message, data) => {
|
|
69
|
+
if (++count > 10000) {
|
|
70
|
+
error = true;
|
|
71
|
+
if (count === 10001)
|
|
72
|
+
emit({ kind: 'limit', message: 'Collector exceeded 10000 messages' });
|
|
73
|
+
resolveDone();
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
if (message.type === 'error') {
|
|
77
|
+
error = true;
|
|
78
|
+
resolveDone();
|
|
79
|
+
}
|
|
80
|
+
emit({ kind: 'message', message, ...(data ? { binaryBase64: data.toString('base64') } : {}) });
|
|
81
|
+
if (config.mode !== 'observe' && message.type === 'send' && message.payload?.kind === config.mode)
|
|
82
|
+
resolveDone();
|
|
83
|
+
});
|
|
84
|
+
await script.load(cancellable);
|
|
85
|
+
loaded = true;
|
|
86
|
+
emit({ kind: 'loaded' });
|
|
87
|
+
observation = setTimeout(resolveDone, duration);
|
|
88
|
+
await done;
|
|
89
|
+
}
|
|
90
|
+
finally {
|
|
91
|
+
if (observation)
|
|
92
|
+
clearTimeout(observation);
|
|
93
|
+
finished = true;
|
|
94
|
+
const cleanup = new frida.Cancellable(), cleanupDeadline = setTimeout(() => cleanup.cancel(), 2000);
|
|
95
|
+
try {
|
|
96
|
+
if (script && !detached) {
|
|
97
|
+
await script.unload(cleanup);
|
|
98
|
+
unloaded = true;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
catch (e) {
|
|
102
|
+
error = true;
|
|
103
|
+
emit({ kind: 'cleanup-error', message: String(e) });
|
|
104
|
+
}
|
|
105
|
+
try {
|
|
106
|
+
if (session && !detached) {
|
|
107
|
+
await session.detach(cleanup);
|
|
108
|
+
sessionDetached = true;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
catch (e) {
|
|
112
|
+
error = true;
|
|
113
|
+
emit({ kind: 'cleanup-error', message: String(e) });
|
|
114
|
+
}
|
|
115
|
+
clearTimeout(cleanupDeadline);
|
|
116
|
+
cleanup.cancel();
|
|
117
|
+
clearTimeout(deadline);
|
|
118
|
+
cancellable.cancel();
|
|
119
|
+
process.off('SIGTERM', stop);
|
|
120
|
+
}
|
|
121
|
+
emit({ kind: 'completed', complete: !error && unloaded && sessionDetached, detached, scriptUnloaded: unloaded, sessionDetached });
|
|
122
|
+
if (interrupted)
|
|
123
|
+
process.exitCode = 130;
|
|
124
|
+
}
|
|
125
|
+
main().catch(error => { process.stderr.write(String(error) + '\n'); process.exitCode = 1; });
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type CommandContext, type CommandDefinition } from '@eyeauras/cli-factory';
|
|
2
|
+
import { ToolInstaller } from './tool-runtime/installer.js';
|
|
3
|
+
import type { Workspace } from './workspace.js';
|
|
4
|
+
export declare function fridaInstaller(c: CommandContext): ToolInstaller;
|
|
5
|
+
export declare function fridaEvents(stdout: string): {
|
|
6
|
+
events: Record<string, any>[];
|
|
7
|
+
summary: {
|
|
8
|
+
totalEvents: number;
|
|
9
|
+
sendMessages: number;
|
|
10
|
+
scriptErrors: number;
|
|
11
|
+
logMessages: number;
|
|
12
|
+
};
|
|
13
|
+
complete: boolean;
|
|
14
|
+
cleanup: Record<string, any>;
|
|
15
|
+
};
|
|
16
|
+
export declare function fridaCommands(workspace: (c: CommandContext) => Workspace): CommandDefinition[];
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { command, Permission } from '@eyeauras/cli-factory';
|
|
2
|
+
import { dirname, join, resolve } from 'node:path';
|
|
3
|
+
import { release } from 'node:os';
|
|
4
|
+
import { readFile, mkdir, writeFile, stat } from 'node:fs/promises';
|
|
5
|
+
import { createRequire } from 'node:module';
|
|
6
|
+
import { fileURLToPath } from 'node:url';
|
|
7
|
+
import { ToolInstaller } from './tool-runtime/installer.js';
|
|
8
|
+
import { defineTool, lifecycleCommands } from './tool-runtime/definition.js';
|
|
9
|
+
import { catalogArtifact } from './tool-runtime/catalog.js';
|
|
10
|
+
import { runTool } from './tool-runtime/run.js';
|
|
11
|
+
import { treeFingerprint } from './tool-runtime/store.js';
|
|
12
|
+
import { processIdentity } from './tool-runtime/identity.js';
|
|
13
|
+
import { fail, text } from './model.js';
|
|
14
|
+
import { number } from './research.js';
|
|
15
|
+
const worker = fileURLToPath(new URL('./frida-worker.js', import.meta.url)), moduleRoot = (entry) => dirname(dirname(dirname(entry)));
|
|
16
|
+
function supported() { if (process.platform !== 'darwin' || process.arch !== 'arm64' || Number(release().split('.')[0]) < 23)
|
|
17
|
+
fail('unsupported', 'This Frida facade requires macOS 14+ ARM64 and an explicitly selected authorized local process.'); }
|
|
18
|
+
async function entryMetadata(entry) {
|
|
19
|
+
if (!entry.endsWith(join('build', 'src', 'frida.js')))
|
|
20
|
+
fail('configuration', 'External Frida selection requires its Node entry module at .../frida/build/src/frida.js; use managed install by default.');
|
|
21
|
+
let metadata;
|
|
22
|
+
try {
|
|
23
|
+
const path = join(moduleRoot(entry), 'package.json');
|
|
24
|
+
if ((await stat(path)).size > 128 * 1024)
|
|
25
|
+
fail('configuration', 'Invalid external Frida metadata.');
|
|
26
|
+
metadata = JSON.parse(await readFile(path, 'utf8'));
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
fail('configuration', 'External Frida Node package metadata is missing or invalid.');
|
|
30
|
+
}
|
|
31
|
+
if (metadata.name !== 'frida' || metadata.version !== '17.24.0')
|
|
32
|
+
fail('configuration', 'Select the Frida 17.24.0 Node entry module with its native NAPI-v8 binding and runtime dependencies.');
|
|
33
|
+
return metadata;
|
|
34
|
+
}
|
|
35
|
+
export function fridaInstaller(c) {
|
|
36
|
+
return new ToolInstaller(c, { id: 'frida', primary: 'frida', components: () => { supported(); return { frida: catalogArtifact('26e9e7b9a8d9c68c87cb3da879c328edd096d587720039095de6a522d2c8765e') }; }, launch: roots => ({ executable: join(roots.frida, 'node_modules/frida/build/src/frida.js'), arguments: [], environment: {} }), externalInputs: async (entry) => {
|
|
37
|
+
supported();
|
|
38
|
+
await entryMetadata(entry);
|
|
39
|
+
const values = { frida: await treeFingerprint(moduleRoot(entry)) };
|
|
40
|
+
for (const name of ['bindings', 'file-uri-to-path', 'minimatch', 'brace-expansion', 'balanced-match']) {
|
|
41
|
+
let found = false;
|
|
42
|
+
for (const base of createRequire(entry).resolve.paths(name) ?? []) {
|
|
43
|
+
try {
|
|
44
|
+
const root = join(base, name), metadata = JSON.parse(await readFile(join(root, 'package.json'), 'utf8'));
|
|
45
|
+
if (metadata.name !== name)
|
|
46
|
+
fail('binding', 'External Frida dependency identity differs.');
|
|
47
|
+
values[name] = await treeFingerprint(root);
|
|
48
|
+
found = true;
|
|
49
|
+
break;
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
if (error.code !== 'ENOENT')
|
|
53
|
+
throw error;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
if (!found)
|
|
57
|
+
fail('configuration', 'External Frida runtime dependency is missing: ' + name);
|
|
58
|
+
}
|
|
59
|
+
return values;
|
|
60
|
+
}, probe: async (launch, context) => {
|
|
61
|
+
supported();
|
|
62
|
+
const metadata = await entryMetadata(launch.executable);
|
|
63
|
+
const result = await runTool(context, { tool: 'frida', role: 'probe', executable: process.execPath, arguments: ['--no-warnings', worker], input: JSON.stringify({ mode: 'probe', module: launch.executable, deadlineUnixSeconds: Math.ceil(Date.now() / 1000) + 10 }), timeoutMs: 10000, nativeDeadline: true, nativeChildDeadlines: true, maxOutputBytes: 65536 });
|
|
64
|
+
const value = JSON.parse(result.stdout);
|
|
65
|
+
if (value.kind !== 'probe' || value.protocol !== 1 || value.device !== 'local')
|
|
66
|
+
fail('binding', 'Frida native binding did not provide a compatible local-device API.');
|
|
67
|
+
return { declaredVersion: metadata.version, node: process.version, entryKind: 'Node module', nativeApi: 'local device', pythonRequired: false };
|
|
68
|
+
} });
|
|
69
|
+
}
|
|
70
|
+
export function fridaEvents(stdout) {
|
|
71
|
+
const events = stdout.trim().split(/\r?\n/).filter(Boolean).map(line => { try {
|
|
72
|
+
return JSON.parse(line);
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
fail('binding', 'Frida collector returned malformed events; inspect retained native diagnostics.');
|
|
76
|
+
} });
|
|
77
|
+
const completed = events.at(-1);
|
|
78
|
+
if (completed?.kind !== 'completed' || typeof completed.complete !== 'boolean')
|
|
79
|
+
fail('partial', 'Frida did not acknowledge bounded capture and cleanup; inspect process diagnostics.');
|
|
80
|
+
const errors = events.some(e => ['detached', 'cleanup-error', 'limit'].includes(e.kind) || e.kind === 'message' && e.message?.type === 'error');
|
|
81
|
+
const summary = { totalEvents: events.length, sendMessages: events.filter(e => e.kind === 'message' && e.message?.type === 'send').length, scriptErrors: events.filter(e => e.kind === 'message' && e.message?.type === 'error').length, logMessages: events.filter(e => e.kind === 'message' && e.message?.type === 'log').length };
|
|
82
|
+
return { events, summary, complete: !errors && completed.complete === true && completed.scriptUnloaded === true && completed.sessionDetached === true && events.some(e => e.kind === 'runtime' && e.version === '17.24.0'), cleanup: completed };
|
|
83
|
+
}
|
|
84
|
+
export function fridaCommands(workspace) {
|
|
85
|
+
const definition = defineTool({ id: 'frida', description: 'Inspect modules/exports or collect bounded Frida script events from an explicit local PID', components: [{ id: 'frida', version: '17.24.0', artifacts: [] }], installOptions: [{ flags: '--archive <path>', description: 'Install a local Frida Node runtime archive' }, { flags: '--archive-sha256 <sha256>', description: 'Expected local archive hash' }, { flags: '--executable <path>', description: 'External Frida Node entry module: .../frida/build/src/frida.js' }, { flags: '--offline', description: 'Use verified local cache without network access' }], lifecycle: { download: (o, c) => fridaInstaller(c).download(Boolean(o.offline)), install: (o, c) => fridaInstaller(c).install(o), uninstall: (o, c) => fridaInstaller(c).uninstall(Boolean(o.purgeCache)), doctor: (_o, c) => fridaInstaller(c).doctor(), status: (_o, c) => fridaInstaller(c).status() } });
|
|
86
|
+
const options = [{ flags: '--pid <pid>', description: 'Explicit authorized local process; its lifetime remains external', required: true }, { flags: '--output <file>', description: 'Save all bounded collector events to a new JSON file' }, { flags: '--limit <count>', description: 'Maximum returned events (1–1000)', defaultValue: 100 }, { flags: '--offset <count>', description: 'Skip events', defaultValue: 0 }];
|
|
87
|
+
const collect = (mode) => command(mode, mode === 'observe' ? 'Load a captured Frida JavaScript file, observe for a bounded interval, unload and detach' : mode === 'modules' ? 'Inventory runtime modules in the selected local process' : 'Inventory exported addresses in one selected runtime module', async ({ options: o }, c) => {
|
|
88
|
+
supported();
|
|
89
|
+
const pid = number(o.pid, 2147483647, 1), before = await processIdentity(pid);
|
|
90
|
+
if (pid === process.pid || !before || ['unavailable', 'unverified'].includes(before.birth))
|
|
91
|
+
fail('binding', 'Select a different live process with an observable OS birth identity.');
|
|
92
|
+
const durationMs = mode === 'observe' ? number(o.durationSeconds ?? 2, 120, 1) * 1000 : 1000, limit = number(o.limit ?? 100, 1000, 1), offset = number(o.offset ?? 0, 1000000), moduleName = mode === 'exports' ? text(o.module, 4096) : undefined;
|
|
93
|
+
let source, scriptSha256;
|
|
94
|
+
if (mode === 'observe') {
|
|
95
|
+
const w = workspace(c), path = resolve(c.cwd, text(o.script, 4096)), metadata = await stat(path);
|
|
96
|
+
if (!metadata.isFile() || metadata.size > 256 * 1024)
|
|
97
|
+
fail('limit', 'Frida script must be a regular file of at most 256 KiB.');
|
|
98
|
+
const artifact = await w.artifacts.capture(path, 'input');
|
|
99
|
+
if (artifact.size > 256 * 1024)
|
|
100
|
+
fail('limit', 'Frida script exceeds 256 KiB.');
|
|
101
|
+
try {
|
|
102
|
+
source = new TextDecoder('utf-8', { fatal: true, ignoreBOM: true }).decode(await readFile(await w.artifacts.verify(artifact)));
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
fail('invalid', 'Frida JavaScript source must be valid UTF-8.');
|
|
106
|
+
}
|
|
107
|
+
scriptSha256 = artifact.sha256;
|
|
108
|
+
}
|
|
109
|
+
return fridaInstaller(c).use(async (selected) => {
|
|
110
|
+
const result = await runTool(c, { tool: 'frida', role: mode, installation: selected.id, metadata: { subjectPid: pid, subjectBirth: before.birth, durationMs, ...(scriptSha256 ? { scriptSha256 } : {}), ...(moduleName ? { moduleName } : {}) }, executable: process.execPath, arguments: ['--no-warnings', worker], input: JSON.stringify({ module: selected.executable, mode, pid, expectedBirth: before.birth, moduleName, source, durationMs, deadlineUnixSeconds: Math.ceil(Date.now() / 1000) + (durationMs + 10000) / 1000 }), timeoutMs: durationMs + 10000, nativeDeadline: true, nativeChildDeadlines: true }), capture = fridaEvents(result.stdout), after = await processIdentity(pid), sameProcess = after?.birth === before.birth, complete = capture.complete && sameProcess;
|
|
111
|
+
const records = mode === 'observe' ? undefined : capture.events.filter(e => e.kind === 'message' && e.message?.type === 'send' && e.message.payload?.kind === mode).flatMap(e => Array.isArray(e.message.payload.items) ? e.message.payload.items : []);
|
|
112
|
+
const base = { state: complete ? 'completed' : 'partial', complete, summary: capture.summary, subject: { pid, birth: before.birth, strongIdentity: before.strong, ownership: 'external', sameProcessAfterCapture: sameProcess }, ...(scriptSha256 ? { scriptSha256 } : {}), process: result.process, diagnostics: result.diagnostics, elapsedMs: result.elapsedMs, stderr: result.stderr, cleanup: capture.cleanup, coverage: 'Observed execution during this interval; static correspondence and unobserved paths require separate evidence. macOS birth identity is best effort. Collector stop/kill never signals the external target.' };
|
|
113
|
+
if (o.output) {
|
|
114
|
+
const output = resolve(c.cwd, text(o.output, 4096)), content = JSON.stringify({ ...base, events: capture.events }, null, 2) + '\n';
|
|
115
|
+
await mkdir(dirname(output), { recursive: true, mode: 0o700 });
|
|
116
|
+
await writeFile(output, content, { flag: 'wx', mode: 0o600 });
|
|
117
|
+
return { ...base, output, bytes: Buffer.byteLength(content), totalEvents: capture.events.length };
|
|
118
|
+
}
|
|
119
|
+
if (records)
|
|
120
|
+
return { ...base, records: records.slice(offset, offset + limit), offset, limit, totalRecords: records.length, truncated: offset + limit < records.length, events: capture.events.filter(e => !(e.kind === 'message' && e.message?.payload?.kind === mode)) };
|
|
121
|
+
return { ...base, events: capture.events.slice(offset, offset + limit), offset, limit, totalEvents: capture.events.length, truncated: offset + limit < capture.events.length };
|
|
122
|
+
});
|
|
123
|
+
}, { permission: Permission.Update, options: [...options, ...(mode === 'exports' ? [{ flags: '--module <name>', description: 'Exact runtime module name or path', required: true }] : mode === 'observe' ? [{ flags: '--script <file>', description: 'Frida JavaScript source file; captured immutably before attach', required: true }, { flags: '--duration-seconds <seconds>', description: 'Observation window after script load (1–120)', defaultValue: 2 }] : [])] });
|
|
124
|
+
return [command('frida', definition.description, [...lifecycleCommands(definition), collect('modules'), collect('exports'), collect('observe')])];
|
|
125
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** Private Python-capable LLDB dependency. The public application remains `ghidra`. */
|
|
2
|
+
import type { CommandContext } from '@eyeauras/cli-factory';
|
|
3
|
+
import { ToolInstaller, type ToolLaunch } from './tool-runtime/installer.js';
|
|
4
|
+
export declare const managedGhidraDebugger: () => boolean;
|
|
5
|
+
export declare function ghidraDebuggerLaunch(root: string): ToolLaunch;
|
|
6
|
+
export declare function ghidraDebuggerInstaller(c: CommandContext): ToolInstaller;
|
|
7
|
+
export declare function prepareGhidraDebugger(c: CommandContext, o?: Record<string, unknown>): Promise<import("./tool-runtime/installer.js").SelectedTool>;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { join } from 'node:path';
|
|
2
|
+
import { release } from 'node:os';
|
|
3
|
+
import { ToolInstaller } from './tool-runtime/installer.js';
|
|
4
|
+
import { catalogArtifact } from './tool-runtime/catalog.js';
|
|
5
|
+
import { runTool } from './tool-runtime/run.js';
|
|
6
|
+
import { fail } from './model.js';
|
|
7
|
+
export const managedGhidraDebugger = () => process.platform === 'darwin' && process.arch === 'arm64' && Number(release().split('.')[0]) >= 24;
|
|
8
|
+
export function ghidraDebuggerLaunch(root) {
|
|
9
|
+
const python = join(root, 'python@3.15/3.15.0/Frameworks/Python.framework/Versions/3.15');
|
|
10
|
+
return { executable: join(root, 'bin/lldb'), arguments: [], environment: { PYTHONHOME: python, PYTHONPATH: join(root, 'lldb/23.1.3_1/lib/python3.15/site-packages'), LLDB_PYTHON_LIBRARY: join(python, 'Python'), LLDB_DEBUGSERVER_PATH: join(root, 'bin/debugserver'), PYTHONNOUSERSITE: '1', PYTHONDONTWRITEBYTECODE: '1' } };
|
|
11
|
+
}
|
|
12
|
+
export function ghidraDebuggerInstaller(c) {
|
|
13
|
+
return new ToolInstaller(c, {
|
|
14
|
+
id: 'ghidra-debugger', primary: 'lldb', components: () => {
|
|
15
|
+
if (!managedGhidraDebugger())
|
|
16
|
+
fail('unsupported', 'The managed Ghidra LLDB/Python backend requires macOS 15+ ARM64.');
|
|
17
|
+
return { lldb: catalogArtifact('0f9e88490490fb2f487ad6f02d7aea774629a2839a10497fdcbaad9c6481c839') };
|
|
18
|
+
}, launch: roots => ghidraDebuggerLaunch(roots.lldb), probe: async (launch) => {
|
|
19
|
+
const result = await runTool(c, { tool: 'ghidra-debugger', role: 'doctor', executable: launch.executable, arguments: ['--no-lldbinit', '--batch', '-o', 'script import lldb,sys; print("INSIGHT_LLDB_PYTHON_OK",lldb.SBDebugger.GetVersionString(),sys.version_info[:2])'], environment: { ...launch.environment, PATH: '/usr/bin:/bin' }, timeoutMs: 30000, maxOutputBytes: 65536, nativeDeadline: true });
|
|
20
|
+
if (!result.stdout.includes('INSIGHT_LLDB_PYTHON_OK lldb version 23.1.3 (3, 15)'))
|
|
21
|
+
fail('configuration', 'The managed debugger must load LLDB 23.1.3 and its own Python 3.15.');
|
|
22
|
+
return { version: '23.1.3', python: '3.15', backend: 'managed-lldb', hostHomebrewRequired: false };
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
export async function prepareGhidraDebugger(c, o = {}) {
|
|
27
|
+
const installer = ghidraDebuggerInstaller(c);
|
|
28
|
+
if (o.archive || (await installer.status()).state !== 'installed')
|
|
29
|
+
await installer.install(o);
|
|
30
|
+
return installer.selected();
|
|
31
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { CommandContext } from '@eyeauras/cli-factory';
|
|
2
|
+
import { type ProcessRecord } from './tool-runtime/supervisor.js';
|
|
3
|
+
import type { ToolProcessHooks } from './tool-runtime/commands.js';
|
|
4
|
+
import type { Scope, Workspace } from './workspace.js';
|
|
5
|
+
export declare function verifyGhidraProcess(r: ProcessRecord, c: CommandContext): Promise<boolean | undefined>;
|
|
6
|
+
export declare function ghidraProcessHooks(workspace: (c: CommandContext) => Workspace, close: (scope: Scope, c: CommandContext) => Promise<unknown>): ToolProcessHooks;
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { runtimeSelection } from './runtime-selection.js';
|
|
2
|
+
import { join, resolve, relative, sep } from 'node:path';
|
|
3
|
+
import { readFile, readdir, realpath } from 'node:fs/promises';
|
|
4
|
+
import { serverIdentity, stopLocalServer } from './server.js';
|
|
5
|
+
import { HttpBridge } from './transport.js';
|
|
6
|
+
import { registerExistingProcess } from './tool-runtime/supervisor.js';
|
|
7
|
+
import { fail } from './model.js';
|
|
8
|
+
async function ownedPath(c, path) {
|
|
9
|
+
if (typeof path !== 'string')
|
|
10
|
+
fail('binding', 'Tool resource moved outside this profile.');
|
|
11
|
+
const supplied = resolve(path), profile = resolve(c.appArguments.AppDataDirectory), canonical = await realpath(profile);
|
|
12
|
+
const base = supplied.startsWith(profile + sep) ? profile : supplied.startsWith(canonical + sep) ? canonical : undefined;
|
|
13
|
+
if (!base)
|
|
14
|
+
fail('binding', 'Tool resource moved outside this profile.');
|
|
15
|
+
// Keep Factory's raw AppData identity in process records, but compare native resources
|
|
16
|
+
// under its canonical profile. Accept the parent alias, never a replaced child link.
|
|
17
|
+
const expected = join(canonical, relative(base, supplied));
|
|
18
|
+
if (await realpath(supplied) !== expected)
|
|
19
|
+
fail('binding', 'Tool resource moved outside this profile.');
|
|
20
|
+
return expected;
|
|
21
|
+
}
|
|
22
|
+
export async function verifyGhidraProcess(r, c) {
|
|
23
|
+
try {
|
|
24
|
+
if (r.metadata?.serverDirectory) {
|
|
25
|
+
const directory = await ownedPath(c, r.metadata.serverDirectory), local = JSON.parse(await readFile(join(directory, 'server/local.json'), 'utf8'));
|
|
26
|
+
return Number((await serverIdentity(local, c)).pid) === r.pid;
|
|
27
|
+
}
|
|
28
|
+
if (r.metadata?.debuggerReceipt) {
|
|
29
|
+
const path = await ownedPath(c, r.metadata.debuggerReceipt), row = JSON.parse(await readFile(path, 'utf8')), root = await ownedPath(c, r.metadata.contextRoot), binding = JSON.parse(await readFile(join(root, 'process.json'), 'utf8'));
|
|
30
|
+
if (row.root !== root || row.ownerToken !== binding.tokenSecret || row.guiPid !== binding.pid || !Number.isSafeInteger(row.identityPort) || row.identityPort < 1 || row.identityPort > 65535)
|
|
31
|
+
return false;
|
|
32
|
+
const token = await c.secrets.require(binding.tokenSecret), response = await c.fetch('http://127.0.0.1:' + row.identityPort + '/identity', { redirect: 'error', signal: AbortSignal.timeout(1000), headers: { Authorization: 'Bearer ' + token } });
|
|
33
|
+
const body = await response.text();
|
|
34
|
+
if (!response.ok || body.length > 4096)
|
|
35
|
+
return false;
|
|
36
|
+
const info = JSON.parse(body);
|
|
37
|
+
return info.id === row.id && info.pid === row.supervisorPid && (r.role === 'debugger' ? info.childPid === r.pid : info.pid === r.pid);
|
|
38
|
+
}
|
|
39
|
+
if (r.metadata?.contextRoot) {
|
|
40
|
+
const root = await ownedPath(c, r.metadata.contextRoot), binding = JSON.parse(await readFile(join(root, 'process.json'), 'utf8'));
|
|
41
|
+
if (binding.root !== root || binding.pid !== r.pid || binding.runtimeFingerprint !== r.installation || binding.target !== r.target)
|
|
42
|
+
return false;
|
|
43
|
+
const token = await c.secrets.require(binding.tokenSecret), info = await new HttpBridge(binding.endpoint, c.fetch, undefined, token, 1500).instance();
|
|
44
|
+
return info.pid === r.pid && info.tcp_port === Number(new URL(binding.endpoint).port) && String(info.project_path ?? '').startsWith(root + sep);
|
|
45
|
+
}
|
|
46
|
+
return undefined;
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
export function ghidraProcessHooks(workspace, close) {
|
|
53
|
+
return {
|
|
54
|
+
verify: verifyGhidraProcess,
|
|
55
|
+
async discover(c) {
|
|
56
|
+
const directory = c.appArguments.AppDataDirectory, executable = runtimeSelection(directory)?.java ?? String(c.profile.values.java ?? 'unverified-legacy-executable');
|
|
57
|
+
async function walk(path, depth = 0) {
|
|
58
|
+
if (depth > 6)
|
|
59
|
+
return;
|
|
60
|
+
let entries;
|
|
61
|
+
try {
|
|
62
|
+
entries = await readdir(path, { withFileTypes: true });
|
|
63
|
+
}
|
|
64
|
+
catch (e) {
|
|
65
|
+
if (e.code === 'ENOENT')
|
|
66
|
+
return;
|
|
67
|
+
throw e;
|
|
68
|
+
}
|
|
69
|
+
for (const entry of entries) {
|
|
70
|
+
const at = join(path, entry.name);
|
|
71
|
+
if (entry.isDirectory())
|
|
72
|
+
await walk(at, depth + 1);
|
|
73
|
+
else if (entry.name === 'process.json') {
|
|
74
|
+
const b = JSON.parse(await readFile(at, 'utf8'));
|
|
75
|
+
if (b.toolProcessId || !b.pid)
|
|
76
|
+
continue;
|
|
77
|
+
let session;
|
|
78
|
+
if (b.context)
|
|
79
|
+
session = workspace(c).contextById(b.context).session;
|
|
80
|
+
try {
|
|
81
|
+
await registerExistingProcess(directory, { tool: 'ghidra', role: b.mode === 'gui' ? 'gui' : b.kind, installation: b.runtimeFingerprint, target: b.target, session, metadata: { contextRoot: b.root } }, executable, b.pid, r => verifyGhidraProcess(r, c));
|
|
82
|
+
}
|
|
83
|
+
catch { }
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
await walk(join(directory, 'workspace/ghidra-native'));
|
|
88
|
+
try {
|
|
89
|
+
const b = JSON.parse(await readFile(join(directory, 'workspace/server/local.json'), 'utf8'));
|
|
90
|
+
if (!b.toolProcessId && b.pid)
|
|
91
|
+
await registerExistingProcess(directory, { tool: 'ghidra', role: 'server', installation: 'legacy', metadata: { serverDirectory: join(directory, 'workspace') } }, executable, b.pid, r => verifyGhidraProcess(r, c));
|
|
92
|
+
}
|
|
93
|
+
catch { }
|
|
94
|
+
},
|
|
95
|
+
async stop(r, c) {
|
|
96
|
+
if (r.metadata?.contextRoot) {
|
|
97
|
+
if (!r.session || !r.target)
|
|
98
|
+
fail('busy', 'Internal Ghidra task is active; finish it before stopping its process.');
|
|
99
|
+
await close({ session: r.session, target: r.target }, c);
|
|
100
|
+
}
|
|
101
|
+
else if (r.role === 'server') {
|
|
102
|
+
const { runtimeProcesses } = await import('./runtime-manager.js');
|
|
103
|
+
if ((await runtimeProcesses(c.appArguments.AppDataDirectory)).some(p => p.kind !== 'server'))
|
|
104
|
+
fail('busy', 'Close Ghidra contexts before stopping their server.');
|
|
105
|
+
await stopLocalServer(await ownedPath(c, r.metadata?.serverDirectory), c);
|
|
106
|
+
}
|
|
107
|
+
},
|
|
108
|
+
async beforeKill(r, c) {
|
|
109
|
+
// Save debugger traces and terminate the inferior through the existing authenticated GUI
|
|
110
|
+
// protocol. A generic signal to LLDB cannot establish that its debuggee has exited.
|
|
111
|
+
if (r.role === 'gui' && r.session && r.target) {
|
|
112
|
+
const scope = { session: r.session, target: r.target }, w = workspace(c), context = w.context(scope);
|
|
113
|
+
const debuggerActive = context.debugger?.connected || context.debugger?.traces.some(t => t.connected) || w.unresolved(scope).some(q => q.execution?.kind === 'debugger');
|
|
114
|
+
if (debuggerActive)
|
|
115
|
+
await close(scope, c);
|
|
116
|
+
}
|
|
117
|
+
if (r.role.startsWith('debugger'))
|
|
118
|
+
fail('blocked', 'Close the owning GUI context to verify debugger and inferior cleanup.');
|
|
119
|
+
},
|
|
120
|
+
};
|
|
121
|
+
}
|
package/dist/src/ghidra.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { runTool } from './tool-runtime/run.js';
|
|
2
|
+
import { launchProcess } from './tool-runtime/supervisor.js';
|
|
2
3
|
import { fileURLToPath } from 'node:url';
|
|
3
|
-
import { spawn, execFile } from 'node:child_process';
|
|
4
4
|
import { createHash, randomUUID } from 'node:crypto';
|
|
5
5
|
import { mkdir, open, readFile, readdir, cp, realpath, stat } from 'node:fs/promises';
|
|
6
6
|
import { join, delimiter, resolve, isAbsolute, sep } from 'node:path';
|
|
@@ -89,7 +89,7 @@ export class GhidraRuntime {
|
|
|
89
89
|
if (bridgeSecret && bridgeToken)
|
|
90
90
|
await this.context.secrets.set(bridgeSecret, bridgeToken);
|
|
91
91
|
const log = await open(join(root, 'process.log'), 'a', 0o600);
|
|
92
|
-
const child =
|
|
92
|
+
const child = await launchProcess(this.context.appArguments.AppDataDirectory, { tool: 'ghidra', role: 'prototype-' + role, installation: expected }, java, ['-Xmx768m', '-Djava.awt.headless=true', '-Dghidra.home=' + home, '-Dapplication.name=GhidraMCP', '-Duser.home=' + root, '-Djava.io.tmpdir=' + root, '-cp', jars.join(delimiter), 'com.xebyte.headless.GhidraMCPHeadlessServer', '--bind', '127.0.0.1', '--port', String(port)], {
|
|
93
93
|
cwd: root, detached: true, stdio: ['ignore', log.fd, log.fd], windowsHide: true,
|
|
94
94
|
env: { PATH: this.context.environment.PATH ?? process.env.PATH, HOME: root, TMPDIR: root, XDG_RUNTIME_DIR: this.directory,
|
|
95
95
|
GHIDRA_SERVER_HOST: url.hostname, GHIDRA_SERVER_PORT: url.port || '13100', GHIDRA_SERVER_USER: user, GHIDRA_SERVER_PASSWORD: password,
|
|
@@ -295,9 +295,9 @@ export class GhidraRuntime {
|
|
|
295
295
|
const script = fileURLToPath(new URL('../../references/InsightRepositoryProbe.java', import.meta.url));
|
|
296
296
|
let stdout;
|
|
297
297
|
try {
|
|
298
|
-
({ stdout } = await
|
|
299
|
-
cwd: root,
|
|
300
|
-
|
|
298
|
+
({ stdout } = await runTool(this.context, { tool: 'ghidra', role: 'prototype-authority', executable: java, arguments: ['-Djava.awt.headless=true', '-Dghidra.home=' + home, '-Duser.home=' + root, '-Djava.io.tmpdir=' + root, '-cp', jars.join(delimiter), '--source', '21', script, t.repository, t.programPath, role],
|
|
299
|
+
cwd: root, timeoutMs: 30000, maxOutputBytes: 262144,
|
|
300
|
+
environment: { PATH: process.env.PATH, HOME: root, TMPDIR: root, GHIDRA_SERVER_HOST: url.hostname, GHIDRA_SERVER_PORT: url.port || '13100', GHIDRA_SERVER_USER: text(values[role === 'reader' ? 'readerUser' : 'publisherUser']), GHIDRA_SERVER_PASSWORD: password }
|
|
301
301
|
}));
|
|
302
302
|
}
|
|
303
303
|
catch {
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type CommandContext, type CommandDefinition } from '@eyeauras/cli-factory';
|
|
2
|
+
import { type ToolArtifact } from './tool-runtime/definition.js';
|
|
3
|
+
import { ToolInstaller } from './tool-runtime/installer.js';
|
|
4
|
+
import type { Workspace } from './workspace.js';
|
|
5
|
+
export declare function ilspyComponents(platform?: string, architecture?: NodeJS.Architecture): Record<string, ToolArtifact>;
|
|
6
|
+
export declare function ilspyInstaller(c: CommandContext): ToolInstaller;
|
|
7
|
+
export declare function ilspyCommands(workspace: (c: CommandContext) => Workspace): CommandDefinition[];
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { textWindow } from './text-window.js';
|
|
2
|
+
import { number } from './research.js';
|
|
3
|
+
import { managedMetadataCommands } from './managed-metadata.js';
|
|
4
|
+
import { command, Permission } from '@eyeauras/cli-factory';
|
|
5
|
+
import { join, resolve, dirname, relative, sep } from 'node:path';
|
|
6
|
+
import { mkdir, writeFile, readdir, lstat, copyFile } from 'node:fs/promises';
|
|
7
|
+
import { constants } from 'node:fs';
|
|
8
|
+
import { randomUUID } from 'node:crypto';
|
|
9
|
+
import { defineTool, lifecycleCommands } from './tool-runtime/definition.js';
|
|
10
|
+
import { ToolInstaller } from './tool-runtime/installer.js';
|
|
11
|
+
import { catalogArtifact } from './tool-runtime/catalog.js';
|
|
12
|
+
import { dotnetArtifact, dotnetLaunch } from './tool-runtime/dotnet.js';
|
|
13
|
+
import { runTool } from './tool-runtime/run.js';
|
|
14
|
+
import { fail, text, id } from './model.js';
|
|
15
|
+
export function ilspyComponents(platform = process.platform, architecture = process.arch) {
|
|
16
|
+
return { ilspy: catalogArtifact('74c07facaf1850c78a779fc509031f756e1c0de24b1a536f3363d7ef81ce001f'), dotnet: dotnetArtifact(platform, architecture) };
|
|
17
|
+
}
|
|
18
|
+
export function ilspyInstaller(c) {
|
|
19
|
+
return new ToolInstaller(c, { id: 'ilspy', primary: 'ilspy', components: ilspyComponents,
|
|
20
|
+
launch: roots => dotnetLaunch(roots.dotnet, join(roots.ilspy, 'ilspycmd.dll')),
|
|
21
|
+
async probe(launch, context) {
|
|
22
|
+
const result = await runTool(context, { tool: 'ilspy', role: 'version', executable: launch.executable, arguments: [...launch.arguments, '--disable-updatecheck', '--version'], environment: launch.environment, timeoutMs: 30000, maxOutputBytes: 65536 });
|
|
23
|
+
if (!/^ilspycmd: 11\.1\.0\.9782\s*$/m.test(result.stdout))
|
|
24
|
+
fail('configuration', 'The selected executable must provide ilspycmd 11.1.0.9782.');
|
|
25
|
+
return { version: '11.1.0.9782', runtime: 'private .NET 10.0.13 for managed installations' };
|
|
26
|
+
},
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
async function exportDirectory(stage, output) {
|
|
30
|
+
const files = [];
|
|
31
|
+
let bytes = 0;
|
|
32
|
+
async function walk(path) {
|
|
33
|
+
for (const entry of await readdir(path)) {
|
|
34
|
+
const at = join(path, entry), info = await lstat(at);
|
|
35
|
+
if (info.isSymbolicLink() || !info.isFile() && !info.isDirectory())
|
|
36
|
+
fail('binding', 'Tool output contains an unsupported link or special file.');
|
|
37
|
+
if (files.length > 100000 || (bytes += info.isFile() ? info.size : 0) > 256 * 1024 ** 2)
|
|
38
|
+
fail('limit', 'ILSpy export exceeds its 100000-file/256-MiB bound.');
|
|
39
|
+
if (info.isDirectory())
|
|
40
|
+
await walk(at);
|
|
41
|
+
else
|
|
42
|
+
files.push({ name: relative(stage, at), size: info.size });
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
await walk(stage);
|
|
46
|
+
await mkdir(dirname(output), { recursive: true, mode: 0o700 });
|
|
47
|
+
await mkdir(output, { mode: 0o700 });
|
|
48
|
+
for (const file of files) {
|
|
49
|
+
const destination = join(output, file.name);
|
|
50
|
+
await mkdir(dirname(destination), { recursive: true, mode: 0o700 });
|
|
51
|
+
await copyFile(join(stage, file.name), destination, constants.COPYFILE_EXCL);
|
|
52
|
+
}
|
|
53
|
+
return { outputDirectory: output, files, bytes };
|
|
54
|
+
}
|
|
55
|
+
export function ilspyCommands(workspace) {
|
|
56
|
+
const installer = (c) => ilspyInstaller(c);
|
|
57
|
+
const common = [{ flags: '--limit-chars <count>', description: 'Returned Unicode text window (1–32768); file export retains the full bounded native text', defaultValue: 16000 }, { flags: '--offset-chars <count>', description: 'Skip Unicode characters in returned text', defaultValue: 0 }, { flags: '--target <id>', description: 'Reuse an immutable research target' }, { flags: '--session <id>', description: 'Associate an existing research session' },
|
|
58
|
+
{ flags: '--output <path>', description: 'Write a new ordinary file (directory for project/resource)' },
|
|
59
|
+
{ flags: '--timeout-seconds <seconds>', description: 'Execution deadline, from 1 to 1800 seconds', defaultValue: 120 }];
|
|
60
|
+
const run = (operation, options = []) => command(operation + ' [input]', 'Static .NET ' + operation, async ({ args, options: o }, c) => {
|
|
61
|
+
const limitChars = number(o.limitChars ?? 16000, 32768, 1), offsetChars = number(o.offsetChars ?? 0, 4 * 1024 ** 2);
|
|
62
|
+
if (Boolean(args.input) === Boolean(o.target))
|
|
63
|
+
fail('invalid', 'Supply exactly one input path or --target.');
|
|
64
|
+
if (o.type && o.member)
|
|
65
|
+
fail('invalid', 'Choose --type or --member.');
|
|
66
|
+
const timeout = Number(o.timeoutSeconds);
|
|
67
|
+
if (!Number.isSafeInteger(timeout) || timeout < 1 || timeout > 1800)
|
|
68
|
+
fail('invalid', 'timeout-seconds must be from 1 to 1800.');
|
|
69
|
+
const w = workspace(c), target = args.input ? await w.importTarget(resolve(c.cwd, text(args.input, 4096))) : w.target(id(o.target)), session = o.session === undefined ? undefined : w.session(id(o.session)).id, input = await w.artifacts.verify(target.input);
|
|
70
|
+
const directory = operation === 'project' || operation === 'resource';
|
|
71
|
+
if (directory && !o.output)
|
|
72
|
+
fail('invalid', 'This operation requires --output DIRECTORY.');
|
|
73
|
+
const stage = directory ? join(c.appArguments.AppDataDirectory, 'runtime/exports', randomUUID()) : undefined;
|
|
74
|
+
if (stage)
|
|
75
|
+
await mkdir(stage, { recursive: true, mode: 0o700 });
|
|
76
|
+
const parameters = ['--disable-updatecheck'];
|
|
77
|
+
if (operation === 'types') {
|
|
78
|
+
const kind = o.kind === undefined ? 'c,i,s,d,e' : text(o.kind, 32);
|
|
79
|
+
if (!/^[cisde](?:,[cisde])*$/.test(kind))
|
|
80
|
+
fail('invalid', 'kind must be c,i,s,d,e selections.');
|
|
81
|
+
parameters.push('--list', kind.replaceAll(',', ''));
|
|
82
|
+
}
|
|
83
|
+
if (o.type)
|
|
84
|
+
parameters.push('--type', text(o.type, 4096));
|
|
85
|
+
if (o.member)
|
|
86
|
+
parameters.push('--member', text(o.member, 4096));
|
|
87
|
+
if (operation === 'il')
|
|
88
|
+
parameters.push('--ilcode');
|
|
89
|
+
if (operation === 'resources')
|
|
90
|
+
parameters.push('--list-resources');
|
|
91
|
+
if (operation === 'resource')
|
|
92
|
+
parameters.push('--resource', text(o.name, 4096), '--outputdir', stage);
|
|
93
|
+
if (operation === 'project')
|
|
94
|
+
parameters.push('--project', '--outputdir', stage);
|
|
95
|
+
if (operation === 'metadata')
|
|
96
|
+
parameters.push('--dump-table', text(o.table, 128), '--json');
|
|
97
|
+
parameters.push(input);
|
|
98
|
+
return installer(c).use(async (selected) => {
|
|
99
|
+
const result = await runTool(c, { tool: 'ilspy', role: operation, installation: selected.id, executable: selected.executable, arguments: [...selected.arguments, ...parameters], environment: selected.environment, timeoutMs: timeout * 1000, target: target.id, session });
|
|
100
|
+
const base = { state: 'completed', target: target.id, inputSha256: target.binarySha256, session, process: result.process, elapsedMs: result.elapsedMs, diagnostics: result.diagnostics, truncated: result.truncated };
|
|
101
|
+
if (stage) {
|
|
102
|
+
const output = resolve(c.cwd, text(o.output, 4096));
|
|
103
|
+
if (output === stage || output.startsWith(stage + sep) || stage.startsWith(output + sep))
|
|
104
|
+
fail('invalid', 'Output directory must be outside tool staging.');
|
|
105
|
+
return { ...base, ...await exportDirectory(stage, output) };
|
|
106
|
+
}
|
|
107
|
+
if (o.output) {
|
|
108
|
+
const output = resolve(c.cwd, text(o.output, 4096));
|
|
109
|
+
await mkdir(dirname(output), { recursive: true, mode: 0o700 });
|
|
110
|
+
await writeFile(output, result.stdout, { flag: 'wx', mode: 0o600 });
|
|
111
|
+
return { ...base, output, bytes: Buffer.byteLength(result.stdout) };
|
|
112
|
+
}
|
|
113
|
+
return { ...base, ...textWindow(result.stdout, limitChars, offsetChars, result.truncated) };
|
|
114
|
+
});
|
|
115
|
+
}, { permission: Permission.Update, options: [...common, ...options] });
|
|
116
|
+
const type = { flags: '--type <name>', description: 'Fully qualified type name' }, member = { flags: '--member <id>', description: 'XML member ID or metadata token' };
|
|
117
|
+
const definition = defineTool({ id: 'ilspy', description: 'Static .NET decompilation with a private runtime', components: [{ id: 'ilspy', version: '11.1.0.9782', artifacts: [], dependencies: ['dotnet'] }, { id: 'dotnet', version: '10.0.13', artifacts: [] }],
|
|
118
|
+
lifecycle: { download: (o, c) => installer(c).download(Boolean(o.offline)), install: (o, c) => installer(c).install(o), uninstall: (o, c) => installer(c).uninstall(Boolean(o.purgeCache)), doctor: (_o, c) => installer(c).doctor(), status: (_o, c) => installer(c).status() },
|
|
119
|
+
installOptions: [{ flags: '--archive <path>', description: 'Pinned ILSpy NuGet/zip archive' }, { flags: '--archive-sha256 <sha256>', description: 'Expected ILSpy archive SHA256' }, { flags: '--dotnet-archive <path>', description: 'Private .NET runtime tar.gz/zip' }, { flags: '--dotnet-archive-sha256 <sha256>', description: 'Expected .NET archive SHA256' }, { flags: '--executable <path>', description: 'External compatible ilspycmd executable; never removed' }, { flags: '--offline', description: 'Use only supplied archives and verified cache' }],
|
|
120
|
+
});
|
|
121
|
+
return [command('ilspy', definition.description, [...lifecycleCommands(definition), ...managedMetadataCommands(workspace, installer), run('types', [{ flags: '--kind <kinds>', description: 'Comma-separated c,i,s,d,e' }]), run('decompile', [type, member]), run('il', [type]), run('resources'), run('resource', [{ flags: '--name <name>', description: 'Resource name', required: true }]), run('project'), run('metadata', [{ flags: '--table <name>', description: 'Metadata table name or number', required: true }])])];
|
|
122
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type CommandContext, type CommandDefinition } from '@eyeauras/cli-factory';
|
|
2
|
+
import { ToolInstaller } from './tool-runtime/installer.js';
|
|
3
|
+
import type { Workspace } from './workspace.js';
|
|
4
|
+
export declare function lldbInstaller(c: CommandContext): ToolInstaller;
|
|
5
|
+
export declare function lldbPlan(o: Record<string, unknown>): string[];
|
|
6
|
+
export declare function lldbSnapshot(stdout: string): {
|
|
7
|
+
inferiorPid: number;
|
|
8
|
+
lines: string[];
|
|
9
|
+
};
|
|
10
|
+
export declare function lldbCommands(workspace: (c: CommandContext) => Workspace): CommandDefinition[];
|