106 lines
7.1 KiB
PowerShell
106 lines
7.1 KiB
PowerShell
param(
|
||
[string]$Package = "com.kuaishou.nebula",
|
||
[string]$Script = "out\probe_nebula_all_layers.js",
|
||
[string]$OutDir = "out",
|
||
[int]$PollSeconds = 90
|
||
)
|
||
|
||
$ErrorActionPreference = "Stop"
|
||
|
||
function Get-AppProcesses {
|
||
param([string]$Pkg)
|
||
|
||
$found = @{}
|
||
|
||
try {
|
||
$rows = & frida-ps -U 2>$null | Select-String $Pkg
|
||
foreach ($row in $rows) {
|
||
$line = $row.Line.Trim()
|
||
if ($line -match "^(\d+)\s+(.+)$") {
|
||
$pidValue = [int]$matches[1]
|
||
$nameValue = $matches[2].Trim()
|
||
$found[$pidValue] = [pscustomobject]@{ Pid = $pidValue; Name = $nameValue; Source = "frida-ps" }
|
||
}
|
||
}
|
||
} catch {}
|
||
|
||
try {
|
||
$rows = & adb shell ps -A 2>$null | Select-String $Pkg
|
||
foreach ($row in $rows) {
|
||
$line = $row.Line.Trim()
|
||
$parts = @($line -split "\s+")
|
||
if ($parts.Length -ge 2 -and $parts[1] -match "^\d+$") {
|
||
$pidValue = [int]$parts[1]
|
||
$nameValue = $parts[$parts.Length - 1]
|
||
$found[$pidValue] = [pscustomobject]@{ Pid = $pidValue; Name = $nameValue; Source = "adb-ps" }
|
||
}
|
||
}
|
||
} catch {}
|
||
|
||
foreach ($item in $found.Values) { $item }
|
||
}
|
||
|
||
function Safe-Name {
|
||
param([string]$Name)
|
||
return (($Name -replace '[^A-Za-z0-9_.-]+', '_').Trim('_'))
|
||
}
|
||
|
||
if (!(Test-Path $Script)) {
|
||
throw "Frida script not found: $Script"
|
||
}
|
||
if (!(Test-Path $OutDir)) {
|
||
New-Item -ItemType Directory -Path $OutDir | Out-Null
|
||
}
|
||
|
||
$Root = (Get-Location).ProviderPath
|
||
$ScriptPath = (Resolve-Path $Script).ProviderPath
|
||
$OutDirPath = (Resolve-Path $OutDir).ProviderPath
|
||
|
||
$ts = Get-Date -Format yyyyMMdd_HHmmss
|
||
$seen = @{}
|
||
$jobs = @()
|
||
$deadline = (Get-Date).AddSeconds($PollSeconds)
|
||
|
||
Write-Host ("MULTI_ATTACH package={0} script={1} poll={2}s ts={3}" -f $Package, $ScriptPath, $PollSeconds, $ts)
|
||
Write-Host "Open the main UI first, then run the login flow. This script polls child processes."
|
||
|
||
while ((Get-Date) -lt $deadline) {
|
||
$procs = @(Get-AppProcesses -Pkg $Package)
|
||
foreach ($p in $procs) {
|
||
if ($seen.ContainsKey($p.Pid)) { continue }
|
||
$seen[$p.Pid] = $true
|
||
|
||
$safe = Safe-Name $p.Name
|
||
$log = Join-Path $OutDirPath ("probe_multi_{0}_{1}_{2}.log" -f $ts, $p.Pid, $safe)
|
||
Write-Host ("ATTACH pid={0} name={1} source={2} log={3}" -f $p.Pid, $p.Name, $p.Source, $log)
|
||
|
||
$jobs += Start-Job -Name ("frida_{0}" -f $p.Pid) -ArgumentList $p.Pid,$p.Name,$ScriptPath,$log,$Root -ScriptBlock {
|
||
param($PidValue, $ProcessName, $ScriptAbsPath, $LogPath, $WorkDir)
|
||
try {
|
||
Set-Location -LiteralPath $WorkDir
|
||
("JOB_BEGIN pid={0} name={1} script={2} ts={3}" -f $PidValue, $ProcessName, $ScriptAbsPath, (Get-Date -Format o)) |
|
||
Out-File -Encoding UTF8 -FilePath $LogPath
|
||
& frida -U -p $PidValue -l $ScriptAbsPath 2>&1 |
|
||
Tee-Object -FilePath $LogPath -Append
|
||
("JOB_EXIT pid={0} exit={1} ts={2}" -f $PidValue, $LASTEXITCODE, (Get-Date -Format o)) |
|
||
Add-Content -Encoding UTF8 -Path $LogPath
|
||
} catch {
|
||
("JOB_ERR pid={0} err={1} ts={2}" -f $PidValue, $_, (Get-Date -Format o)) |
|
||
Add-Content -Encoding UTF8 -Path $LogPath
|
||
}
|
||
}
|
||
}
|
||
Start-Sleep -Seconds 2
|
||
}
|
||
|
||
Write-Host ("POLL_DONE attached_count={0}" -f $seen.Count)
|
||
Write-Host "After login: Get-Job | Stop-Job; Get-Job | Remove-Job"
|
||
Write-Host "View one: Receive-Job -Keep -Name frida_<PID>"
|
||
if ($PollSeconds -le 0) { return }
|
||
|
||
while ($true) {
|
||
Start-Sleep -Seconds 5
|
||
$running = @($jobs | Where-Object { $_.State -eq 'Running' })
|
||
Write-Host ("JOB_STATUS running={0} total={1}" -f $running.Count, $jobs.Count)
|
||
}
|