feat: support '.apks' files (PR #2647)
This commit is contained in:
@@ -23,6 +23,7 @@ dependencies {
|
||||
runtimeOnly(project(":jadx-plugins:jadx-xapk-input"))
|
||||
runtimeOnly(project(":jadx-plugins:jadx-aab-input"))
|
||||
runtimeOnly(project(":jadx-plugins:jadx-apkm-input"))
|
||||
runtimeOnly(project(":jadx-plugins:jadx-apks-input"))
|
||||
|
||||
implementation("org.jcommander:jcommander:2.0")
|
||||
implementation("ch.qos.logback:logback-classic:1.5.18")
|
||||
|
||||
@@ -17,7 +17,7 @@ import jadx.gui.utils.NLS;
|
||||
public class FileDialogWrapper {
|
||||
|
||||
private static final List<String> OPEN_FILES_EXTS = Arrays.asList(
|
||||
"apk", "dex", "jar", "class", "smali", "zip", "aar", "arsc", "jadx.kts", "xapk", "apkm");
|
||||
"apk", "dex", "jar", "class", "smali", "zip", "aar", "arsc", "jadx.kts", "xapk", "apkm", "apks");
|
||||
|
||||
private final MainWindow mainWindow;
|
||||
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
plugins {
|
||||
id("jadx-library")
|
||||
id("jadx-kotlin")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
api(project(":jadx-core"))
|
||||
|
||||
implementation(project(":jadx-plugins:jadx-dex-input"))
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
package jadx.plugins.input.apks
|
||||
|
||||
import jadx.api.plugins.input.ICodeLoader
|
||||
import jadx.api.plugins.input.JadxCodeInput
|
||||
import jadx.api.plugins.utils.CommonFileUtils
|
||||
import jadx.plugins.input.dex.DexInputPlugin
|
||||
import jadx.zip.ZipReader
|
||||
import java.io.File
|
||||
import java.nio.file.Path
|
||||
|
||||
class ApksCustomCodeInput(
|
||||
private val dexInputPlugin: DexInputPlugin,
|
||||
private val zipReader: ZipReader,
|
||||
) : JadxCodeInput {
|
||||
override fun loadFiles(input: List<Path>): ICodeLoader {
|
||||
val apkFiles = mutableListOf<File>()
|
||||
for (file in input.map { it.toFile() }) {
|
||||
if (!file.name.endsWith(".apks")) continue
|
||||
|
||||
// Load all files ending with .apk
|
||||
zipReader.visitEntries<Any>(file) { entry ->
|
||||
if (entry.name.endsWith(".apk")) {
|
||||
val tmpFile = entry.inputStream.use {
|
||||
CommonFileUtils.saveToTempFile(it, ".apk").toFile()
|
||||
}
|
||||
apkFiles.add(tmpFile)
|
||||
}
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
val codeLoader = dexInputPlugin.loadFiles(apkFiles.map { it.toPath() })
|
||||
|
||||
apkFiles.forEach { CommonFileUtils.safeDeleteFile(it) }
|
||||
|
||||
return codeLoader
|
||||
}
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
package jadx.plugins.input.apks
|
||||
|
||||
import jadx.api.ResourceFile
|
||||
import jadx.api.ResourcesLoader
|
||||
import jadx.api.plugins.CustomResourcesLoader
|
||||
import jadx.api.plugins.utils.CommonFileUtils
|
||||
import jadx.zip.ZipReader
|
||||
import java.io.File
|
||||
|
||||
class ApksCustomResourcesLoader(
|
||||
private val zipReader: ZipReader,
|
||||
) : CustomResourcesLoader {
|
||||
private val tmpFiles = mutableListOf<File>()
|
||||
|
||||
override fun load(loader: ResourcesLoader, list: MutableList<ResourceFile>, file: File): Boolean {
|
||||
if (!file.name.endsWith(".apks")) return false
|
||||
|
||||
// Load all files ending with .apk
|
||||
zipReader.visitEntries<Any>(file) { entry ->
|
||||
if (entry.name.endsWith(".apk")) {
|
||||
val tmpFile = entry.inputStream.use {
|
||||
CommonFileUtils.saveToTempFile(it, ".apk").toFile()
|
||||
}
|
||||
loader.defaultLoadFile(list, tmpFile, entry.name + "/")
|
||||
tmpFiles += tmpFile
|
||||
}
|
||||
null
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
override fun close() {
|
||||
tmpFiles.forEach(CommonFileUtils::safeDeleteFile)
|
||||
tmpFiles.clear()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package jadx.plugins.input.apks
|
||||
|
||||
import jadx.api.plugins.JadxPlugin
|
||||
import jadx.api.plugins.JadxPluginContext
|
||||
import jadx.api.plugins.JadxPluginInfo
|
||||
import jadx.plugins.input.dex.DexInputPlugin
|
||||
|
||||
class ApksInputPlugin : JadxPlugin {
|
||||
override fun getPluginInfo() = JadxPluginInfo(
|
||||
"apks-input",
|
||||
"APKS Input",
|
||||
"Load .apks files",
|
||||
)
|
||||
|
||||
override fun init(context: JadxPluginContext) {
|
||||
val dexInputPlugin = context.plugins().getInstance(DexInputPlugin::class.java)
|
||||
context.addCodeInput(ApksCustomCodeInput(dexInputPlugin, context.zipReader))
|
||||
context.decompiler.addCustomResourcesLoader(ApksCustomResourcesLoader(context.zipReader))
|
||||
}
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
jadx.plugins.input.apks.ApksInputPlugin
|
||||
@@ -29,6 +29,7 @@ include("jadx-plugins:jadx-kotlin-source-debug-extension")
|
||||
include("jadx-plugins:jadx-xapk-input")
|
||||
include("jadx-plugins:jadx-aab-input")
|
||||
include("jadx-plugins:jadx-apkm-input")
|
||||
include("jadx-plugins:jadx-apks-input")
|
||||
|
||||
include("jadx-plugins:jadx-script:jadx-script-plugin")
|
||||
include("jadx-plugins:jadx-script:jadx-script-runtime")
|
||||
|
||||
Reference in New Issue
Block a user