Skip to content

Commit 851517d

Browse files
authored
Mark block reference variables (#74)
* Stack block fixes. * Ghidra version fixes. * Remove too-soon API changes. * Move Flag type inside BlockLayout * Move flag class closer to flags, don't use getter for flags. * Remove unused variable. * Add block reference variable markup action. * Add null checks. * Add error check for getting bytes in memory. * Improve block reference variable markup. * Add names to byref2 and byref3 structure components. * Make block reference variable action check more robust.
1 parent b883276 commit 851517d

File tree

9 files changed

+422
-162
lines changed

9 files changed

+422
-162
lines changed
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package lol.fairplay.ghidraapple.actions.markasblock
2+
3+
import docking.ActionContext
4+
import docking.action.MenuData
5+
import ghidra.app.context.ProgramLocationActionContext
6+
import ghidra.app.context.ProgramLocationContextAction
7+
import ghidra.app.decompiler.ClangVariableToken
8+
import ghidra.app.plugin.core.decompile.DecompilerActionContext
9+
import ghidra.framework.plugintool.PluginTool
10+
import lol.fairplay.ghidraapple.GhidraApplePluginPackage
11+
12+
class MarkAsBlockByRefAction(
13+
owner: String,
14+
val plugin: PluginTool,
15+
) : ProgramLocationContextAction(
16+
"Mark As Objective-C Block Reference Variable",
17+
owner,
18+
) {
19+
init {
20+
popupMenuData = MenuData(arrayOf(this.name), GhidraApplePluginPackage.PKG_NAME)
21+
}
22+
23+
override fun actionPerformed(context: ProgramLocationActionContext) {
24+
plugin.executeBackgroundCommand(MarkBlockByRef(context.program, context.address), context.program)
25+
}
26+
27+
override fun isEnabledForContext(context: ActionContext?): Boolean {
28+
val typedContext =
29+
context as? DecompilerActionContext ?: return false
30+
31+
return typedContext.tokenAtCursor is ClangVariableToken // TODO: Make this check more robust.
32+
}
33+
}

src/main/java/lol/fairplay/ghidraapple/actions/markasblock/MarkAsGlobalBlockAction.kt

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,13 @@ class MarkAsGlobalBlockAction(
2929
if (dataAtLocation.dataType.isBlockLayoutType) return false
3030

3131
val pointerBytes = ByteArray(typedContext.program.defaultPointerSize)
32-
val bytesRead = typedContext.program.memory.getBytes(typedContext.address, pointerBytes)
33-
if (bytesRead != pointerBytes.size) return false
32+
try {
33+
val bytesRead =
34+
typedContext.program.memory.getBytes(typedContext.address, pointerBytes)
35+
if (bytesRead != pointerBytes.size) return false
36+
} catch (_: Throwable) {
37+
return false
38+
}
3439

3540
// If the pointer isn't to the global block symbol, it's not a global block.
3641
typedContext.program.symbolTable

src/main/java/lol/fairplay/ghidraapple/actions/markasblock/MarkAsStackBlockAction.kt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,11 @@ import docking.ActionContext
44
import docking.action.MenuData
55
import ghidra.app.context.ProgramLocationActionContext
66
import ghidra.app.context.ProgramLocationContextAction
7+
import ghidra.app.decompiler.ClangStatement
8+
import ghidra.app.plugin.core.decompile.DecompilerActionContext
79
import ghidra.framework.plugintool.PluginTool
810
import lol.fairplay.ghidraapple.GhidraApplePluginPackage
11+
import lol.fairplay.ghidraapple.analysis.objectivec.blocks.doesPCodeOpPutStackBlockPointerOnStack
912
import lol.fairplay.ghidraapple.analysis.objectivec.blocks.doesReferenceStackBlockSymbol
1013
import lol.fairplay.ghidraapple.analysis.objectivec.blocks.isBlockLayout
1114

@@ -31,6 +34,15 @@ class MarkAsStackBlockAction(
3134
// If this is already a block layout, don't allow it to be marked again.
3235
if (typedContext.location.isBlockLayout) return false
3336

37+
if (typedContext is DecompilerActionContext) {
38+
val parent = typedContext.tokenAtCursor.Parent()
39+
if (parent is ClangStatement) {
40+
val op = parent.pcodeOp
41+
return doesPCodeOpPutStackBlockPointerOnStack(op, typedContext.program)
42+
}
43+
return false
44+
}
45+
3446
return typedContext.program.listing
3547
.getInstructionAt(typedContext.address)
3648
?.doesReferenceStackBlockSymbol ?: return false

0 commit comments

Comments
 (0)