def test_read_unsigned(self): data = b"\x01\x02\x03\x04\x05\x06\x07\x08" for word_size in [8, 4]: for byteorder in ["little", "big"]: flags = PlatformFlags(0) if word_size == 8: flags |= PlatformFlags.IS_64_BIT if byteorder == "little": flags |= PlatformFlags.IS_LITTLE_ENDIAN prog = mock_program( Platform(Architecture.UNKNOWN, flags), segments=[MockMemorySegment(data, 0xFFFF0000, 0xA0)], ) for size in [1, 2, 4, 8]: read_fn = getattr(prog, f"read_u{8 * size}") value = int.from_bytes(data[:size], byteorder) self.assertEqual(read_fn(0xFFFF0000), value) self.assertEqual(read_fn(0xA0, True), value) if size == word_size: self.assertEqual(prog.read_word(0xFFFF0000), value) self.assertEqual(prog.read_word(0xA0, True), value) prog = mock_program( MOCK_32BIT_PLATFORM, segments=[MockMemorySegment(data, 0xFFFF0000, 0xA0)] )
def test_adjacent_segments(self): data = b"hello, world!\0foobar" prog = mock_program(segments=[ MockMemorySegment(data[:4], 0xFFFF0000), MockMemorySegment(data[4:14], 0xFFFF0004), MockMemorySegment(data[14:], 0xFFFFF000), ]) self.assertEqual(prog.read(0xFFFF0000, 14), data[:14])
def test_address_overflow(self): for bits in (64, 32): with self.subTest(bits=bits): prog = mock_program( segments=[ MockMemorySegment(b"cd", 0x0), MockMemorySegment(b"abyz", 2**bits - 2), ], platform=MOCK_PLATFORM if bits == 64 else MOCK_32BIT_PLATFORM, ) for start in range(3): for size in range(4 - start): self.assertEqual( prog.read((2**bits - 2 + start) % 2**64, size), b"abcd"[start : start + size], )
def test_bad_address(self): data = b"hello, world!" prog = mock_program(segments=[MockMemorySegment(data, 0xFFFF0000)]) self.assertRaisesRegex(FaultError, "could not find memory segment", prog.read, 0xDEADBEEF, 4) self.assertRaisesRegex(FaultError, "could not find memory segment", prog.read, 0xFFFF0000, 4, True)
def test_bad_address(self): data = b'hello, world!' prog = mock_program(segments=[MockMemorySegment(data, 0xffff0000)]) self.assertRaisesRegex(FaultError, 'could not find memory segment', prog.read, 0xdeadbeef, 4) self.assertRaisesRegex(FaultError, 'could not find memory segment', prog.read, 0xffff0000, 4, True)
def test_simple_read(self): data = b'hello, world' prog = mock_program(segments=[ MockMemorySegment(data, 0xffff0000, 0xa0), ]) self.assertEqual(prog.read(0xffff0000, len(data)), data) self.assertEqual(prog.read(0xa0, len(data), True), data)
def test_read_float(self): pi32 = struct.unpack("f", struct.pack("f", math.pi))[0] for bit_size in [32, 64]: for bit_offset in range(8): for byteorder in ["little", "big"]: if bit_size == 64: fmt = "<d" expected = math.pi else: fmt = "<f" expected = pi32 tmp = int.from_bytes(struct.pack(fmt, math.pi), "little") if byteorder == "little": tmp <<= bit_offset else: tmp <<= (8 - bit_size - bit_offset) % 8 buf = tmp.to_bytes((bit_size + bit_offset + 7) // 8, byteorder) prog = mock_program(segments=[MockMemorySegment(buf, 0)]) obj = Object( prog, prog.float_type( "double" if bit_size == 64 else "float", bit_size // 8, byteorder, ), address=0, bit_offset=bit_offset, ) self.assertEqual(obj.value_(), expected)
def test_segment_overflow(self): data = b"hello, world!" prog = mock_program(segments=[MockMemorySegment(data, 0xFFFF0000)]) self.assertRaisesRegex( FaultError, "could not find memory segment", prog.read, 0xFFFF0000, len(data) + 1, )
def test_read_struct_bit_offset(self): value = 12345678912345678989 for bit_size in range(1, 65): for bit_offset in range(8): size = (bit_size + bit_offset + 7) // 8 size_mask = (1 << (8 * size)) - 1 for byteorder in ["little", "big"]: if byteorder == "little": tmp = value << bit_offset else: tmp = value << (8 - bit_size - bit_offset) % 8 tmp &= size_mask buf = tmp.to_bytes(size, byteorder) + b"\0" prog = mock_program(segments=[MockMemorySegment(buf, 0)]) obj = Object( prog, prog.struct_type( None, (bit_offset + bit_size + 7) // 8, ( TypeMember( Object( prog, prog.int_type( "unsigned long long", 8, False, byteorder, ), bit_field_size=bit_size, ), "x", bit_offset=bit_offset, ), ), ), address=0, ) self.assertEqual(obj.x.value_(), value & ((1 << bit_size) - 1)) self.assertEqual( obj.x.read_().value_(), value & ((1 << bit_size) - 1) ) self.assertEqual( obj.read_().x.value_(), value & ((1 << bit_size) - 1) )
def test_simple_read(self): data = b"hello, world" prog = mock_program(segments=[MockMemorySegment(data, 0xFFFF0000, 0xA0)]) self.assertEqual(prog.read(0xFFFF0000, len(data)), data) self.assertEqual(prog.read(0xA0, len(data), True), data)