From b185b02f86e5ceb2a961eee82d932d9b2530d5f1 Mon Sep 17 00:00:00 2001 From: Romain Guy Date: Wed, 11 Dec 2024 09:57:25 -0800 Subject: [PATCH] Mark static methods as such --- .../kotlin/explorer/code/DataModels.kt | 14 ++++++++++++- .../kotlin/explorer/dex/DexDumpParser.kt | 20 +++++++++++++++---- 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/code/DataModels.kt b/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/code/DataModels.kt index c6fe6d34..82b87dd0 100644 --- a/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/code/DataModels.kt +++ b/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/code/DataModels.kt @@ -81,7 +81,19 @@ enum class ISA(val branchInstructions: ScatterSet, val returnInstruction data class Class(val header: String, val methods: List, val builtIn: Boolean) -data class Method(val header: String, val instructionSet: InstructionSet, val index: Int = -1, val codeSize: Int = -1) +const val AccessPublic = 0x00001 +const val AccessPrivate = 0x00002 +const val AccessStatic = 0x00008 +const val AccessFinal = 0x00010 +const val AccessSynthetic = 0x01000 +const val AccessConstructor = 0x10000 + +data class Method( + val header: String, + val instructionSet: InstructionSet, + val index: Int = -1, + val codeSize: Int = -1 +) data class InstructionSet( val isa: ISA, diff --git a/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/dex/DexDumpParser.kt b/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/dex/DexDumpParser.kt index f1a43a1f..47465029 100644 --- a/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/dex/DexDumpParser.kt +++ b/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/dex/DexDumpParser.kt @@ -30,15 +30,18 @@ import dev.romainguy.kotlin.explorer.oat.codeToOpAndOperands private val PositionRegex = Regex("^\\s*0x(?
[0-9a-f]+) line=(?\\d+)$") private val JumpRegex = Regex("^$HexDigit{4}: .* (?
$HexDigit{4}) // [+-]$HexDigit{4}$") +private val AccessRegex = Regex("^access\\s+:\\s+0x(?[0-9a-fA-F]+)\\s+\\(.+\\)$") private const val ClassStart = "Class #" private const val ClassEnd = "source_file_idx" private const val ClassName = "Class descriptor" private const val Instructions = "insns size" private const val Positions = "positions" +private const val Access = "access" internal class DexDumpParser { fun parse(text: String): CodeContent { + println(text) return try { val lines = text.lineSequence().iterator() val classes = buildList { @@ -61,18 +64,20 @@ internal class DexDumpParser { return null } val methods = buildList { + var access = 0 while (hasNext()) { val line = next().trim() + if (line.startsWith(Access)) access = readAccess(line) when { line.startsWith(ClassEnd) -> break - line.startsWith(Instructions) -> add(readMethod(className)) + line.startsWith(Instructions) -> add(readMethod(className, access)) } } } return Class("class $className", methods, false) } - private fun Iterator.readMethod(className: String): Method { + private fun Iterator.readMethod(className: String, access: Int): Method { val (name, type) = next().substringAfterLast(".").split(':', limit = 2) val instructions = readInstructions() @@ -83,16 +88,23 @@ internal class DexDumpParser { val paramTypes = paramTypesFromType(type).joinToString(", ") return Method( - "$returnType $className.$name($paramTypes)", + "$returnType $className.$name($paramTypes)${accessToString(access)}", InstructionSet(ISA.Dex, instructions.withLineNumbers(positions)) ) } + private fun accessToString(access: Int) = if (access and AccessStatic != 0) " // static" else "" + + private fun readAccess(line: String): Int { + val bitField = AccessRegex.matchEntire(line)?.getValue("bitField") + return if (bitField != null) bitField.toInt(16) else 0 + } + private fun Iterator.readInstructions(): List { return buildList { while (hasNext()) { val line = next() - if (line.startsWith(" ")) { + if (line[0] == ' ') { break } val code = line.substringAfter('|')