ghidra/Ghidra/Features/Base/ghidra_scripts/FindFunctionsUsingTOCinPEFS...

84 lines
2.7 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 finds a .toc symbol, which is used to search for function pointers.
//@category Search
import ghidra.app.cmd.data.CreateDataCmd;
import ghidra.app.plugin.core.analysis.FindReferencesTableModel;
import ghidra.app.script.GhidraScript;
import ghidra.program.model.address.Address;
import ghidra.program.model.data.PointerDataType;
import ghidra.program.model.listing.Listing;
import ghidra.program.model.symbol.*;
import ghidra.util.Msg;
public class FindFunctionsUsingTOCinPEFScript extends GhidraScript {
private int addrSize = 4;
Listing listing;
SymbolTable symbolTable;
@Override
public void run() throws Exception {
listing = currentProgram.getListing();
symbolTable = currentProgram.getSymbolTable();
// Find .toc symbol
Symbol toc = SymbolUtilities.getExpectedLabelOrFunctionSymbol(currentProgram, ".toc",
err -> Msg.error(this, err));
if (toc == null) {
return;
}
Address tocAddress = toc.getAddress();
// Get direct refs to .toc
monitor.setMessage("Finding references to .toc");
FindReferencesTableModel refs =
new FindReferencesTableModel(tocAddress, state.getTool(), currentProgram);
while (refs.isBusy()) {
if (monitor.isCancelled()) {
break;
}
}
// Loop through refs to find functions
for (int i = 0; i < refs.getRowCount(); ++i) {
monitor.setMessage("Finding functions");
if (monitor.isCancelled()) {
break;
}
// Make them pointers to .toc
Address refAddr = refs.getAddress(i);
listing.clearCodeUnits(refAddr, refAddr, false);
listing.createData(refAddr, new PointerDataType());
// Make previous code unit (addr-addrSize) a pointer
Address codeAddr = refAddr.subtract(addrSize);
listing.clearCodeUnits(codeAddr, codeAddr, false);
CreateDataCmd cmd = new CreateDataCmd(codeAddr, new PointerDataType());
cmd.applyTo(currentProgram);
// listing.createData(codeAddr, new PointerDataType());
currentProgram.flushEvents();
}
popup("Script complete.\n\nNote: Auto analyzer may still be running.\n" +
"(Depending on the size of the binary, analysis may take a while...see Ghidra's progress bar.)");
}
}