def recoverAlgorithm(self): if self.normalIRCFG is None: self.getNormalIRCFG() newLocDB = LocationDB() size = BinaryAnalysis.disasmEngine.attrib newIRA = BinaryAnalysis.iraType(newLocDB) newIRCFG = newIRA.new_ircfg() numLockey = 0 head = LocKey(numLockey) todo = [(self.address, head, {}, None)] numLockey += 1 while todo: nextTarget, lockey, state, preBlock = todo.pop() nextTarget, state = self.symbolicExecution(self.normalIRA, self.normalIRCFG, nextTarget, state) if isinstance(nextTarget, ExprCond): newLockey1 = LocKey(numLockey) newLockey2 = LocKey(numLockey + 1) ir_dst = state[newIRCFG.IRDst] new_cond = ExprCond(ir_dst.cond, ExprLoc(newLockey1, size), ExprLoc(newLockey2, size)) state[newIRCFG.IRDst] = new_cond numLockey += 2 newIRBlock = self.addIRBlock(newIRCFG, state, lockey) state[newIRCFG.IRDst] = ir_dst todo.append((nextTarget.src1, newLockey1, state, newIRBlock)) todo.append((nextTarget.src2, newLockey2, state, newIRBlock)) else: self.addIRBlock(newIRCFG, state, lockey) return newLocDB, newIRCFG
def _solve_loop(self, empty_address, recognizer, file_path, conn=None, val=None): func = recognizer.asmcfg deflattener = CFFSolver(recognizer) new_head = deflattener.process(self._pending, val, self._reached_funcs) if val: val = int(val) if not new_head: local_mapping = "skipping 0x%08x with val %s: %s\n" % (func.func_addr, recognizer.merging_var, hex(val or 0x0BADF00D)) print("%s" % local_mapping, end="") return empty_address local_mapping = "0x%08x -> 0x%08x with val %s: %s\n" % (func.func_addr, empty_address, recognizer.merging_var, hex(val or 0x0BADF00D)) print("mapping: %s" % local_mapping, end="") deflattener.out_asmcfg.loc_db.set_location_offset(LocKey(0), empty_address, True) new_addr = write_patches_to_file(deflattener.out_asmcfg, func.exectbl, empty_address, file_path, func.mode, 2 ** 64 - 1, new_head) if conn: conn.modules.idaapi.reload_file(conn.modules.idaapi.get_input_file_path(), 0) conn.modules.ida_funcs.add_func(new_addr) return new_addr
def add_location(self, name=None, offset=None, strict=True): """Add a new location in the locationDB. Returns the corresponding LocKey. If @name is set, also associate a name to this new location. If @offset is set, also associate an offset to this new location. Strict mode (set by @strict, default): If a location with @offset or @name already exists, an error will be raised. Otherwise: If a location with @offset or @name already exists, the corresponding LocKey may be updated and will be returned. """ name = force_bytes(name) # Deprecation handling if is_int(name): assert offset is None or offset == name warnings.warn( "Deprecated API: use 'add_location(offset=)' instead." " An additional 'name=' can be provided to also " "associate a name (there is no more default name)") offset = name name = None # Argument cleaning offset_loc_key = None if offset is not None: offset = int(offset) offset_loc_key = self.get_offset_location(offset) # Test for collisions name_loc_key = None if name is not None: name_loc_key = self.get_name_location(name) if strict: if name_loc_key is not None: raise ValueError("An entry for %r already exists (%r), and " "strict mode is enabled" % (name, name_loc_key)) if offset_loc_key is not None: raise ValueError("An entry for 0x%x already exists (%r), and " "strict mode is enabled" % (offset, offset_loc_key)) else: # Non-strict mode if name_loc_key is not None: known_offset = self.get_offset_location(name_loc_key) if known_offset is None: if offset is not None: self.set_location_offset(name_loc_key, offset) elif known_offset != offset: raise ValueError( "Location with name '%s' already have an offset: 0x%x " "(!= 0x%x)" % (name, offset, known_offset)) # Name already known, same offset -> nothing to do return name_loc_key elif offset_loc_key is not None: if name is not None: # Check for already known name are checked above return self.add_location_name(offset_loc_key, name) # Offset already known, no name specified return offset_loc_key # No collision, this is a brand new location loc_key = LocKey(self._loc_key_num) self._loc_key_num += 1 self._loc_keys.add(loc_key) if offset is not None: assert offset not in self._offset_to_loc_key self._offset_to_loc_key[offset] = loc_key self._loc_key_to_offset[loc_key] = offset if name is not None: self._name_to_loc_key[name] = loc_key self._loc_key_to_names[loc_key] = set([name]) return loc_key
def parse_loc_key(t): assert len(t) == 2 loc_key, size = LocKey(t[0]), t[1] return ExprLoc(loc_key, size)
from __future__ import print_function from miasm.expression.parser import str_to_expr from miasm.expression.expression import ExprInt, ExprId, ExprSlice, ExprMem, \ ExprCond, ExprCompose, ExprOp, ExprAssign, ExprLoc, LocKey for expr_test in [ExprInt(0x12, 32), ExprId('test', 32), ExprLoc(LocKey(12), 32), ExprSlice(ExprInt(0x10, 32), 0, 8), ExprMem(ExprInt(0x10, 32), 32), ExprCond(ExprInt(0x10, 32), ExprInt(0x11, 32), ExprInt(0x12, 32)), ExprCompose(ExprInt(0x10, 16), ExprInt(0x11, 8), ExprInt(0x12, 8)), ExprInt(0x11, 8) + ExprInt(0x12, 8), ExprAssign(ExprId('EAX', 32), ExprInt(0x12, 32)), ]: print('Test: %s' % expr_test) assert str_to_expr(repr(expr_test)) == expr_test