Пример #1
0
 def translate_it_block(block):
     """
     Translate IT block using normal branches
     :param block: instruction list of IT block
     :return: instruction list with normal branches
     """
     itloc = get_loc(block[0])
     res = [
         Types.DoubleInstr(
             ('b' + block[0][1], Types.Label('.LIT_%X.T' % itloc.loc_addr),
              itloc, False))
     ]
     branches = {'t': [], 'e': []}
     for i in xrange(1, len(block[0][0])):
         op = block[i][0].split('.')
         op[0] = op[0][:-2]
         instr = type(block[i])(('.'.join(op), ) + block[i][1:])
         branches[block[0][0][i]].append(instr)
     endloc = get_loc(block[-1])
     branches['e'].append(
         Types.DoubleInstr(('b', Types.Label(
             ('.LIT_%X.E' % itloc.loc_addr)), endloc, False)))
     branches['t'][0][-2].loc_label += '.LIT_%X.T: ' % itloc.loc_addr
     res += branches['e'] + branches['t']
     res.append(
         set_loc(
             block[-1],
             Types.Loc('.LIT_%X.E: ' % itloc.loc_addr, endloc.loc_addr,
                       True)))
     return res
Пример #2
0
 def get_returnenc(curr_instr, popcookie=False):
     """
     Get code block for return address encryption
     :param curr_instr: return instruction
     :param popcookie: True if also frame cookie must be removed
     :return: return encryption instruction list
     """
     pre = list(framecookietail) if popcookie else []
     loc = get_loc(curr_instr)
     if curr_instr[0].upper().startswith('POP'):
         # pop {...,pc}
         i = map(str.upper, curr_instr[1]).index('PC')
         rlist = curr_instr[1][:i] + ('lr', ) + curr_instr[1][i + 1:]
         pre.insert(
             0,
             Types.DoubleInstr(
                 (curr_instr[0], Types.RegList(rlist), None, False)))
         curr_instr = Types.DoubleInstr(
             ('bx', Types.RegClass('lr'), None, False))
     elif curr_instr[0].upper().startswith(
             'LDR') and curr_instr[1].upper() == 'PC':
         # ldr pc, [sp], #4
         pre.insert(
             0,
             type(curr_instr)((curr_instr[0], Types.RegClass('lr')) +
                              curr_instr[2:]))
         curr_instr = Types.DoubleInstr(
             ('bx', Types.RegClass('lr'), None, False))
     return set_inlineblocklocation(loc, pre + returnenc) + \
            [set_loc(curr_instr, Types.Loc('', loc.loc_addr, loc.loc_visible))]
Пример #3
0
 def vinst2ARM(self, iv):
     """
     Analize instruction (ARM)
     :param iv: instruction tuple
     """
     instr = iv[1]
     if instr[0].upper().startswith('MOVW'): self.ARMmovs.append(iv[0])
     if isinstance(instr, Types.DoubleInstr):
         if isinstance(instr[1], Types.TBExp):
             self.insert_text(instr[1].base,
                              int(instr[1].base.split('x')[1], 16))
             self.insert_text(instr[1].dest,
                              int(instr[1].dest.split('x')[1], 16))
             return instr
         return Types.DoubleInstr(
             (instr[0], self.v_exp2(instr[1], instr, None,
                                    False), instr[2], instr[3]))
     if isinstance(instr, Types.TripleInstr):
         if instr[0].startswith('vldr') and isinstance(
                 instr[2], Types.Const):
             self.ARMvldrtargets.append(instr[2])
         return Types.TripleInstr(
             (instr[0], instr[1], self.v_exp2(instr[2], instr, None,
                                              True), instr[3], instr[4]))
     return instr
Пример #4
0
 def vinst2(self, f, instr):
     """
     Analize instruction (x86)
     :param f: unsused
     :param instr: instruction tuple
     """
     if isinstance(instr, Types.SingleInstr): return instr
     elif isinstance(instr, Types.DoubleInstr):
         return Types.DoubleInstr(
             (instr[0], self.v_exp2(instr[1], instr, f,
                                    False), instr[2], instr[3]))
     elif isinstance(instr, Types.TripleInstr):
         is_test = instr[0].upper() in ['TEST', 'TESTL', 'TESTW', 'TESTB']
         return Types.TripleInstr(
             (instr[0], self.v_exp2(instr[1], instr, f, is_test),
              self.v_exp2(instr[2], instr, f, is_test), instr[3], instr[4]))
     elif isinstance(instr, Types.FourInstr):
         return Types.FourInstr(
             (instr[0], instr[1], self.v_exp2(instr[2], instr, f, False),
              self.v_exp2(instr[3], instr, f, False) if instr[0][0].upper()
              == 'V' else instr[3], instr[4], instr[5]))
     elif isinstance(instr, Types.FiveInstr):
         return Types.FiveInstr(
             (instr[0], instr[1], instr[2],
              self.v_exp2(instr[3], instr, f,
                          False), instr[4], instr[5], instr[6]))
     return instr
Пример #5
0
 def bswapsub(reg, loc):
     """
     Replace target register in bswap containing ret encoding bytes
     :param reg: bswapped register
     :param loc: instuction location
     :return: instruction list with replaced bswap
     """
     sub = Types.RegClass('edi' if reg[0].lower() == 'e' else 'rdi')
     substack = Types.RegClass('edi' if ELF_utils.elf_32() else 'rdi')
     return set_inlineblocklocation(loc, [
         Types.DoubleInstr(('push', substack, None, False)),
         Types.TripleInstr(('mov', sub, reg, None, False)),
         Types.DoubleInstr(('bswap', sub, None, False)),
         Types.TripleInstr(('mov', reg, sub, None, False)),
         Types.DoubleInstr(('pop', substack, None, False)),
     ])
Пример #6
0
 def scan(self):
     """
     Scan instruction list and modify PC relative code with labels
     """
     i = 0
     inlen = len(self.instrs) - 1
     while i < inlen:
         h1 = self.instrs[i]
         if get_loc(h1).loc_addr >= self.funcs[self.curr_func][1]:
             # It can be assumed that the base register is set only inside a single function
             self.curr_func += 1
             self.curr_regs.clear()
         if isinstance(h1, Types.TripleInstr) and (self.match_get_pc_thunk(h1) \
           or (h1[0].upper() == 'MOV' and isinstance(h1[2], Types.RegClass) \
           and h1[2].upper() in self.curr_regs and isinstance(h1[1], Types.RegClass))):
             # .got.plt address can also be copied to more than one register
             self.curr_regs.add(h1[1].upper())
         elif len(self.curr_regs) > 0:
             if isinstance(h1, Types.DoubleInstr):
                 self.instrs[i] = Types.DoubleInstr((h1[0], self.v_exp(h1[1]), h1[2], h1[3]))
             elif not isinstance(h1, Types.SingleInstr):
                 if isinstance(h1, Types.TripleInstr):
                     self.instrs[i] = Types.TripleInstr((h1[0], self.v_exp(h1[1]), self.v_exp(h1[2]), h1[3], h1[4]))
                 elif isinstance(h1, Types.FourInstr):
                     self.instrs[i] = Types.FourInstr((h1[0], h1[1], self.v_exp(h1[2]), h1[3], h1[4], h1[5]))
                 if isinstance(h1[1], Types.RegClass) and h1[1].upper() in self.curr_regs:
                     # Remove if overridden
                     self.curr_regs.remove(h1[1].upper())
         i += 1
Пример #7
0
 def pcreloffARM(self, instrs):
     """
     Trying to handle this mess
       ldr r7, label           -> ldr r7, label
       ...                     -> ...
       add r7,pc               -> add r7, #0
       ...                     -> ...
       ldr r1, [r7]            -> ldr r1, [r7]
       ...                     -> ...
       label: .word 0xoffset   -> label: .word (0xoffset + pc)
     :param instrs: instruction list
     """
     i = 0
     offsets = {}
     inlen = len(instrs)
     while i < inlen:
         hi = instrs[i]
         if isinstance(hi, Types.TripleInstr) \
           and hi[0].lower().startswith('ldr') \
           and isinstance(hi[2], Types.Point):
             j = i + 1
             while j - i < config.ARM_maxAddPcDist and j < inlen:
                 hj = instrs[j]
                 if isinstance(hj, Types.TripleInstr) \
                   and hj[0].lower().startswith('add') \
                   and hj[1] == hi[1] \
                   and isinstance(hj[2], Types.RegClass) \
                   and hj[2].lower() == 'pc':
                     offsets[hi[2]] = get_loc(hj).loc_addr + 4
                     instrs[j] = Types.TripleInstr(
                         (hj[0], hj[1], Types.Normal(0), hj[3], hj[4]))
                     break
                 j += 1
         elif isinstance(hi, Types.DoubleInstr) and isinstance(
                 hi[0], Types.InlineData):
             off = offsets.pop(get_loc(hi).loc_addr, None)
             if off:
                 instrs[i] = Types.DoubleInstr(
                     (hi[0], Types.Point((hi[1] + off) & 0xFFFFFFFF), hi[2],
                      hi[3]))
         i += 1
Пример #8
0
"""
Templates for gfree return address encryption and frame cookie
"""

import config
from disasm import Types
from utils.ail_utils import ELF_utils, set_loc, get_loc

if ELF_utils.elf_64():
    # x86_64

    cslab = Types.Label(config.gfree_cookiestackvar + '@tpoff')

    returnenc = [
        Types.DoubleInstr(('pushq', Types.RegClass('rax'), None, False)),
        Types.TripleInstr(('movq', Types.RegClass('rax'),
                           Types.Label(config.gfree_xorkeyvar), None, False)),
        Types.TripleInstr(('xorq', Types.BinOP_PLUS(
            (Types.RegClass('rsp'), 8)), Types.RegClass('rax'), None, False)),
        Types.DoubleInstr(('popq', Types.RegClass('rax'), None, False)),
    ]

    framecookiehead = [
        Types.DoubleInstr(('pushq', Types.RegClass('rax'), None, False)),
        Types.DoubleInstr(('pushq', Types.RegClass('rbx'), None, False)),
        Types.TripleInstr(('addq', Types.SegRef(
            ('fs', cslab)), Types.Normal(1), None, False)),
        Types.TripleInstr(
            ('movq', Types.RegClass('rbx'), Types.SegRef(
                ('fs', cslab)), None, False)),
        Types.TripleInstr(