def FunctionRemoveChunk(any_ins_in_chunk): chunk_function = idc.GetFunctionAttr(any_ins_in_chunk, idc.FUNCATTR_START) result = idc.RemoveFchunk(chunk_function, any_ins_in_chunk) if do_wait: idc.Wait() fn_print("remove-chunk 0x%x: %d" % (any_ins_in_chunk, result)) return result
def init(tests): # workaround ida 6.95 function chunks which should really be functions for ea in [0x6718f260, 0x671a5250]: numrefs = idc.GetFchunkAttr(ea, idc.FUNCATTR_REFQTY) if numrefs <= 1: continue for idx in range(numrefs, 0, -1): idc.RemoveFchunk(idc.GetFchunkReferer(ea, idx - 1), ea) idc.MakeFunction(ea) idc.Wait() YaCo.start_tests()
def _convert_address_to_function(func): """Convert an address that IDA has classified incorrectly into a proper function.""" # If everything goes wrong, we'll try to restore this function. orig = idc.FirstFuncFchunk(func) # If the address is not code, let's undefine whatever it is. if not idc.isCode(idc.GetFlags(func)): if not is_mapped(func): # Well, that's awkward. return False item = idc.ItemHead(func) itemend = idc.ItemEnd(func) if item != idc.BADADDR: _log(1, 'Undefining item {:#x} - {:#x}', item, itemend) idc.MakeUnkn(item, idc.DOUNK_EXPAND) idc.MakeCode(func) # Give IDA a chance to analyze the new code or else we won't be able to create a # function. idc.Wait() idc.AnalyseArea(item, itemend) else: # Just try removing the chunk from its current function. IDA can add it to another function # automatically, so make sure it's removed from all functions by doing it in loop until it # fails. for i in range(1024): if not idc.RemoveFchunk(func, func): break # Now try making a function. if idc.MakeFunction(func) != 0: return True # This is a stubborn chunk. Try recording the list of chunks, deleting the original function, # creating the new function, then re-creating the original function. if orig != idc.BADADDR: chunks = list(idautils.Chunks(orig)) if idc.DelFunction(orig) != 0: # Ok, now let's create the new function, and recreate the original. if idc.MakeFunction(func) != 0: if idc.MakeFunction(orig) != 0: # Ok, so we created the functions! Now, if any of the original chunks are not # contained in a function, we'll abort and undo. if all(idaapi.get_func(start) for start, end in chunks): return True # Try to undo the damage. for start, _ in chunks: idc.DelFunction(start) # Everything we've tried so far has failed. If there was originally a function, try to restore # it. if orig != idc.BADADDR: _log(0, 'Trying to restore original function {:#x}', orig) idc.MakeFunction(orig) return False