Exemple #1
0
	def get_dtype(self):
		if self.dtype is not None:
			return self.dtype
		dm = currentProgram.getDataTypeManager()
		bdm = BuiltInDataTypeManager.getDataTypeManager()
		new_struct = StructureDataType(CategoryPath("/struct"), self.name, self.size)
		size_lookup = {}
		size_lookup[1] = bdm.getDataType("/char")
		size_lookup[2] = bdm.getDataType("/short")
		size_lookup[4] = bdm.getDataType("/int")
		size_lookup[8] = bdm.getDataType("/longlong")
		off = 0
		for i in range(len(self.members)):
			t, size = self.members[i][0], self.members[i][1]
			comment = ""
			if len(self.members[i]) > 2 and self.members[i][2] == False:
				comment = "NOT ACCESSED"
			if isinstance(t, Struct):
				if not t.is_array:
					sub_struct_dtype = t.get_dtype()
					new_struct.replaceAtOffset(off, sub_struct_dtype, ARCH_BITS / 8, "entry_{}".format(i), comment)
				else:
					arr_dtype = bdm.getPointer(size_lookup[1], ARCH_BITS / 8)
					new_struct.replaceAtOffset(off, arr_dtype, ARCH_BITS / 8, "entry_{}".format(i), comment)
			else:
				if size not in size_lookup:
					arr_dtype = ArrayDataType(size_lookup[1], size, 1)
					new_struct.replaceAtOffset(off, arr_dtype, size, "entry_{}".format(i), comment)
				else:
					new_struct.replaceAtOffset(off, size_lookup[size], size, "entry_{}".format(i), comment)
			off += size
		print("DONE CREATING STRUCT", self.name)
		dm.addDataType(new_struct, DataTypeConflictHandler.REPLACE_HANDLER)
		self.dtype = dm.getPointer(new_struct, ARCH_BITS / 8)
		return self.dtype
Exemple #2
0
def defineIOExternalMethodArguments():

    dtm = currentProgram.getDataTypeManager()
    dt = find_struct("IOExternalMethodArguments")
    IOMemoryDescriptor = find_struct("IOMemoryDescriptor")
    if IOMemoryDescriptor == None:
        IOMemoryDescriptor = dtm.getDataType("/ulonglong")

    new = None
    if dt == None:
        dt = StructureDataType("IOExternalMethodArguments", 0)
        new = dt

    elif dt.getLength() > 1:
        yes = askYesNo(
            "IOExternalMethodArguments",
            "[-] Looks like IOExternalMethodArguments is already defined, continue ?"
        )
        if yes == False:
            exit()

    uint = dtm.getDataType("/uint")
    ulonglong = dtm.getDataType("/ulonglong")

    st = dt
    st.add(uint, "version", "")
    st.add(uint, "selector", "")

    st.add(ulonglong, "asyncWakePort", "")
    st.add(PointerDataType(uint), "asyncReference", "")
    st.add(uint, "asyncReferenceCount", "")

    st.add(PointerDataType(ulonglong), "scalarInput", "")
    st.add(uint, "scalarInputCount", "")
    st.add(PointerDataType(ulonglong), "structureInput", "")
    st.add(uint, "structureInputSize", "")

    st.add(PointerDataType(IOMemoryDescriptor), "StructureInputDescriptor", "")

    st.add(PointerDataType(ulonglong), "scalarOutput", "")
    st.add(uint, "scalarOutputCount", "")

    st.add(PointerDataType(ulonglong), "structureOutput", "")
    st.add(uint, "structureOutputSize", "")

    st.add(PointerDataType(IOMemoryDescriptor), "structureOutputDescriptor",
           "")
    st.add(uint, "structureOutputDescriptorSize", "")

    st.add(uint, "__reservedA", "")
    st.add(PointerDataType(ulonglong), "structureVariableOutputData", "")
    st.setInternallyAligned(True)
    if new:
        dtm.addDataType(new, None)
        dtm.addDataType(PointerDataType(new), None)
Exemple #3
0
def prepareClassName(className, classSize):
    locs = ["/", "/Demangler/"]
    for location in locs:
        res = findDataTypeByName(location + className)
        if res:
            return

    class_struct = StructureDataType(className, 0)
    currentProgram.getDataTypeManager().addDataType(class_struct, None)
Exemple #4
0
def createClassType(namespace, vftableDataType):
    dtm = currentProgram.getDataTypeManager()
    categoryPath="/%s" % ('/'.join(namespace.split("::")[:-1]))
    #structDataType=StructureDataType(CategoryPath(categoryPath), namespace.split('::')[-1], 0)
    structDataType=StructureDataType(CategoryPath(categoryPath), namespace, 0)
    dt=dtm.addDataType(structDataType, DataTypeConflictHandler.REPLACE_HANDLER)
    p=PointerDataType(vftableDataType)
    dt.add(p, currentProgram.getDefaultPointerSize(), "fvtable","")
    return dt
Exemple #5
0
def createVftableType(namespace, length):
    dtm = currentProgram.getDataTypeManager()
    programName = getProgramFile().getName()
    categoryPath="/%s" % ('/'.join(namespace.split("::")[:-1]))
    #category=dtm.createCategory(CategoryPath(categoryPath))
    structDataType=StructureDataType(CategoryPath(categoryPath), "%s_vftable" % namespace.split('::')[-1], 0)
    dt=dtm.addDataType(structDataType, DataTypeConflictHandler.REPLACE_HANDLER)
    for i in range(0,length):
        p=PointerDataType()
        dt.add(p, currentProgram.getDefaultPointerSize(), "member%X" % (i),"")
    return dt
    def create_types(self):
        """
        Create custom data types if the don't exist yet (why would they?).
        """
        self.function_type = dtm.getDataType("/ScatterLoadSubFunction")
        if not self.function_type:
            self.function_type = FunctionDefinitionDataType("ScatterLoadSubFunction")
            self.function_type.setReturnType(VoidDataType.dataType)
            self.function_type.setArguments([
                ParameterDefinitionImpl("source", PointerDataType(VoidDataType.dataType), None),
                ParameterDefinitionImpl("destination", PointerDataType(VoidDataType.dataType), None),
                ParameterDefinitionImpl("dest_size", UnsignedIntegerDataType.dataType, None)
            ])

        self.table_entry_type = dtm.getDataType("/ScatterLoadTableEntry")
        if not self.table_entry_type:
            self.table_entry_type = StructureDataType("ScatterLoadTableEntry", 0)
            self.table_entry_type.add(PointerDataType(VoidDataType.dataType), 0, "source", "Source data for RAM initialization")
            self.table_entry_type.add(PointerDataType(VoidDataType.dataType), 0, "destination", "Start of target area in RAM")
            self.table_entry_type.add(UnsignedIntegerDataType.dataType, 0, "dest_size", "Length of target area in RAM, in bytes")
            self.table_entry_type.add(PointerDataType(self.function_type), 0, "func", "Function to be called")
Exemple #7
0
def defineIOExternalTrap():
    dtm = currentProgram.getDataTypeManager()
    dt = dtm.findDataType(currentProgram.getName() + "/" + "IOExternalTrap")

    uint = dtm.getDataType("/uint")
    IOService = dtm.getDataType("/IOService")
    IOTrap_def = "IOService::IOTrap(void * p1, void * p2, void * p3, void * p4, void * p5, void * p6)"

    fdef = FunctionDefinitionDataType(IOTrap_def)
    fdef.setReturnType(uint)
    fdef.setGenericCallingConvention(GenericCallingConvention.thiscall)

    st = StructureDataType("IOExternalTrap", 0)
    st.setToMachineAlignment()
    st.add(PointerDataType(IOService), "object", "")
    st.add(PointerDataType(fdef), "func", "")

    dtm.addDataType(PointerDataType(st), None)
Exemple #8
0
    def create_vtable_structures(class_name):
        this_class = found_classes[class_name]

        # Create a new struct
        vtable_structure_size = this_class.vtable_size * 4
        vtable_struct = StructureDataType(this_class.vtable_struct_name,
                                          vtable_structure_size)

        # Add the base functions if this is a BASE vtable
        if this_class.name.startswith("BASE"):
            for index, base_function_name in enumerate(
                ("CheckType", "GetType", "Destructor", "AddRef", "Release")):
                vtable_struct.replaceAtOffset(index * 4, pointer_type, 4,
                                              base_function_name,
                                              "Base class function")
        else:
            # Add the parent class's vtable structure
            parent_class = found_classes[this_class.parent]
            parent_vtable_struct_path = "/" + parent_class.vtable_struct_name
            parent_vtable_struct = currentProgram.getDataTypeManager(
            ).getDataType(parent_vtable_struct_path)
            assert parent_vtable_struct is not None
            vtable_struct.replaceAtOffset(0, parent_vtable_struct,
                                          parent_class.vtable_size * 4,
                                          parent_class.name, "Base class")

            # Add pointer-sized values for any remaining values
            for index in range(parent_class.vtable_size,
                               this_class.vtable_size):
                vtable_struct.replaceAtOffset(index * 4, pointer_type, 4, None,
                                              None)

        # If the struct already exists, a new struct will be created with ".conflict" in the name
        vtable_struct = currentProgram.getDataTypeManager().addDataType(
            vtable_struct, DataTypeConflictHandler.KEEP_HANDLER)

        # Set the class struct's vtable pointer to point to the new vtable structure
        class_namespace = symbol_table.getNamespace(this_class.name, None)
        class_struct = VariableUtilities.findOrCreateClassStruct(
            class_namespace, currentProgram.getDataTypeManager())

        ptr_to_vtable_type = PointerDataType(vtable_struct)
        class_struct.replaceAtOffset(0, ptr_to_vtable_type, 4, "vtable", None)
Exemple #9
0
def get_structure(entry):
    path = get_datatype_path(entry).getCategoryPath()
    dtm = currentProgram.getDataTypeManager()
    struct = StructureDataType(path, entry["Name"], 0, dtm)
    for comp in entry["Components"]:
        if comp["bitfield"]:
            bitfield = comp["bitfield"]
            struct.insertBitfieldAt(comp["offset"], bitfield["byteWidth"],
                                    bitfield["bitOffset"], get_datatype(bitfield["DataType"]),
                                    bitfield["bitSize"], comp["name"], comp["comment"])
        else:
            struct.insertAtOffset(
                comp["offset"], get_datatype(comp["DataType"]),
                comp["length"], comp["name"], comp["comment"])
            src = prog
        elif dst_prog_string == prog.getName():
            dst = prog

    if src == None or dst == None:
        popup("Could not get src/dst program")
        exit(0)
        
    print src,dst
    
    src_dtm = src.getDataTypeManager()
    dst_dtm = dst.getDataTypeManager()

    structs = src_dtm.getAllStructures()
    
    for s in structs:
        name =  s.getName()
        res = isThere('/'+name,dst_dtm)
        if res == True:
            continue
        
        res = isThere('/Demangler/'+name,dst_dtm)
        if res == True:
            continue
        
        struct = StructureDataType(name,0)
        dst_dtm.addDataType(struct,None)
        dst_dtm.addDataType(PointerDataType(struct),None)
        

import struct

debug = False
process_is_64bit = False

# Init Structs
ptr_data_type = PointerDataType()
byte_data_type = ByteDataType()
char_data_type = CharDataType()
void_data_type = VoidDataType()
unsigned_int_type = UnsignedIntegerDataType()
short_data_type = ShortDataType()
char_ptr_type = ptr_data_type.getPointer(char_data_type, 4)
void_ptr_type = ptr_data_type.getPointer(void_data_type, 4)

vx_5_symtbl_dt = StructureDataType("VX_5_SYMBOL_IN_TBL", 0x10)
vx_5_symtbl_dt.replaceAtOffset(0, unsigned_int_type, 4, "symHashNode", "")
vx_5_symtbl_dt.replaceAtOffset(4, char_ptr_type, 4, "symNamePtr", "")
vx_5_symtbl_dt.replaceAtOffset(8, void_ptr_type, 4, "symPrt", "")
vx_5_symtbl_dt.replaceAtOffset(0x0c, short_data_type, 4, "symGroup", "")
vx_5_symtbl_dt.replaceAtOffset(0x0e, byte_data_type, 1, "symType", "")
vx_5_symtbl_dt.replaceAtOffset(0x0f, byte_data_type, 1, "End", "")

vx_6_symtbl_dt = StructureDataType("VX_6_SYMBOL_IN_TBL", 0x14)
vx_6_symtbl_dt.replaceAtOffset(0, unsigned_int_type, 4, "symHashNode", "")
vx_6_symtbl_dt.replaceAtOffset(4, char_ptr_type, 4, "symNamePtr", "")
vx_6_symtbl_dt.replaceAtOffset(8, void_ptr_type, 4, "symPrt", "")
vx_6_symtbl_dt.replaceAtOffset(0x0c, unsigned_int_type, 4, "symRef",
                               "moduleId of module, or predefined SYMREF")
vx_6_symtbl_dt.replaceAtOffset(0x10, short_data_type, 4, "symGroup", "")
vx_6_symtbl_dt.replaceAtOffset(0x12, byte_data_type, 1, "symType", "")
Exemple #12
0
class KeilRAMInit(object):
    """
    The main flow of the script, put into a class so we can break out logical sections
    of the flow into methods and store intermediate data in the class instance.
    """
    def run(self):
        """
        The high-level flow
        """
        self.ram_block = memory.getBlock("ram")
        if not self.ram_block or self.ram_block.isInitialized():
            yikes("No uninitialized memory block named 'ram' found")

        if currentSelection is None or currentSelection.isEmpty():
            self.scatterload_function = listing.getFunctionContaining(currentAddress)
            if not self.scatterload_function:
                yikes("Please launch the script from within a function")
            self.find_scatterload_table()
        else:
            self.scatterload_table = currentSelection.getFirstRange()

        print("Scatterload table at", self.scatterload_table)

        self.create_types()
        self.parse_scatterload_table()

        if not (self.data_init_start and self.ram_clear_start):
            yikes("Data init or RAM clear entry are missing from the scatterload table")

        print("Initialization data at %s (%d bytes)" % (self.data_init_start, self.data_size_packed))
        print("Uncompressed initialized data size: %d bytes" % self.data_size_unpacked)
        print("Zeroed data at %s (%d bytes)" % (self.ram_clear_start, self.ram_clear_size))

        self.uncompress_init_data()
        self.create_ram_blocks()

        print(r"All done \o/")

    def create_types(self):
        """
        Create custom data types if the don't exist yet (why would they?).
        """
        self.function_type = dtm.getDataType("/ScatterLoadSubFunction")
        if not self.function_type:
            self.function_type = FunctionDefinitionDataType("ScatterLoadSubFunction")
            self.function_type.setReturnType(VoidDataType.dataType)
            self.function_type.setArguments([
                ParameterDefinitionImpl("source", PointerDataType(VoidDataType.dataType), None),
                ParameterDefinitionImpl("destination", PointerDataType(VoidDataType.dataType), None),
                ParameterDefinitionImpl("dest_size", UnsignedIntegerDataType.dataType, None)
            ])

        self.table_entry_type = dtm.getDataType("/ScatterLoadTableEntry")
        if not self.table_entry_type:
            self.table_entry_type = StructureDataType("ScatterLoadTableEntry", 0)
            self.table_entry_type.add(PointerDataType(VoidDataType.dataType), 0, "source", "Source data for RAM initialization")
            self.table_entry_type.add(PointerDataType(VoidDataType.dataType), 0, "destination", "Start of target area in RAM")
            self.table_entry_type.add(UnsignedIntegerDataType.dataType, 0, "dest_size", "Length of target area in RAM, in bytes")
            self.table_entry_type.add(PointerDataType(self.function_type), 0, "func", "Function to be called")

    def extract_scatterload_A(self):
        """
        Extract the scatterload table pointers from a function that loads the pointers individually
        """
        load_values = []
        for i, insn in enumerate(listing.getInstructions(self.scatterload_function.getEntryPoint(), True)):
            pair = get_load_data(insn)
            if pair:
                load_values.append(pair)
                if len(load_values) == 2:
                    break
            if i == 8:
                return None

        print("Type A scatterload function identified")

        retval = []
        for pointed, pointer in sorted(load_values):
            listing.clearCodeUnits(pointer, pointer.add(4), False)
            listing.createData(pointer, PointerDataType.dataType)
            retval.append(pointed)

        return retval

    def extract_scatterload_B(self):
        """
        Extract the pointers from a function that uses a ldmia instruction to load both pointers at once
        """
        insn_adr = listing.getInstructionAt(self.scatterload_function.getEntryPoint())
        insn_ldmia = insn_adr.getNext()
        ldmia_op1 = insn_ldmia.getOpObjects(1)

        # We're looking for an adr/ldmia combination that loads two consecutive values into two regs
        if not (insn_adr.mnemonicString == "adr"
                and insn_ldmia.mnemonicString == "ldmia"
                and insn_adr.getRegister(0) == insn_ldmia.getRegister(0)
                and ldmia_op1 and len(ldmia_op1) == 2):
            return None

        print("Type B scatterload function identified")

        # The stored pointers to the scatterload table are offsets relative to the location of the first pointer
        offsets = currentAddress.getNewAddress(insn_adr.getOpObjects(1)[0].getValue())
        listing.clearCodeUnits(offsets, offsets.add(8), False)
        listing.createData(offsets, UnsignedIntegerDataType.dataType)
        listing.createData(offsets.add(4), UnsignedIntegerDataType.dataType)

        return [offsets.add(offset) for offset in read_uints(offsets, 2)]

    def find_scatterload_table(self):
        """
        Assuming we're really looking at the __scatterload function, extract
        the scatterload table location and size.
        """
        table_pointers = self.extract_scatterload_A() or self.extract_scatterload_B()
        if not table_pointers:
            print("Cannot identify the current function as a scatterload function :(")
            print("If you're certain this is it please help the script along:")
            print(" 1. Find the scatterload table yourself - N*16 bytes large and referenced by this function")
            print(" 2. Select the entire table and re-run the script")
            exit(1)

        scatterload_table_start, scatterload_table_end = table_pointers
        symbols.createLabel(scatterload_table_start, "Region$$Table$$Base", SourceType.USER_DEFINED)
        symbols.createLabel(scatterload_table_end, "Region$$Table$$Limit", SourceType.USER_DEFINED)

        self.scatterload_function.setName("__scatterload", SourceType.USER_DEFINED)
        self.scatterload_table = AddressRangeImpl(scatterload_table_start, scatterload_table_end.subtract(1))

    def parse_scatterload_table(self):
        """
        Go through the scatterload table and identify the calls to unpack the init data and
        clear the bss section.
        """
        self.data_init_start = None
        self.data_size_packed = None
        self.data_size_unpacked = None
        self.ram_clear_start = None
        self.ram_clear_size = None

        if self.scatterload_table.getLength() % 0x10:
            yikes("Scatterload table size not a multiple of 0x10")

        scatterload_nentries = self.scatterload_table.getLength() / 0x10
        if scatterload_nentries < 2:
            yikes("Scatterload table too small to contain a decompress and clear entry")

        # Actually iterating might be unnecessary because the table layout is identical
        # in all targets I've seen so far, but what do I know.
        # The one assumption in here is that the unpack call comes _before_ the clear call.
        for entry in range(scatterload_nentries):
            addr = self.scatterload_table.getMinAddress().add(entry * 0x10)
            listing.clearCodeUnits(addr, addr.add(0x10), False)
            listing.createData(addr, self.table_entry_type)
            entry = read_uints(addr, 4)

            function_name = None
            is_rwdata_init_function = False
            if entry[1] == self.ram_block.getStart().getOffset():
                print("Init data call found:", entry)
                is_rwdata_init_function = True

                self.data_init_start = addr.getNewAddress(entry[0])
                self.data_size_unpacked = entry[2]

            elif self.data_init_start and entry[1] == self.ram_block.getStart().getOffset() + self.data_size_unpacked:
                print("Clear memory call found:", entry)
                function_name = "__scatterload_zeroinit"

                self.data_size_packed = entry[0] - self.data_init_start.getOffset()
                self.ram_clear_start = addr.getNewAddress(entry[1])
                self.ram_clear_size = entry[2]

            function_addr = addr.getNewAddress(entry[3])
            function = createFunction(function_addr, function_name)
            # Using commands for high-level operations is the "Ghidra Way" it seems:
            # https://github.com/NationalSecurityAgency/ghidra/issues/1126
            ApplyFunctionSignatureCmd(function_addr, self.function_type, SourceType.USER_DEFINED, True, False).applyTo(currentProgram)
            if is_rwdata_init_function:
                self.rwdata_init_function = function or getFunctionAt(function_addr)

    def uncompress_init_data(self):
        """
        Uncompress the init data by trying all available decompressors.
        """
        symbols.createLabel(self.data_init_start, "rwdata_init", SourceType.USER_DEFINED).setPrimary()
        listing.clearCodeUnits(self.data_init_start, self.data_init_start.add(self.data_size_packed), False)
        listing.createData(self.data_init_start, ArrayDataType(ByteDataType.dataType, self.data_size_packed, 1))

        packed_data = read_bytes(self.data_init_start, self.data_size_packed)
        if self.data_size_packed == self.data_size_unpacked:
            print("Initialization data packed size equals unpacked size, assuming no compression")
            self.unpacked_data = packed_data
            self.rwdata_init_function.setName("__scatterload_copy", SourceType.USER_DEFINED)
        else:
            print("Uncompressing initialization data")
            for core in unpack_cores:
                self.unpacked_data = unpack(packed_data, self.data_size_unpacked, core)
                if self.unpacked_data is not None:
                    self.rwdata_init_function.setName(core[1], SourceType.USER_DEFINED)
                    break
            else:
                yikes("Failed to uncompress initialization data")

    def create_ram_blocks(self):
        """
        Split the ram block into parts, and initialize them with our unpacked data
        and zeros respectively.
        """
        print("Creating and initializing RAM blocks")

        undef_start = self.ram_clear_start.add(self.ram_clear_size)

        ram_init = self.ram_block
        ram_init.setName("ram.init")

        memory.split(ram_init, self.ram_clear_start)
        ram_clear = memory.getBlock(self.ram_clear_start)
        ram_clear.setName("ram.clear")

        memory.split(ram_clear, undef_start)
        ram_undef = memory.getBlock(undef_start)
        ram_undef.setName("ram.undef")

        ram_clear = memory.convertToInitialized(ram_clear, 0)

        ram_init = memory.convertToInitialized(ram_init, 0)
        ram_init.putBytes(ram_init.getStart(), array("b", array("B", self.unpacked_data).tostring()))
Exemple #13
0
    'char16': '/char16',
    'V3f': '/V3f'
}

for key, primitive in stuff['primitives'].iteritems():
    key = int(key)
    print('key:%x -> prim:%r' % (key, primitive))
    if primitive['name'] in primMap:
        dt = dtmgr.getDataType(primMap[primitive['name']])
        assert dt != None
        assert dt.length == primitive['size']
        print('resolved to %r' % dt)
        typeMap[key] = dt
    elif key not in typeMap:
        print('creating type')
        dt = StructureDataType(saveCatPath, 'SP' + primitive['name'],
                               primitive['size'], dtmgr)
        dt.description = 'saveschema %08x' % key
        dtmgr.addDataType(dt, handler)
        typeMap[key] = dt
    else:
        if typeMap[key].name != 'SP' + primitive['name']:
            typeMap[key].name = 'SP' + primitive['name']

for key, typ in stuff['types'].iteritems():
    key = int(key)
    print('key:%x -> struct:%s' % (key, typ['name']))
    name = typ['name']
    if name.startswith('::Game::Save'):
        name = 'GS' + name[12:]
    elif name.startswith('::Game::'):
        name = 'G' + name[8:]
Exemple #14
0
    # if there are indeed multiple symbols, use the first one
    vptr_sym = symbols[0]

    print("[+] vptr for {} found @ 0x{}, looking for vtable...".format(
        cname, vptr_sym.address))

    vtable_addr = vptr_sym.address.add(alignment +
                                       1)  # one after the alignment
    print("[+] vtable for {} found @ 0x{}, processing entries...".format(
        cname, vtable_addr))
    cur_addr = vtable_addr

    # create the new datatype (Structure/class)
    vtable_type_name = "VTABLE_{}".format(cname)
    vtable_type = StructureDataType(vtable_type_name, 0)

    cutoff_ctr = 0

    while cutoff_ctr < cutoff:
        data = getDataAt(cur_addr)

        if not data:
            cur_addr = cur_addr.add(ptr_size)
            continue

            print("[!] no data @ 0x{}, bailing out...".format(cur_addr))
            break  # no data at this address, skip

        if data.isPointer():  # it will (hopefully) be a function ptr
            func_ptr = getFunctionAt(data.value)
Exemple #15
0
from ghidra.program.model.lang import RegisterValue
from java.math import BigInteger
import xml.etree.ElementTree as ET
import os
import sys

print os.getcwd()

tree = ET.parse('ps3.xml')
root_xml = tree.getroot()

dataTypeManager = currentProgram.getDataTypeManager()
memory = currentProgram.getMemory()
listing = currentProgram.getListing()

libstubstruc = StructureDataType(CategoryPath.ROOT, "_scelibstub", 0)
libstubstruc.add(UnsignedCharDataType(), 1, "structsize", "")
libstubstruc.add(UnsignedCharDataType(), 1, "reserved1", "")
libstubstruc.add(UnsignedShortDataType(), 2, "version", "")
libstubstruc.add(UnsignedShortDataType(), 2, "attribute", "")
libstubstruc.add(UnsignedShortDataType(), 2, "nfunc", "")
libstubstruc.add(UnsignedShortDataType(), 2, "nvar", "")
libstubstruc.add(UnsignedShortDataType(), 2, "ntlsvar", "")
libstubstruc.add(UnsignedCharDataType(), 4, "reserved2", "")
libstubstruc.add(Pointer32DataType(), 4, "libname", "")
libstubstruc.add(Pointer32DataType(), 4, "func_nidtable", "")
libstubstruc.add(Pointer32DataType(), 4, "func_table", "")
libstubstruc.add(Pointer32DataType(), 4, "var_nidtable", "")
libstubstruc.add(Pointer32DataType(), 4, "var_table", "")
libstubstruc.add(Pointer32DataType(), 4, "tls_nidtable", "")
libstubstruc.add(Pointer32DataType(), 4, "tls_table", "")
Exemple #16
0
void_data_type = VoidDataType()
unsigned_int_type = UnsignedIntegerDataType()
int_type = IntegerDataType()
unsigned_long_type = UnsignedLongDataType()
short_data_type = ShortDataType()
char_ptr_type = ptr_data_type.getPointer(char_data_type, 4)
void_ptr_type = ptr_data_type.getPointer(void_data_type, 4)
# Prepare VxWorks symbol types
vx_5_sym_enum = EnumDataType("Vx5symType", 1)
for flag in vx_5_symbol_type_enum:
    vx_5_sym_enum.add(vx_5_symbol_type_enum[flag], flag)
vx_6_sym_enum = EnumDataType("Vx6symType", 1)
for flag in vx_6_symbol_type_enum:
    vx_6_sym_enum.add(vx_6_symbol_type_enum[flag], flag)

vx_5_symtbl_dt = StructureDataType("VX_5_SYMBOL_IN_TBL", 0x10)
vx_5_symtbl_dt.replaceAtOffset(0, unsigned_int_type, 4, "symHashNode", "")
vx_5_symtbl_dt.replaceAtOffset(4, char_ptr_type, 4, "symNamePtr", "")
vx_5_symtbl_dt.replaceAtOffset(8, void_ptr_type, 4, "symPrt", "")
vx_5_symtbl_dt.replaceAtOffset(0x0c, short_data_type, 4, "symGroup", "")
vx_5_symtbl_dt.replaceAtOffset(0x0e, vx_5_sym_enum, 1, "symType", "")
vx_5_symtbl_dt.replaceAtOffset(0x0f, byte_data_type, 1, "End", "")

vx_6_symtbl_dt = StructureDataType("VX_6_SYMBOL_IN_TBL", 0x14)
vx_6_symtbl_dt.replaceAtOffset(0, unsigned_int_type, 4, "symHashNode", "")
vx_6_symtbl_dt.replaceAtOffset(4, char_ptr_type, 4, "symNamePtr", "")
vx_6_symtbl_dt.replaceAtOffset(8, void_ptr_type, 4, "symPrt", "")
vx_6_symtbl_dt.replaceAtOffset(0x0c, unsigned_int_type, 4, "symRef",
                               "moduleId of module, or predefined SYMREF")
vx_6_symtbl_dt.replaceAtOffset(0x10, short_data_type, 4, "symGroup", "")
vx_6_symtbl_dt.replaceAtOffset(0x12, vx_6_sym_enum, 1, "symType", "")
Exemple #17
0
def create_trace_entry():
    """create_trace_entry

    struct TraceEntry {
        uint magic;
        uint unk1;
        uint unk2;
        uint unk_magic;
        char * message;
        uint linenum;
        char * file;
    };
    """
    handler = DataTypeConflictHandler.REPLACE_HANDLER
    bi_dtm = BuiltInDataTypeManager.getDataTypeManager()
    dtm = currentProgram.getDataTypeManager()

    structure = StructureDataType("TraceEntry", 0)
    str_ptr = bi_dtm.getPointer(bi_dtm.getDataType("/string"))
    uint_ty = bi_dtm.getDataType("/uint")

    structure.add(uint_ty, 4, "magic", "")
    structure.add(uint_ty, 4, "unk1", "")
    structure.add(uint_ty, 4, "unk2", "")
    structure.add(uint_ty, 4, "unk_magic", "")
    structure.add(str_ptr, 4, "message", "")
    structure.add(uint_ty, 4, "linenum", "")
    structure.add(str_ptr, 4, "file", "")

    dtm.addDataType(structure, handler)
    if (len(peripheral.registers) == 0):
        print("\t\tNo registers.")
        continue
    if (not peripheral.address_blocks):
        continue
    if (len(peripheral.address_blocks) == 0):
        continue
    try:
        # Iterage through addressBlock of a Peripheral.
        # For each addressBlock create a pripheral strcuture with the name of the peripheral and the size of the actual addressBlock.
        # For each addessBlock iterate through the registers of the peripheral and add a register, if the offset mathes to the address range of the current addressBlock.
        # Enter the addressBlock specific peripheral to Ghidra.
        # Since all these addressBlock-peripheral entries share the same same, they pop up as one name in Ghidra.
        length = calculate_peripheral_size(peripheral, 32)
        # Generate structure for the peripheral
        peripheral_struct = StructureDataType(peripheral.name, length)
        dtm.addDataType(peripheral_struct,
                        DataTypeConflictHandler.REPLACE_HANDLER)

        baseAdr = peripheral.base_address

        for adrBlock in peripheral.address_blocks:
            addr = space.getAddress(baseAdr + adrBlock.offset)
            # Generate peripheral-strcuture for an address block
            peripheral_blk_struct = StructureDataType(peripheral.name,
                                                      adrBlock.size)
            # iterate through all registers in the peripheral and add it to the addressBlock-peripheral structure
            # when the register is part of this addressBlock.
            addRegisters(peripheral_blk_struct, peripheral, 32)
            addRegisters(peripheral_blk_struct, peripheral, 24)
            addRegisters(peripheral_blk_struct, peripheral, 16)
    def createStructure(self, element):
        """
        Convert CastXML XML element into a Ghidra StructureDataType.
        
        Args:
            element (ElementTree): XML element
            
        Returns (StructureDataType): Ghidra StructureDataType
        """
        structName = ""
        if 'name' in element.attrib:
            structName = element.attrib['name']
        if structName == "":
            structName = "anon_struct" + element.attrib['id']

        structByteSize = 0
        if 'size' in element.attrib:
            structBitSize = int(element.attrib['size'])
            structByteSize = structBitSize / 8

        structAlign = 0
        if 'align' in element.attrib:
            structAlign = int(element.attrib['align']) / 8

        filePath = self.getFileFromId(element.attrib['file'])
        categoryPath = self.getCategoryPathFromFile(filePath)

        print("Struct: {0}".format(structName))

        structureDataType = StructureDataType(categoryPath, structName,
                                              structByteSize, self.dtMgr)

        # These will allow Ghidra to pack and align our data types to our program's specs.
        # Unused for now. Let's respect what we have from CastXML.
        #structureDataType.setMinimumAlignment(structAlign)
        #structureDataType.setPackingValue(structAlign)

        self.recordTypeForId(element.attrib['id'], structureDataType)

        # Load all base classes
        if 'bases' in element.attrib:
            baseElements = element.getchildren()
            for i, baseElement in enumerate(baseElements):
                baseTypeElement = self.getTypeInfoElementById(
                    baseElement.attrib['type'])
                baseType = self.getDataType(baseTypeElement)
                baseOffset = 0
                if 'offset' in baseElement.attrib:
                    baseOffset = int(baseElement.attrib['offset'])
                baseName = "base" + str(i) + "_" + str(baseOffset)
                baseLength = baseType.getLength()
                structureDataType.replaceAtOffset(baseOffset, baseType,
                                                  baseLength, baseName,
                                                  hex(baseOffset))

        # Add VTable pointer
        if 'abstract' in element.attrib and 'bases' not in element.attrib:
            if int(element.attrib['abstract']) == 1:
                # TODO: generate vtable structure
                pointerLength = self.getDefaultPointerSize()
                pointerType = PointerDataType(VoidDataType.dataType,
                                              pointerLength)
                structureDataType.replaceAtOffset(0, pointerType,
                                                  pointerType.getLength(),
                                                  "vtable", hex(0))

        # Add each field
        if 'members' in element.attrib:
            members = element.attrib['members']
            memberIds = members.split(" ")
            bitFieldOffset = -1  # -1 = not set
            bitFieldTotalSize = 0
            for memberId in memberIds:
                fieldElement = self.getTypeInfoElementById(memberId)
                if fieldElement.tag != "Field":
                    continue

                typeElement = self.getTypeInfoElementById(
                    fieldElement.attrib['type'])

                fieldName = fieldElement.attrib['name']
                fieldOffset = int(fieldElement.attrib['offset']) / 8
                if fieldOffset >= structByteSize:
                    continue

                # TODO: check if at end of structure and check if structure already has flexible array
                if typeElement.tag == "ArrayType" and int(
                        typeElement.attrib['max']) == -1:
                    # TODO: check if valid arrayDataType
                    arrayElement = self.getTypeInfoElementById(
                        typeElement.attrib['type'])
                    arrayDataType = self.getDataType(arrayElement)
                    structureDataType.setFlexibleArrayComponent(
                        arrayDataType, fieldName, hex(fieldOffset))
                else:
                    fieldDataType = self.getDataType(typeElement)
                    if 'bits' in fieldElement.attrib:
                        # This is a bitfield
                        byteOffset = fieldOffset

                        if bitFieldOffset == -1:
                            # Store first bitfield byteOffset
                            bitFieldOffset = fieldOffset * 8

                        byteWidth = structureDataType.getLength() - (
                            bitFieldOffset / 8)  #fieldDataType.getLength()
                        bitFieldTotalSize = byteWidth * 8

                        bitOffset = int(
                            fieldElement.attrib['offset']) - bitFieldOffset
                        bitSize = int(fieldElement.attrib['bits'])

                        try:
                            structureDataType.insertBitFieldAt(
                                bitFieldOffset / 8, byteWidth, bitOffset,
                                fieldDataType, bitSize, fieldName,
                                hex(bitOffset) + " bits")
                        except JavaException as e:
                            print structName + " -> " + fieldName
                            print "Current bitfield range: " + str(
                                bitOffset) + " - " + str(bitOffset + bitSize)
                            print "bitFieldOffset: " + str(bitFieldOffset)
                            print "bitFieldTotalSize: " + str(
                                bitFieldTotalSize)
                            print "bitFieldDataType: " + str(fieldDataType)
                            print "bitFieldDataTypeSize: " + str(
                                fieldDataType.getLength())
                            print "byteOffset: " + str(byteOffset)
                            print "byteWidth: " + str(byteWidth)
                            print "bitOffset: " + str(bitOffset)
                            print "bitSize: " + str(bitSize)
                            print e

                        if (bitOffset + bitSize) >= bitFieldTotalSize:
                            # This should be the last bitfield
                            bitFieldOffset = -1
                            bitFieldTotalSize = 0
                    else:
                        structureDataType.replaceAtOffset(
                            fieldOffset, fieldDataType,
                            fieldDataType.getLength(), fieldName,
                            hex(fieldOffset) + " bytes")

        return structureDataType
Exemple #20
0
print("Generating peripherals...")
for peripheral in peripherals:
    print("\t" + peripheral.name)

    if (len(peripheral.registers) == 0):
        print("\t\tNo registers.")
        continue

    # try:
    # Iterage registers to get size of peripheral
    # Most SVDs have an address-block that specifies the size, but
    # they are often far too large, leading to issues with overlaps.
    length = calculate_peripheral_size(peripheral, default_register_size)

    # Generate structure for the peripheral
    peripheral_struct = StructureDataType(peripheral.name, length)

    peripheral_start = peripheral.base_address
    peripheral_end = peripheral_start + length

    for register in peripheral.registers:
        register_size = default_register_size if not register._size else register._size

        r_type = UnsignedIntegerDataType()
        rs = register_size / 8
        if rs == 1:
            r_type = ByteDataType()
        elif rs == 2:
            r_type = UnsignedShortDataType()
        elif rs == 8:
            r_type = UnsignedLongLongDataType()
Exemple #21
0
def defineIOExternalAsyncMethod():
    dtm = currentProgram.getDataTypeManager()
    dt = dtm.findDataType(currentProgram.getName() + "/" +
                          "IOExternalAsyncMethod")

    IOService = dtm.getDataType("/IOService")
    IOAsyncMethod_def = "uint IOService::IOAsyncMethod(uint asyncRef[8], void * p1, void * p2, void * p3, void * p4, void * p5, void * p6)"

    uint = dtm.getDataType("/uint")
    ulonglong = dtm.getDataType("/ulonglong")
    fdef = parseCSignature(IOAsyncMethod_def)
    st = StructureDataType("IOExternalAsyncMethod", 0)
    #BUG: Work with alignement
    st.setToMachineAlignment()
    st.add(PointerDataType(IOService), "object", "")
    st.add(PointerDataType(fdef), "func", "")
    st.add(uint, "flags", "")
    st.add(ulonglong, "count0", "")
    st.add(ulonglong, "count1", "")

    dtm.addDataType(PointerDataType(st), None)
char_data_type = CharDataType()
void_data_type = VoidDataType()
unsigned_int_type = UnsignedIntegerDataType()
short_data_type = ShortDataType()
char_ptr_type = ptr_data_type.getPointer(char_data_type, 4)
void_ptr_type = ptr_data_type.getPointer(void_data_type, 4)
# Prepare VxWorks symbol types
vx_5_sym_enum = EnumDataType("Vx5symType", 1)
for flag in vx_5_symbol_type_enum:
    vx_5_sym_enum.add(vx_5_symbol_type_enum[flag], flag)
vx_6_sym_enum = EnumDataType("Vx6symType", 1)
for flag in vx_6_symbol_type_enum:
    vx_6_sym_enum.add(vx_6_symbol_type_enum[flag], flag)

# Init VxWorks symbol table structs
vx_5_symtbl_dt = StructureDataType("VX_5_SYMBOL_IN_TBL", 0x10)
vx_5_symtbl_dt.replaceAtOffset(0, unsigned_int_type, 4, "symHashNode", "")
vx_5_symtbl_dt.replaceAtOffset(4, char_ptr_type, 4, "symNamePtr", "")
vx_5_symtbl_dt.replaceAtOffset(8, void_ptr_type, 4, "symPrt", "")
vx_5_symtbl_dt.replaceAtOffset(0x0c, short_data_type, 4, "symGroup", "")
vx_5_symtbl_dt.replaceAtOffset(0x0e, vx_5_sym_enum, 1, "symType", "")
vx_5_symtbl_dt.replaceAtOffset(0x0f, byte_data_type, 1, "End", "")

vx_6_symtbl_dt = StructureDataType("VX_6_SYMBOL_IN_TBL", 0x14)
vx_6_symtbl_dt.replaceAtOffset(0, unsigned_int_type, 4, "symHashNode", "")
vx_6_symtbl_dt.replaceAtOffset(4, char_ptr_type, 4, "symNamePtr", "")
vx_6_symtbl_dt.replaceAtOffset(8, void_ptr_type, 4, "symPrt", "")
vx_6_symtbl_dt.replaceAtOffset(0x0c, unsigned_int_type, 4, "symRef",
                               "moduleId of module, or predefined SYMREF")
vx_6_symtbl_dt.replaceAtOffset(0x10, short_data_type, 4, "symGroup", "")
vx_6_symtbl_dt.replaceAtOffset(0x12, vx_6_sym_enum, 1, "symType", "")
Exemple #23
0
    0x07: "Global Data",
    0x08: "Local BSS",
    0x09: "Global BSS",
    0x12: "Local Common symbol",
    0x13: "Global Common symbol",
    0x40: "Local Symbols related to a PowerPC SDA section",
    0x41: "Global Symbols related to a PowerPC SDA section",
    0x80: "Local symbols related to a PowerPC SDA2 section",
    0x81: "Global symbols related to a PowerPC SDA2 section"
}

vx_5_sym_enum = EnumDataType("Vx5symType", 1)
for flag in vx_5_symbol_type_enum:
    vx_5_sym_enum.add(vx_5_symbol_type_enum[flag], flag)

vx_5_symtbl_dt = StructureDataType("VX_5_SYMBOL_IN_TBL", 0x10)
vx_5_symtbl_dt.replaceAtOffset(0, unsigned_int_type, 4, "symHashNode", "")
vx_5_symtbl_dt.replaceAtOffset(4, char_ptr_type, 4, "symNamePtr", "")
vx_5_symtbl_dt.replaceAtOffset(8, void_ptr_type, 4, "symPrt", "")
vx_5_symtbl_dt.replaceAtOffset(0x0c, short_data_type, 4, "symGroup", "")
vx_5_symtbl_dt.replaceAtOffset(0x0e, vx_5_sym_enum, 1, "symType", "")
vx_5_symtbl_dt.replaceAtOffset(0x0f, byte_data_type, 1, "End", "")


vx_5_sys_symtab = StructureDataType("VX_5_SYSTEM_SYMBOL_TABLE", 0x3C)
vx_5_sys_symtab.replaceAtOffset(0x00, void_ptr_type, 4, "objCore", "Pointer to object's class")
vx_5_sys_symtab.replaceAtOffset(0x04, void_ptr_type, 4, "nameHashId", "Pointer to HASH_TBL")
vx_5_sys_symtab.replaceAtOffset(0x08, char_data_type, 0x28, "symMutex", "symbol table mutual exclusion sem")
vx_5_sys_symtab.replaceAtOffset(0x30, void_ptr_type, 4, "symPartId", "memory partition id for symbols")
vx_5_sys_symtab.replaceAtOffset(0x34, unsigned_int_type, 4, "sameNameOk", "symbol table name clash policy")
vx_5_sys_symtab.replaceAtOffset(0x38, unsigned_int_type, 4, "PART_ID", "current number of symbols in table")
def generateVtableStruct(vtableAddr):
    mem = currentProgram.getMemory()
    vtableClassName = structName
    vtableName = "vtable" + vtableClassName
    keepgoing = True
    cAddr = vtableAddr  #.add(8)
    structData = StructureDataType(vtableName, 0)
    antiFreeze = 0
    while True:
        #print("Checking " + cAddr.toString())

        fnToCheck = CUManager.getCodeUnitContaining(cAddr)
        #print(fnToCheck.getMnemonicString())
        if fnToCheck != None and fnToCheck.getMnemonicString() == "addr":
            #print("Found start of vtable at")
            cAddr = cAddr.add(4)
            break
        if antiFreeze >= 100:
            print("Something has to have gone wrong...")
            return
        cAddr = cAddr.add(4)
        antiFreeze += 1

    while True:
        fs = getAddress(mem.getInt(cAddr))
        valpart = fs.toString()
        fntoadd = functionManager.getFunctionContaining(getAddress(valpart))
        if fntoadd != None:
            #print("YES, this is an pointer")

            #print(fntoadd)
            if fntoadd != None:
                dt = FunctionDefinitionDataType(
                    fntoadd, False
                )  #Second parameter is "Formality", I think this strips the "this" parameter, so lets not set this True
                #dt.setCategoryPath(CategoryPath("/" + vtableName))
                fnClass = getClassName(fntoadd.toString())
                dt.setCategoryPath(CategoryPath("/vtable" + fnClass))
                dtAdded = dataManager.addDataType(
                    dt, DataTypeConflictHandler.REPLACE_HANDLER)
                ptr = PointerDataType(dtAdded)
                #ptr.setCategoryPath(CategoryPath("/" + vtableName))
                ptr.setCategoryPath(CategoryPath("/vtable" + fnClass))
                ptrAdded = dataManager.addDataType(
                    ptr, DataTypeConflictHandler.REPLACE_HANDLER)
                structData.add(ptrAdded, ptrAdded.getLength(),
                               fntoadd.toString(), "")
        else:
            print("Vtable reached the end.")
            break
        cAddr = cAddr.add(4)

    if structData != None:
        vtableCDataType = dataManager.addDataType(
            structData, DataTypeConflictHandler.REPLACE_HANDLER)
        vtableCDataTypePtr = PointerDataType(vtableCDataType)
        vtableDTtoAdd = dataManager.addDataType(
            vtableCDataTypePtr, DataTypeConflictHandler.REPLACE_HANDLER)
        print("Created " + vtableName)

    else:
        print("Skipped " + vtableName)
def generateVtableStruct(vtableSymbol):
    vtableAddr = vtableSymbol.getAddress()

    nameStartsAt = 5
    while True:
        if vtableSymbol.getName()[nameStartsAt].isdigit():
            nameStartsAt += 1
        else:
            break

    vtableClassName = vtableSymbol.getName()[nameStartsAt:]
    vtableName = ""
    structData = None
    keepgoing = True
    #cAddr = vtableAddr.add(8)
    cAddr = vtableAddr
    #tmp = next(codeUnits)
    #tmp = next(codeUnits)
    antiFreeze = 0
    while True:
        #print("Checking " + cAddr.toString())

        fnToCheck = CUManager.getCodeUnitContaining(cAddr)
        #print(fnToCheck.getMnemonicString())
        if fnToCheck != None and fnToCheck.getMnemonicString() == "addr":
            #print("Found start of vtable at")
            cAddr = cAddr.add(4)
            break
        if antiFreeze >= 50:
            print("Something has to have gone wrong...")
            return
        cAddr = cAddr.add(4)
        antiFreeze += 1

    if "google" in vtableClassName and not doGoogle:
        print("Skipped vtable" + vtableClassName)
        return
    if "CryptoPP" in vtableClassName and not doFOSS:
        print("Skipped vtable" + vtableClassName)
        return

    while True:
        monitor.checkCanceled()
        fs = getAddress(mem.getInt(cAddr))
        valpart = fs.toString()
        fntoadd = functionManager.getFunctionContaining(getAddress(valpart))
        if fntoadd != None:
            #print("YES, this is an pointer")

            if vtableName == "":
                #vtableClassName = getClassName(fntoadd.toString())
                vtableName = "vtable" + vtableClassName

                structData = StructureDataType(vtableName, 0)
                #print("Making vtable for " + vtableClassName)
                monitor.setMessage("Observe: Making vtable for " +
                                   vtableClassName)
            #print(fntoadd)
            if fntoadd != None:
                dt = FunctionDefinitionDataType(
                    fntoadd, False
                )  #Second parameter is "Formality", I think this strips the "this" parameter, so lets not set this True
                #dt.setCategoryPath(CategoryPath("/" + vtableName))
                fnClass = getClassName(fntoadd.toString())
                dt.setCategoryPath(CategoryPath("/vtable" + fnClass))
                dtAdded = dataManager.addDataType(
                    dt, DataTypeConflictHandler.REPLACE_HANDLER)
                ptr = PointerDataType(dtAdded)
                #ptr.setCategoryPath(CategoryPath("/" + vtableName))
                ptr.setCategoryPath(CategoryPath("/vtable" + fnClass))
                ptrAdded = dataManager.addDataType(
                    ptr, DataTypeConflictHandler.REPLACE_HANDLER)
                structData.add(ptrAdded, ptrAdded.getLength(),
                               fntoadd.toString(), "")
        else:
            break
        cAddr = cAddr.add(4)

    if structData != None:
        vtableCDataType = dataManager.addDataType(
            structData, DataTypeConflictHandler.REPLACE_HANDLER)
        vtableCDataTypePtr = PointerDataType(vtableCDataType)
        vtableDTtoAdd = dataManager.addDataType(
            vtableCDataTypePtr, DataTypeConflictHandler.REPLACE_HANDLER)
        print("Created " + vtableName)

    else:
        print("Skipped " + vtableName)
Exemple #26
0
typeManager = currentProgram.getDataTypeManager()
func_manager = currentProgram.getFunctionManager()

d = code_manager.getDataAt(vftableAddress)
assert(d.isArray())
assert(d.getPrimarySymbol().getParentNamespace().getSymbol().getSymbolType()==SymbolType.CLASS)
class_name = d.getPrimarySymbol().getParentNamespace().getName()
vftable_classname = naming_prefix+class_name+"_vftable"

l = []
typeManager.findDataTypes(vftable_classname,l)

if l!=[]:
  print("Class "+vftable_classname+" already exists. Nothing is changed.")
else:
  category = typeManager.createCategory(CategoryPath(categoryPathString))
  vftable_type = StructureDataType(vftable_classname, 0)
  for i in range(d.getNumComponents()):
    comp = d.getComponent(i)
    assert(comp.isPointer())
    func_addr = comp.getValue()
    func = func_manager.getFunctionAt(func_addr)
    assert(func!=None)
    func_name = func.getName()
    func_dt = FunctionDefinitionDataType("TGN_func")
    func_dt.setGenericCallingConvention(GenericCallingConvention.thiscall)
    func_dt.setReturnType(DWordDataType())
    datatype = PointerDataType(func_dt)
    vftable_type.insert(i, datatype, datatype.getLength(), func_name, "TGN: Automatically created field")
  category.addDataType(vftable_type, DataTypeConflictHandler.REPLACE_HANDLER)
  
# Applies a structure to the current GLOBAL addres

# DISCLAIMER: This is meant to be an example. You likely want to use this process in your own script

#@category Tate.AutoScripts

from ghidra.program.model.data import StructureDataType
from ghidra.program.model.data import DWordDataType
from ghidra.program.database.data import DataTypeManagerDB
from ghidra.program.model.data import DataTypeConflictHandler

debug = True
applyGlobal = True

#make a structure with size 4
struct = StructureDataType("scriptStruct", 0x4)

if debug == True:
    print "struct before"
    print struct
# inserts and expands the data type at arg1 offset
# expands structure to size 8
struct.insertAtOffset(0x0, DWordDataType(), 4, "offset 0", None)
struct.replaceAtOffset(4, DWordDataType(), 0, "offset 4", None)

if debug == True:
    print "struct after"
    print struct

#assign the structure to the address
# when assigning to global, the struct will be auto inserted into the manager