Skip to content

Commit

Permalink
Fix ELFixer
Browse files Browse the repository at this point in the history
  • Loading branch information
BryanGIG committed Aug 13, 2023
1 parent 369f993 commit 3ebce4a
Show file tree
Hide file tree
Showing 9 changed files with 91 additions and 87 deletions.
Binary file removed app/src/main/assets/SoFixer/SoFixer32
Binary file not shown.
Binary file removed app/src/main/assets/SoFixer/SoFixer64
Binary file not shown.
Binary file added app/src/main/assets/arm64-v8a/fixer
Binary file not shown.
Binary file added app/src/main/assets/armeabi-v7a/fixer
Binary file not shown.
4 changes: 2 additions & 2 deletions app/src/main/java/com/dumper/android/core/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ class MainActivity : AppCompatActivity() {
dumpFile: Array<String>,
autoFix: Boolean
) {
val soFixerPath = "${filesDir.path}/SoFixer"
val soFixerPath = filesDir.path

Toast.makeText(this, "Please wait...", Toast.LENGTH_SHORT).show()

Expand All @@ -134,7 +134,7 @@ class MainActivity : AppCompatActivity() {

dumpFile.forEach {
dumper.file = it
dumper.dumpFile(this, autoFix, soFixerPath, outHandler)
dumper.dumpFile(this, autoFix, null, outHandler)
}
}
}
Expand Down
27 changes: 13 additions & 14 deletions app/src/main/java/com/dumper/android/dumper/Dumper.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ package com.dumper.android.dumper

import android.content.Context
import android.os.Environment
import com.dumper.android.dumper.MemUtils.getArchELF
import com.dumper.android.dumper.process.Process
import com.dumper.android.utils.DEFAULT_DIR
import com.dumper.android.utils.copyToFile
import com.dumper.android.utils.getArchELF
import com.dumper.android.utils.isELF
import com.dumper.android.utils.removeNullChar
import com.dumper.android.utils.toHex
import com.topjohnwu.superuser.Shell
Expand Down Expand Up @@ -35,7 +36,7 @@ class Dumper(private val pkg: String) {
outLog.appendLine("Output: ${outputFile.parent}")
}

private fun dumpFileNonRoot(ctx: Context, autoFix: Boolean, fixerPath: String, outLog: OutputHandler) {
private fun dumpFileNonRoot(ctx: Context, autoFix: Boolean, outLog: OutputHandler) {

val outputDir = File(ctx.filesDir, "temp")
if (!outputDir.exists())
Expand All @@ -45,7 +46,7 @@ class Dumper(private val pkg: String) {
if (!outputDir.exists())
outputFile.createNewFile()

dump(autoFix, fixerPath, outputFile, outLog)
dump(autoFix, ctx.filesDir.absolutePath, outputFile, outLog)

val fileOutPath = listOf(
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS),
Expand Down Expand Up @@ -83,13 +84,7 @@ class Dumper(private val pkg: String) {

outLog.appendLine("Fixing...")

val fixerELF = fixerPath + when (archELF) {
Arch.ARCH_32BIT -> "32"
Arch.ARCH_64BIT -> "64"
else -> "" //just to disable the warning
}

val fixer = Fixer.fixDump(fixerELF, outputFile, mem.sAddress.toHex())
val fixer = Fixer.fixDump(fixerPath, archELF, outputFile, mem.sAddress.toHex())
// Check output fixer and error fixer
if (fixer.first.isNotEmpty()) {
outLog.appendLine("Fixer output : \n${fixer.first.joinToString("\n")}")
Expand All @@ -107,7 +102,7 @@ class Dumper(private val pkg: String) {
* @param fixerPath ELFixer path
* @return log of the dump
*/
fun dumpFile(ctx: Context?, autoFix: Boolean, fixerPath: String, outLog: OutputHandler) {
fun dumpFile(ctx: Context?, autoFix: Boolean, fixerPath: String?, outLog: OutputHandler) {
try {
mem.pid = Process.getProcessID(pkg) ?: throw Exception("Process not found!")

Expand Down Expand Up @@ -137,10 +132,14 @@ class Dumper(private val pkg: String) {
return
}

if (ctx == null)

if (ctx == null) {
if (fixerPath == null)
throw Exception("Fixer path is null!")
dumpFileRoot(autoFix, fixerPath, outLog)
}
else
dumpFileNonRoot(ctx, autoFix, fixerPath, outLog)
dumpFileNonRoot(ctx, autoFix, outLog)

outLog.appendSuccess("Dump Success")
} catch (e: Exception) {
Expand Down Expand Up @@ -169,7 +168,7 @@ class Dumper(private val pkg: String) {
val map = MapParser(it)
if (mapStart == null) {
if (file.contains(".so")) {
if (map.getPath().contains(file) && MemUtils.isELF(mem.pid, map.getStartAddress())) {
if (map.getPath().contains(file) && isELF(mem.pid, map.getStartAddress())) {
mapStart = map
}
} else {
Expand Down
42 changes: 23 additions & 19 deletions app/src/main/java/com/dumper/android/dumper/Fixer.kt
Original file line number Diff line number Diff line change
@@ -1,32 +1,38 @@
package com.dumper.android.dumper

import android.content.Context
import com.topjohnwu.superuser.Shell
import java.io.File


enum class Arch {
UNKNOWN,
ARCH_32BIT,
ARCH_64BIT
enum class Arch(val value: String) {
UNKNOWN("Unknown"),
ARCH_32BIT("armeabi-v7a"),
ARCH_64BIT("arm64-v8a")
}
object Fixer {


/**
* Extract SoFixer into filesDir and
* Extract folder assets into filesDir and
* set permissions to 777 so the file can be executed
*/
fun extractLibs(ctx: Context) {
val libs = ctx.assets.list("SoFixer")
libs?.forEach { lib ->
ctx.assets.open("SoFixer/$lib").use { input ->
val out = File(ctx.filesDir, lib)
if (!out.exists()) {
input.copyTo(out.outputStream())
Shell.cmd("chmod 777 ${out.absolutePath}").exec()
val filesDir = ctx.filesDir
val list = listOf("armeabi-v7a", "arm64-v8a")
list.forEach { arch ->

val archDir = File(filesDir, arch)
if (!archDir.exists())
archDir.mkdirs()

ctx.assets.list(arch)
?.forEach { v ->
val file = File(archDir, v)
if (!file.exists()) {
ctx.assets.open("$arch/$v").copyTo(file.outputStream())
file.setExecutable(true, false)
}
}
}
}
}

Expand All @@ -38,7 +44,8 @@ object Fixer {
* @return pair of results inputStream, errorStream
*/
fun fixDump(
fixerPath: String,
filesDir: String,
arch: Arch,
dumpFile: File,
startAddress: String
): Pair<List<String>, List<String>> {
Expand All @@ -47,12 +54,9 @@ object Fixer {

val proc = ProcessBuilder(
listOf(
fixerPath,
"-s",
"$filesDir/${arch.value}/fixer",
dumpFile.path,
"-o",
"${dumpFile.parent}/${dumpFile.nameWithoutExtension}_fix.${dumpFile.extension}",
"-m",
"0x$startAddress"
)
)
Expand Down
52 changes: 0 additions & 52 deletions app/src/main/java/com/dumper/android/dumper/MemUtils.kt

This file was deleted.

53 changes: 53 additions & 0 deletions app/src/main/java/com/dumper/android/utils/MemUtils.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package com.dumper.android.utils

import com.dumper.android.dumper.Arch
import com.dumper.android.dumper.Memory
import java.io.File
import java.io.RandomAccessFile
import java.nio.ByteBuffer
import java.nio.channels.FileChannel

private val hElf =
byteArrayOf(0x7F, 'E'.code.toByte(), 'L'.code.toByte(), 'F'.code.toByte())

// Generate documentation

fun isELF(pid: Int, startAddress: Long): Boolean {
val file = File("/proc/$pid/mem")
val mFile = RandomAccessFile(file, "r")
val channel = mFile.channel
val byteHeader = ByteBuffer.allocate(4)
channel.read(byteHeader, startAddress)
channel.close()
mFile.close()
return byteHeader[0] == hElf[0] && byteHeader[1] == hElf[1] &&
byteHeader[2] == hElf[2] && byteHeader[3] == hElf[3]
}

fun getArchELF(mFile: FileChannel, memory: Memory): Arch {
val byteHeader = ByteBuffer.allocate(5)

mFile.read(byteHeader, memory.sAddress)

if (byteHeader[0] != hElf[0] || byteHeader[1] != hElf[1] ||
byteHeader[2] != hElf[2] || byteHeader[3] != hElf[3]
) {
return Arch.UNKNOWN
}


mFile.position(0) //reset pos
return when (byteHeader[4].toInt()) {
1 -> {
Arch.ARCH_32BIT
}

2 -> {
Arch.ARCH_64BIT
}

else -> {
Arch.UNKNOWN
}
}
}

0 comments on commit 3ebce4a

Please sign in to comment.