def StateShot(): idc.RefreshDebuggerMemory() project = load_project() mem = SimSymbolicIdaMemory(memory_backer=project.loader.memory, permissions_backer=None, memory_id="mem") state = project.factory.blank_state(plugins={"memory": mem}) for reg in sorted(project.arch.registers, key=lambda x: project.arch.registers.get(x)[1]): if reg in ("sp", "bp", "ip"): continue try: setattr(state.regs, reg, idc.GetRegValue(reg)) except: pass ## inject code to get brk if we are on linux x86/x86_64 if project.simos.name == "Linux": if project.arch.name in ("AMD64", "X86"): state.posix.set_brk(get_linux_brk()) return state
def sim(self, key, size=None): ''' key: memory address(int) or register name(str) size: size of object in bytes ''' project = load_project() if key in project.arch.registers: if size == None: size = project.arch.registers[key][1] size *= 8 s = claripy.BVS("idangr_reg_" + str(key), size) setattr(self.state.regs, key, s) self.symbolics[key] = (s, size) elif type(key) == int or type(key) == long: if size == None: size = project.arch.bits else: size *= 8 s = claripy.BVS("idangr_mem_" + hex(key), size) self.state.memory.store(key, s) self.symbolics[key] = (s, size) elif type(key) == claripy.ast.bv.BV: key = self.state.solver.eval(key, cast_to=int) self.sim(key, size) else: raise ValueError( "key must be a register name or a memory address, not %s" % str(type(key)))
def __setitem__(self, key, value): if key in load_project().arch.registers: setattr(self.state.regs, key, value) elif type(key) == int or type(key) == long or type( key) == claripy.ast.bv.BV: self.state.memory[key] = value else: raise ValueError("key must be a register name or a memory address")
def __setitem__(self, key, value): if key in load_project().arch.registers: setattr(self.state.regs, key, value) elif isinstance(key, int) or isinstance(key, long) or isinstance( key, claripy.ast.bv.BV): self.state.memory[key] = value else: raise ValueError("key must be a register name or a memory address")
def __getitem__(self, key): if key in load_project().arch.registers: return getattr(self.state.regs, key) elif type(key) == int or type(key) == long: return self.state.mem[key] elif type(key) == claripy.ast.bv.BV: return self.state.mem[key] else: raise ValueError("key must be a register name or a memory address")
def get_registers(): project = load_project() regs = {} for reg in sorted(project.arch.registers, key=lambda x: project.arch.registers.get(x)[1]): if reg in ("sp", "bp", "ip"): continue try: regs[reg] = debugger.get_reg(reg) except BaseException: pass return regs
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
def to_dbg(self, found_state): if isinstance(found_state, StateManager): return self.to_dbg(found_state.state) for key in self.symbolics: try: if key in load_project().arch.registers: r = found_state.solver.eval(self.symbolics[key][0], cast_to=int) self.debugger.set_reg(key, r) else: r = found_state.solver.eval(self.symbolics[key][0], cast_to=str) self.debugger.put_bytes(key, r) except Exception as ee: print " >> failed to write %s to debugger" % key
def to_dbg(self, found_state): if type(found_state) == StateManager: return self.to_dbg(found_state.state) for key in self.symbolics: try: if key in load_project().arch.registers: r = found_state.solver.eval(self.symbolics[key][0], cast_to=int) idc.SetRegValue(r, key) else: r = found_state.solver.eval(self.symbolics[key][0], cast_to=str) for i in xrange(len(r)): idc.PatchByte(key + i, ord(r[i])) except Exception as ee: print " >> failed to write %s to debugger" % key
def concretize(self, found_state): if type(found_state) == StateManager: return self.concretize(found_state.state) ret = {} for key in self.symbolics: try: if key in load_project().arch.registers: r = found_state.solver.eval(self.symbolics[key][0], cast_to=int) ret[key] = r else: r = found_state.solver.eval(self.symbolics[key][0], cast_to=str) ret[key] = r except Exception as ee: print " >> failed to concretize %s" % key #print ee return ret
def simulation_manager(self): return load_project().factory.simulation_manager(self.state)
def sim_from_set(self, simset): for key in simset.symbolics: if key in load_project().arch.registers: setattr(self.state.regs, key, simset.symbolics[key][0]) else: self.state.memory.store(key, simset.symbolics[key][0])
def dict_ddg(function_addr): project = load_project() cfg = project.analysis.CFGAccurate(start=function_addr, context_sensitivity_level=2, keep_state=True)) ddg = project.analysis.DDG(cfg)
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() #print "LOADING 0x%x" % new_page_addr if get_memory_type() == TEXT_SIMPROCS_FROM_LOADER or ( get_memory_type() == ONLY_SIMPROCS_FROM_LOADER and idc.SegName(new_page_addr) == project.arch.got_section_name): #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 = IdaPage.PROT_READ | IdaPage.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: seg = idaapi.getseg( new_page_addr) ### CHANGE TO SUPPORT OTHER DEBUGGERS if seg is not None: perms = 0 if seg.perm & idaapi.SEGPERM_EXEC: perms += IdaPage.PROT_EXEC if seg.perm & idaapi.SEGPERM_WRITE: perms += IdaPage.PROT_WRITE if seg.perm & idaapi.SEGPERM_READ: perms += IdaPage.PROT_READ new_page.permissions = claripy.BVV(perms, 3) #print "permissions setted %x %d" % (new_page_addr, perms) initialized = True setattr(new_page, "from_ida_dbg", True) except Exception as ee: import traceback traceback.print_exc() if self.state is not None: self.state.scratch.pop_priv() return initialized
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