def add_data_label(self):
     dataoff = self.section_addr('.data')
     rodataoff = self.section_addr('.rodata')
     for e in self.locations:
         n, l = e
         if n == '.data':
             self.data_list[l] = (dec_hex(l + dataoff),
                                  self.data_list[l][1])
         elif n == '.rodata':
             self.rodata_list[l] = (dec_hex(l + rodataoff),
                                    self.rodata_list[l][1])
 def doublemovARM(self, instrs):
     """
     insert labels for double mov operations
       movw r0, #0x102c -> movw r0, #:lower16:S_0x2102c
       movt r0, #0x2    -> movt r0, #:upper16:S_0x2102c
     :param instrs: instruction list
     """
     for i in self.ARMmovs:
         mw = list(instrs[i])
         destreg = mw[1]
         tindex = 1
         while tindex < config.ARM_maxDoublemovDist:
             # GCC optimizations causes movw and movt not to be close to each other
             currinstr = instrs[i + tindex]
             if currinstr[0].upper() == 'MOV' and currinstr[2] == destreg:
                 # Sometimes GCC changes idea and picks another register to load the address
                 destreg = instrs[i + tindex][1]
             elif currinstr[1] == destreg:
                 if currinstr[0].upper().split('.')[0] == 'STR':
                     # Some other times GCC wants to have even more fun and changes register using the stack
                     tindex += 1
                     while tindex < config.ARM_maxDoublemovDist:
                         if instrs[i + tindex][2] == currinstr[2]:
                             destreg = instrs[tindex + i][1]
                             break
                         tindex += 1
                 else:
                     break
             tindex += 1
         if tindex >= config.ARM_maxDoublemovDist: continue
         tindex = i + tindex
         mt = list(instrs[tindex])
         if mt[0].upper().startswith('MOVT') and mt[1] == destreg:
             val = (mt[2] << 16) + (mw[2] & 0xffff)
             s = self.check_sec(val)
             if s is not None:
                 s_label = 'S_' + dec_hex(val)
                 self.insert_data(s.sec_name, val)
                 mw[2] = Types.Label('#:lower16:' + s_label)
                 mt[2] = Types.Label('#:upper16:' + s_label)
                 instrs[i] = type(instrs[i])(mw)
                 instrs[tindex] = type(instrs[tindex])(mt)
             if self.check_text(val):
                 val = val & (-2)
                 s_label = 'S_' + dec_hex(val)
                 self.insert_text(s_label, val)
                 mw[2] = Types.Label('#:lower16:' + s_label)
                 mt[2] = Types.Label('#:upper16:' + s_label)
                 instrs[i] = type(instrs[i])(mw)
                 instrs[tindex] = type(instrs[tindex])(mt)
     self.ARMmovs = []
 def process(self):
     """
     Traverse instruction list and insert generated S_ labels in the correct positions
     """
     do_update = lambda s, n: s if n in s else s + '\n' + n
     des1 = self.clean_sort(self.des)
     i = 0
     j = 0
     while True:
         if j == len(des1) or i == len(self.locs):
             break
         # if i == len(self.locs)-1 and j == len(des1)-1:
         #    raise Exception("undefined des list")
         lh = self.locs[i]
         dh = des1[j]
         if dh == lh.loc_addr:
             lhs = 'S_' + dec_hex(lh.loc_addr)
             if ELF_utils.elf_arm() and not isinstance(
                     self.instr_list[i][0], Types.InlineData):
                 lhs = '.thumb_func\n' + lhs
             label = do_update(lh.loc_label, lhs + ' : ')
             self.locs[i].loc_label = label
             j += 1
         elif dh < lh.loc_addr:
             i -= 1
             j += 1
         i += 1
Beispiel #4
0
 def update(self):
     func = 'S_' + dec_hex(self.baddr)
     if func in self.func_set:
         self.func_set[func].func_begin_addr = self.baddr
         self.func_set[func].func_end_addr = self.eaddr
         self.func_set[func].is_lib = False
     else:
         f1 = Func(func, self.baddr, self.eaddr, False)
         self.func_set[func] = f1
 def data_dump(self, funcs):
     """
     Analyze data sections and save them to file
     :param funcs: function list
     """
     t = self.label + self.export_data_dump()
     p = datahandler(t)
     p.text_sec_collect()
     p.set_datas(funcs)
     self.jmpreflist = map(lambda l: 'S_' + dec_hex(l), p.get_textlabel())
     p.data_output()
Beispiel #6
0
 def v_exp(self, e):
     """
     Check if PC relative expression and transform using labels
     :param e: expression
     :return: transformed expression if matching, original one otherwise
     """
     if isinstance(e, (Types.BinOP_PLUS, Types.BinOP_MINUS)):
         r1, addr = e
         if r1.upper() in self.curr_regs:
             addr = -addr if isinstance(e, Types.BinOP_MINUS) else addr
             des = self.gotaddr + addr
             s = self.check_sec(des)
             if s is not None:
                 self.label.append(des)
                 return Types.Label('S_' + dec_hex(des))
     return e
    def gotexternals(self):
        """
        Replace external symbols in .got
        """
        with open('gotglobals.info') as f:

            def mapper(l):
                items = l.split()
                return (int(items[0], 16), items[1].split('@')[0])

            syms = sorted(map(mapper, f), key=lambda e: e[0])
        gotsec = self.sec['.got']
        datatype = '.long ' if ELF_utils.elf_32() else '.quad '
        skiplen = 3 if ELF_utils.elf_32() else 7
        syms = filter(
            lambda s: gotsec.sec_begin_addr <= s[0] < gotsec.sec_begin_addr +
            gotsec.sec_size, syms)
        for s in syms:
            off = s[0] - gotsec.sec_begin_addr
            self.got_list[off] = ('S_' + dec_hex(s[0]) + ': ', datatype + s[1])
            self.got_list[off + 1:off + 1 + skiplen] = [('', '')] * skiplen
 def process(self, lbs, withoff=False):
     """
     Add labels in the corresponding addresses of data sections
     :param lbs: list of tuples (section name, absolute address or offset)
     :param withoff: if True lbs contains absolute addresses
     """
     ds = {
         '.data': self.data_list,
         '.rodata': self.rodata_list,
         '.got': self.got_list,
         '.bss': self.bss_list
     }
     for i in xrange(len(lbs)):
         n, l = lbs[i]
         if n in ds:
             if withoff:
                 off = l - self.section_addr(n)
             else:
                 off = l
                 l += self.section_addr(n)
             ds[n][off] = ('S_' + dec_hex(l) + ': ', ds[n][off][1])
 def v_exp2(self, exp, instr, f, chk):
     """
     Analyze expression and determine if it represent an address.
     If so substitute if with a corresponding symbolic expression using labels
     :param exp: expression
     :param instr: instruction tuple to which the expression belongs to
     :param f: unused
     :param chk: True if instruction is TEST (x86)
     :return: modified expression if matching, original one otherwise
     """
     if isinstance(exp, Types.Const):
         if isinstance(exp, Types.Normal) and chk: return exp
         s = self.check_sec(exp)
         if s is not None:
             self.insert_data(s.sec_name, exp)
             return Types.Label(self.build_symbol(exp))
         if self.check_text(exp):
             if ELF_utils.elf_arm(): exp = type(exp)(exp & (-2))
             s_label = self.build_symbol(exp)
             self.insert_text(s_label, exp)
             return Types.Label(s_label)
         if self.check_plt(exp):
             return Types.Label(self.build_plt_symbol(exp))
     elif isinstance(exp, Types.Symbol):
         if isinstance(exp, Types.JumpDes):
             if self.check_text(exp):
                 s_label = 'S_' + dec_hex(exp)
                 self.insert_text(s_label, exp)
                 return Types.Label(s_label)
             elif self.check_plt(exp) and exp in self.plt_hash:
                 return Types.Label(self.plt_hash[exp])
         elif isinstance(exp, Types.StarDes):
             return Types.StarDes(self.v_exp2(exp.content, instr, f, chk))
         elif isinstance(exp, Types.CallDes):
             if exp.func_name.startswith('S_0'):
                 addr = int(exp.func_name[2:], 16)
                 if self.check_text(addr):
                     s_label = 'S_' + dec_hex(addr)
                     self.insert_text(s_label, addr)
                     return Types.Label(s_label)
                 elif self.check_plt(addr):
                     off = 0
                     while not self.plt_hash.get(addr - off, None):
                         off += 2
                     return Types.Label(self.plt_hash[addr - off])
             else:
                 self.symbol_list.insert(0, exp.func_begin_addr)
     elif isinstance(exp, Types.Ptr):
         if isinstance(exp, (Types.BinOP_PLUS, Types.BinOP_MINUS)):
             r, addr = exp
             s = self.check_sec(addr)
             if s is not None:
                 s_label = 'S_' + dec_hex(addr)
                 self.insert_data(s.sec_name, addr)
                 return Types.BinOP_PLUS_S((r, s_label)) \
                     if isinstance(exp, Types.BinOP_PLUS) \
                     else Types.BinOP_MINUS_S((r, s_label))
         elif isinstance(exp, (Types.FourOP_PLUS, Types.FourOP_MINUS)):
             r1, r2, off, addr = exp
             s = self.check_sec(addr)
             if s is not None:
                 s_label = 'S_' + dec_hex(addr)
                 self.insert_data(s.sec_name, addr)
                 return Types.FourOP_PLUS_S((r1,r2,off,s_label)) \
                     if isinstance(exp, Types.FourOP_PLUS) \
                     else Types.FourOP_MINUS_S((r1,r2,off,s_label))
         elif isinstance(exp, Types.JmpTable_PLUS):
             addr, r, off = exp
             s = self.check_sec(addr)
             if s is not None:
                 s_label = 'S_' + dec_hex(addr)
                 self.insert_data(s.sec_name, addr)
                 return Types.JmpTable_PLUS_S((s_label, r, off))
             if self.check_text(addr):
                 s_label = 'S_' + dec_hex(addr)
                 self.insert_text(s_label, addr)
                 return Types.JmpTable_PLUS_S((s_label, r, off))
         elif isinstance(exp, Types.JmpTable_MINUS):
             addr, r, off = exp
             s = self.check_sec(addr)
             if s is not None:
                 s_label = '-S_' + dec_hex(addr)
                 self.insert_data(s.sec_name, addr)
                 return Types.JmpTable_MINUS_S((s_label, r, off))
             if self.check_text(addr):
                 s_label = '-S_' + dec_hex(addr)
                 self.insert_text(s_label, addr)
                 return Types.JmpTable_MINUS_S((s_label, r, off))
     return exp
Beispiel #10
0
 def build_symbol(self, c):
     if isinstance(c, Types.Point):
         return 'S_' + dec_hex(c)
     elif isinstance(c, Types.Normal):
         return reassemble.normal_char + 'S_' + dec_hex(c)
Beispiel #11
0
 def dump_c2d_labels(self, dl):
     with open('final_c2d_label.txt', 'a') as f:
         f.write('\n'.join(map(lambda e: e[0] + ' : ' + dec_hex(e[1]), dl)))
         f.write('\n')
Beispiel #12
0
 def print_cfi_specified_graph(self):
     self.cfi_specified_tbl()
     for k, v in self.cfi_tbl.iteritems():
         print k
         for l in v:
             print '    ' + dec_hex(l)
Beispiel #13
0
 def print_cg_graph(self):
     for k, v in self.cfi_tbl.iteritems():
         sys.stdout.write(dec_hex(k))
         for f in v:
             print '    ' + f.func_name
Beispiel #14
0
 def func_info(self, l):
     for h in self.funcs:
         if h.func_begin_addr <= l.loc_addr < h.func_end_addr:
             return h
     raise Exception(
         dec_hex(l.loc_addr) + ': cannot find corresponding function')