ghidra/Ghidra/Features/Base/ghidra_scripts/FindX86RelativeCallsScript....

88 lines
2.9 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.
*/
// Search for the start of X86 relative call instructions, look at the potential target and
// and if the function is valid, then disassemble and create a function at the target.
//
// Your mileage may vary! This should only be run after existing code has been found.
// The results should be checked for validity.
// @category Analysis
import ghidra.app.script.GhidraScript;
import ghidra.app.util.PseudoDisassembler;
import ghidra.app.util.PseudoInstruction;
import ghidra.program.model.address.*;
import ghidra.program.model.listing.CodeUnit;
import ghidra.program.model.listing.Instruction;
public class FindX86RelativeCallsScript extends GhidraScript {
@Override
public void run() throws Exception {
Address addr = currentProgram.getMemory().getMinAddress();
PseudoDisassembler pdis = new PseudoDisassembler(currentProgram);
AddressSetView execSet = currentProgram.getMemory().getExecuteSet();
AddressSet disSet = new AddressSet();
while (addr != null) {
addr = this.find(addr, (byte) 0xe8);
if (addr == null) {
break;
}
if (execSet.isEmpty() || execSet.contains(addr)) {
CodeUnit cu = currentProgram.getListing().getUndefinedDataAt(addr);
if (cu != null) {
PseudoInstruction instr = pdis.disassemble(addr);
Address target = instr.getAddress(0);
if (currentProgram.getMemory().contains(target) &&
(execSet.isEmpty() || execSet.contains(target))) {
// println ("e8 call " + addr + " -> " + target);
// also disassemble from this call.
// This will only get a partial function, so maybe it would be better not to do this
if (currentProgram.getFunctionManager().getFunctionAt(target) != null) {
disassemble(addr);
disSet.add(addr);
}
// There should be more checks done here on the validity.
// maybe does the potential function at target start like other functions
// that have already been defined.
Instruction realinstr =
currentProgram.getListing().getInstructionAt(target);
if (realinstr == null) {
boolean isvalid = pdis.isValidSubroutine(target, true);
if (isvalid) {
// println(" found");
disassemble(target);
disSet.add(target);
createFunction(target, null);
}
}
}
}
}
addr = addr.add(1);
}
show("X86 Relative Calls", disSet);
}
}