예제 #1
0
def build_cle_got(proj, state):
    debugger = get_debugger()

    try:
        got_start, got_end = debugger.get_got()
    except:
        print "angrdbg: cannot find .got.plt section"
        return state

    entry_len = proj.arch.bits / 8

    got_start += 3 * entry_len  # skip first 3 entries
    '''
    print "## angr got - before ##"
    for a in xrange(got_start, got_end, entry_len):
        print "0x%x:  0x%x" % (a, state.solver.eval(getattr(state.mem[a], "uint%d_t" % proj.arch.bits).resolved))
    print
    '''

    empty_state = proj.factory.blank_state()
    state.memory.store(got_start,
                       empty_state.memory.load(got_start, got_end - got_start))
    '''
    print "## angr got - final ##"
    for a in xrange(got_start, got_end, entry_len):
        print "0x%x:  0x%x" % (a, state.solver.eval(getattr(state.mem[a], "uint%d_t" % proj.arch.bits).resolved))
    print
    '''

    return state
예제 #2
0
def build_mixed_got(proj, state):
    debugger = get_debugger()

    try:
        got_start, got_end = debugger.get_got()
    except BaseException:
        print "angrdbg: cannot find .got.plt section"
        return state

    try:
        plt_start, plt_end = debugger.get_plt()
    except BaseException:
        print "angrdbg: cannot find .plt section"
        return state

    entry_len = proj.arch.bits / 8
    get_mem = debugger.get_dword if entry_len == 4 else debugger.get_qword

    got_start += 3 * entry_len  # skip first 3 entries

    '''
    print "## angr got - before ##"
    for a in xrange(got_start, got_end, entry_len):
        print "0x%x:  0x%x" % (a, state.solver.eval(getattr(state.mem[a], "uint%d_t" % proj.arch.bits).resolved))
    print
    '''

    empty_state = proj.factory.blank_state()

    for a in xrange(got_start, got_end, entry_len):
        state_val = empty_state.solver.eval(
            getattr(
                empty_state.mem[a],
                "uint%d_t" %
                proj.arch.bits).resolved)
        if state_val in proj._sim_procedures:
            if proj._sim_procedures[state_val].is_stub:  # real simprocs or not?
                dbg_val = get_mem(a)
                name = proj._sim_procedures[state_val].display_name

                if dbg_val >= plt_end or dbg_val < plt_start:  # already resolved by the loader in the dbg
                    setattr(state.mem[a], "uint%d_t" % proj.arch.bits, dbg_val)
                else:
                    ea = debugger.resolve_name(name)
                    if ea is not None:
                        setattr(state.mem[a], "uint%d_t" % proj.arch.bits, ea)

    '''
    print "## angr got - final ##"
    for a in xrange(got_start, got_end, entry_len):
        print "0x%x:  0x%x" % (a, state.solver.eval(getattr(state.mem[a], "uint%d_t" % proj.arch.bits).resolved))
    print
    '''

    return state
예제 #3
0
파일: page.py 프로젝트: wy666444/angrdbg
 def load_mo(self, state, page_idx):
     """
     Loads a memory object from memory.
     :param page_idx: the index into the page
     :returns: a tuple of the object
     """
     mo = self._storage[page_idx - self._page_addr]
     #print filter(lambda x: x != None, self._storage)
     if mo is None and hasattr(self, "from_dbg"):
         byte_val = get_debugger().get_byte(page_idx)
         mo = SimMemoryObject(claripy.BVV(byte_val, 8), page_idx)
         self._storage[page_idx - self._page_addr] = mo
     return mo
예제 #4
0
def StateShot(regs={}, sync_brk=True, from_dump=False, **kwargs):
    debugger = get_debugger()

    if not from_dump:
        if not debugger.is_active():
            raise RuntimeError(
                "The debugger must be active and suspended before calling StateShot"
            )
        debugger.refresh_memory()

    project = load_project()

    debugger.before_stateshot()

    mem = SimSymbolicDbgMemory(memory_backer=project.loader.memory,
                               permissions_backer=None,
                               memory_id="mem")

    state = project.factory.blank_state(plugins={"memory": mem}, **kwargs)

    for reg in sorted(project.arch.registers,
                      key=lambda x: project.arch.registers.get(x)[1]):
        if reg in ("sp", "bp", "ip"):
            continue
        try:
            if reg in regs:
                setattr(state.regs, reg, regs[reg])
            else:
                setattr(state.regs, reg, debugger.get_reg(reg))
        except BaseException:
            pass

    if project.simos.name == "Linux":
        # inject code to get brk if we are on linux x86/x86_64
        if sync_brk and project.arch.name in ("AMD64", "X86"):
            state.posix.set_brk(get_linux_brk(project.arch.bits))

        if get_memory_type() == SIMPROCS_FROM_CLE:
            # insert simprocs when possible or resolve the symbol
            state = build_mixed_got(project, state)
        elif get_memory_type() == ONLY_GOT_FROM_CLE:
            # load the entire got from cle with stubs
            state = build_cle_got(project, state)
        elif get_memory_type() == GET_ALL_DISCARD_CLE:
            # angr must not execute loader code so all symbols must be resolved
            state = build_bind_now_got(project, state)

    debugger.after_stateshot(state)

    return state
예제 #5
0
파일: brk.py 프로젝트: wy666444/angrdbg
def get_dbg_brk_linux64():
    '''
    Return the current brk value in the debugged process (only x86_64 Linux)
    '''
    # TODO this method is so weird, find a unused address to inject code not
    # the base address

    debugger = get_debugger()

    code = '\x0f\x05'  # syscall

    rax = debugger.get_reg("rax")
    rdi = debugger.get_reg("rdi")
    rip = debugger.get_reg("rip")
    efl = debugger.get_reg("efl")

    debugger.set_reg("rax", 12)  # sys_brk
    debugger.set_reg("rdi", 0)

    base = debugger.image_base()

    inj = base

    save = debugger.get_bytes(inj, len(code))

    debugger.put_bytes(inj, code)

    debugger.set_reg("rip", inj)

    debugger.step_into()
    debugger.wait_ready()

    brk_res = debugger.get_reg("rax")

    debugger.set_reg("rax", rax)
    debugger.set_reg("rdi", rdi)
    debugger.set_reg("rip", rip)
    debugger.set_reg("efl", efl)

    debugger.put_bytes(inj, save)

    return brk_res
예제 #6
0
파일: brk.py 프로젝트: wy666444/angrdbg
def get_dbg_brk_linux32():
    '''
    Return the current brk value in the debugged process (only x86 Linux)
    '''
    # TODO this method is so weird, find a unused address to inject code not
    # the base address

    debugger = get_debugger()

    code = '\xcd\x80'  # int 0x80

    eax = debugger.get_reg("eax")
    ebx = debugger.get_reg("ebx")
    eip = debugger.get_reg("eip")
    efl = debugger.get_reg("efl")

    debugger.set_reg("eax", 45)  # sys_brk
    debugger.set_reg("ebx", 0)

    base = debugger.image_base()

    inj = base

    save = debugger.get_bytes(inj, len(code))

    debugger.put_bytes(inj, code)

    debugger.set_reg("eip", inj)

    debugger.step_into()
    debugger.wait_ready()

    brk_res = debugger.get_reg("eax")

    debugger.set_reg("eax", eax)
    debugger.set_reg("ebx", ebx)
    debugger.set_reg("eip", eip)
    debugger.set_reg("efl", efl)

    debugger.put_bytes(inj, save)

    return brk_res
예제 #7
0
파일: page.py 프로젝트: d4em0n/angrdbg
    def load_slice(self, state, start, end):
        """
        Return the memory objects overlapping with the provided slice.
        :param start: the start address
        :param end: the end address (non-inclusive)
        :returns: tuples of (starting_addr, memory_object)
        """
        items = [ ]
        if start > self._page_addr + self._page_size or end < self._page_addr:
            l.warning("Calling load_slice on the wrong page.")
            return items

        for addr in range(max(start, self._page_addr), min(end, self._page_addr + self._page_size)):
            i = addr - self._page_addr
            mo = self._storage[i]
            if mo is None and hasattr(self, "from_dbg"):
                byte_val = get_debugger().get_byte(addr)
                mo = SimMemoryObject(claripy.BVV(byte_val, 8), addr)
                self._storage[i] = mo
            if mo is not None and (not items or items[-1][1] is not mo):
                items.append((addr, mo))
        #print filter(lambda x: x != None, self._storage)
        return items
예제 #8
0
파일: core.py 프로젝트: wy666444/angrdbg
 def __init__(self, state=None):
     self.state = StateShot() if state is None else state
     self.symbolics = {}
     self.debugger = get_debugger()
예제 #9
0
파일: page.py 프로젝트: wy666444/angrdbg
    def _initialize_page(self, n, new_page):
        if n in self._initialized:
            return False
        self._initialized.add(n)

        new_page_addr = n * self._page_size
        initialized = False

        if self.state is not None:
            self.state.scratch.push_priv(True)

        # if self._memory_backer is None:
        #    pass

        project = load_project()
        debugger = get_debugger()

        # TODO handle simbolic address properly
        seg = None
        try:
            seg = debugger.seg_by_addr(new_page_addr)
        except BaseException:
            pass

        #print "LOADING 0x%x - 0x%x | 0x%x - 0x%x" % (new_page_addr, new_page_addr+self._page_size, seg.start, seg.end)

        if get_memory_type() == USE_CLE_MEMORY:  # yes this is weird

            if isinstance(self._memory_backer, cle.Clemory):
                # first, find the right clemory backer
                for addr, backer in self._memory_backer.cbackers if self.byte_width == 8 else (
                    (x, y) for x, _, y in self._memory_backer.stride_repr):
                    start_backer = new_page_addr - addr
                    if isinstance(start_backer, BV):
                        continue
                    if start_backer < 0 and abs(
                            start_backer) >= self._page_size:
                        continue
                    if start_backer >= len(backer):
                        continue

                    # find permission backer associated with the address
                    # fall back to read-write if we can't find any...
                    flags = DbgPage.PROT_READ | DbgPage.PROT_WRITE
                    for start, end in self._permission_map:
                        if start <= new_page_addr < end:
                            flags = self._permission_map[(start, end)]
                            break

                    snip_start = max(0, start_backer)
                    write_start = max(new_page_addr, addr + snip_start)
                    write_size = self._page_size - write_start % self._page_size

                    if self.byte_width == 8:
                        snip = _ffi.buffer(backer)[snip_start:snip_start +
                                                   write_size]
                        mo = SimMemoryObject(claripy.BVV(snip),
                                             write_start,
                                             byte_width=self.byte_width)
                        self._apply_object_to_page(n * self._page_size,
                                                   mo,
                                                   page=new_page)
                    else:
                        for i, byte in enumerate(backer):
                            mo = SimMemoryObject(claripy.BVV(
                                byte, self.byte_width),
                                                 write_start + i,
                                                 byte_width=self.byte_width)
                            self._apply_object_to_page(n * self._page_size,
                                                       mo,
                                                       page=new_page)

                    new_page.permissions = claripy.BVV(flags, 3)
                    initialized = True

            elif len(self._memory_backer) <= self._page_size:
                for i in self._memory_backer:
                    if new_page_addr <= i and i <= new_page_addr + self._page_size:
                        if isinstance(self._memory_backer[i],
                                      claripy.ast.Base):
                            backer = self._memory_backer[i]
                        elif isinstance(self._memory_backer[i], bytes):
                            backer = claripy.BVV(self._memory_backer[i])
                        else:
                            backer = claripy.BVV(self._memory_backer[i],
                                                 self.byte_width)
                        mo = SimMemoryObject(backer,
                                             i,
                                             byte_width=self.byte_width)
                        self._apply_object_to_page(n * self._page_size,
                                                   mo,
                                                   page=new_page)
                        initialized = True
            elif len(self._memory_backer) > self._page_size:
                for i in range(self._page_size):
                    try:
                        if isinstance(self._memory_backer[i],
                                      claripy.ast.Base):
                            backer = self._memory_backer[i]
                        elif isinstance(self._memory_backer[i], bytes):
                            backer = claripy.BVV(self._memory_backer[i])
                        else:
                            backer = claripy.BVV(self._memory_backer[i],
                                                 self.byte_width)
                        mo = SimMemoryObject(backer,
                                             new_page_addr + i,
                                             byte_width=self.byte_width)
                        self._apply_object_to_page(n * self._page_size,
                                                   mo,
                                                   page=new_page)
                        initialized = True
                    except KeyError:
                        pass

        # page from debugger
        try:
            if seg is not None:
                perms = 0
                if seg.perms & SEG_PROT_X:
                    perms += DbgPage.PROT_EXEC
                if seg.perms & SEG_PROT_W:
                    perms += DbgPage.PROT_WRITE
                if seg.perms & SEG_PROT_R:
                    perms += DbgPage.PROT_READ
                new_page.permissions = claripy.BVV(perms, 3)
                #print "permissions setted %x  %d" % (new_page_addr, perms)

                initialized = True
                setattr(new_page, "from_dbg", True)
        except Exception as ee:
            import traceback
            traceback.print_exc()

        if self.state is not None:
            self.state.scratch.pop_priv()
        return initialized