Ejemplo n.º 1
0
    def get_assembly(self, code):
        fil = tempfile.mkstemp(suffix='.S')[1]
        ofil = tempfile.mkstemp()[1]
        F1 = 'MAINKAPPA'
        F2 = 'MAINKAPPA_END'

        code = norm_ins(code)
        s = f'''
{'.THUMB' if self.thumb else ''}
.global {F1}
{F1}:
{code}

.global {F2}
{F2}:
'''

        open(fil, 'w').write(s)
        print('fil', fil, 'ofile', ofil)
        sp.check_call(f'{self.compiler} -c {self.opts} -o {ofil} {fil}'.format(
            **locals()),
                      shell=True)
        from chdrft.emu.elf import ElfUtils
        x = ElfUtils(ofil)
        f1 = x.get_symbol(F1)
        f2 = x.get_symbol(F2)
        data = x.get_range(f1, f2)
        return data
Ejemplo n.º 2
0
 def __init__(self, fname, mc, ofile=None, dry=False):
     from chdrft.emu.elf import ElfUtils
     self.elf_file = ElfUtils(fname)
     self.fname = fname
     self.mc = mc
     self.patches = []
     self.dry = dry
     self.ofile = ofile
Ejemplo n.º 3
0
class FilePatcher:
    def __init__(self, fname, mc, ofile=None, dry=False):
        from chdrft.emu.elf import ElfUtils
        self.elf_file = ElfUtils(fname)
        self.fname = fname
        self.mc = mc
        self.patches = []
        self.dry = dry
        self.ofile = ofile

    def apply(self):
        tgt_file = self.fname
        if self.ofile is not None:
            shutil.copy2(self.fname, self.ofile)
            tgt_file = self.ofile

        with open(tgt_file, 'r+b') as f:
            mm = mmap.mmap(f.fileno(), 0)
            for patch in self.patches:
                pos = patch.pos
                content = patch.content
                if self.dry:
                    before = mm[pos:pos + len(content)]
                    before_ins = self.mc.ins_str(
                        self.mc.get_ins(before, patch.addr))
                    next_ins = self.mc.ins_str(
                        self.mc.get_ins(content, patch.addr))
                    print('fuu ', next_ins, content)
                    print('Applying patch ', patch.to_dict(), next_ins,
                          'replaceing >> ', before_ins)
                else:
                    mm[pos:pos + len(content)] = content
            mm.close()

    def add_patch(self, pos, content, addr=0):
        assert pos is not None
        self.patches.append(Attributize(pos=pos, content=content, addr=addr))

    def patch(self, addr, content):
        self.add_patch(self.elf_file.get_pos(addr), content, addr=addr)

    def patch_one_ins(self, addr, content):
        one_ins = self.elf_file.get_one_ins(addr)

        if isinstance(content, str):
            content = self.mc.get_disassembly(content, addr=addr)

        assert len(content) <= len(
            one_ins.bytes), 'Cannot replace %s with %s(%s)' % (
                one_ins.bytes, one_ins.bytes, content)
        self.patch(addr,
                   Format(content).pad(len(one_ins.bytes), self.mc.nop[0]).v)

    def nop_ins(self, addr):
        return self.patch_one_ins(addr, b'')
Ejemplo n.º 4
0
 def get_entry_address(self):
   if 1:
     return ElfUtils(self.get_file_path()).get_entry_address()
   else:
     s = self.do_execute('info files')
     print(s)
     addr = self.entry_regex.search(s).group(1)
     return int(addr, 16)
Ejemplo n.º 5
0
def test_uc(ctx):
    ctx.stack_params = (2**30, 2**20)
    ctx.heap_params = (2**29, 2**20)
    kern, elf = load_kern(ctx)
    event_log = open('/tmp/evens_{}.out'.format(ctx.runid), 'w')
    vmop_log = open('/tmp/vmop_{}.out'.format(ctx.runid), 'w')
    kern.tracer.cb = lambda x: event_handle(x, event_log, vmop_log)
    ef = ElfUtils(ctx.binary)
    kern.tracer.diff_mode = False

    runner = KernelRunner(kern)
    caller = AsyncMachineCaller(runner, kern.arch, kern.regs, kern.mem)
    client = Client()
    fc = FuncCallWrapperGen(ef, code_db=client.g_code, caller=caller)

    bufacc = MemBufAccessor(kern.mem)
    bufgen = SimpleBufGen(bufacc.read, bufacc.write)
    allocator = DummyAllocator(ctx.heap_params[0], ctx.heap_params[1], bufgen)
    fcaller = AsyncFunctionCaller(allocator, fc)

    ctx.client = client
    handler = AsyncHandler(ctx, kern, fcaller)

    sol = get_sol(kern)
    open('./data.in', 'wb').write(struct.pack('<I', len(sol)) + sol)

    start_addr = elf.get_symbol('_start')

    kern.mu.hook_add(uc.UC_HOOK_CODE, kernel.safe_hook(handler), None,
                     start_addr, start_addr + 1)
    #kern.mu.hook_add(uc.UC_HOOK_CODE, kernel.safe_hook(handler), None, end_addr, end_addr+1)

    #input_addr = elf.get_symbol('opa_input')
    #output_addr = elf.get_symbol('opa_output')
    #kern.mem.write_u32(input_addr, 12)
    #kern.mem.write_u32(input_addr+4, 88)

    try:
        kern.start()
    except uc.UcError as e:
        print('%s' % e)
        tb.print_exc()

    #print(kern.mem.read(output_addr, 20))
    return
Ejemplo n.º 6
0
def test_uc(ctx):
    kern, elf = load_kern(ctx)
    event_log = open('/tmp/evens_{}.out'.format(ctx.runid), 'w')
    vmop_log = open('/tmp/vmop_{}.out'.format(ctx.runid), 'w')
    kern.tracer.cb = lambda x: event_handle(x, event_log, vmop_log)
    ef = ElfUtils(ctx.binary)
    kern.tracer.diff_mode = False
    solver = UCSolver(kern)
    global charset
    kern.ignore_mem_access = True

    clist = list([
        bytearray(x.rstrip(b'\n'))
        for x in open('./test.in', 'rb').readlines()
    ])
    solver.go(clist)

    #runner = KernelRunner(kern)
    #caller = AsyncMachineCaller(runner, kern.arch, kern.regs, kern.mem)
    #client = Client()
    #fc = FuncCallWrapperGen(ef, code_db=client.g_code, caller=caller)

    #bufacc = MemBufAccessor(kern.mem)
    #bufgen = SimpleBufGen(bufacc.read, bufacc.write)
    #allocator = DummyAllocator(ctx.heap_params[0], ctx.heap_params[1], bufgen)
    #fcaller = AsyncFunctionCaller(allocator, fc)
    #ctx.client = client
    #handler = AsyncHandler(ctx, kern, fcaller)

    #kern.mu.hook_add(uc.UC_HOOK_CODE, kernel.safe_hook(handler), None, start_addr, start_addr+1)
    #kern.mu.hook_add(uc.UC_HOOK_CODE, kernel.safe_hook(handler), None, end_addr, end_addr+1)

    try:
        kern.start()
    except uc.UcError as e:
        print('%s' % e)
        tb.print_exc()

    #print(kern.mem.read(output_addr, 20))
    return
Ejemplo n.º 7
0
def load_elf(kern, fil):
  assert fil
  if not isinstance(fil, ElfUtils):
    elf = ElfUtils(fil)
  else:
    elf = fil
  need_load = []
  for seg in elf.elf.iter_segments():
    s = Attributize(seg.header)
    print('GOT SEG ', hex(s.p_vaddr), hex(s.p_offset), s)
    if s.p_type == 'PT_LOAD' and s.p_memsz > 0:
      need_load.append(s)
  flag_mp = [
      (MEM_FLAGS.PF_X, uc.UC_PROT_EXEC),
      (MEM_FLAGS.PF_R, uc.UC_PROT_READ),
      (MEM_FLAGS.PF_W, uc.UC_PROT_WRITE),
  ]

  for s in need_load:
    flag_mem = 0
    for seg_flag, uc_flag in flag_mp:
      if seg_flag & s.p_flags:
        flag_mem = flag_mem | uc_flag

    flag_mem |= uc.UC_PROT_EXEC
    addr = s.p_vaddr
    sz = s.p_memsz
    align = s.p_align
    align = max(align, 4096)

    if s.p_paddr != 0:
      #base_addr = addr - s.p_offset
      base_addr = addr
      base_addr = base_addr - base_addr % align
    else:
      addr =base_addr = s.p_vaddr
    #base_addr = base_addr - addr % align
    seg_sz = sz + addr % align
    seg_sz = (sz + align - 1) & ~(align - 1)
    seg_sz = (seg_sz +4095) & ~4095

    print('LOADING ', flag_mem, hex(base_addr), hex(addr), seg_sz, hex(s.p_offset))
    kern.mem_map(base_addr, seg_sz, flag_mem)

    content = elf.get_seg_content(s)
    print('WRITTING ', hex(addr), len(content))
    kern.mu.mem_write(addr, content)

  kern.post_load()

  regs = kern.regs
  for note in elf.notes:
    if note.n_type != 'NT_PRSTATUS':
      continue
    print(len(note.status.raw))
    print(len(note.data))
    if kern.arch.typ == Arch.arm64:
      assert len(note.data) == 392
      buf = BufferParser(note.data[76+32+4:], arch=kern.arch)
      for i in range(31):
        regs[f'x{i}'] = buf.read_u64()
      regs.sp = buf.read_u64()
      regs.pc = buf.read_u64()
      regs.cpacr_el1 = buf.read_u64()
      glog.info(f'Loaded sp={regs.sp:x}, pc={regs.pc:x} cpacr={regs.cpacr_el1:x}')

      continue

    if 'status' in note:
      for r in note.status.pr_reg._fields:
        vx = r
        if not vx in regs:
          glog.info('could not load reg %s', r)
          continue
        v = note.status.pr_reg[r].get()
        regs[r] = v
      if kern.arch.typ == Arch.x86_64:
        fsbase = note.status.pr_reg.fs_base.get()
        gsbase = note.status.pr_reg.gs_base.get()
        kern.set_fs_base(fsbase)
        kern.set_gs_base(gsbase)
        assert kern.get_gs_base() == gsbase
        assert kern.get_fs_base() == fsbase

    print(note.status.pr_reg)

  return elf
Ejemplo n.º 8
0
  def LoadFrom(
      pe=None,
      elf=None,
      stack_params=None,
      heap_params=None,
      arch=None,
      hook_imports=False,
      orig_elf=None,
      qemu_state=None,
      bochs_state=None,
      base=0,
      core=False,
      **kwargs
  ):

    arch = norm_arch(arch)
    lib = None
    if elf:
      lib = ElfUtils(elf, core=core)
      if arch is None:
        arch = lib.arch
    elif qemu_state:
      assert arch is not None
      lib = qemu_state
    elif bochs_state:
      assert arch is not None
      lib = bochs_state
    elif pe:
      lib = pefile.PE(pe)
      assert arch is not None
    else:
      lib = None

    mu = uc.Uc(arch.uc_arch, arch.uc_mode)
    kern = Kernel(mu, arch, **kwargs)
    if elf:
      assert base == 0
      lib = load_elf(kern, lib)
      if not lib.core: kern.regs[arch.reg_pc] = lib.get_entry_address()
    elif qemu_state:
      lib = load_qemu_state(kern, lib)
    elif bochs_state:
      lib = load_bochs_state(kern, lib)
    elif pe:
      lib = load_pe(kern, lib, base=base)
    else:
      kern.post_load()

    kern.lib = lib

    if stack_params:
      print('MAPPING stack ', stack_params)
      if stack_params[1] < 0:
        stack_params = list(stack_params)
        stack_params[1] = -stack_params[1]
        stack_params[0] -= stack_params[1]
      self.mem_map(stack_params[0], stack_params[1], uc.UC_PROT_READ | uc.UC_PROT_WRITE)
      self.stack_seg = tuple(stack_params)

    if heap_params:
      print('MAPPING heap ', heap_params)
      self.heap_seg = tuple(self.heap_params)
      self.mem_map(heap_params[0], heap_params[1], uc.UC_PROT_READ | uc.UC_PROT_WRITE)

    if hook_imports:
      celf = elf
      if orig_elf: celf = ElfUtils(orig_elf)
      kern.hook_imports(celf.plt)
    kern.post_init()
    return kern, lib
Ejemplo n.º 9
0
 def get_elf(self):
   return ElfUtils(self.get_file_path())