def update_cfd(self, index, instrlist):
     if not self.looking_for_cfd: return
     tl = instrlist[index:index + 5]
     inv = lambda i: get_loc(i).loc_addr in self.locs
     if not any(map(inv, tl)):
         self.looking_for_cfd = False
         self.update_trimtbl(self.up_bound.loc_addr,
                             get_loc(tl[0]).loc_addr)
 def vinst(self, i):
     loc = get_loc(i)
     if self.skip_entry:
         if loc.loc_addr == self.end_loc.loc_addr:
             bn = 'BB_' + str(cfg.counter)
             cfg.counter += 1
             b = Types.Bblock('', bn, loc, loc, i)
             self.bb_list.insert(0, b)
         else:
             self.entry_loc = loc
             self.entry_instr = i
             self.found_entry = True
             self.skip_entry = False
             self.last_loc = loc
             return self.help_exit(
                 i) if Opcode_utils.is_control_transfer_op(i[0]) else i
     elif loc.loc_addr == self.end_loc.loc_addr:
         return self.help_exit(i)
     elif self.bb_entry(i):
         self.help_entry(i)
         return self.help_exit(i) if Opcode_utils.is_control_transfer_op(
             i[0]) else i
     elif isinstance(
             i,
         (Types.DoubleInstr, Types.SingleInstr)) and self.bb_exit(i[0]):
         return self.help_exit(i)
     self.last_loc = loc
     return i
 def visit(self, instrlist):
     self.locs = filter(
         lambda i: self.invalid_opcode(i) or self.invalid_transfer(i),
         instrlist)
     self.locs = map(lambda i: get_loc(i).loc_addr, self.locs)
     if len(self.locs) != 0: self.validate(instrlist)
     return instrlist
 def unify_loc(self, instrs):
     last_label = ''
     for i in xrange(len(instrs)):
         lo = get_loc(instrs[i])
         if lo.loc_label != '' and lo.loc_label == last_label:
             instrs[i] = set_loc(instrs[i],
                                 Types.Loc('', lo.loc_addr, True))
         else:
             last_label = lo.loc_label
     return instrs
 def build_func_info(self):
     self.func_begins = unify_int_list(self.func_begins)
     self.func_begins = self.filter_addr_by_secs(self.func_begins)
     for i in range(len(self.func_begins)-1):
         self.baddr = self.func_begins[i]
         self.eaddr = self.func_begins[i+1]
         self.update()
     self.baddr = self.func_begins[-1]
     self.eaddr = get_loc(self.instrs[0]).loc_addr
     self.update()
 def help_entry(self, i):
     if self.found_entry:
         bn = 'BB_' + str(cfg.counter)
         cfg.counter += 1
         b = Types.Bblock('', bn, self.entry_loc, self.last_loc,
                          self.entry_instr)
         self.bb_list.insert(0, b)
     self.found_entry = True
     self.entry_instr = i
     self.entry_loc = get_loc(i)
     self.last_loc = self.entry_loc
     return i
 def visit(self, instrs):
     self.end_loc = get_loc(instrs[-1])
     il1 = map(self.vinst, instrs)
     self.update_bl()
     self.fb_list(self.bl)
     self.bl_sort = sorted(self.bl,
                           cmp=lambda b1, b2: b1.bblock_begin_loc.loc_addr -
                           b2.bblock_begin_loc.loc_addr)
     self.bl_sort = map(
         lambda b: tb(b.bblock_name, b.bblock_begin_loc.loc_addr, b.
                      bblock_end_loc.loc_addr), self.bl_sort)
     return il1
    def visit_heuristic_analysis(self, instrs):
        func = lambda i: self.check_text(get_loc(i).loc_addr)
        self.instr_list = instrs
        tl = map(lambda i: self.vinst2(func, i), instrs)
        is_32 = 1 if ELF_utils.elf_32() else 0

        def desmapper(l):
            try:
                return int(l[2:10 + is_32], 16)
            except:
                return int(l[3:11 + is_32], 16)

        tl1 = map(desmapper, self.deslist)
        self.symbol_list = tl1 + self.symbol_list
        return tl
 def add_func_label(self, ufuncs, instrs):
     i = 0
     j = 0
     while True:
         if i == len(ufuncs) or j == len(instrs):
             break
         hf = ufuncs[i]
         hi = instrs[j]
         iloc = get_loc(hi)
         if hf.func_begin_addr == iloc.loc_addr:
             iloc.loc_label = '\n' + hf.func_name + ' : ' + iloc.loc_label
             instrs[j] = set_loc(hi, iloc)
             i += 1
             j -= 1
         elif hf.func_begin_addr < iloc.loc_addr:
             i += 1
         j += 1
     return instrs
Exemple #10
0
 def help_exit(self, i):
     loc = get_loc(i)
     if self.found_entry:
         self.last_loc = loc
         bn = 'BB_' + str(cfg.counter)
         cfg.counter += 1
         b = Types.Bblock('', bn, self.entry_loc, self.last_loc,
                          self.entry_instr)
         self.bb_list.insert(0, b)
         self.found_entry = False
         self.skip_entry = True
     elif loc.loc_addr == self.end_loc.loc_addr:
         bn = 'BB_' + str(cfg.counter)
         cfg.counter += 1
         b = Types.Bblock('', bn, loc, loc, i)
         self.bb_list.insert(0, b)
     else:
         self.last_loc = loc
     return i
 def add_bblock_label(self, bbl, instrs):
     bbl1 = sorted(
         bbl, lambda b1, b2: b1.bblock_begin_loc.loc_addr - b2.
         bblock_begin_loc.loc_addr)
     i = 0
     j = 0
     while True:
         if i == len(instrs) and j < len(bbl1):
             raise Exception('failed to add block label')
         if j == len(bbl1): break
         hi = instrs[i]
         hb = bbl1[j]
         iloc = get_loc(hi)
         bloc = hb.bblock_begin_loc
         if bloc.loc_addr == iloc.loc_addr:
             iloc = Types.Loc(hb.bblock_name + ': ' + iloc.loc_label,
                              iloc.loc_addr, iloc.loc_visible)
             instrs[i] = set_loc(instrs[i], iloc)
             j += 1
         i += 1
     return instrs
 def validate(self, instrlist):
     self.five_q = simple_queue()
     for (index, i) in enumerate(instrlist):
         loc = get_loc(i)
         if loc.loc_addr in self.locs:
             self.up_bound = dis_validator.icf_stack.pop()
             self.looking_for_cfd = True
         else:
             if len(loc.loc_label) > 1:
                 self.update_cfd(index)
                 self.update_cft_track(i)
             else:
                 p = get_op(i)
                 e = get_cf_des(i)
                 if p == 'CALL':
                     print "detected call instruction in disassembly validator"
                     self.update_cfd(index + 1)
                     if self.is_icf(p, e): self.update_cft_stack(i)
                 elif self.is_icf(p, e):
                     self.update_cft_stack(i)
                 self.update_cft_track(i)
Exemple #13
0
 def aux(bnl, acc, i):
     if isinstance(i, Types.SingleInstr) and Opcode_utils.is_ret(i[0]):
         bn = self.bbn_byloc(get_loc(i).loc_addr)
         acc.insert(0, (bn, (Types.J(), 'RET')))
     elif isinstance(i, Types.DoubleInstr):
         if Opcode_utils.is_indirect(i[1]):
             bn = self.bbn_byloc(get_loc(i).loc_addr)
             acc.insert(0, (bn, (Types.J(), 'T')))
         elif Opcode_utils.is_call(i[0]):
             bn = self.bbn_byloc(get_loc(i).loc_addr)
             bn1 = self.next_bb(bnl, bn)
             acc.insert(0, (bn, (Types.J(), bn1)))
             acc.insert(0, (bn, (Types.J(), 'INTER')))
         elif Opcode_utils.is_jmp(i[0]):
             bn = self.bbn_byloc(get_loc(i).loc_addr)
             if Opcode_utils.is_func(i[1]):
                 acc.insert(0, (bn, (Types.J(), 'INTER')))
             else:
                 en = recover_addr_from_label(p_exp(i[1]))
                 if en == -1:
                     acc.insert(0, (bn, (Types.J(), 'T')))
                 else:
                     dn = self.bbn_byloc(en)
                     acc.insert(0, (bn, (Types.J(), dn)))
         elif Opcode_utils.is_cond_jmp(i[0]):
             if not Opcode_utils.is_func(i[1]):
                 bn = self.bbn_byloc(get_loc(i).loc_addr)
                 sn = self.next_bb(bnl, bn)
                 acc.insert(0, (bn, (Types.F(), sn)))
             else:
                 assert (False)
     else:
         bn = self.bbn_byloc(get_loc(i).loc_addr)
         dn = self.next_bb(bnl, bn)
         acc.insert(0, (bn, (Types.F(), dn)))
     return acc
Exemple #14
0
 def bb_entry(self, i):
     return ':' in get_loc(i).loc_label
 def v_exp2(self, exp, instr, f, chk):
     # TODO: create subfunctions to simplify this mess
     # check_test_condition = lambda l,c: not (isinstance(l, Types.Normal) and c)
     if isinstance(exp, Types.Const):
         if isinstance(exp, Types.Normal) and chk: return exp
         l1 = self.parse_const(exp)
         s = self.check_sec(l1)
         if s is not None:
             s_label = self.build_symbol(exp)
             loc1 = get_loc(instr)
             if not self.has_data(l1):
                 reassemble.data_set[l1] = ''
                 self.label.insert(0, (s.sec_name, l1))
             self.c2d_addr.insert(0, loc1.loc_addr)
             return Types.Label(s_label)
         if self.check_text(l1):
             s_label = self.build_symbol(exp)
             loc1 = get_loc(instr)
             if not self.has_text(l1):
                 reassemble.text_set[l1] = ''
                 self.deslist.insert(0, s_label)
             self.deslist_reloc.insert(0, loc1.loc_addr)
             return Types.Label(s_label)
         if self.check_plt(l1):
             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)
                 if not self.has_text(exp):
                     reassemble.text_set[exp] = ''
                     self.deslist.insert(0, s_label)
                 return Types.Label(s_label)
         elif isinstance(exp, Types.StarDes):
             return Types.StarDes(self.v_exp2(exp.content, instr, f, chk))
         elif isinstance(exp, Types.CallDes):
             fn = exp.func_name[2:]
             is_dig_loc = False
             try:
                 addr = int(fn, 16)
                 is_dig_loc = True
             except:
                 self.symbol_list.insert(0, exp.func_begin_addr)
             if is_dig_loc:
                 if self.check_text(addr):
                     s_label = 'S_' + dec_hex(addr)
                     if not self.has_text(addr):
                         reassemble.text_set[addr] = ''
                         self.deslist.insert(0, s_label)
                     return Types.Label(s_label)
     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)
                 loc1 = get_loc(instr)
                 if not self.has_data(addr):
                     reassemble.data_set[addr] = ''
                     self.label.insert(0, (s.sec_name, addr))
                 self.c2d_addr.insert(0, loc1.loc_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)
                 loc1 = get_loc(instr)
                 if not self.has_data(addr):
                     reassemble.data_set[addr] = ''
                     self.label.insert(0, (s.sec_name, addr))
                 self.c2d_addr.insert(0, loc1.loc_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)
                 loc1 = get_loc(instr)
                 if not self.has_data(addr):
                     reassemble.data_set[addr] = ''
                     self.label.insert(0, (s.sec_name, addr))
                 self.c2d_addr.insert(0, loc1.loc_addr)
                 return Types.JmpTable_PLUS_S((s_label, r, off))
             if self.check_text(addr):
                 s_label = 'S_' + dec_hex(addr)
                 loc1 = get_loc(instr)
                 if not self.has_text(addr):
                     reassemble.text_set[addr] = ''
                     self.deslist.insert(0, s_label)
                 self.deslist_reloc.insert(0, loc1.loc_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)
                 loc1 = get_loc(instr)
                 if not self.has_data(addr):
                     reassemble.data_set[addr] = ''
                     self.label.insert(0, (s.sec_name, addr))
                 self.c2d_addr.insert(0, loc1.loc_addr)
                 return Types.JmpTable_MINUS_S((s_label, r, off))
             if self.check_text(addr):
                 s_label = '-S_' + dec_hex(addr)
                 loc1 = get_loc(instr)
                 if not self.has_text(addr):
                     reassemble.text_set[addr] = ''
                     self.deslist.insert(0, s_label)
                 self.deslist_reloc.insert(0, loc1.loc_addr)
                 return Types.JmpTable_MINUS_S((s_label, r, off))
     return exp
 def update_cft_stack(self, instr):
     inv = lambda i: get_loc(i).loc_addr in self.locs
     if not self.five_q.exists(inv):
         dis_validator.icf_stack.push(get_loc(instr))