예제 #1
0
def test_struct_typedefs():
    structs = dump_struct_layout(
        "struct s { int y; }; typedef struct s s_t; struct x { s_t s1; };",
        None)

    assert len(structs.keys()) == 2
    x = structs["x"].fields
    assert x["s1"] == (0, StructField(32, "s"))
    # not by typedef
    assert "s" in structs
    assert "s_t" not in structs

    structs = dump_struct_layout(
        "typedef struct { int y; } s_t; struct x { s_t s1; };", None)

    assert len(structs.keys()) == 2
    x = structs["x"].fields
    assert x["s1"] == (0, StructField(32, "s_t"))
    assert "s" not in structs
    assert "s_t" in structs

    # also for enums, they have special treatment
    x = dump_struct_layout(
        "typedef enum { y = 1, } e_t; struct x { e_t e1; };", "x")["x"].fields
    assert x["e1"] == (0, Scalar(32, "e_t", False))

    x = dump_struct_layout(
        "typedef enum e { y = 1, } e_t; struct x { e_t e1; };",
        "x")["x"].fields
    assert x["e1"] == (0, Scalar(32, "e", False))
예제 #2
0
def test_struct_array_flexible_and_zero():
    s = dump_struct_layout("struct x { int arr[0]; };", "x")["x"].fields
    assert len(s.keys()) == 1
    assert s["arr"] == (0, Array(0, 0, Scalar(32, "int", True)))

    # flexible array can't be the first field.
    s = dump_struct_layout("struct x { int y; int arr[]; };", "x")["x"].fields
    assert len(s.keys()) == 2
    assert s["y"] == (0, Scalar(32, "int", True))
    assert s["arr"] == (32, Array(0, 0, Scalar(32, "int", True)))
예제 #3
0
def test_struct_dump_all():
    decls = dump_struct_layout("struct a { int x; }; struct b { int y; };",
                               None)

    b = decls["b"].fields
    assert len(b.keys()) == 1
    assert b["y"] == (0, Scalar(32, "int", True))

    b = decls["a"].fields
    assert len(b.keys()) == 1
    assert b["x"] == (0, Scalar(32, "int", True))
예제 #4
0
def test_struct_union():
    structs = dump_struct_layout(
        "union u { int x; char c; long l; }; struct c { union u u; };", "c")

    c = structs["c"].fields
    assert len(c.keys()) == 1
    assert c["u"] == (0, StructField(64, "u"))

    u = structs["u"]
    assert u.total_size == 64
    u = u.fields
    assert len(u.keys()) == 3
    assert u["x"] == (0, Scalar(32, "int", True))
    assert u["c"] == (0, Scalar(8, "char", True))
    assert u["l"] == (0, Scalar(64, "long int", True))
예제 #5
0
def test_struct_struct():
    s = (dump_struct_layout(
        "struct a { int x; }; struct b { struct a aa; int xx; };",
        "b")["b"].fields)
    assert len(s.keys()) == 2
    assert s["aa"] == (0, StructField(32, "a"))
    assert s["xx"] == (32, Scalar(32, "int", True))
예제 #6
0
def test_struct_dump_only_necessary():
    structs = dump_struct_layout("struct a { int x; }; struct b { int y; };",
                                 "b")

    b = structs["b"].fields
    assert len(b.keys()) == 1
    assert b["y"] == (0, Scalar(32, "int", True))

    assert "a" not in structs
예제 #7
0
class ArrayPtr(object):
    CHAR_TYPE = Scalar(8, "char", True)

    def __init__(self, base, num_elem, elem_type):
        self.____ptr = base
        self._num_elem = num_elem or None
        self._elem_type = elem_type

    def __check_index(self, key):
        if self._num_elem and not (0 <= key < self._num_elem):
            raise IndexError("Index {!r} not in range: 0 - {!r}".format(
                key, self._num_elem - 1))

    def __getitem__(self, key):
        self.__check_index(key)
        return _read_accessor(self._elem_type, self.____ptr,
                              key * self._elem_type.total_size)

    def __setitem__(self, key, value):
        self.__check_index(key)
        return _write_accessor(self._elem_type, self.____ptr,
                               key * self._elem_type.total_size, value)

    def __eq__(self, other):
        if not isinstance(other, ArrayPtr):
            return NotImplemented

        return (self.____ptr == other.____ptr
                and self._num_elem == other._num_elem
                and self._elem_type == other._elem_type)

    def __len__(self):
        return self._num_elem

    def __repr__(self):
        return "ArrayPtr(0x{:x}, {!r}, {!r})".format(self.____ptr,
                                                     self._num_elem,
                                                     self._elem_type)

    def __int__(self):
        return self.____ptr

    def read(self, n=None):
        n = n if n is not None else self._num_elem
        items = []
        for i in range(n):
            items.append(self[i])

        if self._elem_type == ArrayPtr.CHAR_TYPE:
            # special case: if type is "char", convert to string
            s = "".join(map(chr, items))
            if s.find('\x00') != -1:
                s = s[:s.find('\x00')]
            return s
        else:
            return items
예제 #8
0
def test_accessor_pointer():
    set_memory_struct(">QL", MEM_BASE + 8, 5)

    s = partial_struct(
        dump_struct_layout("struct x { int *ptr; int x; };",
                           "x")["x"])(MEM_BASE)

    assert s.x == 5
    assert s.ptr == Ptr(Scalar(32, "int", True), MEM_BASE + 8)
    assert s.ptr.p() == 5
예제 #9
0
def test_struct_pointer():
    s = dump_struct_layout("struct x { void *p; void **h; const int ***z; };",
                           "x")["x"].fields
    assert len(s.keys()) == 3
    assert s["p"] == (0, Pointer(64, Void()))
    assert s["h"] == (64, Pointer(64, Pointer(64, Void())))
    assert s["z"] == (128,
                      Pointer(
                          64, Pointer(64, Pointer(64, Scalar(32, "int",
                                                             True)))))
예제 #10
0
def test_struct_bitfields():
    x = (dump_struct_layout(
        "struct x { int bf1: 3; int:5; int bf2: 1; int n; int bf3: 29; unsigned int bf4: 1; };",
        "x")["x"].fields)

    assert len(x.keys()) == 5
    assert x["bf1"] == (0, Bitfield(3, True))
    assert x["bf2"] == (8, Bitfield(1, True))
    assert x["n"] == (32, Scalar(32, "int", True))
    assert x["bf3"] == (64, Bitfield(29, True))
    assert x["bf4"] == (93, Bitfield(1, False))
예제 #11
0
def test_accessor_pointer_to_array():
    set_memory_struct(">Q3L", MEM_BASE + 8, 0, 1, 2)

    s = partial_struct(
        dump_struct_layout("struct x { int (*aptr)[3]; };",
                           "x")["x"])(MEM_BASE)

    assert s.aptr == ArrayPtr(MEM_BASE + 8, 3, Scalar(32, "int", True))
    assert s.aptr[0] == 0
    assert s.aptr[1] == 1
    assert s.aptr[2] == 2
예제 #12
0
def test_struct_recursive_dump():
    structs = dump_struct_layout(
        "struct a { int x; }; struct b { struct a a; }; ", "b")

    b = structs["b"].fields
    assert len(b.keys()) == 1
    assert b["a"] == (0, StructField(32, "a"))

    a = structs[b["a"][1].type].fields
    assert len(a.keys()) == 1
    assert a["x"] == (0, Scalar(32, "int", True))
예제 #13
0
def test_accessor_set_pointer():
    set_memory_struct(">QL", 0, 5)

    s = partial_struct(
        dump_struct_layout("struct x { int *ptr; int x; };",
                           "x")["x"])(MEM_BASE)

    assert s.ptr == Ptr(Scalar(32, "int", True), 0)

    s.ptr = MEM_BASE + 8

    assert s.ptr[0] == s.x
예제 #14
0
def test_struct_array_two_dimensions():
    s = dump_struct_layout("struct x { int arr[5][2]; };", "x")["x"].fields
    assert len(s.keys()) == 1
    assert s["arr"] == (0,
                        Array(5 * 2 * 32, 5,
                              Array(2 * 32, 2, Scalar(32, "int", True))))
예제 #15
0
def test_struct_array():
    s = dump_struct_layout("struct x { int arr[5]; void *p[2]; };",
                           "x")["x"].fields
    assert len(s.keys()) == 2
    assert s["arr"] == (0, Array(5 * 32, 5, Scalar(32, "int", True)))
    assert s["p"] == (5 * 32 + 32, Array(2 * 64, 2, Pointer(64, Void())))
예제 #16
0
def test_struct_basic():
    s = dump_struct_layout("struct x { int y; unsigned char z; };",
                           "x")["x"].fields
    assert len(s.keys()) == 2
    assert s["y"] == (0, Scalar(32, "int", True))
    assert s["z"] == (32, Scalar(8, "unsigned char", False))
예제 #17
0
def test_struct_anonymous_enum():
    x = dump_struct_layout("struct x { enum { x = 5, } e; };", "x")["x"].fields

    assert len(x.keys()) == 1
    assert x["e"] == (0, Scalar(32, "anonymous enum", False))
예제 #18
0
def test_struct_anonymous_union():
    s = dump_struct_layout("struct c { union { int x; float f; }; };",
                           "c")["c"].fields
    assert len(s.keys()) == 2
    assert s["x"] == (0, Scalar(32, "int", True))
    assert s["f"] == (0, Scalar(32, "float", True))