WIP
This commit is contained in:
parent
ab0c1473ec
commit
080b9f7b8c
|
@ -9,6 +9,7 @@ import ghidra.program.model.mem.MemoryBlock;
|
||||||
import ghidra.program.model.address.*;
|
import ghidra.program.model.address.*;
|
||||||
import ghidra.program.model.scalar.Scalar;
|
import ghidra.program.model.scalar.Scalar;
|
||||||
import ghidra.program.model.symbol.Reference;
|
import ghidra.program.model.symbol.Reference;
|
||||||
|
import ghidra.program.model.pcode.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import re3lib.RemanConfig;
|
import re3lib.RemanConfig;
|
||||||
|
@ -89,34 +90,123 @@ public class FindRelocations extends GhidraScript {
|
||||||
private void analyzeInstruction(Instruction instruction) {
|
private void analyzeInstruction(Instruction instruction) {
|
||||||
String mnemonic = instruction.getMnemonicString().toLowerCase();
|
String mnemonic = instruction.getMnemonicString().toLowerCase();
|
||||||
|
|
||||||
boolean trace = instruction.getAddress().getOffset() == 0x0049b154;
|
boolean trace = instruction.getAddress().getOffset() == 0x0049b154 || instruction.getAddress().getOffset() == 0x00401280;
|
||||||
if (trace) {
|
if (trace) {
|
||||||
println("DEBUG: " + mnemonic + " at " + instruction.getAddress());
|
println("DEBUG: " + mnemonic + " at " + instruction.getAddress());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for instructions that commonly use absolute addresses
|
// Check for instructions that commonly use absolute addresses
|
||||||
if (isRelocatableInstruction(mnemonic)) {
|
if (isRelocatableInstruction(mnemonic)) {
|
||||||
// Check references from this instruction
|
boolean foundViaPcode = false;
|
||||||
Reference[] refs = instruction.getReferencesFrom();
|
|
||||||
for (Reference ref : refs) {
|
|
||||||
Address toAddr = ref.getToAddress();
|
|
||||||
|
|
||||||
boolean isInMainMemorySpace = isInMainMemorySpace(toAddr);
|
// First try pcode analysis (better for complex addressing)
|
||||||
if (trace) {
|
foundViaPcode = analyzePcodeForConstants(instruction, trace);
|
||||||
println(" isInMainMemorySpace: " + toAddr + " " + isInMainMemorySpace);
|
|
||||||
|
// 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)
|
for (PcodeOp op : pcodeOps) {
|
||||||
int operandOffset = findAbsoluteAddressOffset(instruction, toAddr, trace);
|
// Look for constants in the pcode that look like addresses
|
||||||
if (operandOffset >= 0) {
|
Varnode[] inputs = op.getInputs();
|
||||||
recordRelocation(instruction.getAddress(), toAddr, mnemonic,
|
for (Varnode input : inputs) {
|
||||||
"absolute_" + ref.getReferenceType().getName(), operandOffset);
|
if (input.isConstant()) {
|
||||||
} else {
|
long constantValue = input.getOffset();
|
||||||
if (trace) {
|
|
||||||
println(" operandOffset was not found: " + operandOffset);
|
// 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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
49273
game_re/relocations.def
49273
game_re/relocations.def
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue