Beispiel #1
0
def test_decoder_020():
    c = b'\x68\x01\x02\x03\xff'
    i = cpu.disassemble(c)
    assert i.mnemonic == 'PUSH'
    assert i.operands[0].size == 32
    assert i.operands[0] == 0xff030201
    c = b'\x48\x68\x01\x02\x03\xff'
    i = cpu.disassemble(c)
    assert i.mnemonic == 'PUSH'
    assert i.operands[0].size == 64
    assert i.operands[0] == 0xffffffffff030201
Beispiel #2
0
def test_mapper_000():
    # create two instructions
    # movq    %rcx, (%rip)
    # movq    (%rip), %rcx
    i0 = cpu.disassemble(b"\x48\x89\x0d\x00\x00\x00\x00")
    i1 = cpu.disassemble(b"\x48\x8b\x0d\x00\x00\x00\x00")
    # modify the first instruction to insert a label, e.g. because
    # there is a relocation
    # movq    %rcx, foo(%rip)
    i0.operands[0].a.disp = expressions.lab('foo', size=64)
    # evaluate those two instructions
    m = mapper()
    i0(m)
    i1(m)
    assert str(m[rcx]) == 'M64(rip+14)'
Beispiel #3
0
def test_decoder_019():
    c = b'\xff\x35\x00\x00\x00\x00'
    i = cpu.disassemble(c)
    assert i.mnemonic == 'PUSH'
    assert i.operands[0].size == 64
    assert i.operands[0].a.base == rip
    assert i.operands[0].a.disp == 0
Beispiel #4
0
def test_decoder_012():
    c = codecs.decode('488b0d19000000', 'hex')
    i = cpu.disassemble(c)
    assert i.mnemonic == 'MOV'
    assert i.operands[0].ref == 'rcx'
    assert i.operands[1].a.base == rip
    assert i.operands[1].a.disp == 0x19
Beispiel #5
0
def test_decoder_013():
    c = codecs.decode('8b5c240c', 'hex')
    i = cpu.disassemble(c)
    assert i.mnemonic == 'MOV'
    assert i.operands[0].ref == 'ebx'
    assert i.operands[1].size == 32
    assert i.operands[1].a.base == rsp
    assert i.operands[1].a.disp == 0xc
Beispiel #6
0
def test_decoder_029():
    i = cpu.disassemble(b'\x3e\xff\x34\x25\xd2\x04\x00\x00')
    assert i.mnemonic == 'PUSH'
    assert i.operands[0].size == 64
    assert i.operands[0].a.base == 0x4d2
    assert i.operands[0].a.disp == 0
    assert i.operands[0].a.seg.ref == 'ds'
    assert str(i) == 'push        qword ptr ds:[0x4d2]'
Beispiel #7
0
def test_decoder_025():
    c = codecs.decode('4c69f1020000f0', 'hex')
    i = cpu.disassemble(c)
    assert i.mnemonic == 'IMUL'
    assert i.operands[0].ref == 'r14'
    assert i.operands[1].ref == 'rcx'
    assert i.operands[2].size == 64
    assert i.operands[2] == cpu.cst(0xf0000002, 32).signextend(64)
Beispiel #8
0
def test_decoder_026():
    c = b'\x66\x41\xc7\x84\x55\x11\x11\x11\x11\x22\x22'
    i = cpu.disassemble(c)
    assert i.mnemonic == 'MOV'
    assert i.operands[0]._is_mem
    assert i.operands[0].size == 16
    assert i.operands[0].a.base == cpu.r13 + (cpu.rdx * 2)
    assert i.operands[0].a.disp == 0x11111111
    assert i.operands[1] == cpu.cst(0x2222, 16)
Beispiel #9
0
def test_mapper_001():
    # create three instructions
    # movq    %rax, (%rip)
    # movl    %eax, (%rip)
    # movq    -16(%rbp), %rcx
    i0 = cpu.disassemble(b"\x48\x89\x05\x00\x00\x00\x00")
    i1 = cpu.disassemble(b"\x89\x05\x00\x00\x00\x00")
    i2 = cpu.disassemble(b"\x48\x8b\x4d\xf0")
    # modify the first two instructions to insert a label
    # movq    %rax, foo(%rip)
    i0.operands[0].a.disp = expressions.lab('foo', size=64)
    # movb    %eax, bar(%rip)
    i1.operands[0].a.disp = expressions.lab('bar', size=64)
    # evaluate those three instructions
    m = mapper()
    i0(m)
    i1(m)
    i2(m)
    assert str(m[rcx]) == 'M64(rbp-16)'
Beispiel #10
0
 def from_bin(self, in_str, section):
     ''' binary input, in assembly format '''
     self.section = section
     self.offset = in_str.offset
     from plasmasm.parse_bin import endofsection_address
     end_of_section = endofsection_address(self.symbols, section)
     end_of_instr = in_str.offset + cpu_amoco.disassemble.maxlen
     if end_of_instr > end_of_section:
         end_of_instr = end_of_section
     instr = cpu_amoco.disassemble(in_str[self.offset:end_of_instr])
     log.debug("> %s", instr)
     if instr is None:
         instr = StubNone(self.offset, in_str[self.offset:self.offset + 1])
     self.bytelen = instr.length
     in_str.offset = self.offset + self.bytelen
     self.amoco = instr
     return self
Beispiel #11
0
def test_decoder_005():
    c = b'\x8b\x2c\x25\x00\x00\x00\x00'
    i = cpu.disassemble(c)
    assert i.operands[1].a.base == 0
Beispiel #12
0
def test_decoder_004():
    c = b'\x64\x48\x8b\x04\x25\x28\0\0\0'
    i = cpu.disassemble(c)
    assert i.operands[1].a.base == 40
Beispiel #13
0
def test_decoder_003():
    c = b'\x48\x8b\x04\xc5\0\0\0\0'
    i = cpu.disassemble(c)
    assert i.operands[1].a.base == (rax * 8)
Beispiel #14
0
def test_decoder_002():
    c = b'\x48\x0f\xbe\xc0'
    i = cpu.disassemble(c)
    assert i.mnemonic == 'MOVSX'
    assert i.operands[0].ref == 'rax'
    assert i.operands[1].ref == 'al'
Beispiel #15
0
def test_decoder_028():
    i = cpu.disassemble(b'f\x0f\x16\x15\x0c\x00\x00\x00')
    assert i.mnemonic == 'MOVHPD'
    assert i.operands[0].ref == 'xmm2'
    assert i.operands[1].size == 64
Beispiel #16
0
def test_decoder_015():
    c = b'\x48\x63\xd2'
    i = cpu.disassemble(c)
    assert i.mnemonic == 'MOVSXD'
Beispiel #17
0
def test_decoder_016():
    c = b'\x86\xf1'
    i = cpu.disassemble(c)
    assert i.mnemonic == 'XCHG'
    assert i.operands[0].ref == 'dh'
    assert i.operands[1].ref == 'cl'
Beispiel #18
0
def test_decoder_009():
    c = b'\xf3\x0f\x2a\xc0'
    i = cpu.disassemble(c)
    assert i.mnemonic == 'CVTSI2SS'
    assert i.operands[1].ref == 'eax'
Beispiel #19
0
def test_decoder_001():
    c = b'f\x0fo\x04%\xbc\x00`\x00'
    i = cpu.disassemble(c)
    assert i.mnemonic == 'MOVDQA'
    assert i.operands[0].ref == 'xmm0'
    assert i.operands[1].a.base == 0x6000bc
Beispiel #20
0
def test_decoder_021():
    c = b'\x66\x68\x03\xff'
    i = cpu.disassemble(c)
    assert i.mnemonic == 'PUSH'
    assert i.operands[0].size == 16
    assert i.operands[0] == 0xff03
Beispiel #21
0
 def apply_reloc(self, pos, reloc):
     ''' 'reloc' is a relocation at offset 'pos'
         This function modifies the argument impacted by the relocation '''
     # Step 1: find which arg is impacted
     pos -= self.offset
     b, = struct.unpack("B", self.amoco.bytes[pos:pos + 1])
     b = struct.pack("B", (1 + b) % 256)
     o = cpu_amoco.disassemble(self.amoco.bytes)
     patched = self.amoco.bytes[:pos] + b + self.amoco.bytes[pos + 1:]
     p = cpu_amoco.disassemble(patched)
     if o is None or p is None or o.mnemonic != p.mnemonic:
         log.error("Relocation changes instruction! %s => %s", o, p)
         log.error("   at offset %r with reloc %r", pos, reloc)
         log.error("   for '%s' at %s, address=%s", self, self.section,
                   self.offset)
         return
     # To find if an argument has changed, we compute the difference
     # and test if it is non-zero
     argpos = None
     for idx, (oa, na) in enumerate(zip(o.operands, p.operands)):
         try:
             d = na - oa
         except ValueError:
             log.error("Invalid relocation effect")
             log.error("    incompatible sizes %s %s", na, oa)
             log.error("    reloc %r for '%s'", reloc, self)
             return
         if d._is_cst and int(d) == 0:
             # Not changed
             continue
         if argpos is not None:
             log.error("Relocation touches many arguments")
             log.error("    reloc %r for '%s'", reloc, self)
             return
         argpos = idx
     if argpos is None:
         log.error("Relocation touches no argument")
         log.error("    reloc %r for '%s'", reloc, self)
         log.error("ARGPOS %s", argpos)
         return
     # Step 2: modify the argument by using the reloc data
     address = None  # TODO SWITCH label_for_optimised_switch(self)
     if self.amoco.operands[argpos]._is_cst:
         offset = int(self.amoco.operands[argpos])
         if offset >= (1 << (cpu_addrsize - 1)):
             offset -= 1 << cpu_addrsize  # Signed
         self.amoco.operands[argpos] -= offset
     elif self.amoco.operands[argpos]._is_mem:
         base = self.amoco.operands[argpos].a.base
         if base._is_cst:
             offset = int(base)
             self.amoco.operands[argpos].a.base -= offset
         else:
             if base._is_eqn and base.op.symbol == '+':
                 pass
                 # We may want to extract the constant from an operation
                 # (reg+imm), but normally it is stored as (base+disp)
             offset = self.amoco.operands[argpos].a.disp
             self.amoco.operands[argpos].a.disp -= offset
     else:
         log.error("Arg of type %s", self.amoco.operands[argpos].__class__)
         return
     if address is None:
         from plasmasm.get_symbols import analyze_reloc
         label, label_dif, offset, size = analyze_reloc(
             self, reloc, offset, pos, self.bytelen)
         r_type, data = reloc
         from elfesteem import elf
         if r_type[0] == 'ELF' and \
            r_type[1] == elf.EM_X86_64 and \
            r_type[2] in [
                 elf.R_X86_64_PC32,
                 elf.R_X86_64_GOT32,
                 elf.R_X86_64_PLT32,
                 elf.R_X86_64_32S,
                 ]:
             # The 32-bit reloc is expanded to 64-bit argument by amoco
             # but not with PUSH...
             # Note that the binutils syntax for PUSH immediate is very
             # inconsistent; objdump outputs:
             # 6a 08          (push one byte)   => pushq $0x8
             # 66 6a 08       (push two bytes)  => pushw $0x8
             # 66 68 08 00    (push two bytes)  => pushw $0x8
             # 68 08 00 00 00 (push four bytes) => pushq $0x8
             # the latter being used for relocs
             # we would have expected either always pushq, or depending
             # on the argument size pushb, pushw, pushl
             if self.opname != 'push': size = 64
         if r_type[0] == 'ELF' and \
            r_type[1] == elf.EM_X86_64 and \
            r_type[2] == elf.R_X86_64_PC32 and \
            getattr(label, 'bind', None) == 'weak':
             # In some cases, a new label has to be generated, or we get
             # an error: 'relocation R_X86_64_PC32 against symbol ... can
             # not be used when making a shared object'
             label = label.symbols.find_symbol(name='.LTHUNK%d' %
                                               len(label.symbols.symbols),
                                               data={'set': label})
     else:
         # Special case: offset to a switch table
         r_type, data = reloc
         TODO
     ext_label = expressions.lab(label, size=size)
     if label_dif is not None:
         NEVER
         ext_label -= expressions.lab(label_dif, size=size)
     if offset != 0:
         ext_label = ext_label + offset
     if self.amoco.operands[argpos]._is_cst:
         self.amoco.operands[argpos] += ext_label
     elif self.amoco.operands[argpos]._is_mem and self.amoco.operands[
             argpos].a.base._is_cst:
         self.amoco.operands[argpos].a.base += ext_label
     elif self.amoco.operands[argpos]._is_mem:
         self.amoco.operands[argpos].a.disp += ext_label
     else:
         NEVER
Beispiel #22
0
def test_decoder_017():
    c = b'\x2a\xf1'
    i = cpu.disassemble(c)
    assert i.mnemonic == 'SUB'
    assert i.operands[0].ref == 'dh'
    assert i.operands[1].ref == 'cl'
Beispiel #23
0
def test_decoder_007():
    c = b'\x40\x80\xcc\x0c'
    i = cpu.disassemble(c)
    assert i.operands[0].ref == 'spl'
Beispiel #24
0
def test_decoder_011():
    c = codecs.decode('41ffd7', 'hex')
    i = cpu.disassemble(c)
    assert i.mnemonic == 'CALL'
    assert i.operands[0].ref == 'r15'
Beispiel #25
0
def test_decoder_008():
    c = codecs.decode('48B88877665544332211', 'hex')
    i = cpu.disassemble(c)
    assert i.operands[1] == 0x1122334455667788
Beispiel #26
0
def test_decoder_000():
    c = b'\x90'
    i = cpu.disassemble(c)
    assert i.mnemonic == 'NOP'
Beispiel #27
0
def test_decoder_010():
    c = codecs.decode('488d0c59', 'hex')
    i = cpu.disassemble(c)
    assert i.operands[1].a.base == ((rbx * 0x2) + rcx)
Beispiel #28
0
def test_decoder_027():
    c = b'\xf2\x48\x0f\x2c\xf3'
    i = cpu.disassemble(c)
    assert i.mnemonic == 'CVTTSD2SI'
    assert i.operands[0].ref == 'rsi'
    assert i.operands[1].ref == 'xmm3'
Beispiel #29
0
def test_decoder_024():
    c = b'\x66\x51'
    i = cpu.disassemble(c)
    assert i.mnemonic == 'PUSH'
    assert i.operands[0].ref == 'cx'
Beispiel #30
0
def test_decoder_014():
    c = b'\x48\xa5'
    i = cpu.disassemble(c)
    assert i.mnemonic == 'MOVSQ'