102 lines
3.3 KiB
Java
102 lines
3.3 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 cleans up the disassembly for kext files by locating "Bad Instruction" bookmarks caused by incorrectly defined data in valid code flows.
|
|
//@author
|
|
//@category iOS
|
|
//@keybinding
|
|
//@menupath
|
|
//@toolbar
|
|
|
|
import ghidra.app.cmd.disassemble.DisassembleCommand;
|
|
import ghidra.app.cmd.function.CreateFunctionCmd;
|
|
import ghidra.app.plugin.core.analysis.AutoAnalysisManager;
|
|
import ghidra.app.script.GhidraScript;
|
|
import ghidra.program.model.address.*;
|
|
import ghidra.program.model.lang.Register;
|
|
import ghidra.program.model.lang.RegisterValue;
|
|
import ghidra.program.model.listing.*;
|
|
|
|
public class BadInstructionCleanup extends GhidraScript {
|
|
|
|
@Override
|
|
public void run() throws Exception {
|
|
BookmarkManager bmgr = currentProgram.getBookmarkManager();
|
|
AddressSetView baddrs = bmgr.getBookmarkAddresses("Error");
|
|
AddressSetView previousSet = baddrs;
|
|
boolean isMoreBad = true;
|
|
while (isMoreBad) {
|
|
AddressIterator bai = baddrs.getAddresses(true);
|
|
while (bai.hasNext()) {
|
|
Address ba = bai.next();
|
|
cleanup(ba);
|
|
}
|
|
while (AutoAnalysisManager.getAnalysisManager(currentProgram).isAnalyzing()) {
|
|
Thread.sleep(500);
|
|
}
|
|
baddrs = bmgr.getBookmarkAddresses("Error");
|
|
if (baddrs.equals(previousSet)) {
|
|
isMoreBad = false;
|
|
}
|
|
else {
|
|
previousSet = baddrs;
|
|
}
|
|
}
|
|
}
|
|
|
|
public void cleanup(Address ba) throws Exception {
|
|
|
|
Program p = currentProgram;
|
|
BookmarkManager bmgr = p.getBookmarkManager();
|
|
Bookmark bm = bmgr.getBookmark(ba, "Error", "Bad Instruction");
|
|
Listing listing = p.getListing();
|
|
if (bm != null) {
|
|
Register contextReg = p.getProgramContext().getRegister("TMode");
|
|
Address ba_end = ba;
|
|
if (listing.getCodeUnitAt(ba) != null) {
|
|
ba_end = listing.getCodeUnitAt(ba).getMaxAddress();
|
|
}
|
|
while (getDataContaining(ba_end.add(4)) != null) {
|
|
ba_end = getDataContaining(ba_end.add(4)).getMaxAddress();
|
|
}
|
|
while (getDataContaining(ba.subtract(1)) != null) {
|
|
ba = getDataContaining(ba.subtract(1)).getAddress();
|
|
}
|
|
listing.clearCodeUnits(ba, ba_end, false);
|
|
if (contextReg != null) {
|
|
Address paddr = listing.getInstructionBefore(ba).getAddress();
|
|
RegisterValue rv;
|
|
if (paddr != null) {
|
|
rv = p.getProgramContext().getRegisterValue(contextReg,
|
|
paddr);
|
|
p.getProgramContext().setRegisterValue(ba, ba_end, rv);
|
|
}
|
|
}
|
|
DisassembleCommand cmd = new DisassembleCommand(ba, null, true);
|
|
cmd.applyTo(p, monitor);
|
|
Function f = getFunctionBefore(ba);
|
|
if (f != null) {
|
|
CreateFunctionCmd cf = new CreateFunctionCmd(f.getName(), f
|
|
.getEntryPoint(), null, f.getSymbol().getSource(),
|
|
true, true);
|
|
cf.applyTo(p);
|
|
}
|
|
bmgr.removeBookmark(bm);
|
|
bmgr.setBookmark(ba, "Analysis", "Cleanup",
|
|
"Converted invalid pointer to code");
|
|
}
|
|
}
|
|
}
|