This commit is contained in:
Guus Waals 2025-06-06 01:14:59 +08:00
parent ab0c1473ec
commit 080b9f7b8c
2 changed files with 24817 additions and 24582 deletions

View File

@ -9,6 +9,7 @@ import ghidra.program.model.mem.MemoryBlock;
import ghidra.program.model.address.*;
import ghidra.program.model.scalar.Scalar;
import ghidra.program.model.symbol.Reference;
import ghidra.program.model.pcode.*;
import java.util.*;
import java.io.*;
import re3lib.RemanConfig;
@ -89,34 +90,123 @@ public class FindRelocations extends GhidraScript {
private void analyzeInstruction(Instruction instruction) {
String mnemonic = instruction.getMnemonicString().toLowerCase();
boolean trace = instruction.getAddress().getOffset() == 0x0049b154;
boolean trace = instruction.getAddress().getOffset() == 0x0049b154 || instruction.getAddress().getOffset() == 0x00401280;
if (trace) {
println("DEBUG: " + mnemonic + " at " + instruction.getAddress());
}
// Check for instructions that commonly use absolute addresses
if (isRelocatableInstruction(mnemonic)) {
// Check references from this instruction
Reference[] refs = instruction.getReferencesFrom();
for (Reference ref : refs) {
Address toAddr = ref.getToAddress();
boolean foundViaPcode = false;
boolean isInMainMemorySpace = isInMainMemorySpace(toAddr);
if (trace) {
println(" isInMainMemorySpace: " + toAddr + " " + isInMainMemorySpace);
// First try pcode analysis (better for complex addressing)
foundViaPcode = analyzePcodeForConstants(instruction, trace);
// If pcode didn't find anything, fall back to reference analysis
if (!foundViaPcode) {
analyzeReferences(instruction, trace);
}
}
}
private boolean analyzePcodeForConstants(Instruction instruction, boolean trace) {
boolean foundAny = false;
try {
// Get the pcode operations for this instruction
PcodeOp[] pcodeOps = instruction.getPcode();
if (trace) {
println("DEBUG: Analyzing pcode for " + instruction.getAddress());
for (PcodeOp op : pcodeOps) {
println("DEBUG: PcodeOp: " + op.toString());
}
if (isInMainMemorySpace) {
// Check if the target address appears in the instruction bytes (absolute
// addressing)
int operandOffset = findAbsoluteAddressOffset(instruction, toAddr, trace);
if (operandOffset >= 0) {
recordRelocation(instruction.getAddress(), toAddr, mnemonic,
"absolute_" + ref.getReferenceType().getName(), operandOffset);
} else {
if (trace) {
println(" operandOffset was not found: " + operandOffset);
}
for (PcodeOp op : pcodeOps) {
// Look for constants in the pcode that look like addresses
Varnode[] inputs = op.getInputs();
for (Varnode input : inputs) {
if (input.isConstant()) {
long constantValue = input.getOffset();
// Check if this constant looks like an address in our target range
if (looksLikeAddress(constantValue)) {
if (trace) {
println("DEBUG: Found constant: 0x" + Long.toHexString(constantValue) + " that looks like an address");
}
try {
Address targetAddr = currentProgram.getAddressFactory().getDefaultAddressSpace().getAddress(constantValue);
if (isInMainMemorySpace(targetAddr)) {
// Find where this constant appears in the instruction bytes
int operandOffset = findAbsoluteAddressOffset(instruction, targetAddr, trace);
if (operandOffset >= 0) {
recordRelocation(instruction.getAddress(), targetAddr, instruction.getMnemonicString(),
"pcode_constant", operandOffset);
foundAny = true;
}
}
} catch (Exception e) {
if (trace) {
println("DEBUG: Invalid address from constant: " + e.getMessage());
}
}
}
}
// Also check for address space references (like *[ram]0x77d4c8)
else if (input.isAddress() && input.getAddress() != null) {
long addressValue = input.getAddress().getOffset();
if (trace) {
println("DEBUG: Found address varnode: 0x" + Long.toHexString(addressValue));
}
if (looksLikeAddress(addressValue)) {
try {
Address targetAddr = input.getAddress();
if (isInMainMemorySpace(targetAddr)) {
int operandOffset = findAbsoluteAddressOffset(instruction, targetAddr, trace);
if (operandOffset >= 0) {
recordRelocation(instruction.getAddress(), targetAddr, instruction.getMnemonicString(),
"pcode_address", operandOffset);
foundAny = true;
}
}
} catch (Exception e) {
if (trace) {
println("DEBUG: Invalid address from varnode: " + e.getMessage());
}
}
}
}
}
}
} catch (Exception e) {
if (trace) {
println("DEBUG: Error analyzing pcode: " + e.getMessage());
}
}
return foundAny;
}
private void analyzeReferences(Instruction instruction, boolean trace) {
// Check references from this instruction (original approach)
Reference[] refs = instruction.getReferencesFrom();
for (Reference ref : refs) {
Address toAddr = ref.getToAddress();
boolean isInMainMemorySpace = isInMainMemorySpace(toAddr);
if (trace) {
println("DEBUG: Reference to " + toAddr + " isInMainMemorySpace: " + isInMainMemorySpace);
}
if (isInMainMemorySpace) {
// Check if the target address appears in the instruction bytes (absolute addressing)
int operandOffset = findAbsoluteAddressOffset(instruction, toAddr, trace);
if (operandOffset >= 0) {
recordRelocation(instruction.getAddress(), toAddr, instruction.getMnemonicString(),
"reference_" + ref.getReferenceType().getName(), operandOffset);
} else {
if (trace) {
println("DEBUG: operandOffset was not found: " + operandOffset);
}
}
}
}

File diff suppressed because it is too large Load Diff