158 lines
4.4 KiB
Java
158 lines
4.4 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.
|
|
*/
|
|
//@category iOS
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
|
|
import ghidra.app.script.GhidraScript;
|
|
import ghidra.app.util.demangler.DemangledObject;
|
|
import ghidra.app.util.demangler.DemanglerUtil;
|
|
import ghidra.framework.model.*;
|
|
import ghidra.program.model.address.Address;
|
|
import ghidra.program.model.listing.*;
|
|
import ghidra.program.model.mem.Memory;
|
|
import ghidra.util.exception.CancelledException;
|
|
|
|
public class GetSymbolForDynamicAddress extends GhidraScript {
|
|
private Address addressToLookFor;
|
|
private boolean foundSymbol = false;
|
|
private List<String> programsWithAddress = new ArrayList<>();
|
|
|
|
@Override
|
|
public void run() throws Exception {
|
|
try {
|
|
addressToLookFor = askAddress("Enter Dynamic Address",
|
|
"Please enter the address you want to find a symbol for: ");
|
|
}
|
|
catch (CancelledException e) {
|
|
println("User cancelled script");
|
|
return;
|
|
}
|
|
String[] parts = currentProgram.getDomainFile().getPathname().split("/");
|
|
String firmwareVersion = parts[1];
|
|
Project project = state.getProject();
|
|
ProjectData projectData = project.getProjectData();
|
|
DomainFolder rootFolder = projectData.getRootFolder();
|
|
DomainFolder folder = rootFolder.getFolder(firmwareVersion);
|
|
if (folder == null) {
|
|
println("Run this script from a program under an iOS firmware directory.");
|
|
return;
|
|
}
|
|
processFolder(folder);
|
|
if (!foundSymbol) {
|
|
printFailureExplanation();
|
|
}
|
|
}
|
|
|
|
private void processFolder(DomainFolder domainFolder) {
|
|
if (foundSymbol) {
|
|
return;
|
|
}
|
|
DomainFolder[] folders = domainFolder.getFolders();
|
|
for (DomainFolder folder : folders) {
|
|
processFolder(folder);
|
|
}
|
|
DomainFile[] files = domainFolder.getFiles();
|
|
for (DomainFile file : files) {
|
|
processFile(file);
|
|
}
|
|
}
|
|
|
|
private void processFile(DomainFile file) {
|
|
if (foundSymbol) {
|
|
return;
|
|
}
|
|
DomainObject domainObject = null;
|
|
try {
|
|
domainObject =
|
|
file.getDomainObject(this, true /* upgrade */, false /* do not recover */, monitor);
|
|
if (domainObject instanceof Program) {
|
|
Program program = (Program) domainObject;
|
|
processProgram(program);
|
|
}
|
|
}
|
|
catch (Exception e) {
|
|
printerr(e.getMessage());
|
|
}
|
|
finally {
|
|
if (domainObject != null) {
|
|
domainObject.release(this);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void processProgram(Program program) throws Exception {
|
|
if (foundSymbol) {
|
|
return;
|
|
}
|
|
if (!program.getLanguageID().equals(currentProgram.getLanguageID())) {
|
|
return;
|
|
}
|
|
Memory memory = program.getMemory();
|
|
if (memory.contains(addressToLookFor)) {
|
|
programsWithAddress.add(program.getName());
|
|
Listing listing = program.getListing();
|
|
Function function = listing.getFunctionAt(addressToLookFor);
|
|
if (function == null) {
|
|
return;
|
|
}
|
|
String functionName = function.getName();
|
|
demangleAndCreateSymbol(functionName);
|
|
|
|
foundSymbol = true;
|
|
}
|
|
}
|
|
|
|
private void demangleAndCreateSymbol(String functionName) throws Exception {
|
|
String demangledName = attemptToDemangle(functionName);
|
|
if (demangledName == null) {
|
|
demangledName = functionName;
|
|
}
|
|
try {
|
|
createLabel(addressToLookFor, demangledName, true);
|
|
println("Created symbol \"" + demangledName + "\" for address: " + addressToLookFor);
|
|
}
|
|
catch (Exception e) {
|
|
printerr(e.getMessage());
|
|
printerr(
|
|
"Tried to create symbol \"" + demangledName + "\" for address " + addressToLookFor);
|
|
}
|
|
}
|
|
|
|
private void printFailureExplanation() {
|
|
if (programsWithAddress.size() != 0) {
|
|
println("No function existed at the address " + addressToLookFor.toString());
|
|
println("The programs that contain the address are: ");
|
|
for (String name : programsWithAddress) {
|
|
println("\t" + name);
|
|
}
|
|
}
|
|
else {
|
|
println("Didn't find any programs that contain that address");
|
|
}
|
|
}
|
|
|
|
private String attemptToDemangle(String name) throws Exception {
|
|
|
|
DemangledObject demangledObject = DemanglerUtil.demangle(name);
|
|
if (demangledObject != null) {
|
|
return demangledObject.getName();
|
|
}
|
|
return null;
|
|
}
|
|
}
|