Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ class MarkAsGlobalBlockAction(
if (dataAtLocation.dataType.isBlockLayoutType) return false

val pointerBytes = ByteArray(typedContext.program.defaultPointerSize)
// Check if address is external, if so, return false because we can't read it.
if (context.program.memory.isExternalBlockAddress(context.address)) return false

try {
val bytesRead =
typedContext.program.memory.getBytes(typedContext.address, pointerBytes)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@ class MarkNSConcreteStackBlock(
.decompileFunction(function, 30, monitor)
.also { decompiler.dispose() }
}
if (decompileResults.highFunction == null) {
Msg.error(this, "Failed to decompile function at ${function.entryPoint}")
return false
}

val pcodeOps =
decompileResults.highFunction.pcodeOps
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package lol.fairplay.ghidraapple.analysis.objectivec.modelling

import ghidra.program.model.address.Address
import ghidra.program.model.listing.Data
import ghidra.program.model.listing.Program
import ghidra.program.model.symbol.Namespace
import ghidra.util.Msg
import lol.fairplay.ghidraapple.analysis.utilities.StructureHelpers.deref
import lol.fairplay.ghidraapple.analysis.utilities.StructureHelpers.derefUntyped
import lol.fairplay.ghidraapple.analysis.utilities.StructureHelpers.get
Expand Down Expand Up @@ -151,6 +153,11 @@ class StructureParsing(
)
}

fun parseClass(
address: Address,
isMetaclass: Boolean = false,
): OCClass? = parseClass(address.offset, isMetaclass)

fun parseClass(
address: Long,
isMetaclass: Boolean = false,
Expand Down Expand Up @@ -234,10 +241,20 @@ class StructureParsing(

fun parseMethod(dat: Data): OCMethod? {
if (dat.dataType.name == "method_t") {
val signatureString = dat[1].deref<String>()
val parsedSignature =
kotlin
.runCatching {
parseSignature(signatureString, EncodedSignatureType.METHOD_SIGNATURE)
}.getOrElse {
Msg.error(this, "Failed to parse method signature", it)
return null
}

return OCMethod(
parent = parentStack.last(),
name = dat[0].deref<String>(),
signature = parseSignature(dat[1].deref<String>(), EncodedSignatureType.METHOD_SIGNATURE),
signature = parsedSignature,
implAddress = dat[2].longValue(false),
)
} else if (dat.dataType.name == "method_small_t") {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ class OCMethodAnalyzer : AbstractAnalyzer(NAME, DESCRIPTION, AnalyzerType.FUNCTI
runCatching {
parser.parseClass(klassData.address.unsignedOffset)
}.onFailure { exception ->
Msg.error(this, "Could not parse class at ${klassData.address.unsignedOffset}", exception)
Msg.error(this, "Could not parse class at ${klassData.address.unsignedOffset.toString(16)}", exception)
}.getOrNull() ?: return@forEach

monitor.message = "Propagating signatures for ${model.name}..."
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ class ARCFixupInstallerAnalyzer : AbstractAnalyzer(NAME, DESCRIPTION, AnalyzerTy
"___chkstk_darwin",
"_objc_opt_self",
"_objc_unsafeClaimAutoreleasedReturnValue",
"_objc_retainBlock",
*retainRegisters.toTypedArray(),
)

Expand Down Expand Up @@ -108,6 +109,8 @@ class ARCFixupInstallerAnalyzer : AbstractAnalyzer(NAME, DESCRIPTION, AnalyzerTy
"*(x0 + x3) = x2;",
"_objc_setProperty",
"_objc_setProperty_atomic",
"_objc_setProperty_atomic_copy",
"_objc_setProperty_nonatomic",
"_objc_setProperty_nonatomic_copy",
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ package lol.fairplay.ghidraapple.core.objc.encodings

const val EOF_RAW = '\u0000'

class EncodingLexer(private val input: String) {
class EncodingLexer(
val input: String,
) {
private var pos = 0
var latestToken: Token? = null

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ abstract class EncodingParser(val lexer: EncodingLexer) {
if (token is T) {
return token
} else {
throw IllegalArgumentException("Expected token ${T::class} but found ${token::class}")
throw ParserException(lexer, "Expected token ${T::class} but found ${token::class}")
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package lol.fairplay.ghidraapple.core.objc.encodings

class ParserException(
// The input that caused the exception. We use the lexer instead of the string so we don't accidentally mix up
// the two string arguments
val lexer: EncodingLexer,
message: String? = null,
cause: Throwable? = null,
) : Exception(message, cause) {
override fun toString(): String = "ParserException(input='${lexer.input}', message='${message ?: ""}', cause=${cause?.message})"
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class TypeEncodingParser(lexer: EncodingLexer) : EncodingParser(lexer) {
is Token.ObjectType -> parseObject()
is Token.SelectorType -> parseSelectorType()
is Token.ClassObjectType -> parseClassObject()
else -> throw IllegalArgumentException("Unexpected token: $currentToken")
else -> throw ParserException(lexer, "Unexpected token: $currentToken")
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,10 @@ data class OCClass(
fun baseProperties(): List<OCProperty> {
return (baseInstanceProperties ?: listOf()) + (baseClassProperties ?: listOf())
}

fun getImplementationForSelector(selector: String): OCMethod? {
return resolvedMethods().find { it.name == selector }?.concrete()
}
}

data class OCProtocol(
Expand Down
Loading