Merge remote-tracking branch 'origin/Ghidra_11.3'

This commit is contained in:
Ryan Kurtz
2025-01-27 06:17:07 -05:00
18 changed files with 1144 additions and 293 deletions
@@ -4,9 +4,9 @@
* 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.
@@ -22,10 +22,11 @@
import java.io.File;
import java.io.PrintWriter;
import java.util.Iterator;
import java.util.*;
import ghidra.app.script.GhidraScript;
import ghidra.program.model.data.*;
import ghidra.program.model.data.Enum;
import ghidra.program.model.data.StandAloneDataTypeManager.ArchiveWarning;
import ghidra.util.UniversalID;
@@ -162,7 +163,22 @@ public class CompareGDTs extends GhidraScript {
return dtmArchive.findDataTypeForID(universalID);
}
}
return dtmArchive.getDataType(dataType.getCategoryPath(), dataType.getName());
// find by exact path
DataType fdt = dtmArchive.getDataType(dataType.getCategoryPath(), dataType.getName());
if (fdt != null) {
return fdt;
}
// find by name
List<DataType> list = new ArrayList<DataType>();
dtmArchive.findDataTypes(dataType.getName(), list );
for (DataType dtc : list) {
if (dataType.getCategoryPath().getPath().toLowerCase().equals(dtc.getCategoryPath().getPath().toLowerCase())) {
return dtc;
}
}
return null;
}
private long outputWhereTypesDiffer(FileDataTypeManager dtmArchive1,
@@ -247,6 +263,10 @@ public class CompareGDTs extends GhidraScript {
Class<?> dtClass = dataType.getClass();
Class<?> sameNamedDtClass = matchingDataType.getClass();
if (dtClass == sameNamedDtClass) {
if (dataType instanceof Enum && (((Enum) dataType).getCount()==1)) {
// don't check single entry enums. Size will vary, and they are extracted defines
return checkEnum((Enum) dataType, (Enum) matchingDataType);
}
if (!dataType.isEquivalent(matchingDataType)) {
String message =
dataType.getPathName() + " (" + dtClass.getSimpleName() + ")";
@@ -258,6 +278,22 @@ public class CompareGDTs extends GhidraScript {
return false;
}
private boolean checkEnum(Enum e1, Enum e2) {
if (e1.getCount() != e2.getCount()) {
return true;
}
// Check that the name is the same
if (! e1.getNames()[0].equals(e2.getNames()[0])) {
return true;
}
// Check the value is the same
if (e1.getValues()[0] != e2.getValues()[0]) {
return true;
}
return false;
}
private boolean outputIfDifferentSizes(DataType dataType, FileDataTypeManager dtmArchive) {
if (!checkPointers && dataType instanceof Pointer) {
@@ -273,6 +309,10 @@ public class CompareGDTs extends GhidraScript {
Class<?> dtClass = dataType.getClass();
Class<?> sameNamedDtClass = matchingDataType.getClass();
if (dtClass == sameNamedDtClass) {
if (dataType instanceof Enum && (((Enum) dataType).getCount()==1)) {
// don't check single entry enums. Size will vary, and they are extracted defines
return checkEnum((Enum) dataType, (Enum) matchingDataType);
}
if (dataType.getLength() != matchingDataType.getLength()) {
String message = dataType.getPathName() + " (" + dtClass.getSimpleName() +
") " + dataType.getLength() + " != " + matchingDataType.getLength();
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,138 @@
/* ###
* 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.
*/
//
// Parses UEFI header file gdt archives from
// git clone https://github.com/tianocore/edk2
//
// To replace existing header files and have the data type ID's synchronized
//
// Must run SynchronizeGDTCategoryPaths.java script with old and replacement GDT
// archive to synchronize upper/lower case paths
/// (only on windows archives)
//
// Then Run DataTypeArchiveTransformer in eclipse to synchronize old data types ID's
// if an existing .gdt file is being replaced
//
//@category Data Types
import java.io.File;
import java.io.IOException;
import ghidra.app.script.GhidraScript;
import ghidra.app.util.cparser.C.CParserUtils;
import ghidra.app.util.cparser.C.CParserUtils.CParseResults;
import ghidra.app.util.cparser.C.ParseException;
import ghidra.program.model.data.DataTypeManager;
import ghidra.program.model.data.FileDataTypeManager;
import ghidra.util.Msg;
public class CreateUEFIGDTArchivesScript extends GhidraScript {
private File outputDirectory;
private static String headerFilePath = "/data/HeaderFiles/git/edk2";
@Override
protected void run() throws Exception {
outputDirectory = askDirectory("Select Directory for GDT files", "Select GDT Output Dir");
parseUEFIHeaders("X64", "x86:LE:64:default", "windows");
parseUEFIHeaders("Ia32", "x86:LE:32:default", "windows");
parseUEFIHeaders("AArch64", "AARCH64:LE:64:v8A", "windows");
parseUEFIHeaders("Arm", "ARM:LE:32:v8", "default");
parseUEFIHeaders("RiscV64", "RISCV:LE:64:RV64G", "gcc");
parseUEFIHeaders("LoongArch64", "Loongarch:LE:64:lp64d", "default");
}
private void parseHeaderFilesToGDT(File outputDir, String gdtName, String languageID, String compiler,
String[] filenames, String includePaths[], String[] args)
throws ParseException, ghidra.app.util.cparser.CPP.ParseException, IOException {
DataTypeManager openTypes[] = null;
parseHeaderFilesToGDT(openTypes, outputDir, gdtName, languageID, compiler, filenames, includePaths, args);
}
private void parseHeaderFilesToGDT(DataTypeManager openTypes[], File outputDir, String gdtName, String languageID, String compiler,
String[] filenames, String[] includePaths, String[] args)
throws ParseException, ghidra.app.util.cparser.CPP.ParseException, IOException {
String dataTypeFile = outputDir + File.separator + gdtName + ".gdt";
File f = getArchiveFile(dataTypeFile);
FileDataTypeManager dtMgr = CParserUtils.parseHeaderFiles(openTypes, filenames,
includePaths, args, f.getAbsolutePath(), languageID, compiler, monitor);
dtMgr.save();
dtMgr.close();
}
/**
* Turn string into a file, delete old archive if it exists
*
* @param dataTypeFile
*
* @return file
*/
private File getArchiveFile(String dataTypeFile) {
File f = new File(dataTypeFile);
if (f.exists()) {
f.delete();
}
String lockFile = dataTypeFile + ".ulock";
File lf = new File(lockFile);
if (lf.exists()) {
lf.delete();
}
return f;
}
public void parseUEFIHeaders(String name, String languageID, String compiler) throws Exception {
String filenames[] = {
"ProcessorBind.h",
"Uefi/UefiBaseType.h",
"Uefi/UefiSpec.h",
"PiDxe.h",
"PiMm.h",
"PiPei.h",
"PiSmm.h",
"Library/DxeCoreEntryPoint.h",
"Library/PeiCoreEntryPoint.h",
"Library/PeimEntryPoint.h",
"Library/StandaloneMmDriverEntryPoint.h",
"Library/UefiApplicationEntryPoint.h",
"Library/UefiDriverEntryPoint.h",
headerFilePath+"/MdePkg/Include/Pi/",
headerFilePath+"/MdePkg/Include/Ppi/",
headerFilePath+"/MdePkg/Include/Protocol/",
headerFilePath+"/MdePkg/Include/IndustryStandard/",
};
String includePaths[] = {
headerFilePath+"/MdePkg/Include/"+name,
headerFilePath+"/MdePkg/Include",
};
String args[] = {
};
parseHeaderFilesToGDT(outputDirectory, "uefi_"+name, languageID, compiler, filenames, includePaths, args);
}
}