This commit is contained in:
parent
faf2e134f2
commit
f1b346fb0e
|
@ -10,17 +10,21 @@ import ghidra.program.model.symbol.Reference;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import re3lib.RemanConfig;
|
import re3lib.RemanConfig;
|
||||||
import ghidra.util.task.TaskMonitor;
|
|
||||||
|
|
||||||
public class FindRelocations extends GhidraScript {
|
public class FindRelocations extends GhidraScript {
|
||||||
private Set<Address> foundRelocations = new HashSet<>();
|
private Set<Address> foundRelocations = new HashSet<>();
|
||||||
private PrintWriter outputFile;
|
private PrintWriter outputFile;
|
||||||
|
|
||||||
|
long addrMin, addrMax;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() throws Exception {
|
public void run() throws Exception {
|
||||||
RemanConfig.INSTANCE = new RemanConfig(this);
|
RemanConfig.INSTANCE = new RemanConfig(this);
|
||||||
RemanConfig.INSTANCE.createDirectories();
|
RemanConfig.INSTANCE.createDirectories();
|
||||||
|
|
||||||
|
addrMin = RemanConfig.INSTANCE.staticMemoryBlockStart.getOffset();
|
||||||
|
addrMax = RemanConfig.INSTANCE.staticMemoryBlockEnd.getOffset();
|
||||||
|
|
||||||
// Create output file for relocations
|
// Create output file for relocations
|
||||||
File relocFile = new File(RemanConfig.INSTANCE.outputDir, "relocations.txt");
|
File relocFile = new File(RemanConfig.INSTANCE.outputDir, "relocations.txt");
|
||||||
outputFile = new PrintWriter(new FileWriter(relocFile));
|
outputFile = new PrintWriter(new FileWriter(relocFile));
|
||||||
|
@ -111,12 +115,12 @@ public class FindRelocations extends GhidraScript {
|
||||||
private boolean isRelocatableInstruction(String mnemonic) {
|
private boolean isRelocatableInstruction(String mnemonic) {
|
||||||
// Instructions that commonly use absolute addresses
|
// Instructions that commonly use absolute addresses
|
||||||
return mnemonic.equals("mov") || mnemonic.equals("lea") ||
|
return mnemonic.equals("mov") || mnemonic.equals("lea") ||
|
||||||
mnemonic.equals("call") || mnemonic.equals("jmp") ||
|
mnemonic.equals("call") || mnemonic.equals("jmp") ||
|
||||||
mnemonic.equals("push") || mnemonic.equals("cmp") ||
|
mnemonic.equals("push") || mnemonic.equals("cmp") ||
|
||||||
mnemonic.equals("test") || mnemonic.equals("add") ||
|
mnemonic.equals("test") || mnemonic.equals("add") ||
|
||||||
mnemonic.equals("sub") || mnemonic.equals("and") ||
|
mnemonic.equals("sub") || mnemonic.equals("and") ||
|
||||||
mnemonic.equals("or") || mnemonic.equals("xor") ||
|
mnemonic.equals("or") || mnemonic.equals("xor") ||
|
||||||
mnemonic.startsWith("j"); // conditional jumps
|
mnemonic.startsWith("j"); // conditional jumps
|
||||||
}
|
}
|
||||||
|
|
||||||
private void analyzeOperand(Instruction instruction, int opIndex) {
|
private void analyzeOperand(Instruction instruction, int opIndex) {
|
||||||
|
@ -127,7 +131,7 @@ public class FindRelocations extends GhidraScript {
|
||||||
Address addr = (Address) obj;
|
Address addr = (Address) obj;
|
||||||
if (isInMainMemorySpace(addr)) {
|
if (isInMainMemorySpace(addr)) {
|
||||||
recordRelocation(instruction.getAddress(), addr,
|
recordRelocation(instruction.getAddress(), addr,
|
||||||
instruction.getMnemonicString(), "operand_" + opIndex);
|
instruction.getMnemonicString(), "operand_" + opIndex);
|
||||||
}
|
}
|
||||||
} else if (obj instanceof Scalar) {
|
} else if (obj instanceof Scalar) {
|
||||||
Scalar scalar = (Scalar) obj;
|
Scalar scalar = (Scalar) obj;
|
||||||
|
@ -138,7 +142,7 @@ public class FindRelocations extends GhidraScript {
|
||||||
Address addr = currentProgram.getAddressFactory().getDefaultAddressSpace().getAddress(value);
|
Address addr = currentProgram.getAddressFactory().getDefaultAddressSpace().getAddress(value);
|
||||||
if (isInMainMemorySpace(addr)) {
|
if (isInMainMemorySpace(addr)) {
|
||||||
recordRelocation(instruction.getAddress(), addr,
|
recordRelocation(instruction.getAddress(), addr,
|
||||||
instruction.getMnemonicString(), "scalar_" + opIndex);
|
instruction.getMnemonicString(), "scalar_" + opIndex);
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// Invalid address, ignore
|
// Invalid address, ignore
|
||||||
|
@ -170,7 +174,7 @@ public class FindRelocations extends GhidraScript {
|
||||||
|
|
||||||
long value = 0;
|
long value = 0;
|
||||||
for (int i = 0; i < bytes.length; i++) {
|
for (int i = 0; i < bytes.length; i++) {
|
||||||
value |= ((long)(bytes[i] & 0xFF)) << (i * 8);
|
value |= ((long) (bytes[i] & 0xFF)) << (i * 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (looksLikeAddress(value)) {
|
if (looksLikeAddress(value)) {
|
||||||
|
@ -203,17 +207,19 @@ public class FindRelocations extends GhidraScript {
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isInMainMemorySpace(Address addr) {
|
private boolean isInMainMemorySpace(Address addr) {
|
||||||
if (addr == null) return false;
|
if (addr == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
// Check if address is in a loaded memory block
|
// Check if address is in a loaded memory block
|
||||||
return currentProgram.getMemory().contains(addr) &&
|
return currentProgram.getMemory().contains(addr) &&
|
||||||
!addr.getAddressSpace().isOverlaySpace();
|
!addr.getAddressSpace().isOverlaySpace();
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean looksLikeAddress(long value) {
|
private boolean looksLikeAddress(long value) {
|
||||||
// Heuristic: check if value is in reasonable address range
|
// Heuristic: check if value is in reasonable address range
|
||||||
// Adjust these ranges based on your target architecture
|
// Adjust these ranges based on your target architecture
|
||||||
return value >= 0x400000 && value <= 0x7FFFFFFF; // Typical executable range
|
return value >= addrMin
|
||||||
|
&& value <= addrMax; // Typical executable range
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean usesAbsoluteAddressing(Instruction instruction, Reference ref) {
|
private boolean usesAbsoluteAddressing(Instruction instruction, Reference ref) {
|
||||||
|
@ -245,11 +251,11 @@ public class FindRelocations extends GhidraScript {
|
||||||
if (foundRelocations.add(toAddr)) {
|
if (foundRelocations.add(toAddr)) {
|
||||||
String instructionBytes = getInstructionBytesString(fromAddr);
|
String instructionBytes = getInstructionBytesString(fromAddr);
|
||||||
String line = String.format("0x%s -> 0x%s (%s) [%s] | %s",
|
String line = String.format("0x%s -> 0x%s (%s) [%s] | %s",
|
||||||
fromAddr.toString(),
|
fromAddr.toString(),
|
||||||
toAddr.toString(),
|
toAddr.toString(),
|
||||||
instruction,
|
instruction,
|
||||||
type,
|
type,
|
||||||
instructionBytes);
|
instructionBytes);
|
||||||
println(line);
|
println(line);
|
||||||
outputFile.println(line);
|
outputFile.println(line);
|
||||||
outputFile.flush();
|
outputFile.flush();
|
||||||
|
@ -263,7 +269,8 @@ public class FindRelocations extends GhidraScript {
|
||||||
byte[] bytes = instruction.getBytes();
|
byte[] bytes = instruction.getBytes();
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
for (int i = 0; i < bytes.length; i++) {
|
for (int i = 0; i < bytes.length; i++) {
|
||||||
if (i > 0) sb.append(" ");
|
if (i > 0)
|
||||||
|
sb.append(" ");
|
||||||
sb.append(String.format("%02x", bytes[i] & 0xFF));
|
sb.append(String.format("%02x", bytes[i] & 0xFF));
|
||||||
}
|
}
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
|
@ -275,7 +282,8 @@ public class FindRelocations extends GhidraScript {
|
||||||
currentProgram.getMemory().getBytes(addr, bytes);
|
currentProgram.getMemory().getBytes(addr, bytes);
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
for (int i = 0; i < bytes.length; i++) {
|
for (int i = 0; i < bytes.length; i++) {
|
||||||
if (i > 0) sb.append(" ");
|
if (i > 0)
|
||||||
|
sb.append(" ");
|
||||||
sb.append(String.format("%02x", bytes[i] & 0xFF));
|
sb.append(String.format("%02x", bytes[i] & 0xFF));
|
||||||
}
|
}
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
|
|
Loading…
Reference in New Issue