示例#1
0
def annotateVirtualCall(calledFunc, startingFunc, callAddr, thisOverride=None):
    print calledFunc
    funcDef = FunctionDefinitionDataType(calledFunc.signature)
    if thisOverride is not None:
        originalThis = funcDef.arguments[0]
        funcDef.replaceArgument(0, originalThis.name, thisOverride, originalThis.comment, SourceType.DEFAULT)
    HighFunctionDBUtil.writeOverride(startingFunc, callAddr, funcDef)
    currentProgram.listing.setComment(callAddr, CodeUnit.PRE_COMMENT, "{@symbol %s}"%calledFunc.symbol.getName(True))
示例#2
0
    def createFunction(self, element):
        """
        Convert CastXML XML element into a Ghidra FunctionDefinitionDataType.
        
        Args:
            element (ElementTree): XML element
            
        Returns (FunctionDefinitionDataType): Ghidra FunctionDefinitionDataType
        """
        functionName = ""
        if 'name' in element.attrib:
            functionName = element.attrib['name']
        else:
            functionName = "anon_func" + element.attrib['id']

        print("Function: {0}".format(functionName))

        functionType = None
        if 'file' in element.attrib:
            filePath = self.getFileFromId(element.attrib['file'])
            categoryPath = self.getCategoryPathFromFile(filePath)
            functionType = FunctionDefinitionDataType(categoryPath,
                                                      functionName)
        else:
            functionType = FunctionDefinitionDataType(functionName)

        returnTypeElement = self.getTypeInfoElementById(
            element.attrib['returns'])
        returnType = self.getDataType(returnTypeElement)
        functionType.setReturnType(returnType)

        parms = []
        argumentElements = element.getchildren()
        for i, argumentElement in enumerate(argumentElements):
            if argumentElement.tag == "Argument":
                argumentName = ""
                if 'name' in argumentElement.attrib:
                    argumentName = argumentElement.attrib['name']
                else:
                    argumentName = "a" + str(i)

                argumentTypeElement = self.getTypeInfoElementById(
                    argumentElement.attrib['type'])
                parmDataType = self.getDataType(argumentTypeElement)

                parms.append(
                    ParameterDefinitionImpl(argumentName, parmDataType, ""))
            elif argumentElement.tag == "Elipsis":
                functionType.setVarArgs(True)

        functionType.setArguments(parms)

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

        return functionType
示例#3
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")
示例#4
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)
示例#5
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 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)
示例#7
0
        if data.isPointer():  # it will (hopefully) be a function ptr
            func_ptr = getFunctionAt(data.value)

            if not func_ptr:  # weird stuff, just skip
                cur_addr = cur_addr.add(ptr_size)
                continue

            print(
                "[+] {} reference @ 0x{} ( -> 0x{}), adding to the vtable struct"
                .format(func_ptr.toString(), cur_addr, data.value))

            func_name = func_ptr.toString()  # include namespace

            # create a function definition
            func_definition = FunctionDefinitionDataType(
                CategoryPath.ROOT, func_name, func_ptr.getSignature())
            dtm.addDataType(func_definition, conflict_handler)

            # add a function pointer to the structure
            vtable_type.add(func_definition, ptr_size, func_name, "")
            cur_addr = cur_addr.add(ptr_size)
        cutoff_ctr += 1

    dtm.addDataType(vtable_type, conflict_handler)

    cmd = CreateStructureCmd(vtable_type, vtable_addr)
    success = cmd.applyTo(currentProgram)

    # pointer to the create data type
    vtable_ptr = dtm.getPointer(vtable_type)
示例#8
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()))
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)
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)
示例#11
0
def fixLabel(data):
    name = getSymbolAt(data).getName()
    labelAddress = getSymbolAt(data).getAddress()
    #print labelAddress, name
    # ghidra refers to some functions as data, I've seen only one case
    if ("LAB_" not in name):
        currentProgram.getListing().clearCodeUnits(data, data.add(8), False)
        name = name.split("_")[1]
        ret = createFunction(labelAddress, "LAB_" + name)

    labelName = name.replace("LAB_", "FUN_")
    #print disassemble(labelAddress)
    if disassemble(labelAddress) == False:
        popup("This Label " + labelAddress + "cannot be disassembled !")
        return -1
    #print "labelName:",labelName
    ret = createFunction(labelAddress, labelName)
    func = getFunctionAt(labelAddress)
    if func == None:
        # Calling CreateFunction twice will force function creation
        # Don't ask me,ask NSA
        ret = createFunction(labelAddress, labelName)

    # why it sometimes returns None ? last chance
    func = getFunctionAt(labelAddress)
    if (func == None):
        listing = currentProgram.getListing()
        blockModelService = state.getTool().getService(BlockModelService)
        cbm = blockModelService.getActiveSubroutineModel()
        cbIter = cbm.getCodeBlocksContaining(labelAddress, monitor)
        l = labelAddress
        currentProgram.getListing().clearCodeUnits(l, l.add(8), True)
        createFunction(labelAddress, "FUN_" + name)

        #x = getFunctionAt(labelAddress)
        #print cbIter
        #x = CreateFunctionCmd(labelAddress,False)
        #print type(x)
        #funcBody =  x.getFunctionBody(currentProgram,labelAddress)
        #print funcBody
        #mgr = currentProgram.getFunctionManager()
        #mgr.createFunction("test",labelAddress,funcBody,SourceType.USER_DEFINED)
        #raise Exception("Unable to create a function 0x%s" %(labelAddress.toString()))
        #x = ApplyFunctionSignatureCmd(labelName)
        #print x

        #return

    func = getFunctionAt(labelAddress)
    assert (func != None)
    func.setCustomVariableStorage(False)
    #params = func.getParameters()
    df = FunctionDefinitionDataType(func, False)

    # TODO : remove the below line , no need to change calling convention
    #df.setGenericCallingConvention(GenericCallingConvention.thiscall)
    df.setReturnType(func.getReturnType())

    #df = FunctionDefinitionDataType(func,False)
    """
    func.replaceParameters(FunctionUpdateType.DYNAMIC_STORAGE_ALL_PARAMS,#CUSTOM_STORAGE,
            True,
            SourceType.USER_DEFINED,
            params)
    """
    x = ApplyFunctionSignatureCmd(func.getEntryPoint(), df,
                                  SourceType.USER_DEFINED)
    x.applyTo(func.getProgram())
dword = DWordDataType()

#parameter definitions
#WARNING, a NEW definition will need to be created for each of the same instance in a signature
#to give the parameter a default name change the first argument
pointer32Def = ParameterDefinitionImpl("p32", pointer32, "32 bit pointer")
dwordDef = ParameterDefinitionImpl(None, dword, "double word")

# list of functions to change signatures
functionsToChange = [
    "foo", "bar"
    #...
]

#function definitions
fooDef = FunctionDefinitionDataType("foo")
fooDef.setArguments([pointer32Def, dwordDef])
barDef = FunctionDefinitionDataType("bar")
barDef.setArguments([pointer32Def])
functionDefs = [fooDef, barDef]

func = getFirstFunction()

#loop though functions looking names that match our list
while func is not None:
    func_name = func.getName()
    if func_name in functionsToChange:
        for defi in functionDefs:
            if func_name == defi.getName():
                cmd = ApplyFunctionSignatureCmd(func.getEntryPoint(), defi,
                                                SourceType.USER_DEFINED)