diff --git a/app/src/main/java/com/dumper/android/dumper/OutputHandler.kt b/app/src/main/java/com/dumper/android/dumper/OutputHandler.kt index 786cc76..9d982bb 100644 --- a/app/src/main/java/com/dumper/android/dumper/OutputHandler.kt +++ b/app/src/main/java/com/dumper/android/dumper/OutputHandler.kt @@ -7,6 +7,9 @@ import com.dumper.android.utils.TAG import java.io.FileOutputStream import java.io.OutputStream +/** + * Class responsible for handling output messages. + */ class OutputHandler { private var isRoot = false private lateinit var parcelFileDescriptor: ParcelFileDescriptor @@ -16,11 +19,10 @@ class OutputHandler { private constructor() /** - * This method is used to send message to client - * Use this method if you're on root services - * @param from: Message from client - * @param reply: Message to client - */ + * Constructor for root services. + * + * @param parcelFileDescriptor The ParcelFileDescriptor for root services. + */ constructor(parcelFileDescriptor: ParcelFileDescriptor) : this() { isRoot = true this.parcelFileDescriptor = parcelFileDescriptor @@ -28,15 +30,20 @@ class OutputHandler { } /** - * This method is used to append message to console - * Use this method if you're on non-root - * @param console: ConsoleViewModel to append - */ + * Constructor for non-root services. + * + * @param console The ConsoleViewModel to append messages to. + */ constructor(console: ConsoleViewModel) : this() { isRoot = false this.console = console } + /** + * Process the input string and send it to the appropriate output. + * + * @param str The string to be processed. + */ private fun processInput(str: String) { if (isRoot) { try { @@ -49,6 +56,11 @@ class OutputHandler { } } + /** + * Finish the output handling and close resources. + * + * @param code The exit code. + */ fun finish(code: Int) { if (isRoot) { try { @@ -62,26 +74,56 @@ class OutputHandler { } } + /** + * Append text to the output. + * + * @param text The text to append. + */ fun append(text: String) { processInput(text) } + /** + * Append a line of text to the output. + * + * @param text The text to append. + */ fun appendLine(text: String) { processInput(text + "\n") } + /** + * Append an error message to the output. + * + * @param text The error message to append. + */ fun appendError(text: String) { appendLine("[ERROR] $text") } + /** + * Append a warning message to the output. + * + * @param text The warning message to append. + */ fun appendWarning(text: String) { appendLine("[WARNING] $text") } + /** + * Append an info message to the output. + * + * @param text The info message to append. + */ fun appendInfo(text: String) { appendLine("[INFO] $text") } + /** + * Append a success message to the output. + * + * @param text The success message to append. + */ fun appendSuccess(text: String) { appendLine("[SUCCESS] $text") } diff --git a/app/src/main/java/com/dumper/android/dumper/elf/ElfUtils.kt b/app/src/main/java/com/dumper/android/dumper/elf/ElfUtils.kt index 3960ea4..0068a8e 100644 --- a/app/src/main/java/com/dumper/android/dumper/elf/ElfUtils.kt +++ b/app/src/main/java/com/dumper/android/dumper/elf/ElfUtils.kt @@ -6,9 +6,17 @@ import java.io.RandomAccessFile import java.nio.ByteBuffer import java.nio.channels.FileChannel +// ELF header magic number private val hElf = byteArrayOf(0x7F, 'E'.code.toByte(), 'L'.code.toByte(), 'F'.code.toByte()) +/** + * Checks if the memory at the given start address of a process is an ELF file. + * + * @param pid The process ID. + * @param startAddress The start address in the process memory. + * @return True if the memory at the start address is an ELF file, false otherwise. + */ fun isELF(pid: Int, startAddress: Long): Boolean { val mFile = RandomAccessFile("/proc/$pid/mem", "r") val channel = mFile.channel @@ -19,11 +27,23 @@ fun isELF(pid: Int, startAddress: Long): Boolean { return byteHeader.array().contentEquals(hElf) } +/** + * Determines the architecture of the ELF file in the given memory. + * + * @param mFile The file channel of the memory. + * @param memory The memory map line parser. + * @return The architecture of the ELF file. + */ fun getArchELF(mFile: FileChannel, memory: MapLineParser): Arch { val byteHeader = ByteBuffer.allocate(5) mFile.read(byteHeader, memory.getStartAddress()) + for (i in 0 until 4) { + if (byteHeader[i] != hElf[i]) { + return Arch.UNKNOWN + } + } if (byteHeader[0] != hElf[0] || byteHeader[1] != hElf[1] || byteHeader[2] != hElf[2] || byteHeader[3] != hElf[3] ) { diff --git a/app/src/main/java/com/dumper/android/dumper/process/Process.kt b/app/src/main/java/com/dumper/android/dumper/process/Process.kt index 5e73cbe..2a6bc78 100644 --- a/app/src/main/java/com/dumper/android/dumper/process/Process.kt +++ b/app/src/main/java/com/dumper/android/dumper/process/Process.kt @@ -12,13 +12,25 @@ import java.io.File object Process { + /** + * Get all processes running on the device. + * + * @param ctx The application context. + * @param isRoot Boolean indicating if the device is rooted. + * @return List of ProcessData containing process information. + */ fun getAllProcess(ctx: Context, isRoot: Boolean) = if (isRoot) getAllProcessRoot(ctx) else getAllProcessNoRoot() - + /** + * Get all processes running on a rooted device. + * + * @param ctx The application context. + * @return List of ProcessData containing process information. + */ private fun getAllProcessRoot(ctx: Context): List { val activityManager = ctx.getSystemService(ACTIVITY_SERVICE) as ActivityManager return activityManager.runningAppProcesses @@ -36,6 +48,11 @@ object Process { } } + /** + * Get all processes running on a non-rooted device. + * + * @return List of ProcessData containing process information. + */ private fun getAllProcessNoRoot(): List { return File("/proc") .listFiles().orEmpty() @@ -58,8 +75,10 @@ object Process { } /** - * Get the PID - * @return pid of process or null if process id is not found + * Get the PID of a process by its package name. + * + * @param pkg The package name of the process. + * @return The PID of the process or null if not found. */ fun getProcessID(pkg: String): Int? { return File("/proc") diff --git a/app/src/main/java/com/dumper/android/dumper/process/ProcessData.kt b/app/src/main/java/com/dumper/android/dumper/process/ProcessData.kt index 84ed4db..b07b3ca 100644 --- a/app/src/main/java/com/dumper/android/dumper/process/ProcessData.kt +++ b/app/src/main/java/com/dumper/android/dumper/process/ProcessData.kt @@ -5,10 +5,5 @@ import kotlinx.parcelize.Parcelize @Parcelize data class ProcessData(val processName: String, val appName: String): Parcelable { - fun getDisplayName(): String { - return if (processName.contains(":")) - "$appName (${processName.substringAfter(":")})" - else - appName - } + fun getDisplayName() = if (processName.contains(":")) "$appName (${processName.substringAfter(":")})" else appName } \ No newline at end of file diff --git a/app/src/main/java/com/dumper/android/dumper/sofixer/Fixer.kt b/app/src/main/java/com/dumper/android/dumper/sofixer/Fixer.kt index ae48758..a1a2196 100644 --- a/app/src/main/java/com/dumper/android/dumper/sofixer/Fixer.kt +++ b/app/src/main/java/com/dumper/android/dumper/sofixer/Fixer.kt @@ -8,8 +8,21 @@ import kotlinx.coroutines.awaitAll import kotlinx.coroutines.runBlocking import java.io.File +/** + * Class responsible for fixing ELF files using SoFixer. + * + * @property fixerPath The path to the SoFixer executable. + */ class Fixer(private val fixerPath: String) { + /** + * Fix the dumped ELF file. + * + * @param startAddress The start address of the ELF file. + * @param archELF The architecture of the ELF file. + * @param outputFile The output file to be fixed. + * @param outLog The output handler for logging messages. + */ fun fixELFFile( startAddress: Long, archELF: Arch, @@ -32,7 +45,13 @@ class Fixer(private val fixerPath: String) { } /** - * Run SoFixer + * Run SoFixer to fix the dumped ELF file. + * + * @param arch The architecture of the ELF file. + * @param dumpFile The dumped ELF file to be fixed. + * @param startAddress The start address of the ELF file in hexadecimal format. + * @param onSuccess Callback function to handle success messages. + * @param onError Callback function to handle error messages. */ private fun fixDump( arch: Arch, @@ -49,7 +68,6 @@ class Fixer(private val fixerPath: String) { "0x$startAddress" ) ) - .redirectErrorStream(true) .start() runBlocking { diff --git a/app/src/main/java/com/dumper/android/dumper/sofixer/FixerUtils.kt b/app/src/main/java/com/dumper/android/dumper/sofixer/FixerUtils.kt index 9caa021..663ad15 100644 --- a/app/src/main/java/com/dumper/android/dumper/sofixer/FixerUtils.kt +++ b/app/src/main/java/com/dumper/android/dumper/sofixer/FixerUtils.kt @@ -6,8 +6,10 @@ import java.io.File object FixerUtils { /** - * Extract folder assets into filesDir and - * set permissions to 777 so the file can be executed + * Extracts folder assets into the application's files directory and + * sets permissions to 777 so the files can be executed. + * + * @param ctx The application context. */ fun extractLibs(ctx: Context) { val filesDir = ctx.filesDir diff --git a/app/src/main/java/com/dumper/android/ui/console/ConsoleViewModel.kt b/app/src/main/java/com/dumper/android/ui/console/ConsoleViewModel.kt index 83c37e6..1f147e2 100644 --- a/app/src/main/java/com/dumper/android/ui/console/ConsoleViewModel.kt +++ b/app/src/main/java/com/dumper/android/ui/console/ConsoleViewModel.kt @@ -12,12 +12,14 @@ class ConsoleViewModel : ViewModel() { val console = MutableLiveData("") val finishCode = MutableLiveData>() + fun copyConsole(context: Context) { val clipboard = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager val clip = ClipData.newPlainText("PADumper-Log", console.value) clipboard.setPrimaryClip(clip) Toast.makeText(context, "Log Copied!", Toast.LENGTH_SHORT).show() } + fun append(text: String) { console.value += text }