mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-03 17:59:46 +02:00
161 lines
4.5 KiB
Java
161 lines
4.5 KiB
Java
/* ###
|
|
* IP: GHIDRA
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
// This script creates references on scalar operands which can be directly
|
|
// correlated to a symbol or equate via a relocation table entry. Only symbols within
|
|
// byte-oriented address spaces will be considered.
|
|
//@category Analysis
|
|
|
|
import java.util.Iterator;
|
|
import java.util.List;
|
|
|
|
import ghidra.app.script.GhidraScript;
|
|
import ghidra.program.model.address.Address;
|
|
import ghidra.program.model.listing.Instruction;
|
|
import ghidra.program.model.listing.Listing;
|
|
import ghidra.program.model.reloc.Relocation;
|
|
import ghidra.program.model.reloc.RelocationTable;
|
|
import ghidra.program.model.scalar.Scalar;
|
|
import ghidra.program.model.symbol.*;
|
|
|
|
public class CreateRelocationBasedOperandReferences extends GhidraScript {
|
|
|
|
@Override
|
|
public void run() throws Exception {
|
|
if (currentProgram == null) {
|
|
popup("No active Program to analyze");
|
|
return;
|
|
}
|
|
|
|
Listing listing = currentProgram.getListing();
|
|
ReferenceManager refMgr = currentProgram.getReferenceManager();
|
|
EquateTable equateTable = currentProgram.getEquateTable();
|
|
SymbolTable symbolTable = currentProgram.getSymbolTable();
|
|
|
|
RelocationTable relocationTable = currentProgram.getRelocationTable();
|
|
if (relocationTable.getSize() == 0) {
|
|
popup("Program does not have relocations");
|
|
return;
|
|
}
|
|
|
|
Iterator<Relocation> relocations = relocationTable.getRelocations();
|
|
|
|
monitor.initialize(relocationTable.getSize());
|
|
int refCount = 0;
|
|
|
|
while (relocations.hasNext()) {
|
|
monitor.checkCancelled();
|
|
Relocation r = relocations.next();
|
|
monitor.incrementProgress(1);
|
|
|
|
Instruction instr = listing.getInstructionAt(r.getAddress());
|
|
if (instr == null) {
|
|
continue;
|
|
}
|
|
|
|
Equate equate = null;
|
|
Symbol symbol = null;
|
|
long value;
|
|
|
|
List<Symbol> symbols = symbolTable.getLabelOrFunctionSymbols(r.getSymbolName(), null);
|
|
if (symbols.size() == 0) {
|
|
// check for possible equate definition
|
|
equate = equateTable.getEquate(r.getSymbolName());
|
|
if (equate == null) {
|
|
continue;
|
|
}
|
|
value = equate.getValue();
|
|
}
|
|
else if (symbols.size() == 1) {
|
|
symbol = symbols.get(0);
|
|
Address a = symbol.getAddress();
|
|
if (a.getAddressSpace().getAddressableUnitSize() != 1) {
|
|
continue;
|
|
}
|
|
value = a.getOffset();
|
|
}
|
|
else {
|
|
continue;
|
|
}
|
|
|
|
Reference[] referencesFrom = null;
|
|
|
|
int opCnt = instr.getNumOperands();
|
|
for (int opIndex = 0; opIndex < opCnt; opIndex++) {
|
|
Scalar scalar =
|
|
getScalarOperand(instr.getDefaultOperandRepresentationList(opIndex));
|
|
if (scalar == null || scalar.getUnsignedValue() != value) {
|
|
continue;
|
|
}
|
|
if (referencesFrom == null) {
|
|
referencesFrom = refMgr.getReferencesFrom(instr.getAddress());
|
|
}
|
|
if (hasReference(referencesFrom, opIndex)) {
|
|
continue; // reference exists on operand
|
|
}
|
|
if (equateTable.getEquates(instr.getAddress(), opIndex).size() != 0) {
|
|
continue; // equate reference exists on operand
|
|
}
|
|
if (symbol != null) {
|
|
Reference ref = refMgr.addMemoryReference(instr.getAddress(),
|
|
symbol.getAddress(), RefType.DATA, SourceType.ANALYSIS, opIndex);
|
|
refMgr.setAssociation(symbol, ref);
|
|
}
|
|
else {
|
|
equate.addReference(instr.getAddress(), opIndex);
|
|
}
|
|
++refCount;
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
popup("Added " + refCount + " relocation-based references");
|
|
}
|
|
|
|
private Scalar getScalarOperand(List<Object> defaultOperandRepresentationList) {
|
|
Scalar s = null;
|
|
for (Object obj : defaultOperandRepresentationList) {
|
|
if (obj instanceof String) {
|
|
continue;
|
|
}
|
|
if (obj instanceof Character) {
|
|
continue;
|
|
}
|
|
if (obj instanceof Scalar) {
|
|
if (s != null) {
|
|
// more than one scalar found
|
|
return null;
|
|
}
|
|
s = (Scalar) obj;
|
|
}
|
|
else {
|
|
// non-scalar found
|
|
return null;
|
|
}
|
|
}
|
|
return s;
|
|
}
|
|
|
|
private boolean hasReference(Reference[] referencesFrom, int opIndex) {
|
|
for (Reference r : referencesFrom) {
|
|
if (r.getOperandIndex() == opIndex) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
}
|