mirror of
https://github.com/morluto/rea.git
synced 2026-11-05 22:36:08 +00:00
fix(ghidra): update the host no-return probe for the current bridge (#8462)
The host no-return verifier, scripts/verify-real-ghidra-noreturn.mjs, fails before its Evidence checks. ReaNoReturnProbe calls private bridge methods through reflection, and two bridge changes left the probe behind: -d4bd65c53added a Function parameter to noReturnCallLimitations, and225f26a5frenamed the method to functionBoundaryLimitations. The probe still looked up noReturnCallLimitations(Iterable) and stopped with NoSuchMethodException. -01a1b3fdamade procedureReferences return a function observation envelope. The probe read references and unresolved_calls from the top level of that envelope instead of from its value. Pass each function and its instructions to functionBoundaryLimitations, and read procedureReferences results from the envelope value. The require checks are unchanged. CI does not run this verifier. These edits are the probe repair from robotaro's open draft that treats demangled C++ runtime imports as returning, copied line for line, so either change merges cleanly after the other. Co-authored-by: robotaro <1141230+robotaro@users.noreply.github.com>
This commit is contained in:
1 parent
52ff3123cb
commit
1df7ac9320
1 file changed
+12
-7
@@ -123,7 +123,8 @@ public class ReaNoReturnProbe extends GhidraScript {
|
||||
query.addProperty("direction", "outgoing");
|
||||
Method read = bridge.getClass().getDeclaredMethod("procedureReferences", JsonObject.class);
|
||||
read.setAccessible(true);
|
||||
JsonObject output = (JsonObject) read.invoke(bridge, query);
|
||||
// procedureReferences returns a function observation envelope.
|
||||
JsonObject output = ((JsonObject) read.invoke(bridge, query)).getAsJsonObject("value");
|
||||
require("interior_reference_keeps_known_procedure", output.getAsJsonArray("references").asList().stream().anyMatch(
|
||||
edge -> !edge.getAsJsonObject().get("target_procedure").isJsonNull() &&
|
||||
edge.getAsJsonObject().getAsJsonObject("target_procedure").get("name").getAsString().equals(target.getName())));
|
||||
@@ -185,13 +186,13 @@ public class ReaNoReturnProbe extends GhidraScript {
|
||||
query.addProperty("direction", "outgoing");
|
||||
Method edges = bridge.getClass().getDeclaredMethod("procedureReferences", JsonObject.class);
|
||||
edges.setAccessible(true);
|
||||
JsonObject known = (JsonObject) edges.invoke(bridge, query);
|
||||
JsonObject known = ((JsonObject) edges.invoke(bridge, query)).getAsJsonObject("value");
|
||||
require("non_call_known_reference_is_not_unresolved", known.getAsJsonArray("unresolved_calls").isEmpty());
|
||||
references.delete(added);
|
||||
Address unknown = currentProgram.getMemory().getMaxAddress().add(0x1000);
|
||||
added = references.addMemoryReference(source.getAddress(), unknown,
|
||||
RefType.UNCONDITIONAL_CALL, SourceType.USER_DEFINED, -1);
|
||||
JsonObject unresolved = (JsonObject) edges.invoke(bridge, query);
|
||||
JsonObject unresolved = ((JsonObject) edges.invoke(bridge, query)).getAsJsonObject("value");
|
||||
require("non_call_unknown_reference_keeps_site", unresolved.getAsJsonArray("unresolved_calls").size() == 1);
|
||||
} finally {
|
||||
references.delete(added);
|
||||
@@ -253,14 +254,18 @@ public class ReaNoReturnProbe extends GhidraScript {
|
||||
!adjacentCaller.getBody().contains(adjacentEntry));
|
||||
|
||||
GhidraScript bridge = script("ReaGhidraBridge.java", new File(directory, "ReaGhidraBridge.java"));
|
||||
Method warnings = bridge.getClass().getDeclaredMethod("noReturnCallLimitations", Iterable.class);
|
||||
Method warnings = bridge.getClass().getDeclaredMethod(
|
||||
"functionBoundaryLimitations", Function.class, Iterable.class);
|
||||
warnings.setAccessible(true);
|
||||
Object reported = warnings.invoke(bridge, currentProgram.getListing().getInstructions(function("rea_unknown").getBody(), true));
|
||||
Object reported = warnings.invoke(bridge, function("rea_unknown"),
|
||||
currentProgram.getListing().getInstructions(function("rea_unknown").getBody(), true));
|
||||
require("unknown_boundary_named", reported instanceof List<?> values &&
|
||||
values.stream().anyMatch(value -> value.toString().contains("rea_unknown_stop") && value.toString().contains("fallthrough")));
|
||||
Object healthy = warnings.invoke(bridge, currentProgram.getListing().getInstructions(function("rea_tls").getBody(), true));
|
||||
Object healthy = warnings.invoke(bridge, function("rea_tls"),
|
||||
currentProgram.getListing().getInstructions(function("rea_tls").getBody(), true));
|
||||
require("healthy_boundary_no_warning", healthy instanceof List<?> values && values.isEmpty());
|
||||
Object guarded = warnings.invoke(bridge, currentProgram.getListing().getInstructions(adjacentCaller.getBody(), true));
|
||||
Object guarded = warnings.invoke(bridge, adjacentCaller,
|
||||
currentProgram.getListing().getInstructions(adjacentCaller.getBody(), true));
|
||||
require("unrepaired_boundary_named", guarded instanceof List<?> values &&
|
||||
values.stream().anyMatch(value -> value.toString().contains("malloc")));
|
||||
Method initialize = bridge.getClass().getDeclaredMethod("initializeDecompiler");
|
||||
|
||||
Reference in new issue
Block a user