119 lines
4.1 KiB
PowerShell
119 lines
4.1 KiB
PowerShell
param(
|
|
[string]$IlFile = "runs/offline-evidence-intake/zyl-qqfile-20260709/metadata/c28-il/IMPlatformClient.exe.il",
|
|
[string]$OutDir = "runs/offline-chat-window"
|
|
)
|
|
|
|
$ErrorActionPreference = "Stop"
|
|
$repo = Resolve-Path -LiteralPath (Join-Path $PSScriptRoot "..")
|
|
|
|
function Resolve-RepoPath([string]$PathValue) {
|
|
if ([System.IO.Path]::IsPathRooted($PathValue)) {
|
|
return $PathValue
|
|
}
|
|
return (Join-Path $repo $PathValue)
|
|
}
|
|
|
|
$ilFull = Resolve-RepoPath $IlFile
|
|
$outFull = Resolve-RepoPath $OutDir
|
|
if (-not (Test-Path -LiteralPath $ilFull)) {
|
|
throw "IL file not found: $ilFull"
|
|
}
|
|
New-Item -ItemType Directory -Force -Path $outFull | Out-Null
|
|
|
|
$lines = Get-Content -LiteralPath $ilFull
|
|
$endIndex = $null
|
|
for ($i = 0; $i -lt $lines.Count; $i++) {
|
|
if ($lines[$i] -match 'end of method frmP2PChat::\.ctor') {
|
|
$endIndex = $i
|
|
break
|
|
}
|
|
}
|
|
if ($null -eq $endIndex) {
|
|
throw "frmP2PChat::.ctor end marker not found"
|
|
}
|
|
|
|
$startIndex = $null
|
|
for ($i = $endIndex; $i -ge 0; $i--) {
|
|
if ($lines[$i] -match '^\s*\.method\s+public\s+hidebysig\s+specialname\s+rtspecialname') {
|
|
$startIndex = $i
|
|
break
|
|
}
|
|
}
|
|
if ($null -eq $startIndex) {
|
|
throw "frmP2PChat::.ctor method start not found before line $($endIndex + 1)"
|
|
}
|
|
|
|
$ctorIlFile = Join-Path $outFull "frmP2PChat-ctor.il.txt"
|
|
$riskCsvFile = Join-Path $outFull "frmP2PChat-ctor-null-risk.csv"
|
|
$riskMdFile = Join-Path $outFull "frmP2PChat-ctor-null-risk.md"
|
|
|
|
$ctorLines = New-Object System.Collections.Generic.List[string]
|
|
for ($i = $startIndex; $i -le $endIndex; $i++) {
|
|
$ctorLines.Add(("{0}: {1}" -f ($i + 1), $lines[$i]))
|
|
}
|
|
$ctorLines | Set-Content -LiteralPath $ctorIlFile -Encoding UTF8
|
|
|
|
$riskRows = New-Object System.Collections.Generic.List[object]
|
|
foreach ($entry in $ctorLines) {
|
|
if ($entry -notmatch '\b(callvirt|ldfld)\b') {
|
|
continue
|
|
}
|
|
$offset = $null
|
|
if ($entry -match '(IL_[0-9a-fA-F]{4})') {
|
|
$offset = $matches[1].ToLowerInvariant().Replace("il_", "IL_")
|
|
}
|
|
$op = if ($entry -match '\b(callvirt|ldfld)\b') { $matches[1] } else { $null }
|
|
$target = ($entry -replace '^.*?\b(callvirt|ldfld)\b\s+', '').Trim()
|
|
$riskRows.Add([pscustomobject]@{
|
|
source_line = [int]($entry -replace '^(\d+):.*$', '$1')
|
|
il_offset = $offset
|
|
opcode = $op
|
|
target = $target
|
|
null_risk = if ($op -eq "callvirt") { "receiver_null_possible" } else { "instance_field_owner_null_possible" }
|
|
evidence = $entry.Trim()
|
|
})
|
|
}
|
|
|
|
$riskRows | Sort-Object source_line | Export-Csv -LiteralPath $riskCsvFile -NoTypeInformation -Encoding UTF8
|
|
|
|
$topEvidence = $riskRows |
|
|
Where-Object {
|
|
$_.target -match 'Connection::add_OnConnectError|Connection::add_OnReConnectOk|P2PChat::get_OtherJid|Jid::getBareJid|IMPPManager::get_UserInfo|UCChatSendMessageBox::GetChatRichTextBox|UCChatSendMessageBox::GetReceiptCheckBox|MessageCenter::add_OnTcpMessageArrived|RosterManager::UpdateStrangerStatus|BaseConfig::VisualPhoneEnable'
|
|
} |
|
|
Select-Object -First 40
|
|
|
|
$md = New-Object System.Collections.Generic.List[string]
|
|
$md.Add("# frmP2PChat constructor IL NullRisk")
|
|
$md.Add("")
|
|
$md.Add("- Source IL: $ilFull")
|
|
$md.Add("- Constructor source lines: $($startIndex + 1)-$($endIndex + 1)")
|
|
$md.Add("- Constructor line count: $($ctorLines.Count)")
|
|
$md.Add("- callvirt / ldfld risk rows: $($riskRows.Count)")
|
|
$md.Add("")
|
|
$md.Add("## High-signal risks")
|
|
$md.Add("")
|
|
$md.Add("| source_line | il_offset | opcode | target |")
|
|
$md.Add("|---:|---|---|---|")
|
|
foreach ($row in $topEvidence) {
|
|
$target = ($row.target -replace '\|', '\\|')
|
|
$md.Add("| $($row.source_line) | $($row.il_offset) | $($row.opcode) | $target |")
|
|
}
|
|
$md.Add("")
|
|
$md.Add("## Files")
|
|
$md.Add("")
|
|
$md.Add("- Full constructor IL: $ctorIlFile")
|
|
$md.Add("- Full NullRisk CSV: $riskCsvFile")
|
|
$md | Set-Content -LiteralPath $riskMdFile -Encoding UTF8
|
|
|
|
[pscustomobject]@{
|
|
ok = $true
|
|
il_file = $ilFull
|
|
ctor_line_start = $startIndex + 1
|
|
ctor_line_end = $endIndex + 1
|
|
ctor_line_count = $ctorLines.Count
|
|
risk_count = $riskRows.Count
|
|
ctor_il_file = $ctorIlFile
|
|
risk_csv_file = $riskCsvFile
|
|
risk_md_file = $riskMdFile
|
|
} | ConvertTo-Json -Compress
|