示例#1
0
文件: elf.py 项目: adc/rcos-binstat
 def lookup_rel(target, r, symtab, strtab):
   r_type  = r.r_info & 0xff
   pos = r.r_info >> 8
   addr = r.r_offset
   
   symbol = Elf32Sym( target.memory.getrange(symtab+pos*16 ,   symtab+pos*16 + 16))
   if(symbol.st_name):
     string_ptr = symbol.st_name + strtab      
     name = util.pull_ascii(target.memory, string_ptr)
     return name
   else:
     return "!unknown"
示例#2
0
def transform(arch, callgraph, bin):
  sg = callgraph.keys()
  sg.sort()
  
  constant_regs = arch.get_analysis_constant_regs(bin)
  
  for r in arch.registers:
    if "stack" in r.aliases:
      stack_reg = r
    elif "pc" in r.aliases:
      pc_reg = r
  
  for func in sg:
    for block in callgraph[func]:
      for instr in block.code:
        aux_loc = block.code.index(instr)
        
        if instr.type == 'operation':
          #check for stack assignment operation
          if len(instr.ops) > 2:
            if instr.ops[1] == '=':
              reg_name = str(instr.ops[0].register_name)
              if reg_name in block.ssa_vals:

                #here we look at addr+1 because we're interested in the result after
                # this instruction
                values = block.ssa_vals[reg_name].get_states(instr.address, aux_loc+1)
                out = ""
                for value in values:
                  if isinstance(value, int):
                    if value in bin.memory:
                      data = util.pull_ascii(bin.memory, value)
                      if len(data) > 1:
                        out +=  ' @@@@@  ' + `data` + '\n'
                  else:
                    n = []
                    for v in values:
                      #dont print out if unresolved remain
                      if isinstance(v, ssa.ssa_state):
                        if None not in v.eval():
                          n += ['{'+",".join(str(x) for x in v.eval())+'}']
                        else:
                          n += [str(v)]
                      else:
                        n += [str(v)]
                    out += str(n)
                instr.annotation += " "*20 + out
                      
        elif instr.type == 'load':
          src_addrs = block.ssa_vals[str(instr.src.register_name)].get_values(instr.address, aux_loc)
          if None in src_addrs:
            src_addrs = block.ssa_vals[str(instr.src.register_name)].get_states(instr.address, aux_loc)
          
          for src_addr in src_addrs:
            if isinstance(src_addr,int):
              addr = src_addr
              #update on load
              if addr in bin.memory and addr+instr.size in bin.memory:
                sizemap = {1: 'B', 2: 'H', 4: 'L', 8: 'Q'}
                value = struct.unpack(arch.endianness + "%s"%sizemap[instr.size], bin.memory.getrange(addr, instr.size+addr))[0]
                value = "%d"%value
                if value in bin.memory:
                  data = util.pull_ascii(bin.memory, value)
                  if len(data) > 1:
                    value = data
                instr.annotation = "%%%% (%s) <- addr_%x"%(value,addr)
            else:
              instr.annotation = " "*10+"%s <- addr_[%s]"%(instr.dest, src_addr)
                
            
        elif instr.type == 'store':

          if instr.src.type == 'register':
            src_name = str(instr.src.register.register_name)
            src_addrs = block.ssa_vals[src_name].get_values(instr.address, aux_loc)
            if None in src_addrs:
              src_addrs = block.ssa_vals[src_name].get_states(instr.address, aux_loc) 
          else:
            src_addrs = [instr.src.value]

          if instr.dest.type == 'register':
            dest_addrs = block.ssa_vals[str(instr.dest.register.register_name)].get_values(instr.address, aux_loc)
            if None in dest_addrs:
              dest_addrs = block.ssa_vals[str(instr.dest.register.register_name)].get_states(instr.address, aux_loc) 
          else:
            dest_addrs = [instr.dest.value]
          
          o = ""
          for src_addr in src_addrs:
            for dest_addr in dest_addrs:
              o += " "*20 + " %s -> %s OR\n"%(src_addr, dest_addr)
          o = o[:-3]
          instr.annotation = o

        elif instr.type == 'call' or instr.type == 'jump':
          libcall_transform(arch, block.ssa_vals, instr, aux_loc)
示例#3
0
文件: elf.py 项目: adc/rcos-binstat
def mips_resolve_external_funcs(target):
  #XXX this is irix specific right now
  funcs = {}
  
  addr = 0
  for phdr in target.binformat.Phdrs:
    if phdr.type == PT_DYNAMIC:
      addr = phdr.vaddr
      break
  
  strsz = None
  strtab = None
  symtab = None
  dthash = None
  pltgot = None
  Edyn = Elf32Dyn(target.memory.getrange(addr, addr+8), target.binformat.endianness)
  
  while Edyn.d_tag != DT_NULL:
    #print hex(addr),'>>>>=    ',hex(Edyn.d_tag), hex(Edyn.d_val)
    if Edyn.d_tag == DT_STRTAB:
      strtab = Edyn.d_val
      #print "STRTAB"
    elif Edyn.d_tag == DT_SYMTAB:
      symtab = Edyn.d_val
      #print "SYMTAB", hex(symtab)
    elif Edyn.d_tag == DT_HASH:
      dthash = Edyn.d_val
      #print "HASH"
    elif Edyn.d_tag == DT_STRSZ:
      strsz = Edyn.d_val
      #print "STRSZ"
    elif Edyn.d_tag == DT_PLTGOT:
      pltgot = Edyn.d_val
    elif Edyn.d_tag == 0x7000000a:
      localgotno = Edyn.d_val
    elif Edyn.d_tag == 0x70000011:
      symtabno = Edyn.d_val
    elif Edyn.d_tag == 0x70000013:
      gotsym = Edyn.d_val
    addr += 8
    Edyn = Elf32Dyn(target.memory.getrange(addr, addr+8), target.binformat.endianness)
  
  #BUGCHECK this is pulled together from comparing
  # a bunch of different irix binaries with elfdump + elfls + objdump
  addr = symtab+16
  Esym = Elf32Sym(target.memory.getrange(addr, addr+16), target.binformat.endianness)
  i = 1
  while Esym.st_name != 0:

    if i >= gotsym:
      entry_addr = (localgotno+i-gotsym)*4+pltgot
      
      value = struct.unpack(">L", target.memory.getrange(entry_addr, entry_addr+4))[0]
      
      #print "=>>>>", util.pull_ascii(target.memory, strtab+Esym.st_name), hex(Esym.st_size),\
      #              hex(Esym.st_value), hex(Esym.st_info), hex(Esym.st_other),\
      #              hex(Esym.st_shndx), "%x %x"%(addr, value)
      
      funcs[value] = util.pull_ascii(target.memory, strtab+Esym.st_name)
      
    i += 1
    addr += 16
    Esym = Elf32Sym(target.memory.getrange(addr, addr+16), target.binformat.endianness)
  
  return funcs