Files

160 lines
4.8 KiB
PowerShell

#requires -Version 7
[CmdletBinding()]
param(
[Parameter(Mandatory = $true)]
[string]$ApkPath,
[string]$Name,
[string]$OutRoot,
[switch]$SkipJadx,
[switch]$SkipApktool,
[switch]$Clean
)
Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'
[Console]::InputEncoding = [System.Text.UTF8Encoding]::new($false)
[Console]::OutputEncoding = [System.Text.UTF8Encoding]::new($false)
$OutputEncoding = [System.Text.UTF8Encoding]::new($false)
function Get-ToolPath {
param([Parameter(Mandatory = $true)][string]$Name)
$cmd = Get-Command $Name -ErrorAction SilentlyContinue
if (-not $cmd) {
$toolRoot = (Resolve-Path (Join-Path $PSScriptRoot '..\..\..')).Path
$fallbacks = @{
'jadx' = @(
(Join-Path $toolRoot 'jadx\bin\jadx.bat')
)
'apktool' = @(
(Join-Path $toolRoot 'apktool\apktool.bat')
)
}
if ($fallbacks.Contains($Name)) {
foreach ($candidate in $fallbacks[$Name]) {
if (Test-Path -LiteralPath $candidate) {
return $candidate
}
}
}
throw "Missing required CLI tool: $Name"
}
return $cmd.Source
}
function Get-SafeName {
param([Parameter(Mandatory = $true)][string]$PathValue)
$raw = [System.IO.Path]::GetFileNameWithoutExtension($PathValue)
if ([string]::IsNullOrWhiteSpace($raw)) {
$raw = 'apk'
}
return ($raw -replace '[^A-Za-z0-9._-]', '_')
}
function Get-DefaultOutRoot {
param([Parameter(Mandatory = $true)][string]$ApkFilePath)
$parent = Split-Path -Path $ApkFilePath -Parent
if ([string]::IsNullOrWhiteSpace($parent)) {
return [System.IO.Directory]::GetCurrentDirectory()
}
return $parent
}
function Get-ManifestPackage {
param([Parameter(Mandatory = $true)][string]$ManifestPath)
if (-not (Test-Path -LiteralPath $ManifestPath)) {
return ''
}
try {
$xml = [xml](Get-Content -LiteralPath $ManifestPath -Raw -Encoding UTF8)
return [string]$xml.manifest.package
}
catch {
return ''
}
}
if (-not (Test-Path -LiteralPath $ApkPath)) {
throw "APK not found: $ApkPath"
}
$jadxPath = $null
$apktoolPath = $null
if (-not $SkipJadx) {
$jadxPath = Get-ToolPath -Name 'jadx'
}
if (-not $SkipApktool) {
$apktoolPath = Get-ToolPath -Name 'apktool'
}
$taskName = if ($Name) { $Name } else { Get-SafeName -PathValue $ApkPath }
$resolvedOutRoot = if ([string]::IsNullOrWhiteSpace($OutRoot)) { Get-DefaultOutRoot -ApkFilePath $ApkPath } else { $OutRoot }
$taskRoot = Join-Path $resolvedOutRoot $taskName
$jadxOut = Join-Path $taskRoot 'jadx'
$apktoolOut = Join-Path $taskRoot 'apktool'
if (-not (Test-Path -LiteralPath $resolvedOutRoot)) {
New-Item -ItemType Directory -Path $resolvedOutRoot -Force | Out-Null
}
if ($Clean -and (Test-Path -LiteralPath $taskRoot)) {
Remove-Item -LiteralPath $taskRoot -Recurse -Force
}
if (-not (Test-Path -LiteralPath $taskRoot)) {
New-Item -ItemType Directory -Path $taskRoot -Force | Out-Null
}
$jadxExitCode = $null
if (-not $SkipJadx) {
if (Test-Path -LiteralPath $jadxOut) {
Remove-Item -LiteralPath $jadxOut -Recurse -Force
}
& $jadxPath -d $jadxOut $ApkPath
$jadxExitCode = $LASTEXITCODE
}
$apktoolExitCode = $null
if (-not $SkipApktool) {
if (Test-Path -LiteralPath $apktoolOut) {
Remove-Item -LiteralPath $apktoolOut -Recurse -Force
}
& $apktoolPath d $ApkPath -o $apktoolOut -f
$apktoolExitCode = $LASTEXITCODE
}
$manifestPath = Join-Path $apktoolOut 'AndroidManifest.xml'
$packageName = if (-not $SkipApktool) { Get-ManifestPackage -ManifestPath $manifestPath } else { '' }
$javaCount = if ((Test-Path -LiteralPath $jadxOut)) { (Get-ChildItem -LiteralPath $jadxOut -Recurse -File -Filter '*.java' | Measure-Object).Count } else { 0 }
$smaliDirCount = if ((Test-Path -LiteralPath $apktoolOut)) { (Get-ChildItem -LiteralPath $apktoolOut -Directory -Filter 'smali*' | Measure-Object).Count } else { 0 }
$libCount = if ((Test-Path -LiteralPath $apktoolOut)) { (Get-ChildItem -LiteralPath $apktoolOut -Recurse -File -Filter '*.so' | Measure-Object).Count } else { 0 }
$resXmlCount = if ((Test-Path -LiteralPath $apktoolOut)) { (Get-ChildItem -LiteralPath $apktoolOut -Recurse -File -Filter '*.xml' | Measure-Object).Count } else { 0 }
"task_root=$taskRoot"
"jadx_out=$jadxOut"
"apktool_out=$apktoolOut"
"package=$packageName"
"jadx_exit_code=$jadxExitCode"
"apktool_exit_code=$apktoolExitCode"
"java_files=$javaCount"
"smali_dirs=$smaliDirCount"
"so_files=$libCount"
"xml_files=$resXmlCount"
if (($jadxExitCode -ne $null) -and ($jadxExitCode -ne 0)) {
"warning=jadx returned non-zero exit code; inspect output but treat exported sources as usable if present"
}