docs: add offline b-route reverse decision
This commit is contained in:
168
scripts/build-offline-broute-reverse-index.ps1
Normal file
168
scripts/build-offline-broute-reverse-index.ps1
Normal file
@@ -0,0 +1,168 @@
|
||||
param(
|
||||
[string]$OutputDir = "runs/offline-broute-reverse",
|
||||
[string]$ReportPath = "docs/source-discovery/2026-07-12-offline-broute-reverse-index.md"
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
$repo = (Resolve-Path -LiteralPath (Join-Path $PSScriptRoot "..")).Path
|
||||
$outDir = Join-Path $repo $OutputDir
|
||||
$reportFullPath = Join-Path $repo $ReportPath
|
||||
New-Item -ItemType Directory -Force -Path $outDir | Out-Null
|
||||
New-Item -ItemType Directory -Force -Path (Split-Path -Parent $reportFullPath) | Out-Null
|
||||
|
||||
$samples = @(
|
||||
@{
|
||||
path = "runs/offline-real-client-window/full/zyl/Impp/IMPlatformClient.exe"
|
||||
role = "main managed client; text send, chat window, plugin/IPC candidates"
|
||||
expected_sha256 = "E2966E58360DAEEBF178410A961E2DC52748C63E9CCBD94BD6EC8434A1A09CB7"
|
||||
},
|
||||
@{
|
||||
path = "runs/offline-real-client-window/full/zyl/Impp/IMPP.Service.dll"
|
||||
role = "file upload service candidates"
|
||||
expected_sha256 = "F859DE2F34E024B5F372D95F22CBF8A018C780F24203E7A76D392E52BD90CADD"
|
||||
},
|
||||
@{
|
||||
path = "runs/offline-real-client-window/full/zyl/Impp/IMPP.Interface.dll"
|
||||
role = "service/interface contract candidates"
|
||||
expected_sha256 = "DD093CF61FAE85C2D2581F289B01AA477546712E098FEF81272FDD989E50D12D"
|
||||
},
|
||||
@{
|
||||
path = "runs/offline-real-client-window/full/zyl/Impp/IMPP.Model.dll"
|
||||
role = "model/parameter types"
|
||||
expected_sha256 = "7CBABDD23A7234D15E294C549EEEC78EFBAD6E957CD45A6E8A85309349A624A5"
|
||||
},
|
||||
@{
|
||||
path = "runs/offline-real-client-window/full/zyl/Impp/IMPP.UI.dll"
|
||||
role = "UI/plugin helpers and possible send controls"
|
||||
expected_sha256 = "4C61212519C01D1B731ED4F20DF3411C491616F4ADA98A4529722A6AA3689E6D"
|
||||
},
|
||||
@{
|
||||
path = "runs/offline-real-client-window/full/zyl/Impp/IMPP.Common.dll"
|
||||
role = "shared utility and message types"
|
||||
expected_sha256 = "02A47C99C27C9BFE2BADC438389300C92220B07609BD87C48B4B5E1B4EE6AEB4"
|
||||
},
|
||||
@{
|
||||
path = "runs/offline-real-client-window/full/zyl/Impp/IMPP.Helper.dll"
|
||||
role = "helper abstractions"
|
||||
expected_sha256 = "30932D082B6678699C832C63F923E01EAD84674FAEDB613D631E034E03742FB9"
|
||||
},
|
||||
@{
|
||||
path = "runs/offline-real-client-window/full/zyl/Impp/smack.dll"
|
||||
role = "XMPP chat/send layer"
|
||||
expected_sha256 = "BAD0BB0591765DB153B17CECC1112B0BBDBF3B1D3370DDF973F91974E92CEC66"
|
||||
},
|
||||
@{
|
||||
path = "runs/offline-real-client-window/full/zyl/Impp/TcpFileTransfer.dll"
|
||||
role = "native/transfer candidate"
|
||||
expected_sha256 = "6C4874B46D1E7DC04C9B6784180603452400B881E04509D464A0D58814EFEDA7"
|
||||
},
|
||||
@{
|
||||
path = "runs/offline-real-client-window/full/zyl/Impp/HttpServerLib.dll"
|
||||
role = "local API/IPC candidate"
|
||||
expected_sha256 = "FFDB633216AE332B8EDFFC83E2AE546B7A80144C659FF4053FDFE4FE382A8D12"
|
||||
},
|
||||
@{
|
||||
path = "runs/offline-real-client-window/full/zyl/Impp/INetwork.dll"
|
||||
role = "network abstraction candidate"
|
||||
expected_sha256 = "E40BE4EE2439E4280461F4D2BADB318A5F4572428F069AB6D17B4C4F0E8CFAC9"
|
||||
},
|
||||
@{
|
||||
path = "runs/offline-real-client-window/full/zyl/Impp/IOClientNetwork.dll"
|
||||
role = "network implementation candidate"
|
||||
expected_sha256 = "64CA231A614771325741A5F098E52EBF20F7190E339B64962DE2EDEDCFFFF904"
|
||||
}
|
||||
)
|
||||
|
||||
$entries = foreach ($sample in $samples) {
|
||||
$fullPath = Join-Path $repo $sample.path
|
||||
$exists = Test-Path -LiteralPath $fullPath -PathType Leaf
|
||||
$item = $null
|
||||
$sha256 = ""
|
||||
$matches = $false
|
||||
if ($exists) {
|
||||
$item = Get-Item -LiteralPath $fullPath
|
||||
$sha256 = (Get-FileHash -LiteralPath $fullPath -Algorithm SHA256).Hash.ToUpperInvariant()
|
||||
$matches = ($sha256 -eq $sample.expected_sha256)
|
||||
}
|
||||
[pscustomobject]@{
|
||||
path = $sample.path
|
||||
file_name = Split-Path -Leaf $sample.path
|
||||
role = $sample.role
|
||||
exists = $exists
|
||||
size_bytes = if ($item) { $item.Length } else { $null }
|
||||
last_write_time = if ($item) { $item.LastWriteTime.ToString("o") } else { $null }
|
||||
sha256 = $sha256
|
||||
expected_sha256 = $sample.expected_sha256
|
||||
sha256_matches_expected = $matches
|
||||
}
|
||||
}
|
||||
|
||||
$summary = [pscustomobject]@{
|
||||
generated_at = (Get-Date).ToUniversalTime().ToString("o")
|
||||
repository = $repo
|
||||
output_dir = $OutputDir
|
||||
samples_total = @($entries).Count
|
||||
samples_present = @($entries | Where-Object { $_.exists }).Count
|
||||
hash_matches = @($entries | Where-Object { $_.sha256_matches_expected }).Count
|
||||
originals_copied = $false
|
||||
originals_modified = $false
|
||||
entries = $entries
|
||||
}
|
||||
|
||||
$jsonPath = Join-Path $outDir "index.json"
|
||||
$summary | ConvertTo-Json -Depth 8 | Set-Content -LiteralPath $jsonPath -Encoding UTF8
|
||||
|
||||
$lines = New-Object System.Collections.Generic.List[string]
|
||||
$lines.Add("# Offline B-Route Reverse Index")
|
||||
$lines.Add("")
|
||||
$lines.Add("Date: 2026-07-12")
|
||||
$lines.Add("")
|
||||
$lines.Add("## Scope")
|
||||
$lines.Add("")
|
||||
$lines.Add("This index records the read-only offline samples for B-route reverse engineering. The script reads metadata and SHA256 hashes only; it does not copy or modify the original binaries.")
|
||||
$lines.Add("")
|
||||
$lines.Add("## Summary")
|
||||
$lines.Add("")
|
||||
$lines.Add("- Samples total: $($summary.samples_total)")
|
||||
$lines.Add("- Samples present: $($summary.samples_present)")
|
||||
$lines.Add("- Hash matches: $($summary.hash_matches)")
|
||||
$lines.Add("- Originals copied: false")
|
||||
$lines.Add("- Originals modified: false")
|
||||
$lines.Add("- Machine JSON: ``$OutputDir/index.json``")
|
||||
$lines.Add("")
|
||||
$lines.Add("## Sample table")
|
||||
$lines.Add("")
|
||||
$lines.Add("| Sample | Role | Size | SHA256 match | SHA256 |")
|
||||
$lines.Add("| --- | --- | ---: | --- | --- |")
|
||||
foreach ($entry in $entries) {
|
||||
$size = if ($null -ne $entry.size_bytes) { [string]$entry.size_bytes } else { "missing" }
|
||||
$match = if ($entry.sha256_matches_expected) { "yes" } else { "no" }
|
||||
$sha = if ($entry.sha256) { $entry.sha256 } else { "missing" }
|
||||
$lines.Add("| ``$($entry.path)`` | $($entry.role) | $size | $match | ``$sha`` |")
|
||||
}
|
||||
$lines.Add("")
|
||||
$lines.Add("## Verified facts")
|
||||
$lines.Add("")
|
||||
$lines.Add("- All metadata came from local filesystem reads under the repository workspace.")
|
||||
$lines.Add("- The expected primary B-route samples are present if `Samples present` equals `Samples total`.")
|
||||
$lines.Add("- Hash matching only proves local file identity against this plan's recorded sample list; it does not prove runtime invocability.")
|
||||
$lines.Add("")
|
||||
$lines.Add("## Next reverse targets")
|
||||
$lines.Add("")
|
||||
$lines.Add("1. Text-send static call graph: `SendTxtMessageByJid`, `MessageScheduling.SendChatMessage`, `Chat.SendMessage`, `XMPPConnection.send`.")
|
||||
$lines.Add("2. File-send/upload static call graph: `OffLineFileSend.sendFile`, `FileTransfer.FileUpload`, `AsynFileUpload`, `sendFileMessage`.")
|
||||
$lines.Add("3. Bridge/IPC/plugin map: `HttpServerLib`, plugin loaders, local HTTP, named pipes, command-line switches, services.")
|
||||
|
||||
($lines -join "`n") + "`n" | Set-Content -LiteralPath $reportFullPath -Encoding UTF8
|
||||
|
||||
[pscustomobject]@{
|
||||
ok = $true
|
||||
json_path = $jsonPath
|
||||
report_path = $reportFullPath
|
||||
samples_total = $summary.samples_total
|
||||
samples_present = $summary.samples_present
|
||||
hash_matches = $summary.hash_matches
|
||||
originals_copied = $false
|
||||
originals_modified = $false
|
||||
} | ConvertTo-Json -Depth 4
|
||||
Reference in New Issue
Block a user