Beispiel #1
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)
Beispiel #2
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
Beispiel #3
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)
Beispiel #4
0
def defineIOExternalMethod():
    dtm = currentProgram.getDataTypeManager()
    dt = dtm.findDataType(currentProgram.getName() + "/" + "IOExternalMethod")

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

    fdef = parseCSignature(IOMethod_def)
    st = StructureDataType("IOExternalMethod", 0)

    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)
Beispiel #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
Beispiel #6
0
    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")
Beispiel #7
0
def strToDataType(s):
    """
    Converts a C-Style type like `uint` or `CTFPlayer *` to a Ghidra DataType
    """
    indirection = 0
    while s[-1] == '*':
        s = s[:-1]
        indirection += 1
    s = s.rstrip()
    t = all_datatypes.get(s, all_datatypes['undefined1'])
    for i in range(0, indirection):
        t = PointerDataType(t)
    return t
Beispiel #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)
    def createPointer(self, element):
        """
        Convert CastXML XML element into a Ghidra PointerDataType.
        
        Args:
            element (ElementTree): XML element
            
        Returns (PointerDataType): Ghidra PointerDataType
        """
        pointeeElement = self.getTypeInfoElementById(element.attrib['type'])
        dataType = self.getDataType(pointeeElement)
        if dataType == None:
            dataType = Undefined.getUndefinedDataType(1)
            print "Invalid DataType returned for PointerType: tag={0} id={1}".format(
                pointeeElement.tag, pointeeElement.attrib['id'])
        pointerLength = self.getDefaultPointerSize()
        if 'size' in element.attrib:
            pointerLength = int(element.attrib['size']) / 8
        pointerType = PointerDataType(dataType, pointerLength)

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

        return pointerType
Beispiel #10
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)
  
    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
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.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)
Beispiel #13
0
def get_pointer_type():
    """
    Get the correct pointer size for the current architecture.
    """
    return PointerDataType(None, currentProgram.getDefaultPointerSize())
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)
    0x02: "Local Absolute",
    0x03: "Global Absolute",
    0x04: "Local .text",
    0x05: "Global .text",
    0x08: "Local Data",
    0x09: "Global Data",
    0x10: "Local BSS",
    0x11: "Global BSS",
    0x20: "Local Common symbol",
    0x21: "Global Common symbol",
    0x40: "Local Symbols",
    0x41: "Global Symbols"
}

# Init data type
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)
# 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)
            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)
        

Beispiel #17
0
                elif bits <= 16:
                    field_data_type = dataManager.getDataType("/ushort" if unsigned else "/short")
                    field_size = 2
                elif bits <= 32:
                    field_data_type = dataManager.getDataType("/uint" if unsigned else "/int")
                    field_size = 4
                else:
                    print("ERROR! integer has too many bits! ({})".format(bits))
                '''
            elif field_type == "float":
                # TODO: Might some floats not be 32bit?
                field_data_type = dataManager.getDataType("/float")
                field_size = 4
            elif field_type == "string":
                # TODO: Is this just plain wrong?
                field_data_type = PointerDataType(
                    dataManager.getDataType("/TerminatedCString"))
                field_size = 4
            elif field_type == "array":
                print("SKIPPING array type for field {} of {}".format(
                    field_name, class_name))
                continue
            else:
                print("ERROR! unknown type ({})".format(field_type))

            # Use the trail to build up the offset and field_name
            field_name = ""
            field_offset = offset
            for i in range(1, indentation):
                name, offset = trail[i]
                if name is not None:
                    field_name = field_name + name + "_"
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)