diff --git a/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/CodeTextArea.kt b/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/CodeTextArea.kt index 20f771a8..0fb8f8d6 100644 --- a/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/CodeTextArea.kt +++ b/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/CodeTextArea.kt @@ -16,6 +16,7 @@ package dev.romainguy.kotlin.explorer +import dev.romainguy.kotlin.explorer.jump.JumpDetector import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea import java.awt.Graphics import java.awt.Graphics2D @@ -24,11 +25,9 @@ import javax.swing.event.CaretListener open class CodeTextArea( private val explorerState: ExplorerState, - jumpRegex: Regex, - addressedRegex: Regex, + private val jumpDetector: JumpDetector, private val lineNumberRegex: Regex?, ) : RSyntaxTextArea() { - private val jumpDetector = JumpDetector(jumpRegex, addressedRegex) private var jumpOffsets: JumpOffsets? = null private var fullText = "" @@ -114,17 +113,6 @@ open class CodeTextArea( } ?: this private data class JumpOffsets(val src: Int, val dst: Int) - - private class Jump(val address: String, val direction: Int) - - private class JumpDetector(private val jumpRegex: Regex, private val addressedRegex: Regex) { - fun detectJump(line: String): Jump? { - val match = jumpRegex.matchEntire(line) ?: return null - return Jump(match.getValue("address"), if (match.getValue("direction") == "+") 1 else -1) - } - - fun detectAddressed(line: String) = addressedRegex.matchEntire(line)?.getValue("address") - } } private fun String.countPadding() = indexOfFirst { it != ' ' } diff --git a/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/dex/DexTextArea.kt b/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/dex/DexTextArea.kt index 677526f3..817fb1ac 100644 --- a/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/dex/DexTextArea.kt +++ b/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/dex/DexTextArea.kt @@ -18,11 +18,13 @@ package dev.romainguy.kotlin.explorer.dex import dev.romainguy.kotlin.explorer.CodeTextArea import dev.romainguy.kotlin.explorer.ExplorerState +import dev.romainguy.kotlin.explorer.jump.RegexJumpDetector +// DEX Syntax: ' 0005: if-nez v0, 0008 // +0003' private val DexJumpRegex = Regex("^.{9}[0-9a-fA-F]{4}: .+(?
[0-9a-fA-F]{4}) // (?[+-])[0-9a-fA-F]{4}$") private val DexAddressedRegex = Regex("^.{9}(?
[0-9a-fA-F]{4}): .+$") private val DexLineNumberRegex = Regex("^(? +\\d+: )([0-9a-f]{4}: )", RegexOption.MULTILINE) class DexTextArea(explorerState: ExplorerState) : - CodeTextArea(explorerState, DexJumpRegex, DexAddressedRegex, DexLineNumberRegex) + CodeTextArea(explorerState, RegexJumpDetector(DexJumpRegex, DexAddressedRegex), DexLineNumberRegex) diff --git a/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/jump/CompoundJumpDetector.kt b/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/jump/CompoundJumpDetector.kt new file mode 100644 index 00000000..ec1d9658 --- /dev/null +++ b/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/jump/CompoundJumpDetector.kt @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2023 Romain Guy + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.romainguy.kotlin.explorer.jump + +class CompoundJumpDetector(private vararg val detectors: JumpDetector) : JumpDetector { + override fun detectJump(line: String) = detectors.firstNotNullOfOrNull { it.detectJump(line) } + + override fun detectAddressed(line: String) = detectors.firstNotNullOfOrNull { it.detectAddressed(line) } +} \ No newline at end of file diff --git a/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/jump/Jump.kt b/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/jump/Jump.kt new file mode 100644 index 00000000..dd44e020 --- /dev/null +++ b/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/jump/Jump.kt @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2023 Romain Guy + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.romainguy.kotlin.explorer.jump + +class Jump(val address: Int, val direction: Int) diff --git a/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/jump/JumpDetector.kt b/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/jump/JumpDetector.kt new file mode 100644 index 00000000..416ac0e7 --- /dev/null +++ b/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/jump/JumpDetector.kt @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2023 Romain Guy + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.romainguy.kotlin.explorer.jump + +interface JumpDetector { + fun detectJump(line: String): Jump? + + fun detectAddressed(line: String): Int? +} \ No newline at end of file diff --git a/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/jump/RegexJumpDetector.kt b/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/jump/RegexJumpDetector.kt new file mode 100644 index 00000000..549925ee --- /dev/null +++ b/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/jump/RegexJumpDetector.kt @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2023 Romain Guy + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.romainguy.kotlin.explorer.jump + +import dev.romainguy.kotlin.explorer.getValue + +class RegexJumpDetector(private val jumpRegex: Regex, private val addressedRegex: Regex) : JumpDetector { + override fun detectJump(line: String): Jump? { + val match = jumpRegex.matchEntire(line) ?: return null + return Jump(match.getValue("address").toInt(16), if (match.getValue("direction") == "+") 1 else -1) + } + + override fun detectAddressed(line: String) = addressedRegex.matchEntire(line)?.getValue("address")?.toInt(16) +} \ No newline at end of file diff --git a/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/oat/OatTextArea.kt b/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/oat/OatTextArea.kt index 796cc838..454f1509 100644 --- a/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/oat/OatTextArea.kt +++ b/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/oat/OatTextArea.kt @@ -18,10 +18,29 @@ package dev.romainguy.kotlin.explorer.oat import dev.romainguy.kotlin.explorer.CodeTextArea import dev.romainguy.kotlin.explorer.ExplorerState +import dev.romainguy.kotlin.explorer.jump.CompoundJumpDetector +import dev.romainguy.kotlin.explorer.jump.RegexJumpDetector -private val OatJumpRegex = - Regex("^ +0x[0-9a-fA-F]{8}: .+ (?[+-])\\d+ \\((?
0x[0-9a-fA-F]{8})\\)$") -private val OatAddressedRegex = Regex("^ +(?
0x[0-9a-fA-F]{8}): .+$") +// Arm64 syntax: ' 0x00001040: b.ge #+0x48 (addr 0x1088)' +private val Arm64JumpRegex = + Regex("^ +0x[0-9a-fA-F]{8}: .+ #(?[+-])0x[0-9a-fA-F]+ \\(addr 0x(?
[0-9a-fA-F]+)\\)$") + +// X86 syntax: ' 0x00001048: jnl/ge +103 (0x000010b5)' +private val X86JumpRegex = + Regex("^ +0x[0-9a-fA-F]{8}: .+ (?[+-])\\d+ \\(0x(?
[0-9a-fA-F]{8})\\)$") + +private val OatAddressedRegex = Regex("^ +0x(?
[0-9a-fA-F]{8}): .+$") class OatTextArea(explorerState: ExplorerState) : - CodeTextArea(explorerState, OatJumpRegex, OatAddressedRegex, lineNumberRegex = null) \ No newline at end of file + CodeTextArea( + explorerState, + CompoundJumpDetector( + RegexJumpDetector(Arm64JumpRegex, OatAddressedRegex), + RegexJumpDetector(X86JumpRegex, OatAddressedRegex) + ), + lineNumberRegex = null + ) + +fun main() { + println(X86JumpRegex.matchEntire(" 0x00001048: jnl/ge +103 (0x000010b5)")) +} \ No newline at end of file