Exemple #1
0
def main():
    path = ida_kernwin.ask_file(0, '*.*', 'Select a dumped IAT file.')
    if not path:
        return
    for line in open(path, 'r'):
        line = line.replace('`', '')  # take out ' if exists
        # parse an address
        if re.match('^[0-9a-f]{8} ', line):
            # 32bit
            addr = line[0:9]
            symbol = line[19:]
            bytewise = 4
            optype = ida_bytes.FF_DWORD
        elif re.match('^[0-9a-f]{16} ', line):
            # 64bit
            addr = line[0:17]
            symbol = line[27:]
            bytewise = 8
            optype = ida_bytes.FF_DWORD
        else:
            continue
        if re.match('^.+!.+$', symbol) is None:
            continue
        addr = int(addr, 16)
        _, api = symbol.rstrip().split('!')  # only needs a function name

        # Remove garbage to make IDA understand API's signature

        # Discard after space (source code path)
        api = api.split(' ')[0]
        # Fix for ExitProcess often gets a wrong name
        if api.endswith('FSPErrorMessages::CMessageMapper::StaticCleanup+0xc'):
            api = api.replace(
                'FSPErrorMessages::CMessageMapper::StaticCleanup+0xc',
                'ExitProcess')
        # Fix for kernelbase.dll related stub functions
        if api.endswith('Implementation'):
            api = api.replace('Implementation', '')
        elif api.endswith('Stub'):
            api = api.replace('Stub', '')
        # IDA does not like +
        api = api.replace('+', '_')
        print(hex(addr), api)

        # Set a data type on the IDB
        ida_bytes.del_items(addr, bytewise, ida_bytes.DELIT_EXPAND)
        ida_bytes.create_data(addr, optype, bytewise, 0)
        if idc.set_name(addr, api, SN_CHECK | SN_NOWARN) == 1:
            continue
        # Try to name it as <name>_N up to _99
        for i in range(100):
            if idc.set_name(addr, api + '_' + str(i),
                            SN_CHECK | SN_NOWARN) == 1:
                break
            if i == 99:
                idc.set_name(addr, api, SN_CHECK)  # Display an error message
    print(
        'Load an appropriate FLIRT signature if it is not applied yet.\n'
        'Then, use [Options] > [General] > [Analysis] > [Reanalyze program] to'
        ' reflect those API signatures.')
Exemple #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)
def main():
    for segstart, segend, segname in enum_segments():
        if segname not in ('.rdata', 'UPX1'):
            continue

        print(segname)
        for src, dst, size in find_pointers(segstart, segend):
            if idc.get_segm_name(dst) not in (".text", "UPX0"):
                continue

            if is_code(dst):
                continue

            print("new function pointer: 0x%x -> 0x%x" % (src, dst))

            ida_auto.auto_make_code(dst)
            ida_auto.auto_make_proc(dst)

            ida_bytes.del_items(src, size)
            ida_bytes.create_data(src,
                                  idc.FF_QWORD if size == 8 else idc.FF_DWORD,
                                  size, idc.BADADDR)
            # this doesn't seem to always work :-(
            idc.op_plain_offset(src, -1, 0)
            ida_name.set_name(src, "j_%s_%x" % (src, dst))
Exemple #4
0
    def req_patch(self, hash):
        addr, value, length = hash['addr'], hash['value'], hash['len']

        if length == 4:
            prev_value = idc.get_wide_dword(addr)
            if not ida_bytes.create_data(ea, FF_DWORD, 4, ida_idaapi.BADADDR):
                rs_log('[x] ida_bytes.create_data FF_DWORD failed')
            if not ida_bytes.patch_dword(addr, value):
                rs_log('[x] patch_dword failed')
            if not idc.op_plain_offset(addr, 0, 0):
                rs_log('[x] op_plain_offset failed')

        elif length == 8:
            prev_value = idc.get_qword(addr)
            if not ida_bytes.create_data(addr, FF_QWORD, 8,
                                         ida_idaapi.BADADDR):
                rs_log('[x] ida_bytes.create_data FF_QWORD failed')
            if not ida_bytes.patch_qword(addr, value):
                rs_log('[x] patch_qword failed')
            if not idc.op_plain_offset(addr, 0, 0):
                rs_log('[x] op_plain_offset failed')

        else:
            rs_log("[x] unsupported length: %d" % length)
            return

        rs_log("patched 0x%x = 0x%x (previous was 0x%x)" %
               (addr, value, prev_value))
Exemple #5
0
 def makeDQWord(self, api):
     match = re.search(r"\((?P<bitness>..)bit\)", api[2])
     if match:
         bitness = int(match.group("bitness"))
     if bitness == 32:
         ida_bytes.create_data(api[0], FF_DWORD, 4, idaapi.BADADDR)
     elif bitness == 64:
         ida_bytes.create_data(api[0], FF_QWORD, 8, idaapi.BADADDR)
Exemple #6
0
def _make_array_entry(ea, item_size):
  if item_size == 4:
    item_type = idc.FF_DWORD
  elif item_size == 8:
    item_type = idc.FF_QWORD
  else:
    raise ValueError("Invalid item size")

  ida_bytes.create_data(ea, item_type, item_size, ida_idaapi.BADADDR)
Exemple #7
0
def __import_names(start_address, names):

    for addr in range(start_address, start_address + (len(names) * 4), 4):
        print('0x{:08x}'.format(addr))
        ida_bytes.create_data(addr, idc.FF_DWORD, 4, ida_idaapi.BADADDR)
        name = names.pop(0)
        idc.set_name(addr, name, idc.SN_NOWARN)

    return True
Exemple #8
0
def _make_array_entry(ea, item_size):
    if item_size == 4:
        item_type = idc.FF_DWORD
    elif item_size == 8:
        item_type = idc.FF_QWORD
    else:
        raise ValueError("Invalid item size")

    ida_bytes.create_data(ea, item_type, item_size, ida_idaapi.BADADDR)
Exemple #9
0
    def load(infos):
        for info in infos:
            ida_name.set_name(info['address'], info['name'])
            type = info.get('type', None)

            # TODO this code is kind of mashed together... not sure of the
            # right way.
            tid = ida_struct.get_struc_id(type) if type else BADADDR
            if type:
                ida_bytes.create_struct(info['address'], info['sz'], tid)
            ida_bytes.create_data(
                info['address'], info['flags'], info['sz'], tid)
Exemple #10
0
    def load(infos):
        for info in infos:
            ida_name.set_name(info['address'], info['name'])

            # TODO this code is kind of mashed together... not sure of the
            # right way.
            tid = ida_struct.get_struc_id(
                info['type']) if info['type'] else BADADDR
            if info['type']:
                print(info['type'], hex(tid))
                ida_bytes.create_struct(info['address'], info['sz'], tid)
            ida_bytes.create_data(info['address'], info['flags'], info['sz'],
                                  tid)
Exemple #11
0
def main():
    for segstart, segend, segname in enum_segments():
        for head in idautils.Heads(segstart, segend):
            if not is_code(head):
                continue

            # pattern:
            #
            #   lea     rax, unk_6BDF88
            #   mov     [rsp+0], rax
            #   mov     qword ptr [rsp+8], 40h
            if ida_ua.ua_mnem(head) != "lea":
                continue

            next_head = ida_bytes.next_head(head, idc.BADADDR)
            if ida_ua.ua_mnem(next_head) != "mov":
                continue

            next_head2 = ida_bytes.next_head(next_head, idc.BADADDR)
            if ida_ua.ua_mnem(next_head2) != "mov":
                continue

            dst = idc.get_operand_value(head, 1)
            if idc.get_segm_name(dst) not in (".rdata", "UPX1"):
                continue

            size = idc.get_operand_value(next_head2, 1)

            if size > 0x100:
                continue
            if size <= 2:
                continue

            buf = ida_bytes.get_bytes(dst, size)
            if not buf:
                continue

            if b"\x00" in buf:
                continue

            try:
                s = buf.decode("ascii")
            except UnicodeDecodeError:
                continue

            print("string pointer: 0x%x -> 0x%x: %s" % (head, dst, s))
            ida_bytes.del_items(dst, 1)
            ida_bytes.create_data(dst, idc.FF_BYTE, 1, idc.BADADDR)
            ida_bytes.set_cmt(dst, s, True)
            ida_name.set_name(dst, "s_%x" % (dst))
Exemple #12
0
 def create_table(self):
     screen_ea = idaapi.get_screen_ea()
     print("Creating table at: ", hex(screen_ea))
     ida_bytes.del_items(screen_ea, 0, 4*6)
     ret = ida_bytes.create_data(screen_ea, ida_bytes.FF_DWORD, 4, idaapi.BADNODE)
     print("got return: ", ret)
     idc.MakeArray(screen_ea, 6)
Exemple #13
0
 def implement(self):
     if self._is_make_data:
         ea, flags, tid, len = self._type.split(":")
         ida_bytes.create_data(int(ea), int(flags), int(len), int(tid))
     else:
         py_type = [encode_bytes(t) for t in self._type]
         if len(py_type) == 3:
             py_type = py_type[1:]
         if len(py_type) >= 2:
             ida_typeinf.apply_type(
                 None,
                 py_type[0],
                 py_type[1],
                 self._ea,
                 ida_typeinf.TINFO_DEFINITE,
             )
Exemple #14
0
    def _defineImportThunk(self, start, thunk_val):
        """If the binary has the Import Thunk filled, define it as a data chunk of appropriate size.
        """

        info = idaapi.get_inf_structure()
        if info.is_64bit():
            curr_val = idc.get_qword(start)
            if (curr_val == thunk_val):
                return ida_bytes.create_data(start, idaapi.FF_QWORD, 8,
                                             idaapi.BADADDR)
        elif info.is_32bit():
            curr_val = ida_bytes.get_dword(start)
            if (curr_val == thunk_val):
                return ida_bytes.create_data(start, idaapi.FF_DWORD, 4,
                                             idaapi.BADADDR)
        return False
def main():
    for segstart, segend, segname in enum_segments():
        if segname not in ('.rdata', 'UPX1' ):
            continue

        for src, dst, psize in find_pointers(segstart, segend):
            if idc.get_segm_name(dst) not in (".rdata", "UPX0"):
                continue
                
            if psize == 8:
                size = ida_bytes.get_qword(src + 0x8)
            else:
                size = ida_bytes.get_dword(src + 0x4)
                
            if size > 0x100:
                continue
            if size <= 2:
                continue

            buf = ida_bytes.get_bytes(dst, size)
            if not buf:
                continue

            if b"\x00" in buf:
                continue

            try:
                s = buf.decode("ascii")
            except UnicodeDecodeError:
                continue

            print("string pointer: 0x%x -> 0x%x: %s" % (src, dst, s))

            ida_bytes.del_items(src, 1)
            ida_bytes.set_cmt(dst, s, True)

            # pointer
            ida_bytes.del_items(src, psize)
            ida_bytes.create_data(src, idc.FF_QWORD if size == 8 else idc.FF_DWORD, psize, idc.BADADDR)
            # this doesn't seem to always work :-(
            idc.op_plain_offset(src, -1, 0)
            ida_name.set_name(src, "s_%x" % (src))
            ida_bytes.set_cmt(src, s, True)

            # size
            ida_bytes.del_items(src + psize, psize)
            ida_bytes.create_data(src + psize, idc.FF_QWORD if size == 8 else idc.FF_DWORD, psize, idc.BADADDR)
Exemple #16
0
    def init_vtable(self):
        my_start_idx = self.vtable_start_idx()

        # Fix: support 64bit work
        if idc.__EA64__:
            pointer_size = idaapi.DEF_ADDRSIZE
            pfn_make_ptr = lambda x: ida_bytes.create_data(x, idc.FF_QWORD, 8, idaapi.BADADDR) #MakeQword
            pfn_get_ptr_value = ida_bytes.get_qword
        else:
            pointer_size = idaapi.DEF_ADDRSIZE
            pfn_make_ptr =  lambda x: ida_bytes.create_data(x, idc.FF_DWORD, 4, idaapi.BADADDR) #ida_bytes.MakeDword
            pfn_get_ptr_value = ida_bytes.get_dword

        for idx, ea in enumerate(range(self.vtable_start, self.vtable_end, pointer_size)):
            pfn_make_ptr(ea)
            idc.op_plain_offset(ea, 0, 0)
            dst = pfn_get_ptr_value(ea)

            if idx < my_start_idx:
                base_method = self.base.vmethods[idx]
                if base_method.is_dst_equal(dst):                   # Method from base class
                    self.vmethods.append(self.base.vmethods[idx])
                elif Method.s_is_pure_virtual_dst(dst):             # New pure virtual override
                    opvm = PureVirtualOverrideMethod(self, base_method, idx)
                    opvm.refresh()
                    self.vmethods.append(opvm)
                elif Method.s_is_deleted_virtual_dst(dst):          # New deleted override
                    dom = DeletedOverrideMethod(self, base_method, idx)
                    dom.refresh()
                    self.vmethods.append(dom)
                else:                                               # New override
                    om = OverrideMethod(dst, self, base_method, idx)
                    om.refresh()
                    self.vmethods.append(om)
            elif Method.s_is_pure_virtual_dst(dst):                 # New pure virtual
                pvm = PureVirtualMethod(self, 'vf%X' % (idx*4), idx)
                pvm.refresh()
                self.vmethods.append(pvm)
            elif Method.s_is_deleted_virtual_dst(dst):              # New deleted virtual
                pvm = DeletedVirtualMethod(self, 'vf%X' % (idx*4), idx)
                pvm.refresh()
                self.vmethods.append(pvm)
            else:                                                   # New virtual
                vm = VirtualMethod(dst, self, 'vf%X' % (idx*4), idx)
                vm.refresh()
                self.vmethods.append(vm)
Exemple #17
0
def load_file(f, neflags, format):
    f.seek(0)

    magic = f.read(4)
    version = struct.unpack("<I", f.read(4))[0]
    flags = struct.unpack("<I", f.read(4))[0]
    memType = struct.unpack("<I", f.read(4))[0]
    serviceType = struct.unpack("<I", f.read(4))[0]
    numInstances = struct.unpack("<I", f.read(4))[0]
    uuid = struct.unpack("<IIII", f.read(16))
    driverId = struct.unpack("<I", f.read(4))[0]
    numThreads = struct.unpack("<I", f.read(4))[0]
    textVA = struct.unpack("<I", f.read(4))[0]
    textLen = struct.unpack("<I", f.read(4))[0]
    dataVA = struct.unpack("<I", f.read(4))[0]
    dataLen = struct.unpack("<I", f.read(4))[0]
    bssLen = struct.unpack("<I", f.read(4))[0]
    entry = struct.unpack("<I", f.read(4))[0]

    f.seek(MCLF_TEXT_INFO_OFFSET)

    idaapi.set_processor_type("arm", ida_idp.SETPROC_LOADER_NON_FATAL)

    # Set VA for .text and add the segment
    f.file2base(0, textVA, textVA + textLen, True)
    idaapi.add_segm(0, textVA, textVA + textLen, ".text", "CODE")

    # Set VA for .data and add the segment
    f.file2base(textLen, dataVA, dataVA + dataLen, True)
    idaapi.add_segm(0, dataVA, dataVA + dataLen, ".data", "DATA")

    # Add BSS segment after .text and .data
    idaapi.add_segm(0, dataVA + dataLen, dataVA + dataLen + bssLen, ".bss",
                    "BSS")

    if entry % 4 == 1:
        #Thumb address is always +1 to set the T bit
        idaapi.add_entry(entry - 1, entry - 1, "_entry", 1)
        idc.split_sreg_range(entry - 1, "T", 0x1, ida_segregs.SR_user)
    else:
        idaapi.add_entry(entry, entry, "_entry", 1)
        idc.split_sreg_range(entry, "T", 0x0, ida_segregs.SR_user)

    ida_bytes.create_data(tlApiLibEntry, idaapi.FF_DWORD, 4, idaapi.BADADDR)
    idc.set_name(tlApiLibEntry, "tlApiLibEntry", ida_name.SN_CHECK)
    return 1
Exemple #18
0
    def __init__(self,
                 logger,
                 num_bits,
                 is_elf,
                 data_fptr_alignment=4,
                 mixed_code_and_data=False):
        """Create the analyzer's base class instance.

        Args:
            logger (logger): logger instance
            num_bits (int): bitness of the CPU (32 bits by default)
            data_fptr_alignment (int, optional): byte alignment needed for global fptrs (4 by default)
            mixed_code_and_data (bool, optional): True iff the main code section includes RO data constants (False by default)
        """
        self.logger = logger
        self._num_bits = num_bits
        self._is_elf = is_elf
        self.data_fptr_alignment = data_fptr_alignment
        self._mixed_code_and_data = mixed_code_and_data
        if num_bits == 64:
            self._address_parse_fn = idc.get_qword
            self._address_make_fn = lambda x: ida_bytes.create_data(
                x, idc.FF_QWORD, 8, idc.BADADDR)
            self.address_pack_format = "Q"
        elif num_bits == 32:
            self._address_parse_fn = idc.get_wide_dword
            self._address_make_fn = lambda x: ida_bytes.create_data(
                x, idc.FF_DWORD, 4, idc.BADADDR)
            self.address_pack_format = "L"
        else:
            self._address_parse_fn = idc.get_wide_word
            self._address_make_fn = lambda x: ida_bytes.create_data(
                x, idc.FF_WORD, 2, idc.BADADDR)
            self.address_pack_format = "H"
        # fields to be linked later on
        self.func_classifier = None
        self.fptr_identifier = None
        self.str_identifier = None
        self.locals_identifier = None
        self.switch_identifier = None
        # code types
        self._active_code_types = list(self.codeTypes())
Exemple #19
0
def MakeN(addr: int, size: int) -> None:
    """
    Make a integer with the given size at the given address.

    Args:
      addr (int): effective address.
      size (int): the size of the integer, one of 1, 2, 4, or 8.
    """
    if size == 1:
        ida_bytes.create_data(addr, ida_bytes.FF_BYTE, 1, ida_idaapi.BADADDR)
    elif size == 2:
        ida_bytes.create_data(addr, ida_bytes.FF_WORD, 2, ida_idaapi.BADADDR)
    elif size == 4:
        ida_bytes.create_data(addr, ida_bytes.FF_DWORD, 4, ida_idaapi.BADADDR)
    elif size == 8:
        ida_bytes.create_data(addr, ida_bytes.FF_QWORD, 8, ida_idaapi.BADADDR)
Exemple #20
0
    def is_qword(self, value):
        """
            Property setter which allow to transform this object in a defined
            object on 8 bytes. If set as False the value is undefined
            whichever its previous type.

            :param value: True for setting this data object as being on 8
                bytes, False for undefining the object type.
            :raise RuntimeError: If value was True and it was not able
                to correctly set the type for current item.
        """
        if value:
            if not ida_bytes.create_data(self.ea, ida_bytes.FF_QWORD, 8, idc.BADADDR):
                raise RuntimeError("Unable to set type for {}".format(self))
        else:
            del self.type
Exemple #21
0
def nDB(ea, name):
    ida_bytes.create_data(ea, ida_bytes.FF_BYTE, 1, ida_idaapi.BADADDR)
    ida_name.set_name(ea, name, ida_name.SN_NOCHECK)
Exemple #22
0
    def locateLocalConstants(self, scs, sds):
        """Locate and define all of the local strings / numeric constants, that match our observed pattern.

        Args:
            scs (list): List of (sark) code segments.
            sds (list): List of (sark) data segments.
        """
        self._analyzer.logger.info(
            "Locating local strings / constants in the code sections")
        for sc in scs:
            cur_ea = pad(sc.start_ea, self._local_alignment)
            while cur_ea < sc.end_ea:
                # check for a data constant
                if self.isDataConstant(cur_ea):
                    # check for a string (refs already checked)
                    if self._analyzer.str_identifier.isLocalAsciiString(
                            cur_ea, check_refs=False):
                        length = self._analyzer.str_identifier.defineAsciiString(
                            cur_ea)
                        padded_length = pad(length, self._local_alignment)
                        if padded_length != length:
                            ida_bytes.del_items(cur_ea + length, 0,
                                                padded_length - length)
                            ida_bytes.create_data(cur_ea + length, 0,
                                                  padded_length - length, 0)
                        cur_ea += padded_length
                    # This means it is a constant
                    else:
                        if self._local_pad is None:
                            ida_bytes.create_data(cur_ea, 0,
                                                  self._local_alignment, 0)
                        else:
                            # check the size of the constant using the byte padding
                            for offset in range(self._local_alignment - 1, -1,
                                                -1):
                                if idc.get_wide_byte(
                                        cur_ea + offset) != self._local_pad:
                                    break
                            # prepare the bytes
                            ida_bytes.del_items(cur_ea, 0,
                                                self._local_alignment)
                            # the data constant - try to make it pretty
                            if offset + 1 == 2:
                                ida_bytes.create_data(cur_ea, idc.FF_WORD, 2,
                                                      idc.BADADDR)
                            elif offset + 1 == 4:
                                ida_bytes.create_data(cur_ea, idc.FF_DWORD, 4,
                                                      idc.BADADDR)
                            elif offset + 1 == 8:
                                ida_bytes.create_data(cur_ea, idc.FF_QWORD, 8,
                                                      idc.BADADDR)
                            else:
                                ida_bytes.create_data(cur_ea, 0, offset + 1, 0)
                            # the padding
                            ida_bytes.create_data(
                                cur_ea + offset + 1, 0,
                                self._local_alignment - offset + 1, 0)
                            # Now check for a pointer (only supports code pointers for now)
                            if offset + 1 == self._analyzer.addressSize():
                                value = self._analyzer.parseAdderss(cur_ea)
                                # only support pointers inside our local segment (more probable)
                                if sc.start_ea <= value and value < sc.end_ea:
                                    self._analyzer.markCodePtr(
                                        cur_ea, value, aggressive=False)
                                # try a pointer to a declared string
                                else:
                                    for sd in sds:
                                        if sd.start_ea <= value and value <= sd.end_ea:
                                            line = sark.Line(value)
                                            if line.is_string and line.start_ea == value:
                                                self._analyzer.markDataPtr(
                                                    cur_ea,
                                                    value,
                                                    aggressive=False)
                                            break
                        # now move onward
                        cur_ea += self._local_alignment
                # found nothing, move on
                else:
                    cur_ea += self._local_alignment
Exemple #23
0
for name, (addr, size) in data["peripherals"].items():
    seg = ida_segment.getseg(addr)
    if seg:
        old_name = ida_segment.get_segm_name(seg)
        ida_segment.set_segm_name(seg, "%s_%s" % (old_name, name))
    else:
        add_segment(addr, size, name)

for name, (addr, reg_count, reg_size, clu_count, clu_size) in data["addresses"].items():
    for m in range(clu_count):
        for n in range(reg_count):
            reg_name = name.replace('<m>', str(m)).replace('<n>', str(n))
            reg_addr = addr + m * clu_size + n * reg_size

            ida_bytes.create_data(reg_addr, {
                1: ida_bytes.byte_flag(),
                2: ida_bytes.word_flag(),
                4: ida_bytes.dword_flag()
            }[reg_size], reg_size, ida_netnode.BADNODE)
            ida_name.set_name(reg_addr, reg_name)

base_addr = ida_segment.get_segm_by_name("ROM").start_ea
for name, offset in data["interrupts"].items():
    addr = base_addr + (16 + offset) * 4
    name = "%s_%s" % ("arm" if offset < 0 else "irq", name.lower())
    ida_bytes.del_items(addr, 0, 4)
    ida_bytes.create_dword(addr, 4, True)
    ida_name.set_name(addr, name, 0)
    if ida_bytes.get_dword(addr) > 0:
        ida_offset.op_plain_offset(addr, 0, 0)
    def run(self, arg):
        for function in idautils.Functions():
            values = {}
            #function = ida_kernwin.get_screen_ea()
            function_start = idc.get_func_attr(function, idc.FUNCATTR_START)
            function_end = idc.get_func_attr(function, idc.FUNCATTR_END)
            function_name = idc.get_func_name(function)
            if re.search("func\d+", function_name):
                try:
                    decompiled_code = str(ida_hexrays.decompile(function))
                    lenght = re.search(r"i < (\w+); \+\+i", decompiled_code)

                    if lenght != None:
                        # Getting hex values displayed in the decompiled code
                        values[function_name] = []
                        for z in re.findall("= (0[xX][0-9a-fA-F]+)",
                                            decompiled_code):
                            values[function_name].append(
                                binascii.hexlify(
                                    struct.pack(
                                        '<Q',
                                        int(int(z.replace("0x", ""),
                                                base=16)))).decode(
                                                    "windows-1252").replace(
                                                        "00", ""))

                        # Getting values from xmmwords
                        xmmwords = re.findall(r"xmmword_(\w+)",
                                              decompiled_code)

                        for xmmword in xmmwords:
                            #print(f"\nxmmword_{xmmword} -> {int(xmmword, 16)}")

                            ida_bytes.create_data(
                                int(xmmword, 16), ida_bytes.byte_flag(), 1,
                                ida_netnode.BADNODE
                            )  # create byte at the specified address
                            data = binascii.hexlify(
                                idaapi.get_bytes(
                                    int(xmmword,
                                        16), int(lenght.group(1),
                                                 16))).decode("windows-1252")
                            values[function_name].append(data)
                            #print(binascii.hexlify(idaapi.get_bytes(int(xmmword, 16), int(lenght, 16)))) # get bytes

                except idaapi.DecompilationFailure:
                    pass

                try:
                    lenght = int(len(values[function_name]) / 2)
                    string = self.to_decimal(values[function_name][0:lenght])
                    key = self.to_decimal(values[function_name][lenght::])
                    str_decrypted = ""
                    for i in range(0, len(string)):
                        str_decrypted += chr(string[i] ^ key[i % len(key)])
                        #idaapi.msg(f"{string[i]} ^ {key[i % len(key)]}\n")
                    if str_decrypted != "":
                        #idaapi.msg(str_decrypted+"\n")
                        idc.set_func_cmt(function_start, str_decrypted, 0)
                        rowPosition = self.plg.table.rowCount()
                        self.plg.table.insertRow(rowPosition)
                        self.plg.table.setItem(
                            rowPosition, 0,
                            QtWidgets.QTableWidgetItem(
                                function_name.replace(".", "_")))
                        self.plg.table.setItem(
                            rowPosition, 1,
                            QtWidgets.QTableWidgetItem(str_decrypted))
                except:
                    pass
Exemple #25
0
def nDD(ea, name):
    ida_bytes.create_data(ea, ida_bytes.FF_DWORD, 4, ida_idaapi.BADADDR)
    ida_name.set_name(ea, name, ida_name.SN_NOCHECK)
 def __call__(self):
     ida_bytes.create_data(self.ea, self.flags, self.size, self.tid)
Exemple #27
0
    def run(self, arg):
        for function in idautils.Functions():
            values = {}
            #function = ida_kernwin.get_screen_ea()
            function_start = idc.get_func_attr(function, idc.FUNCATTR_START)
            function_end = idc.get_func_attr(function, idc.FUNCATTR_END)
            function_name = idc.get_func_name(function)
            if re.search("func\d+", function_name):
                try:
                    decompiled_code = str(ida_hexrays.decompile(function))
                    lenght = re.search(r"i < (\w+); \+\+i", decompiled_code)

                    if lenght != None:
                        # Getting hex values displayed in the decompiled code
                        values[function_name] = []
                        for z in re.findall(" = 0[xX]([0-9a-fA-F]+)",
                                            decompiled_code):
                            swapped_list = []
                            for i in range(0, len(z), 2):
                                swapped_list.insert(0, z[i:i + 2])
                            z = "".join(map(str, swapped_list))
                            #print(f"\n{function_name}: {z}")
                            values[function_name].append(z)
                            #print(f"Appending: {z} {function_name}")

                        # Getting values from xmmword and unk_ chunks
                        xmmwords = re.findall(r"xmmword_(\w+)",
                                              decompiled_code)

                        for xmmword in xmmwords:
                            #print(f"\nxmmword_{xmmword} -> {int(xmmword, 16)}")

                            ida_bytes.create_data(
                                int(xmmword, 16), ida_bytes.byte_flag(), 1,
                                ida_netnode.BADNODE
                            )  # create byte at the specified address
                            data = binascii.hexlify(
                                idaapi.get_bytes(
                                    int(xmmword,
                                        16), int(lenght.group(1),
                                                 16))).decode("windows-1252")
                            values[function_name].append(data)
                            #print(binascii.hexlify(idaapi.get_bytes(int(xmmword, 16), int(lenght, 16)))) # get bytes

                        unks_data = re.findall(r"qmemcpy.*&unk_(.*),",
                                               decompiled_code)
                        if unks_data != []:
                            values[function_name] = []
                            for unk in unks_data:
                                unk_data = data = binascii.hexlify(
                                    idaapi.get_bytes(
                                        int(unk, 16),
                                        int(lenght.group(1),
                                            16))).decode("windows-1252")
                                values[function_name].append(unk_data)
                                #print(f"""\n{function_name}
                                #unk_{unk}: {unk_data}
                                #""")
                                #print(f"Appending: {unk_data} {function_name}")

                except idaapi.DecompilationFailure:
                    pass

                try:
                    lenght = int(len(values[function_name]) / 2)
                    #print(function_name)
                    string = self.to_decimal(values[function_name][0:lenght])
                    key = self.to_decimal(values[function_name][lenght::])
                    # print(f"""
                    # String: {string}
                    # Key: {key}
                    # Lenght: {lenght}
                    # """)
                    str_decrypted = ""
                    for i in range(0, len(key)):
                        str_decrypted += chr(string[i % len(string)]
                                             ^ key[i % len(key)])
                        #idaapi.msg(f"\n{hex(string[i % len(string)])} ^ {hex(key[i % len(key)])} {chr(string[i % len(string)] ^ key[i % len(key)])}\n")
                    if str_decrypted != "":
                        #idaapi.msg("Decrypted: "+str_decrypted+"\n")
                        idc.set_func_cmt(function_start, str_decrypted, 0)
                        rowPosition = self.plg.table.rowCount()
                        self.plg.table.insertRow(rowPosition)
                        self.plg.table.setItem(
                            rowPosition, 0,
                            QtWidgets.QTableWidgetItem(
                                function_name.replace(".", "_")))
                        self.plg.table.setItem(
                            rowPosition, 1,
                            QtWidgets.QTableWidgetItem(str_decrypted))
                except:
                    pass
Exemple #28
0
 def __call__(self):
     ida_bytes.create_data(
         self.ea, ida_bytes.calc_dflags(self.flags, True), self.size,
         ida_struct.get_struc_id(self.sname)
         if self.sname else ida_netnode.BADNODE)
Exemple #29
0
def load_file(f, neflags, format):
    f.seek(0)

    ida_idp.set_processor_type("metapc", ida_idp.SETPROC_LOADER)
    MGROUPStart = 0
    magic = f.read(2)

    if magic == MZ_HEADER_MAGIC:
        f.seek(0x22)
        MGROUPStart = DW(f) * 16
        f.seek(MGROUPStart)
        magic = f.read(2)

    headerSize = DW(f)
    segmentDataAlignment = DW(f)
    nextExeOff = DD(f)
    SegDataOff = DD(f)

    f.file2base(MGROUPStart, 0, SegDataOff, True)
    ida_segment.add_segm(0, 0, 0x50, "HEADER", "MODULE")
    f.seek(MGROUPStart + 2)

    headerSize = rnDW(f, "headerSize", MGROUPStart)
    segmentDataAlignment = rnDW(f, "segmentDataAlignment", MGROUPStart)
    nextExeOff = rnDD(f, "nextExeOff", MGROUPStart)
    SegDataOff = rnDD(f, "SegDataOff", MGROUPStart)

    ResDataOff = rnDD(f, "ResDataOff", MGROUPStart)
    flags = rnDW(f, "flags", MGROUPStart)
    version = rnDB(f, "version", MGROUPStart)
    revision = rnDB(f, "revision", MGROUPStart)
    AutoDataSegNo = rnDW(f, "AutoDataSegNo", MGROUPStart)
    HeapSize = rnDW(f, "HeapSize", MGROUPStart)
    StackSize = rnDW(f, "StackSize", MGROUPStart)
    StartProc = rnDD(f, "StartProc", MGROUPStart)
    LoadProc = rnDD(f, "LoadProc", MGROUPStart)
    FreeProc = rnDD(f, "FreeProc", MGROUPStart)
    nSegments = rnDW(f, "nSegments", MGROUPStart)
    pSegTable = rnDW(f, "pSegTable", MGROUPStart)
    cbResTab = rnDW(f, "cbResTab", MGROUPStart)
    pResTab = rnDW(f, "pResTab", MGROUPStart)
    cbEntTab = rnDW(f, "cbEntTab", MGROUPStart)
    pEntTab = rnDW(f, "pEntTab", MGROUPStart)
    cbNamTab = rnDW(f, "cbNamTab", MGROUPStart)
    pNamTab = rnDW(f, "pNamTab", MGROUPStart)
    cbStrTab = rnDW(f, "cbStrTab", MGROUPStart)
    pStrTab = rnDW(f, "pStrTab", MGROUPStart)
    cbNRNamTab = rnDW(f, "cbNRNamTab", MGROUPStart)
    pNRNamTab = rnDW(f, "pNRNamTab", MGROUPStart)

    ida_segment.add_segm(0, pSegTable,
                         pSegTable + (nSegments * SEG_STRUCT_SIZE), "SEGTABLE",
                         "MODULE")
    ida_segment.add_segm(0, pResTab, pResTab + cbResTab, "RESOURCES", "MODULE")
    ida_segment.add_segm(0, pEntTab, pEntTab + cbEntTab, "ENTTABLE", "MODULE")
    ida_segment.add_segm(0, pNamTab, pNamTab + cbNamTab, "ENTNAME", "MODULE")
    ida_segment.add_segm(0, pStrTab, pStrTab + cbStrTab, "IMPORTS", "MODULE")
    ida_segment.add_segm(0, pNRNamTab, pNRNamTab + cbNRNamTab, "NRENTNAME",
                         "MODULE")

    #parse segtable
    segentsid = defSEGENT()
    base = SegDataOff // 16

    importCount = 0
    for i in range(nSegments):
        segEntStart = pSegTable + i * SEG_STRUCT_SIZE
        ida_bytes.create_struct(segEntStart, SEG_STRUCT_SIZE, segentsid)
        segStart = ida_bytes.get_word(segEntStart + 2)
        segLen = ida_bytes.get_word(segEntStart + 4)
        segImports = ida_bytes.get_word(segEntStart + 6)
        importCount += segImports
        f.file2base(MGROUPStart + SegDataOff + segStart * 16,
                    SegDataOff + segStart * 16,
                    SegDataOff + (segStart + segLen) * 16, True)

        segBase = (base + segStart) * 16
        #segmentDef = ida_segment.segment_t()
        #segmentDef.start_ea = segBase
        #segmentDef.end_ea = (base+segStart+segLen)*16
        #ida_segment.set_selector()
        print(base + segStart)
        ida_segment.add_segm(base + segStart, segBase,
                             (base + segStart + segLen) * 16, "", "", 0)
        sel = ida_segment.find_selector(base + segStart)
        seg = ida_segment.getseg(segBase)
        ida_segment.set_segm_addressing(seg, 0)
        segtable[i] = seg
        segimportstable[i] = segImports
        if i + 1 == AutoDataSegNo:
            ida_segment.set_segm_name(seg, "DATA", 0)
            ida_segment.set_segm_class(seg, "DATA", 0)
            dataSel = sel
        else:
            ida_segment.set_segm_name(seg, "TEXT", 0)
            ida_segment.set_segm_class(seg, "CODE", 0)
            if AutoDataSegNo == 0:
                dataSel = sel
    ida_segregs.set_default_dataseg(dataSel)

    #parse enttable
    pENT = pEntTab
    currord = 1
    while pENT < pEntTab + cbEntTab:
        bundleCount = ida_bytes.get_byte(pENT)
        bundleFlags = ida_bytes.get_byte(pENT + 1)
        if bundleCount == 0 and bundleFlags == 0:
            break
        pENT += 2
        for i in range(bundleCount):
            if bundleFlags == 0xFF:
                ordFlags = ida_bytes.get_byte(pENT)
                if ordFlags & 0x80:
                    toexport.append(currord)
                segNo = ida_bytes.get_byte(pENT + 3)
                segOff = ida_bytes.get_word(pENT + 4)

                enttable[currord] = (segtable[segNo - 1].start_ea // 16,
                                     segOff)
                pENT += 6
            else:
                ordFlags = ida_bytes.get_byte(pENT)
                if ordFlags & 0x80:
                    toexport.append(currord)
                segOff = ida_bytes.get_word(pENT + 1)
                enttable[currord] = (segtable[bundleFlags - 1].start_ea // 16,
                                     segOff)
                pENT += 3

            currord += 1

    modulename = readPASSTR(pNamTab)

    make_entry(StartProc, modulename + "_start")
    make_entry(LoadProc, modulename + "_load")
    make_entry(FreeProc, modulename + "_free")

    #export named ordinals
    namedordtable = loadExportsF(f)

    for i in toexport:
        if i in namedordtable:
            name = namedordtable[i]
        else:
            name = "Ordinal" + str(i)
        (base, off) = enttable[i]
        addr = base * 16 + off
        ida_entry.add_entry(i, addr, name, 1)

    #process imports

    ida_segment.add_segm(0xF000, 0xF0000, 0xF0000 + importCount * 2, "IMPORTS",
                         "XTRN", 0)

    import_ea = 0xF0000

    for seg in segtable:
        segend = segtable[seg].end_ea
        f.seek(MGROUPStart + segend)

        for i in range(segimportstable[seg]):
            count = DB(f)
            mode = DB(f)
            relocStart = DW(f)
            module = DW(f)
            proc = DW(f)

            if (module == 0xFFFF):
                (base, off) = enttable[proc]
            else:
                modulestr = readPASSTR(pStrTab + module)
                if (proc & 0x8000) != 0:  # read by ord
                    ordinal = proc & 0x7FFF
                    procname = modulestr + "_Ordinal" + str(ordinal)
                    if not modulestr in importedmodules:
                        if os.path.isfile(modulestr + ".EXE"):
                            importedmodules[modulestr] = loadExports(
                                modulestr + ".EXE")
                        else:
                            filename = ida_kernwin.ask_file(
                                0, modulestr + ".EXE",
                                "Select file to name exports")
                            if filename is not None and os.path.isfile(
                                    filename):
                                importedmodules[modulestr] = loadExports(
                                    filename)
                            else:
                                importedmodules[modulestr] = None
                    if modulestr in importedmodules and (
                            importedmodules[modulestr] is not None
                    ) and ordinal in importedmodules[modulestr]:
                        procname = importedmodules[modulestr][ordinal]
                else:
                    procname = readPASSTR(pStrTab + proc)
                ida_bytes.create_data(import_ea, ida_bytes.FF_WORD, 2,
                                      ida_idaapi.BADADDR)
                ida_name.force_name(import_ea, procname)
                ida_bytes.set_cmt(import_ea, "Imported from " + modulestr, 1)
                base = 0xF000
                off = import_ea - 0xF0000
                import_ea += 2

            for xx in range(count):
                next = ida_bytes.get_word(segtable[seg].start_ea + relocStart)
                if mode == 0x20:
                    ida_bytes.put_word(segtable[seg].start_ea + relocStart + 2,
                                       base)
                    ida_bytes.put_word(segtable[seg].start_ea + relocStart,
                                       off)
                elif mode == 0x10:
                    ida_bytes.put_word(segtable[seg].start_ea + relocStart,
                                       off)
                elif mode == 0x0:
                    ida_bytes.put_word(segtable[seg].start_ea + relocStart,
                                       base)
                relocStart = next

            #print "import %d: seg %d mode %s count %d relocStart %s module %s proc %s" % (i, seg, hex(mode), count, hex(relocStart), modulestr, hex(proc))

    return 1
Exemple #30
0
def load_file(f: ida_idaapi.loader_input_t, neflags: Any, format: Any) -> int:
    """
    load the given file into the current IDA Pro database.

    Args:
      f (file): the file-like object to load.
      neflags (Any): unused
      format (Any): unused

    Returns:
      int: 1 on success, 0 on failure
    """

    # compute file size, then read the entire contents
    f.seek(0x0, os.SEEK_END)
    flen = f.tell()
    f.seek(0x0)
    buf = f.read(flen)

    # mark the proc type, so IDA can invoke the correct disassembler/processor.
    # this must match `processor.wasm_processor_t.psnames`
    ida_idp.set_processor_type('wasm', ida_idp.SETPROC_LOADER_NON_FATAL)

    f.seek(0x0)
    # load the entire file directly at address zero.
    f.file2base(0, 0, len(buf), True)

    p = 0
    sections = wasm.decode_module(buf)
    for i, section in enumerate(sections):
        if i == 0:
            sname = 'header'
        else:
            if section.data.id == wasm.wasmtypes.SEC_UNK:
                if section.data.name:
                    sname = section.data.name.tobytes().decode('utf-8')
                else:
                    sname = ''
            else:
                sname = idawasm.const.WASM_SECTION_NAMES.get(
                    section.data.id, 'unknown')

        if sname != 'header' and section.data.id in (
                wasm.wasmtypes.SEC_CODE, wasm.wasmtypes.SEC_GLOBAL):
            stype = 'CODE'
        else:
            stype = 'DATA'

        # add IDA segment with type, name, size as appropriate
        slen = sum(section.data.get_decoder_meta()['lengths'].values())
        ida_segment.add_segm(0, p, p + slen, sname, stype)

        if sname != 'header':
            loader = SECTION_LOADERS.get(section.data.id)
            if loader is not None:
                loader(section, p)

            load_section(section, p)

        p += slen

    # magic
    ida_bytes.create_data(0x0, ida_bytes.FF_DWORD, 4, ida_idaapi.BADADDR)
    ida_name.set_name(0x0, 'WASM_MAGIC', ida_name.SN_CHECK)
    # version
    ida_bytes.create_data(0x4, ida_bytes.FF_DWORD, 4, ida_idaapi.BADADDR)
    ida_name.set_name(0x4, 'WASM_VERSION', ida_name.SN_CHECK)

    return 1
Exemple #31
0
 def MakeQWord(self, ea):
     if idaapi.IDA_SDK_VERSION < 700:
         return idc.MakeQword(ea)
     else:
         return ida_bytes.create_data(ea, FF_QWORD, 8, idaapi.BADADDR)