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)