Esempio n. 1
0
def main():
    tid = get_guid_tid()
    for type_name, type_prefix, filepath in GUID_LIST:
        print('[*] scanning {}'.format(type_name))
        fp = open(filepath, 'r')
        for line in fp.readlines():
            line = line.strip()
            if line == "":
                continue
            guid, guid_name = line.split(' ')
            guid_name = type_prefix + guid_name
            binary_pattern = make_binary_pattern(guid)

            ea = 0
            while True:
                ea = idc.find_binary(
                    ea, ida_search.SEARCH_DOWN | ida_search.SEARCH_NEXT
                    | ida_search.SEARCH_NOSHOW, binary_pattern)
                if ea == idaapi.BADADDR:
                    break

                idc.del_items(ea, 16, 0)
                ida_bytes.create_struct(ea, ida_struct.get_struc_size(tid),
                                        tid)
                if idc.set_name(ea, guid_name, ida_name.SN_NOWARN) != 1:
                    for i in range(0, 100):
                        if idc.set_name(ea, guid_name + "_" + str(i),
                                        ida_name.SN_NOWARN) == 1:
                            break
                    else:
                        print("[!] 0x{:X}: failed to apply {}".format(
                            ea, guid_name))
                print("[*] 0x{:X}: {}".format(ea, guid_name))

    print("[*] finished")
Esempio n. 2
0
def make_array(ea, size):
  if ea != idc.BADADDR and ea != 0:
    flags = idc.get_full_flags(ea)
    if not idc.isByte(flags) or idc.get_item_size(ea) != 1:
      idc.del_items(ea, idc.DOUNK_SIMPLE, 1)
      ida_bytes.create_data(ea, ida_bytes.FF_BYTE, 1, ida_idaapi.BADADDR)
    idc.make_array(ea, size)
Esempio n. 3
0
def make_array(ea, size):
  if ea != idc.BADADDR and ea != 0:
    flags = idc.get_full_flags(ea)
    if not idc.isByte(flags) or idc.get_item_size(ea) != 1:
      idc.del_items(ea, idc.DOUNK_SIMPLE, 1)
      idc.MakeByte(ea)
    idc.MakeArray(ea, size)
Esempio n. 4
0
 def type(self, value):
     if value is None or value == "":
         raise ValueError("value: %s" % value)
     if SetType(self.__ea, "%s %s" % (value, self.name)) == 0:
         del_items(self.__ea, 0)
         if SetType(self.__ea, "%s %s" % (value, self.name)) == 0:
             print('SetType(0x{:x}, "{} {}") has failed'.format(self.__ea, value, self.name))
Esempio n. 5
0
def create_func_by_prefix(func_name, prefix, force=False):
    addrs = []
    start_addr = 0
    func_addr = 0
    while func_addr != idc.BADADDR:
        func_addr = ida_search.find_binary(start_addr, idc.BADADDR, prefix, 16,
                                           idc.SEARCH_DOWN)
        if func_addr == idc.BADADDR:
            break

        # already existing function but it is not the right prefix
        addr = idc.get_func_attr(func_addr, idc.FUNCATTR_START)
        if addr != idc.BADADDR and func_addr != addr:
            if not force:
                start_addr = func_addr + 4
                continue

            idc.del_func(addr)
            idc.del_items(func_addr)

        # add_func is not applied to the existing function
        idc.add_func(func_addr)

        func_name = set_entry_name(func_addr, func_name)
        print("%s: 0x%x" % (func_name, func_addr))

        addrs.append(func_addr)
        start_addr = func_addr + 4

    return addrs
Esempio n. 6
0
def make_array(ea, size):
    if ea != idc.BADADDR and ea != 0:
        flags = idc.get_full_flags(ea)
        if not idc.isByte(flags) or idc.get_item_size(ea) != 1:
            idc.del_items(ea, idc.DOUNK_SIMPLE, 1)
            idc.MakeByte(ea)
        idc.MakeArray(ea, size)
Esempio n. 7
0
    def resolve_symbols(self, dll):
        tmpdir = tempfile.gettempdir().replace('\\', '/') + '/'
        # File who will first contain ordinals then symbols
        tmpfile = tmpdir + "dotNIETsymbols.txt"
        tmplog = tmpdir + "dotNIETlogs.txt"
        # Destination path for a copy of SharedLibrary.dll
        tmpdll = tmpdir + os.path.basename(dll)
        # Path to the idat binary, needed to parse a remote idb
        idat = idc.idadir().replace('\\','/') + '/' + 'idat' + \
               ['64' if utils.is_x64(dll) else ''][0]

        if os.getenv("windir") is not None:
            idat += '.exe'
        # script called along with idat in order to parse SharedLibrary.idb
        parsing_script_path = '"' + os.path.dirname(os.path.realpath(__file__)).replace('\\','/')\
                              + '/dotNIET/resolve.py"'

        # we first copy SharedLibrary.dll to tmp to be sure we are in a
        # writable location
        shutil.copyfile(dll, tmpdll)

        # we have to use temporary files because of the ida headless stuff...
        # pretty dirty
        ordinals = []
        with open(tmpfile, 'w') as f:
            for i in range(self.nb_symbols):
                ordinals.append((idaapi.get_qword(self.ordinals + i * 8)
                                 & ~0x8000000000000000) * 4)
            f.write(",".join([str(x) for x in ordinals]))

        # be prepared to wait as this will load the binary + pdb
        idaapi.msg("Starting parsing of %d symbols...\n" % self.nb_symbols)
        subprocess.run([idat, "-L" + tmplog, "-c", "-A", "-S" + \
                        parsing_script_path + " " + tmpfile, tmpdll],
                        creationflags=subprocess.CREATE_NO_WINDOW,
                        check=True)

        # we read back tmpfile which now contains symbols
        symbols = []
        with open(tmpfile, 'r') as f:
            symbolsArray = f.read()
            symbols = symbolsArray.split(',')

        # we first have to undef structure as it is an array and ida will
        # refuse to set names within it
        idc.del_items(self.ordinals)
        idc.set_cmt(self.ordinals - 8, "Custom imports from SharedLibrary.dll",
                    0)
        # we then apply the symbols at this very same location (start of .idata)
        for i in range(self.nb_symbols):
            idc.set_name(self.ordinals + i * 8, symbols[i],
                         SN_NOCHECK | SN_FORCE | SN_NODUMMY)

        # finally we remove our temp files
        os.remove(tmpfile)
        os.remove(tmpdll)
        # ida generate a db
        os.remove(tmpdll + '.i64')
        # if everything went smoothly, we should not need this anymore
        os.remove(tmplog)
Esempio n. 8
0
    def check_address(address):
        # Checks if given address contains virtual table. Returns True if more than 2 function pointers found
        # Also if table's addresses point to code in executable section, than tries to make functions at that addresses
        if helper.is_code_ea(address):
            return False

        if not idaapi.get_name(address):
            return False

        functions_count = 0
        while True:
            func_address = helper.get_ptr(address)
            # print "[INFO] Address 0x{0:08X}".format(func_address)
            if helper.is_code_ea(func_address) or helper.is_imported_ea(
                    func_address):
                functions_count += 1
                address += const.EA_SIZE
            else:
                segment = idaapi.getseg(func_address)
                if segment and segment.perm & idaapi.SEGPERM_EXEC:
                    idc.del_items(func_address, 1, idaapi.DELIT_SIMPLE)
                    if idc.add_func(func_address):
                        functions_count += 1
                        address += const.EA_SIZE
                        continue
                break
            idaapi.auto_wait()
        return functions_count
Esempio n. 9
0
def unkTillName(ea):
    d = Data.Data(ea)
    while True:
        size = d.getSize()
        idc.del_items(d.ea, d.getSize())
        d = Data.Data(d.ea + size)
        if d.getName(): break
    return d.ea
Esempio n. 10
0
def assign_struct_to_address(address, struct_name):
    idc.apply_type(address, get_Tinfo_from_name(struct_name))
    struct_id = idaapi.get_struc_id(struct_name)
    if struct_id != 0xffffffffffffffff:
        struct_size = idaapi.get_struc_size(struct_id)
        for i in range(struct_size):
            idc.del_items(address + i, 0)
        return idaapi.create_struct(address, struct_size, struct_id)
    return False
Esempio n. 11
0
def read_string(ea):
    s = idc.get_strlit_contents(ea, -1, idc.ASCSTR_C)
    if s:
        slen = len(s) + 1
        idc.del_items(ea, idc.DOUNK_SIMPLE, slen)
        idaapi.make_ascii_string(ea, slen, idc.ASCSTR_C)
        return s, ea + slen
    else:
        return s, ea
Esempio n. 12
0
def read_string(ea):
  s = idc.get_strlit_contents(ea, -1, idc.ASCSTR_C)
  if s:
    slen = len(s)+1
    idc.del_items(ea, idc.DOUNK_SIMPLE, slen)
    idaapi.make_ascii_string(ea, slen, idc.ASCSTR_C)
    return s, ea + slen
  else:
    return s, ea
Esempio n. 13
0
 def define(self):
     """
     Defines the string in the IDB.
     """
     try:
         idc.del_items(self.start_ea, idc.DELIT_SIMPLE, len(self.decoded_data))
         idaapi.create_strlit(self.start_ea, len(self.decoded_data), self.string_type)
     except Exception as e:
         logger.warning('Unable to define string at 0x{:0X}: {}'.format(self.start_ea, e))
Esempio n. 14
0
def convert_code_data_region_to_code(start_ea, end_ea):
    size = end_ea - start_ea
    score, count = code_score(start_ea, end_ea)
    if score >= 0.75:
        #print '{:016x}  {:8x}  {}'.format(start_ea, size, score)
        idc.del_items(start_ea, idc.DELIT_SIMPLE, size)
        for ea in range(start_ea, end_ea, 4):
            ilen = idc.create_insn(ea)
            if ilen == 0:
                idc.create_dword(ea)
Esempio n. 15
0
def delShiftedContent(ea):
    d = Data.Data(ea)
    content = d.getContent()
    if type(content) == list or not d.getXRefsFrom(
    )[1] or content < 0x8000000 or not d.isPointer(content):
        return False
    dContent = Data.Data(content)
    if content == dContent.ea or dContent.isCode():
        return False
    if not idc.del_items(dContent.ea, dContent.getSize()):
        for i in range(dContent.ea, dContent.ea + dContent.getSize()):
            idc.del_items(i, 1)
    return True
Esempio n. 16
0
def forceItemOp(ea, op, *args, **kwargs):
    """
    This forces a change to an item, like MakeWord, in the database
    :param ea: linear address of item
    :param op: the operation to apply. Expected to return a success status
    :param args: arguments to op
    :param kwargs: kwargs to op
    :return: success of op
    """
    success = op(*args, **kwargs)
    if not success:
        idc.del_items(ea)
        success = op(*args, **kwargs)
    return success
Esempio n. 17
0
def delete_and_make_function(ea, func_size, func_name, is_thumb):
    if ea == 0x8001030:
        raise Exception('target found!')
    print('{:X} <{}>: make function'.format(ea, func_name))
    # delete items and make sure that the area is thumb or arm
    for item_ea in next_item_ea(ea, func_size):
        idc.del_items(item_ea)  
        idc.SetRegEx(item_ea, 'T', is_thumb, idc.SR_user)
    idc.MakeFunction(ea)

    # check that the function was created
    import IDAItems.Function
    f = IDAItems.Function.Function(ea)
    if f.getSize(withPool=True) != func_size:
        raise Exception('Function {:07X} could not be successfully created'.format(ea))
Esempio n. 18
0
def registerUncompFile(ea, force=True):
    # type: (int) -> bool
    d = Data.Data(ea)
    compPtr = d.getContent()
    if not idc.is_dword(d.getFlags()) or type(compPtr) == list:
        if not force: return False
        print('[%07X] -> dword' % (ea))
        forceItemOp(ea, idc.create_dword, ea)
        d = Data.Data(ea)
        compPtr = d.getContent()

    # compressed pointers have the 31th bit set
    if not compPtr & (1 << 31):
        return False

    compPtr = compPtr - (1 << 31)

    #  make its content an array, and set a name for it, and a size
    compData = Data.Data(compPtr)
    if compData.ea != compPtr:
        idc.del_items(compData.ea)
        compData = Data.Data(compPtr)
    compSize = getLZ77CompressedSize(compPtr)
    # size must have been identified
    if compSize == -1:
        return False
    if compSize % 4 != 0:
        compSize += 4 - (compSize % 4)  # must be word aligned

    if compData.getSize() != compSize:
        if not idc.del_items(compPtr, compSize):
            for i in range(compPtr, compPtr + compSize):
                idc.del_items(i, 1)
        idc.make_array(compPtr, compSize)

    if not compData.getName():
        compData.setName('comp_%07X' % compData.ea)

    idc.op_man(ea, 0, '%s + 1<<31' % compData.getName())

    # now register the compressed data as its own file
    filename = 'data/compressed/%s.lz77' % compData.getName()
    print('[%07X] addFile %s' % (ea, filename))
    dis = Terminal.DisTerminal()
    dis.addFile(filename, compPtr, compPtr + compSize)

    return True
Esempio n. 19
0
def removeRedCode(start_ea, end_ea):
    """
    unconditionally removes all red code within a specified region
    :param start_ea: start of the region
    :param end_ea: end of the region
    :return:
    """
    srchNext = next
    redStart_ea = redEnd_ea = srchNext.red(start_ea, end_ea, ui=False)
    while redEnd_ea < end_ea:
        d = Data.Data(redEnd_ea)
        while d.isCode() and not Function.isFunction(d.ea):
            redEnd_ea += 2
            d = Data.Data(redEnd_ea)
        # change to bytes
        print("%07X: del red code (%07X, %07X)" %
              (redStart_ea, redStart_ea, redEnd_ea))
        idc.del_items(redStart_ea, 0, redEnd_ea - redStart_ea)
        redStart_ea = redEnd_ea = srchNext.red(redEnd_ea, end_ea, ui=False)
Esempio n. 20
0
def removeFakeRedCode(start_ea, end_ea):
    """
    Removes instances of code recognized by IDA to be code, but are unlikely not to be by making them bytes.
    :param start_ea: start of the range to fix
    :param end_ea: end of the range to fix
    :return:
    """
    srchNext = next
    redStart_ea, redEnd_ea = srchNext.fakered(start_ea,
                                              end_ea,
                                              ui=False,
                                              hexOut=False)
    while redStart_ea < end_ea:
        # change to bytes
        print("%07X: del fake red code (%07X, %07X)" %
              (redStart_ea, redStart_ea, redEnd_ea))
        idc.del_items(redStart_ea, 0, redEnd_ea - redStart_ea)
        redStart_ea, redEnd_ea = srchNext.fakered(redEnd_ea,
                                                  end_ea,
                                                  ui=False,
                                                  hexOut=False)
Esempio n. 21
0
def expandUnkArrays(start_ea, end_ea, verbose=True):
    """
    Finds all named byte_xxx and dword_xxx arrays, and turns them to unknowns.
    If an array is unnamed, and it's a byte array, it's also turned into unknowns.
    :param start_ea: start of the range
    :param end_ea: end of the range
    :param verbose: if True, print all changes
    :return: status of the expansion
    """
    d = Data.Data(start_ea)
    while d.ea < end_ea:
        if (not idc.isAlign(d.getFlags()) and (
                # known dummy array
            (d.getName() and (d.getName().startswith('byte_')
                              or d.getName().startswith('dword_')))
                # byte/dword array
                or (not d.getName() and type(d.getContent()) == list and
                    (d.getSize() / len(d.getContent()) == 1
                     or d.getSize() / len(d.getContent()) == 4)))):
            if verbose: print('%07X: delete unk arr' % d.ea)
            idc.del_items(d.ea, d.getSize())
        d = Data.Data(d.ea + d.getSize())
Esempio n. 22
0
    def arr2dword(pointerRange):
        d = Data.Data(pointerRange[0])
        outputStatus = True
        while (d.ea < pointerRange[1]):
            content = d.getContent()

            # case: byte array that's 4 elements. Likely a word
            if type(content) == list and len(content) == 4 and (d.getSize() / len(content) == 1):
                # transform to dword
                status = idc.del_items(d.ea)
                status = status and idc.MakeDword(d.ea)
                outputStatus = outputStatus and status
                if status:
                    print('[OK] %07X: u8[4] -> u32 %07X' % (d.ea, d.getContent()))
                else:
                    print('[FAIL] %07X: u8[4] -> u32' % d.ea)
                # advance 4 bytes
                d = Data.Data(d.ea + 4)
            else:
                d = Data.Data(d.ea + d.getSize())
        return outputStatus
Esempio n. 23
0
 def makeInsn(self, addr):
     if idc.create_insn(addr) == 0:
         idc.del_items(addr, idc.DELIT_EXPAND)
         idc.create_insn(addr)
     idc.auto_wait()
Esempio n. 24
0
def reset_db():
    idc.del_items(min_ea, size=max_ea - min_ea)
    idc.delete_all_segments()
    clear_names()
    ida_auto.auto_wait()
Esempio n. 25
0
def delete_items(ea, size):
    for item_ea in next_item_ea(ea, size):
        idc.del_items(item_ea)
Esempio n. 26
0
    def DoDescentParser(self, Prologue):
        '''
            @brief Walk the function leveraging a recursive descent parser. 

            @detail Starting with a prologue walk each instruction until the associated epilogue is reached. For functions 
                    with multiple epilogues, iterate over each one. 

                    As each instruction is traversed, do the following three
                    things:

                        - Undefine the instruction
                        - Mark the instruction as code
                        - Check to see if the instruction is already a member of another function
                    
                    If an instruction is a member of another function, undefine that function and place it in a queue. At the end
                     of traversing each function, a new function is going to be created with the new prologue and the new epilogue.
                     In addition, the undefined function queue is going to be iterated over and each function will be redefined. This
                     should clean up messy function
                    
                    much thanks to the author of "Practical Malware Analysis" for the break down of the algorithm in Chapter 8.
        '''

        #
        #   jmps = [eval("idaapi."+name) for name in dir(idaapi) if "NN_j" in name]
        #
        jcc_terminators = [
            'jnz', 'jz', 'jo', 'jno', 'js', 'jns', 'je', 'jne', 'jb', 'jnae',
            'jc', 'jnb', 'jae', 'jnc', 'jbe', 'jna', 'ja', 'jnbe', 'jl',
            'jnge', 'jge', 'jnl', 'jle', 'jng', 'jg', 'jnle', 'jp', 'jpe',
            'jnp', 'jpo', 'jcxz', 'jecxz'
        ]

        #print EndAddresses

        while len(self.deferred_targets) > 0:

            curr_insn_ea = self.deferred_targets.pop()

            if curr_insn_ea in self.instructions_walked:
                #
                #   skip instructions that were already walked
                #
                continue

            #for target in self.deferred_targets:
            #    print "deferred target: %08x" % target

            while curr_insn_ea not in Prologue.possible_epilogues:
                #
                # walk only to a known epilogue
                #

                #print "Current EA: %08x" % (curr_insn_ea)

                self.instructions_walked.append(curr_insn_ea)

                #
                #   Verify current instruction information
                #
                curr_insn = ida_ua.insn_t()
                decode_result = ida_ua.decode_insn(curr_insn, curr_insn_ea)
                if decode_result < 1:
                    #
                    #   break if instruction invalid
                    #
                    break

                represented_insn_dism = idc.generate_disasm_line(
                    curr_insn_ea, 0)
                curr_insn_dism = idc.generate_disasm_line(curr_insn_ea, 1)
                if curr_insn_dism != represented_insn_dism:
                    #
                    #   If the item shown at this address in IDA does not match
                    #     what should be shown (due to obfuscation), fix it
                    #

                    #print "Instructions don't match: %08x" % (curr_insn_ea)
                    idc.del_items(curr_insn_ea, 1)
                    #idc.plan_and_wait(curr_insn_ea, curr_insn_ea+curr_insn.size)
                    idc.create_insn(curr_insn_ea)
                    #idc.plan_and_wait(curr_insn_ea, curr_insn_ea+curr_insn.size)

                curr_func_name = idc.get_func_name(curr_insn_ea)
                if curr_func_name:
                    #
                    #   check if in function, undefine function, add to list to redefine later
                    #

                    #print "Part of another function: %08x" % (curr_insn_ea)
                    curr_func_ea = idc.get_name_ea_simple(curr_func_name)
                    func_end_ea = idc.find_func_end(curr_func_ea)
                    idc.del_func(curr_func_ea)

                    for curr_function in self.wrong_functions:
                        if curr_function not in curr_function:
                            self.wrong_functions.append(
                                [curr_func_ea, func_end_ea])

                if curr_insn_dism.startswith(tuple(jcc_terminators)):
                    #
                    #   JCC conditionals, recursion control case
                    #

                    #print "Adding jcc target: %08x" % (curr_insn_ea)
                    jmp_target_ea = self.GetInstuctionTargetAddress(curr_insn)
                    if jmp_target_ea not in self.deferred_targets:
                        self.deferred_targets.append(jmp_target_ea)

                    curr_insn_ea = curr_insn_ea + curr_insn.size

                elif curr_insn_dism.startswith("jmp"):
                    jmp_target_ea = self.GetInstuctionTargetAddress(curr_insn)

                    #print "Adding jump target: %08x" % (curr_insn_ea)
                    if jmp_target_ea not in self.deferred_targets:
                        self.deferred_targets.append(jmp_target_ea)
                    break

                elif curr_insn_dism.startswith("retn"):
                    break

                else:
                    curr_insn_ea = curr_insn_ea + curr_insn.size

            if curr_insn_ea in Prologue.possible_epilogues:
                Prologue.connected_epilogues.append(curr_insn_ea)
                continue
Esempio n. 27
0
 def cmd_undefine(self, a):
     return str(idc.del_items(int(a, 0), 1))
Esempio n. 28
0
 def __call__(self):
     idc.del_items(self.ea)
Esempio n. 29
0
def delRange(start_ea, end_ea):
    status = True
    for ea in range(start_ea, end_ea):
        idc.del_items(ea, 1)
    return status