def append_segment(segment_name): """ Add a new segment to the IDB file and return its starting address. Information about function arguments will be stored here. Only works if the segment name is not used yet. This does not affect the original binary. Arguments: segment_name -- the name of the segment to be added """ for segment in idautils.Segments(): if idc.SegName(segment) == segment_name: g_logger.warning('Segment ' + segment_name + ' already exists') return idc.SegStart(segment) new_segment_start = get_end_of_last_segment() g_logger.debug('Adding new segment at 0x%08x' % new_segment_start) if not idc.AddSeg(new_segment_start, (new_segment_start + NEW_SEGMENT_SIZE), 0, 1, 0, idaapi.scPub) == 1: raise FailedToAppendSegmentException('Could not add segment') # set new segment's attributes if not idc.RenameSeg(new_segment_start, segment_name): raise FailedToAppendSegmentException('Could not rename segment') if not idc.SetSegClass(new_segment_start, 'DATA'): raise FailedToAppendSegmentException('Could not set segment class') if not idc.SegAlign(new_segment_start, idc.saRelPara): raise FailedToAppendSegmentException('Could not align segment') if not idc.SetSegAddressing(new_segment_start, 1): # 1 -- 32 bit raise FailedToAppendSegmentException( 'Could not set segment addressing') return new_segment_start
def main(argv=None): if argv is None: argv = sys.argv[:] try: seg = prompt_for_segment() except BadInputError: logger.error('bad input, exiting...') return -1 with open(seg.path, 'rb') as f: buf = f.read() seglen = len(buf) if seglen % 0x1000 != 0: seglen = seglen + (0x1000 - (seglen % 0x1000)) if not idc.AddSeg(seg.addr, seg.addr + seglen, 0, 1, 0, idaapi.scPub): logger.error('failed to add segment: 0x%x', seg.addr) return -1 if not idc.RenameSeg(seg.addr, seg.name): logger.warning('failed to rename segment: %s', seg.name) if not idc.SetSegClass(seg.addr, 'CODE'): logger.warning('failed to set segment class CODE: %s', seg.name) if not idc.SegAlign(seg.addr, idc.saRelPara): logger.warning('failed to align segment: %s', seg.name) idaapi.patch_many_bytes(seg.addr, buf)
def __to_native(self, function, is_recursive_mode=False, fixupfile=None): """ Process translating VM byte code to native machine code :param function: Function descriptor :param is_recursive_mode: Enable recursive mode :param fixupfile: Path to fixup file :return: Address of new segment where were native code wrote """ print "[+] Translate begin. Function %s" % hex(function.begin_ea) ks = None if self.mode == 32: ks = Ks(KS_ARCH_X86, KS_MODE_32) else: ks = Ks(KS_ARCH_X86, KS_MODE_64) locs = { function.graph.nodes[na].begin_ea for na in function.graph.nodes } func_addresses = [] for x in function.graph.nodes: for y in range( function.graph.nodes[x].begin_ea, function.graph.nodes[x].end_ea + self.instruction_size, self.instruction_size): func_addresses.append(y) func_ins = {x: self.instructions[x] for x in func_addresses} vr0x86_blocks = self.get_vr0blocks(func_ins) print "[+] Blocks for %s" % hex(function.begin_ea).replace("L", "") i = 0 for pc in vr0x86_blocks.keys(): c_vr0, c_end_vr0_block = vr0x86_blocks[pc] print "----BLOCK %s----" % i print " -> [?] Block begin: %s" % hex(pc).replace("L", "") print " -> [?] Block end: %s" % hex(c_end_vr0_block).replace( "L", "") print " -> [?] Block vr0: %s" % c_vr0 i += 1 labels = {} li = 0 for loc in locs: labels[loc] = "label_%s" % li li += 1 function_real_base = function.machine_handler print "[+] Real function base: %s" % hex(function_real_base).replace( "L", "") if self.mode == 32: asm_text = self._asm_creator_x86( func_ins, labels, vr0x86_blocks, function.machine_handler, is_recursive_mode=is_recursive_mode, fixupfile=fixupfile) else: asm_text = self._asm_creator_x64( func_ins, labels, vr0x86_blocks, function.machine_handler, is_recursive_mode=is_recursive_mode, fixupfile=fixupfile) print asm_text segs = list(idautils.Segments()) last_seg_ea = idc.SegEnd(segs[len(segs) - 1]) encoding, count = ks.asm(asm_text, addr=last_seg_ea) seg_name = ".devirt_%s" % function.name seg_size = len(encoding) + self.machine_word_size if not idc.AddSeg(last_seg_ea, last_seg_ea + seg_size, 0, 1, 0, idaapi.scPub): print "[~] Can't create segment at address %s" % hex(last_seg_ea) return if not idc.RenameSeg(last_seg_ea, seg_name): print "[!] Failed rename segment. Segment name %s" % seg_name if not idc.SetSegClass(last_seg_ea, 'CODE'): print "[!] Failed set CODE class. Segment name %s" % seg_name if not idc.SegAlign(last_seg_ea, idc.saRelPara): print "[!] Failed set align. Segment name %s" % seg_name bitness = 1 if self.mode == 64: bitness = 2 if not idc.SetSegAddressing(last_seg_ea, bitness): print "[!] Failed set bitness. Segment name %s" % seg_name if self.mode == 32: idc.PatchDword(last_seg_ea, 0) else: idc.PatchQword(last_seg_ea, 0) last_seg_ea += self.machine_word_size waddr = last_seg_ea for b in encoding: idc.PatchByte(waddr, b) waddr += 1 print "[+] Write binary to: %s" % hex(last_seg_ea).replace("L", "") self.devirtualized_functions[function.begin_ea] = (last_seg_ea, len(encoding) + 4) return last_seg_ea