ghidra: fix vmethods not being explicitly thiscall.

ghidra: fix vmethods that returned void returning undefined.

ghidra: fix method used to get Win32 binary timestamps.
develop
Ben Lubar 2020-03-16 19:18:22 -05:00
parent 137d173d67
commit d741456a58
No known key found for this signature in database
GPG Key ID: 92939677AB59EDA4
1 changed files with 51 additions and 8 deletions

@ -27,7 +27,7 @@ public class import_df_structures extends GhidraScript
private Symbols symbols; private Symbols symbols;
private SymbolTable symbolTable; private SymbolTable symbolTable;
private DataTypeManager dtm; private DataTypeManager dtm;
private Category dtc, dtcStd, dtcEnums, dtcVTables; private Category dtc, dtcStd, dtcEnums, dtcVTables, dtcVMethods;
private DataType dtUint8, dtUint16, dtUint32, dtUint64; private DataType dtUint8, dtUint16, dtUint32, dtUint64;
private DataType dtInt8, dtInt16, dtInt32, dtInt64; private DataType dtInt8, dtInt16, dtInt32, dtInt64;
private DataType dtInt, dtLong, dtSizeT; private DataType dtInt, dtLong, dtSizeT;
@ -234,6 +234,7 @@ public class import_df_structures extends GhidraScript
this.dtcEnums = dtc.createCategory("enums"); this.dtcEnums = dtc.createCategory("enums");
this.dtcVTables = dtc.createCategory("vtables"); this.dtcVTables = dtc.createCategory("vtables");
this.dtcVMethods = dtcVTables.createCategory("methods");
} }
private void processXMLInputs() throws Exception private void processXMLInputs() throws Exception
@ -421,7 +422,45 @@ public class import_df_structures extends GhidraScript
public SymbolTable findTable(Program currentProgram) throws Exception public SymbolTable findTable(Program currentProgram) throws Exception
{ {
var actualTS = currentProgram.getCreationDate().getTime() / 1000; long actualTS = 0;
if (currentProgram.getExecutableFormat().equals("Portable Executable (PE)"))
{
// TODO: is there a *good* way to do this with Ghida APIs?
var dtm = currentProgram.getDataTypeManager();
var dosHeader = currentProgram.getListing().getDataAt(currentProgram.getImageBase());
var dosHeaderType = (Structure)dosHeader.getBaseDataType();
DataTypeComponent ntHeaderOffsetField = null;
for (var dosHeaderField : dosHeaderType.getComponents())
{
if (dosHeaderField.getFieldName().equals("e_lfanew"))
{
ntHeaderOffsetField = dosHeaderField;
break;
}
}
var ntHeaderOffset = dosHeader.getUnsignedInt(ntHeaderOffsetField.getOffset());
var ntHeaderAddr = currentProgram.getImageBase().add(ntHeaderOffset);
var ntHeader = currentProgram.getListing().getDataAt(ntHeaderAddr);
var ntHeaderType = (Structure)ntHeader.getBaseDataType();
for (var ntHeaderField : ntHeaderType.getComponents())
{
if (ntHeaderField.getFieldName().equals("FileHeader"))
{
var fileHeader = ntHeader.getComponent(ntHeaderField.getOrdinal());
var fileHeaderType = (Structure)fileHeader.getDataType();
for (var fileHeaderField : fileHeaderType.getComponents())
{
if (fileHeaderField.getFieldName().equals("TimeDateStamp"))
{
actualTS = fileHeader.getUnsignedInt(fileHeaderField.getOffset());
break;
}
}
break;
}
}
}
var actualMD5 = currentProgram.getExecutableMD5(); var actualMD5 = currentProgram.getExecutableMD5();
if (actualMD5 == null) if (actualMD5 == null)
{ {
@ -1097,9 +1136,13 @@ public class import_df_structures extends GhidraScript
private DataType createMethodDataType(String name, TypeDef.VMethod vm) throws Exception private DataType createMethodDataType(String name, TypeDef.VMethod vm) throws Exception
{ {
var ft = new FunctionDefinitionDataType(name); var ft = new FunctionDefinitionDataType(name);
ft.setGenericCallingConvention(GenericCallingConvention.thiscall);
if (vm.returnType != null) if (vm.returnType == null)
ft.setReturnType(DataType.VOID);
else
ft.setReturnType(getDataType(vm.returnType)); ft.setReturnType(getDataType(vm.returnType));
var args = new ParameterDefinition[vm.arguments.size()]; var args = new ParameterDefinition[vm.arguments.size()];
for (int i = 0; i < vm.arguments.size(); i++) for (int i = 0; i < vm.arguments.size(); i++)
{ {
@ -1113,17 +1156,17 @@ public class import_df_structures extends GhidraScript
} }
ft.setArguments(args); ft.setArguments(args);
return createDataType(dtcVTables, ft); return createDataType(dtcVMethods, ft);
} }
private DataType createVTableDataType(TypeDef t) throws Exception private DataType createVTableDataType(TypeDef t) throws Exception
{ {
var name = "vtable_" + (t.originalName != null ? t.originalName : t.typeName); var name = t.originalName != null ? t.originalName : t.typeName;
var existing = dtcVTables.getDataType(name); var existing = dtcVTables.getDataType("vtable_" + name);
if (existing != null) if (existing != null)
return existing; return existing;
Structure st = new StructureDataType(name, 0); Structure st = new StructureDataType("vtable_" + name, 0);
// add early to avoid recursion // add early to avoid recursion
st = (Structure)dtcVTables.addDataType(st, DataTypeConflictHandler.REPLACE_HANDLER); st = (Structure)dtcVTables.addDataType(st, DataTypeConflictHandler.REPLACE_HANDLER);
st.setToDefaultAlignment(); st.setToDefaultAlignment();
@ -1144,7 +1187,7 @@ public class import_df_structures extends GhidraScript
mname = "~" + name; mname = "~" + name;
else else
mname = "_anon_vmethod_" + (st.getLength() / currentProgram.getDefaultPointerSize()); mname = "_anon_vmethod_" + (st.getLength() / currentProgram.getDefaultPointerSize());
st.add(dtm.getPointer(createMethodDataType("_" + name + "::" + mname, vm), currentProgram.getDefaultPointerSize()), mname, null); st.add(dtm.getPointer(createMethodDataType(name + "::" + mname, vm), currentProgram.getDefaultPointerSize()), mname, null);
} }
return createDataType(dtcVTables, st); return createDataType(dtcVTables, st);