-
Notifications
You must be signed in to change notification settings - Fork 75
Open
Description
I tried to modify the APK, but most of them gave an error: Attempt to invoke virtual method 'boolean com.reandroid.arsc.chunk.xml.ResXmIStartNamespace.removelfNoReference()' on a nullobject reference
`package com.nekolaska.apk
import android.app.Activity
import com.luajava.LuaFunction
import com.reandroid.apkeditor.Util
import com.reandroid.apkeditor.compile.Builder
import com.reandroid.apkeditor.decompile.Decompiler
import java.io.File
import kotlin.concurrent.thread
class Editor(private val context: Activity) {
val cacheDir: String = File(context.cacheDir, "editor").absolutePath
fun start(
inApkPath: String,
outApkPath: String,
newPackage: String,
callback: LuaFunction<*>,
onError: LuaFunction<*>
) {
if (!File(inApkPath).exists()) {
onError.call("APK file does not exist")
return
}
thread {
decompile(inApkPath, newPackage, callback, onError)
build(outApkPath, callback, onError)
Util.deleteDir(File(cacheDir))
context.runOnUiThread {
callback.call("Task completed")
}
}
}
// Command line equivalent:
// java -jar C:\\Users\\NekoLaska\\Downloads\\APKEditor-1.3.9.jar d -i C:\\Users\\NekoLaska\\Downloads\\example.apk -o test_json
fun decompile(
apkPath: String,
newPackage: String,
callback: LuaFunction<*>,
onError: LuaFunction<*>
) = try {
decode(apkPath, newPackage, callback)
} catch (e: Exception) {
context.runOnUiThread {
callback.call("An exception occurred: " + e.message)
}
try {
decode(apkPath, newPackage, callback)
} catch (e: Exception) {
context.runOnUiThread {
onError.call("An exception occurred: " + e.message)
}
}
}
private fun decode(
apkPath: String,
newPackage: String,
callback: LuaFunction<*>,
) {
val outFile = File(cacheDir)
Util.deleteDir(outFile)
outFile.mkdirs()
Decompiler.execute(callback, "-i", apkPath, "-o", cacheDir)
modifyJson(newPackage)
modifyManifest(newPackage)
}
// Command line equivalent:
// java -jar C:\\Users\\NekoLaska\\Downloads\\APKEditor-1.3.9.jar b -i test_json -o test_edit.apk
fun build(apkPath: String, callback: LuaFunction<*>, onError: LuaFunction<*>) =
try {
File(apkPath).delete()
Builder.execute(callback, "-i", cacheDir, "-o", apkPath)
} catch (e: Exception) {
context.runOnUiThread {
callback.call("An exception occurred: " + e.message)
}
try {
File(apkPath).delete()
Builder.execute(callback, "-i", cacheDir, "-o", apkPath)
} catch (e: Exception) {
context.runOnUiThread {
onError.call("An exception occurred: " + e.message)
}
}
}
fun modifyJson(newPackage: String) {
val jsonPath = findJson()
var json = readString(jsonPath)
json = replacePackageText2(json!!, newPackage)
writeString(json, jsonPath)
}
fun modifyManifest(newPackage: String) {
val manifestPath = findManifest()
var manifest = readString(manifestPath)
manifest = replacePackageText(manifest!!, newPackage)
writeString(manifest, manifestPath)
}
fun writeString(str: String, path: String?) {
try {
if (path == null) {
return
}
val file = File(path)
file.writeText(str)
} catch (e: Exception) {
e.printStackTrace()
}
}
fun readString(path: String?): String? {
try {
if (path == null) {
return null
}
val file = File(path)
return file.readText()
} catch (e: Exception) {
e.printStackTrace()
}
return null
}
private fun replacePackageText(inputText: String, replacementText: String): String {
val pattern = "package=\\"([^\\"]*)\\""
return inputText.replace(pattern.toRegex(), "package=\\"$replacementText\\"")
}
private fun replacePackageText2(inputText: String, replacementText: String): String {
val pattern = "\\"package_name\\": \\"([^\\"]*)\\""
return inputText.replace(pattern.toRegex(), "\\"package_name\\": \\"$replacementText\\"")
}
private fun findFile(dirPath: String, fileName: String): String? {
val dir = File(dirPath) // Create a File object representing the specified directory path
if (!dir.exists()) { // If the directory doesn't exist, return null
return null
}
val files = dir.listFiles() ?: return null // Get list of all files in the directory, return null if empty
for (file in files) { // Iterate through the file list
if (file.isDirectory) {
val result = findFile(file.absolutePath, fileName)
if (result != null) { // If the file is found, return its path
return result
}
} else { // If it's a file
if (file.name.equals(fileName)) { // If the file name matches fileName, return its absolute path
return file.absolutePath
}
}
}
return null // If the file is not found, return null
}
fun findJson(): String? = findFile(cacheDir, "package.json")
fun findManifest(): String? = findFile(cacheDir, "AndroidManifest.xml")
}`
Metadata
Metadata
Assignees
Labels
No labels