Пример #1
0
    def get_value_info(self, v, stack_view=False):
        result = ""
        ptr = v.value
        val_type = v.type
        level = v.level

        if not idaapi.is_loaded(ptr):
            result += self.get_printable(ptr)
            return result

        area_name = ""
        if config.show_area_name:
            area_name = self.as_area_name(v)

        if val_type == T_CODE:
            result += area_name
            if self.is_code(ptr):
                result += self.as_disasm(ptr)
        else:
            if val_type not in (T_STACK, T_HEAP):
                result += area_name

            if stack_view:
                if level == 0:
                    result += self.get_ptr_value(v)
                else:
                    result += self.str_or_value(v)
            else:
                result += self.str_or_value(v)

        return result
Пример #2
0
    def value(self, value):
        """
        Set the operand to the specified value within the cpu_context.
        """
        # Value may be signed.
        if isinstance(value, int) and value < 0:
            value = utils.unsigned(value, bit_width=self.width * 8)

        # If we are writing to an immediate, I believe they want to write to the memory at the immediate.
        # TODO: Should we fail instead?
        if self.is_immediate:
            offset = self.value
            if idaapi.is_loaded(offset):
                self._cpu_context.mem_write(offset, value)
            return

        if self.is_register:
            # Convert the value from string to integer...
            if isinstance(value, str):
                value = utils.struct_unpack(value)
            self._cpu_context.registers[self.text] = value
            return

        if self.is_memory_reference:
            # FIXME: Usage of numpy is most likely symptomatic of a bug in an opcode
            #   implementation passing in bad data.
            #   Update this to just is "isinstance" and then fix the buggy opcode.
            # For data written to the frame or memory, this data MUST be a byte string.
            if numpy.issubdtype(type(value), numpy.integer):
                value = utils.struct_pack(value, width=self.width)
            self._cpu_context.mem_write(self.addr, value)
            return

        raise FunctionTracingError(f"Invalid operand type: {self.type}",
                                   ip=self.ip)
Пример #3
0
def get_struct(address, struct_type):
    assert idaapi.is_loaded(
        address) == True, "Can't access memory at 0x%x" % address
    sbytes = idaapi.get_bytes(address, sizeof(struct_type))
    struct = struct_type.from_buffer_copy(sbytes)
    struct._addr = address
    return struct
Пример #4
0
def get_value_type(ea):
    addr_type = T_VALUE

    if not idaapi.is_loaded(ea):
        return addr_type

    segm_name = idc.SegName(ea)
    segm = idaapi.getseg(ea)
    flags = idc.GetFlags(ea)
    is_code = idc.isCode(flags)

    if "stack" in segm_name.lower() or \
    (dbg.stack_segm and dbg.stack_segm.start_ea == segm.start_ea):
        addr_type = T_STACK

    elif "heap" in segm_name.lower():
        addr_type = T_HEAP

    elif not is_code and segm.perm & idaapi.SEGPERM_READ and \
    segm.perm & idaapi.SEGPERM_WRITE and \
    segm.perm & idaapi.SEGPERM_EXEC:
        addr_type = T_RWX

    elif is_code or \
    (segm.perm & idaapi.SEGPERM_READ and segm.perm & idaapi.SEGPERM_EXEC):
        addr_type = T_CODE

    elif segm.perm & idaapi.SEGPERM_READ and \
    segm.perm & idaapi.SEGPERM_WRITE:
        addr_type = T_DATA

    elif segm.perm & idaapi.SEGPERM_READ:
        addr_type = T_RODATA

    return addr_type
Пример #5
0
def find_main_arena():
    main_arena = idc.LocByName("main_arena")  # from libc6-dbg
    if main_arena != idc.BADADDR:
        return main_arena

    ea = idc.SegStart(idc.LocByName("_IO_2_1_stdin_"))
    end_ea = idc.SegEnd(ea)

    # &main_arena->next
    offsets = {
        4: [1088, 1096],  # 32 bits
        8: [2152, 2160]  # 64 bits
    }

    if ea == idc.BADADDR or end_ea == idc.BADADDR:
        return None

    get_ptr = config.get_ptr
    while ea < end_ea:
        ptr = get_ptr(ea)  # ptr to main_arena
        if idaapi.is_loaded(ptr) and ptr < ea and get_ptr(
                ptr) == 0:  # flags=0x0
            if (ea - ptr) in offsets[config.ptr_size]:
                return ptr
        ea += config.ptr_size
    return None
Пример #6
0
 def OnDblClick(self, shift):
     symbol = self.get_current_word()
     if symbol is not None:
         ea = self.resolve_expr(symbol)
         if ea and idaapi.is_loaded(ea):
             idaapi.jumpto(ea)
             return True
     return False
Пример #7
0
def get_loaded_bytes(start_addr, size, fill_with="\x00"):
  data = ""
  cur_ea = start_addr
  while cur_ea < (start_addr+size):
    if idaapi.is_loaded(cur_ea):
      data += chr(idaapi.get_byte(cur_ea))
    else:
      data += fill_with
    cur_ea += 1
  return bytes(data, 'latin1')
Пример #8
0
    def jump_in_hex(self):
        ea = self.get_current_expr_ea()
        if not ea or not idaapi.is_loaded(ea):
            idaapi.warning("Unable to resolve current expression\n")

        widget = self.find_hex_view()
        if not widget:
            idaapi.warning("Unable to find hex view")
            return
        self.jumpto_in_view(widget, ea)
Пример #9
0
def get_chain(value, limit=config.deref_limit):
    count = 0
    stop = False
    result = [value]

    if not idaapi.is_loaded(value):
        return result, False

    next_val = dbg.get_ptr(value)
    while not stop and count < limit:
        if result.count(next_val) >= 2 or not idaapi.is_loaded(next_val):
            stop = True
            continue

        result.append(next_val)
        next_val = dbg.get_ptr(next_val)
        count += 1

    exceeded = not stop
    return result, exceeded
Пример #10
0
    def jump_in_new_window(self):
        ea = self.get_current_expr_ea()
        if not ea or not idaapi.is_loaded(ea):
            return

        window_name = "D-0x%x" % ea
        widget = idaapi.open_disasm_window(window_name)
        if widget:
            self.jumpto_in_view(widget, ea)
        else:
            idaapi.warning("Unable to create the new window")
Пример #11
0
 def StartDump(self):
     # print self.start
     # print self.endorlen
     self.filepath = idaapi.ask_file(1, "*.dump", "save dump file")
     if self.dumptype == 0:
         ea = self.getHexNum(self.start)
         len = self.getHexNum(self.endorlen)
         if not idaapi.is_loaded(ea) or not idaapi.is_loaded(ea + len):
             idaapi.warning("arrary is out of bound")
             return -1
         if len <= 0:
             idaapi.warning("len is <= 0")
             return -1
         print("start read bytes")
         self.Close(0)
         idaapi.show_wait_box("read bytes")
         self.memdata = idaapi.get_bytes(ea, len)
         print("read bytes end")
         #idaapi.hide_wait_box("read end")
         idaapi.hide_wait_box()
     elif self.dumptype == 1:
         ea = self.getHexNum(self.start)
         len = self.getHexNum(self.endorlen) - self.getHexNum(self.start)
         if not idaapi.is_loaded(ea) or not idaapi.is_loaded(ea + len):
             idaapi.warning("arrary is out of bound")
             return -1
         if len <= 0:
             idaapi.warning("len is <= 0")
             return -1
         print("start read bytes")
         self.Close(0)
         idaapi.show_wait_box("read bytes")
         self.memdata = idaapi.get_bytes(ea, len)
         print("read bytes end")
         #idaapi.hide_wait_box("read end")
         idaapi.hide_wait_box()
     fp = open(self.filepath, 'wb')
     fp.write(self.memdata)
     fp.close()
     idaapi.msg("save:" + self.filepath)
     return 1
Пример #12
0
 def OnDblClick(self, shift):
     symbol = self.get_current_word()
     if symbol is not None:
         if symbol.isupper() and symbol.replace("*", "") in dbg.registers:
             self.modify_value()
             return True
         else:
             ea = self.resolve_expr(symbol)
             if ea and idaapi.is_loaded(ea):
                 idaapi.jumpto(ea)
                 return True
     return False
Пример #13
0
    def reload_info(self):
        if not dbg.is_process_suspended():
            return False

        base_addr = None
        if self.base_expr is None:
            base_addr = idc.get_reg_value(dbg.registers.stack)
        else:
            base_addr = idaapi.str2ea(self.base_expr)
            if base_addr == idc.BADADDR:
                idaapi.warning("Invalid base expr: %s" % self.base_expr)
                return False

            if not idaapi.is_loaded(base_addr):
                idaapi.warning("Memory address is not loaded: $#x" % base_addr)
                return False

        self.ClearLines()
        dbg.set_thread_info()

        try:
            segm_end = idc.get_segm_end(base_addr)
            n_entries = config.n_stack_entries or ((segm_end - base_addr) //
                                                   dbg.ptr_size)

            for i in range(n_entries):
                offset = i * dbg.ptr_size
                ptr = base_addr + offset

                if not idaapi.is_loaded(ptr):
                    break

                value = dbg.get_ptr(ptr)
                self.add_line("%02d:%04X  %s" %
                              (i, offset, self.parse_value(ptr)))

        except Exception as e:
            idaapi.warning(str(e))
            return False
        return True
Пример #14
0
 def is_read_only_inited_var(self, address):
     s: segment_t = getseg(address)
     if s is None:
         return False
     if s.perm != (SEGPERM_READ | SEGPERM_WRITE):
         return False
     if is_loaded(address):
         return False
     ref_finder = xrefblk_t()
     is_ok = ref_finder.first_to(address, XREF_DATA)
     while is_ok:
         if ref_finder.type == dr_W:
             return False
         is_ok = ref_finder.next_to()
     return True
Пример #15
0
    def value(self, value):
        """
        Set the operand to the specified value within the cpu_context.
        """
        # If we are writing to an immediate, I believe they want to write to the memory at the immediate.
        # TODO: Should we fail instead?
        if self.is_immediate:
            offset = self.value
            if idaapi.is_loaded(offset):
                self._cpu_context.mem_write(offset, value)
            return

        if self.is_register:
            # Convert the value from string to integer...
            if isinstance(value, str):
                value = utils.struct_unpack(value)

            # On 64-bit, the destination register must be set to 0 first (per documentation)
            # TODO: Check if this happens regardless of the source size
            if idc.__EA64__ and self.width == 4:  # Only do this for 32-bit setting
                reg64 = utils.convert_reg(self.text, 8)
                self._cpu_context.registers[reg64] = 0

            self._cpu_context.registers[self.text] = value
            return

        # TODO: Determine if this is still necessary.
        # FS, GS (at least) registers are identified as memory addresses.  We need to identify them as registers
        # and handle them as such
        if self.type == idc.o_mem:
            if "fs" in self.text:
                self._cpu_context.registers.fs = value
                return
            elif "gs" in self.text:
                self._cpu_context.registers.gs = value
                return

        if self.is_memory_reference:
            # For data written to the frame or memory, this data MUST be a byte string.
            if numpy.issubdtype(type(value), numpy.integer):
                value = utils.struct_pack(value, width=self.width)
            self._cpu_context.mem_write(self.addr, value)
            return

        raise FunctionTracingError('Invalid operand type: {}'.format(
            self.type),
                                   ip=self.ip)
Пример #16
0
    def next_on_click(self):
        chunk_addr = self.get_chunk_address()
        if chunk_addr is None:
            idaapi.warning("Invalid address / expression")
            return
        try:
            chunk = self.heap.get_chunk(chunk_addr)
            chunk_size = chunk.norm_size
            next_addr = chunk_addr+chunk_size
            if idaapi.is_loaded(next_addr):
                self.show_chunk("%#x" % next_addr)
            else:
                idaapi.warning("%#x: next chunk (%#x) is not loaded" % \
                    (chunk_addr, next_addr))

        except Exception as e:
            idaapi.warning("ERROR: " + str(e))
Пример #17
0
    def arenas(self):
        results = []
        main_arena_addr = self.main_arena_addr

        arena = self.get_arena()  # main_arena
        results.append([main_arena_addr, arena])
        next_ptr = arena.next

        while next_ptr not in (main_arena_addr, 0):

            if not idaapi.is_loaded(next_ptr):
                break

            arena = self.get_arena(next_ptr)
            results.append([next_ptr, arena])
            next_ptr = arena.next

        return results
Пример #18
0
 def modify_value(self):
     ea = self.get_current_expr_ea()
     if not ea or not idaapi.is_loaded(ea):
         return
     stack_val = 0
     if idaapi.inf_is_64bit():
         stack_val = ida_bytes.get_qword(ea)
     else:
         stack_val = ida_bytes.get_dword(ea)
     b = idaapi.ask_str("0x%X" % stack_val, 0, "Modify value")
     if b is not None:
         try:
             value = int(idaapi.str2ea(b))
             if idaapi.inf_is_64bit():
                 idc.patch_qword(ea, value)
             else:
                 idc.patch_dword(ea, value)
             self.reload_info()
         except:
             idaapi.warning("Invalid expression")
Пример #19
0
def find_malloc_par():
    mp_ = idc.get_name_ea_simple("mp_")
    if mp_ != idc.BADADDR:
        return mp_

    segm = idaapi.get_segm_by_name("[heap]")
    if segm is None:
        return None

    offset = get_struct_offsets(malloc_par()).get('sbrk_base')
    sbrk_base = segm.start_ea
    ea = idc.get_segm_start(get_name_ea_simple("_IO_2_1_stdin_"))
    end_ea = idc.get_segm_end(ea)

    while ea < end_ea:
        ptr = config.get_ptr(ea)
        if idaapi.is_loaded(ptr) and ptr == sbrk_base:
            return (ea - offset)
        ea += config.ptr_size

    return None
Пример #20
0
def find_main_arena():
    main_arena = idc.get_name_ea_simple("main_arena")  # from libc6-dbg
    if main_arena != idc.BADADDR:
        return main_arena

    ea = idc.get_segm_start(idc.get_name_ea_simple("_IO_2_1_stdin_"))
    end_ea = idc.get_segm_end(ea)

    # &main_arena->next
    offsets = {
        4: [1088, 1096],  # 32 bits
        8: [2152, 2160]  # 64 bits
    }[config.ptr_size]

    if ea == idc.BADADDR or end_ea == idc.BADADDR:
        return None

    while ea < end_ea:
        ptr = config.get_ptr(ea)  # ptr to main_arena
        if idaapi.is_loaded(ptr) and ptr < ea:
            if (ea - ptr) in offsets:
                return ptr
        ea += config.ptr_size
    return None
Пример #21
0
    def view_chunk_info(self):
        chunk_template = '''
            <style>
                td {
                    padding-right: 30px;
                }
                table {
                    font-size: 12px;
                    white-space: nowrap;
                    overflow: hidden;
                }
                body {
                    width: 100%%;
                }
                #hexdump {
                    font-family:Monaco;
                    font-size:12px;
                    white-space:pre;
                }
            </style>
            <p><b>[ %#x ]</b><br>
            <!-- Chunk fields -->
            %s
            <br>
            <p><b>[ hexdump ]</b></p>
            <p id="hexdump";>%s</p>
        '''

        chunk_addr = self.get_chunk_address()
        if chunk_addr is None:
            idaapi.warning("Invalid address / expression")
            return

        try:
            splitted = False
            in_use = None
            chunk_data = ""
            chunk_hexdump = ""
            chunk = self.heap.get_chunk(chunk_addr)
            chunk_bytes = chunk.norm_size
      
            if chunk_bytes > config.hexdump_limit: 
                chunk_bytes = config.hexdump_limit
                splitted = True

            if chunk_bytes > 0 and idaapi.is_loaded(chunk_addr + chunk_bytes):
                chunk_data = idaapi.get_bytes(chunk_addr, chunk_bytes)
            else:
                chunk_data = chunk.data

            if idaapi.is_loaded(chunk_addr + chunk.norm_size):
                in_use = self.heap.next_chunk(chunk_addr).prev_inuse

            chunk_table = self.html_chunk_table(chunk, in_use)
            if chunk_data:
                chunk_hexdump = self.html_chunk_hexdump(chunk_data, splitted)

            self.te_chunk_info.clear()
            chunk_info = chunk_template % (chunk_addr, chunk_table, chunk_hexdump)
            self.te_chunk_info.insertHtml(chunk_info)

        except Exception as e:
            idaapi.warning("ERROR: " + str(e))