Ejemplo n.º 1
0
class EXCEPTION_REGISTRATION_RECORD(MemStruct):
    """
    +0x00 Next    : struct _EXCEPTION_REGISTRATION_RECORD *
    +0x04 Handler : Ptr32 Void
    """

    fields = [
        ("Next", Ptr("<I", Self())),
        ("Handler", Ptr("<I", Void())),
    ]
Ejemplo n.º 2
0
class UnhealthyIdeas(MemStruct):
    fields = [
        ("pastruct", Ptr("I", Array(RawStruct("=Bf")))),
        ("apstr", Array(Ptr("I", Str()), 10)),
        ("pself", Ptr("I", Self())),
        ("apself", Array(Ptr("I", Self()), 2)),
        ("ppself", Ptr("I", Ptr("I", Self()))),
        ("pppself", Ptr("I", Ptr("I", Ptr("I", Self())))),
    ]
Ejemplo n.º 3
0
class MyStruct(MemStruct):
    fields = [
        # Number field: just struct.pack fields with one value
        ("num", Num("I")),
        ("flags", Num("B")),
        # This field is a pointer to another struct, it has a numeric
        # value (mystruct.other.val) and can be dereferenced to get an
        # OtherStruct instance (mystruct.other.deref)
        ("other", Ptr("I", OtherStruct)),
        # Ptr to a variable length String
        ("s", Ptr("I", Str())),
        ("i", Ptr("I", Num("I"))),
    ]
Ejemplo n.º 4
0
class EXCEPTION_RECORD(MemStruct):
    """
    DWORD                    ExceptionCode;
    DWORD                    ExceptionFlags;
    struct _EXCEPTION_RECORD *ExceptionRecord;
    PVOID                    ExceptionAddress;
    DWORD                    NumberParameters;
    ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];
    """
    EXCEPTION_MAXIMUM_PARAMETERS = 15

    fields = [
        ("ExceptionCode", Num("<I")),
        ("ExceptionFlags", Num("<I")),
        ("ExceptionRecord", Ptr("<I", Self())),
        ("ExceptionAddress", Ptr("<I", Void())),
        ("NumberParameters", Num("<I")),
        ("ExceptionInformation", Ptr("<I", Void())),
    ]
Ejemplo n.º 5
0
class DataArray(MemStruct):
    fields = [
        ("val1", Num("B")),
        ("val2", Num("B")),
        # Ptr can also be instanciated with a Type instance as an argument, the
        # corresponding Memtype will be returned when dereferencing
        # Here, data_array.array.deref will allow to access an Array
        ("arrayptr", Ptr("<I", Array(Num("B"), 16))),
        # Array of 10 uint8
        ("array", Array(Num("B"), 16)),
    ]
Ejemplo n.º 6
0
class PEB(MemStruct):
    """
    +0x000 InheritedAddressSpace    : UChar
    +0x001 ReadImageFileExecOptions : UChar
    +0x002 BeingDebugged            : UChar
    +0x003 SpareBool                : UChar
    +0x004 Mutant                   : Ptr32 Void
    +0x008 ImageBaseAddress         : Ptr32 Void
    +0x00c Ldr                      : Ptr32 _PEB_LDR_DATA
    +0x010 processparameter
    """

    fields = [
        ("InheritedAddressSpace", Num("B")),
        ("ReadImageFileExecOptions", Num("B")),
        ("BeingDebugged", Num("B")),
        ("SpareBool", Num("B")),
        ("Mutant", Ptr("<I", Void())),
        ("ImageBaseAddress", Num("<I")),
        ("Ldr", Ptr("<I", PEB_LDR_DATA)),
    ]
Ejemplo n.º 7
0
class TEB(MemStruct):
    """
    +0x000 NtTib                     : _NT_TIB
    +0x01c EnvironmentPointer        : Ptr32 Void
    +0x020 ClientId                  : _CLIENT_ID
    +0x028 ActiveRpcHandle           : Ptr32 Void
    +0x02c ThreadLocalStoragePointer : Ptr32 Void
    +0x030 ProcessEnvironmentBlock   : Ptr32 _PEB
    +0x034 LastErrorValue            : Uint4B
    ...
    """

    fields = [
        ("NtTib", NT_TIB),
        ("EnvironmentPointer", Ptr("<I", Void())),
        ("ClientId", Array(Num("B"), 0x8)),
        ("ActiveRpcHandle", Ptr("<I", Void())),
        ("ThreadLocalStoragePointer", Ptr("<I", Void())),
        ("ProcessEnvironmentBlock", Ptr("<I", PEB)),
        ("LastErrorValue", Num("<I")),
    ]
Ejemplo n.º 8
0
class ListNode(MemStruct):
    fields = [
        # The "<I" is the struct-like format of the pointer in memory, in this
        # case a Little Endian 32 bits unsigned int.
        # One way to handle reference to ListNode in ListNode is to use the
        # special marker Self().
        # You could also generate ListNode's fields with ListNode.gen_field
        # after the class declaration, so that the ListNode is defined when
        # fields are generated.
        ("next", Ptr("<I", Self())),
        # Ptr(_, Void()) is analogous to void*, Void() is a kind of "empty type"
        ("data", Ptr("<I", Void())),
    ]

    def get_next(self):
        if self.next.val == 0:
            return None
        return self.next.deref

    def get_data(self, data_type=None):
        if data_type is not None:
            return self.data.deref.cast(data_type)
        else:
            return self.data.deref
Ejemplo n.º 9
0
class PEB_LDR_DATA(MemStruct):
    """
    +0x000 Length                          : Uint4B
    +0x004 Initialized                     : UChar
    +0x008 SsHandle                        : Ptr32 Void
    +0x00c InLoadOrderModuleList           : _LIST_ENTRY
    +0x014 InMemoryOrderModuleList         : _LIST_ENTRY
    +0x01C InInitializationOrderModuleList         : _LIST_ENTRY
    """

    fields = [("Length", Num("<I")), ("Initialized", Num("<I")),
              ("SsHandle", Ptr("<I", Void())),
              ("InLoadOrderModuleList", ListEntry),
              ("InMemoryOrderModuleList", ListEntry),
              ("InInitializationOrderModuleList", ListEntry)]
Ejemplo n.º 10
0
class LdrDataEntry(MemStruct):
    """
    +0x000 InLoadOrderLinks : _LIST_ENTRY
    +0x008 InMemoryOrderLinks : _LIST_ENTRY
    +0x010 InInitializationOrderLinks : _LIST_ENTRY
    +0x018 DllBase : Ptr32 Void
    +0x01c EntryPoint : Ptr32 Void
    +0x020 SizeOfImage : Uint4B
    +0x024 FullDllName : _UNICODE_STRING
    +0x02c BaseDllName : _UNICODE_STRING
    +0x034 Flags : Uint4B
    +0x038 LoadCount : Uint2B
    +0x03a TlsIndex : Uint2B
    +0x03c HashLinks : _LIST_ENTRY
    +0x03c SectionPointer : Ptr32 Void
    +0x040 CheckSum : Uint4B
    +0x044 TimeDateStamp : Uint4B
    +0x044 LoadedImports : Ptr32 Void
    +0x048 EntryPointActivationContext : Ptr32 Void
    +0x04c PatchInformation : Ptr32 Void
    """

    fields = [
        ("InLoadOrderLinks", ListEntry),
        ("InMemoryOrderLinks", ListEntry),
        ("InInitializationOrderLinks", ListEntry),
        ("DllBase", Ptr("<I", Void())),
        ("EntryPoint", Ptr("<I", Void())),
        ("SizeOfImage", Num("<I")),
        ("FullDllName", UnicodeString),
        ("BaseDllName", UnicodeString),
        ("Flags", Array(Num("B"), 4)),
        ("LoadCount", Num("H")),
        ("TlsIndex", Num("H")),
        ("union1",
         Union([
             ("HashLinks", Ptr("<I", Void())),
             ("SectionPointer", Ptr("<I", Void())),
         ])),
        ("CheckSum", Num("<I")),
        ("union2",
         Union([
             ("TimeDateStamp", Num("<I")),
             ("LoadedImports", Ptr("<I", Void())),
         ])),
        ("EntryPointActivationContext", Ptr("<I", Void())),
        ("PatchInformation", Ptr("<I", Void())),
    ]
Ejemplo n.º 11
0
class NT_TIB(MemStruct):
    """
    +00 struct _EXCEPTION_REGISTRATION_RECORD *ExceptionList
    +04 void *StackBase
    +08 void *StackLimit
    +0c void *SubSystemTib
    +10 void *FiberData
    +10 uint32 Version
    +14 void *ArbitraryUserPointer
    +18 struct _NT_TIB *Self
    """

    fields = [
        ("ExceptionList", Ptr("<I", EXCEPTION_REGISTRATION_RECORD)),
        ("StackBase", Ptr("<I", Void())),
        ("StackLimit", Ptr("<I", Void())),
        ("SubSystemTib", Ptr("<I", Void())),
        (None, Union([("FiberData", Ptr("<I", Void())),
                      ("Version", Num("<I"))])),
        ("ArbitraryUserPointer", Ptr("<I", Void())),
        ("Self", Ptr("<I", Self())),
    ]
Ejemplo n.º 12
0
assert bit.flags.f4_1 == 1


# Unhealthy ideas
class UnhealthyIdeas(MemStruct):
    fields = [
        ("pastruct", Ptr("I", Array(RawStruct("=Bf")))),
        ("apstr", Array(Ptr("I", Str()), 10)),
        ("pself", Ptr("I", Self())),
        ("apself", Array(Ptr("I", Self()), 2)),
        ("ppself", Ptr("I", Ptr("I", Self()))),
        ("pppself", Ptr("I", Ptr("I", Ptr("I", Self())))),
    ]


p_size = Ptr("I", Void()).size

ideas = UnhealthyIdeas(jitter.vm)
ideas.memset()
ideas.pself = ideas.get_addr()
assert ideas == ideas.pself.deref

ideas.apself[0] = ideas.get_addr()
assert ideas.apself[0].deref == ideas
ideas.apself[1] = my_heap.vm_alloc(jitter.vm, UnhealthyIdeas.sizeof())
ideas.apself[1].deref = ideas
assert ideas.apself[1] != ideas.get_addr()
assert ideas.apself[1].deref == ideas

ideas.ppself = my_heap.vm_alloc(jitter.vm, p_size)
ideas.ppself.deref.val = ideas.get_addr()
Ejemplo n.º 13
0
class LinkedList(MemStruct):
    fields = [
        # For convenience, either a Type instance (like Self() or Num("I") or a
        # MemStruct subclass can be passed to the Ptr constructor.
        ("head", Ptr("<I", ListNode)),
        ("tail", Ptr("<I", ListNode)),
        # Num can take any one-field struct-like format, including floats and
        # doubles
        ("size", Num("<I")),
    ]

    def get_head(self):
        """Returns the head ListNode instance"""
        if self.head == 0:
            return None
        return self.head.deref

    def get_tail(self):
        """Returns the tail ListNode instance"""
        if self.tail == 0:
            return None
        return self.tail.deref

    def push(self, data):
        """Push a data (MemType instance) to the linked list."""
        # Allocate a new node
        node = ListNode(self._vm)

        # Set the data pointer
        node.data = data.get_addr()

        # re-link
        if self.head != 0:
            # get the head ListNode
            head = self.get_head()
            node.next = head.get_addr()

        # pointer to head assigned to the new node address
        self.head = node.get_addr()

        # Do not forget the tail :)
        if self.tail == 0:
            self.tail = node.get_addr()

        self.size += 1

    def pop(self, data_type=None):
        """Pop one data from the LinkedList."""
        # Nothing to pop
        if self.head == 0:
            return None

        node = self.get_head()
        self.head = node.next

        # empty
        if self.head == 0:
            self.tail = 0

        self.size -= 1

        return node.get_data(data_type)

    def empty(self):
        """True if the list is empty."""
        return self.head == 0

    def __iter__(self):
        if not self.empty():
            cur = self.get_head()
            while cur is not None:
                yield cur.data.deref
                cur = cur.get_next()
Ejemplo n.º 14
0
class DataStr(MemStruct):
    fields = [
        ("valshort", Num("<H")),
        # Pointer to an utf16 null terminated string
        ("data", Ptr("<I", Str("utf16"))),
    ]
Ejemplo n.º 15
0
class UnicodeString(MemStruct):
    fields = [
        ("length", Num("H")),
        ("maxlength", Num("H")),
        ("data", Ptr("<I", Str("utf16"))),
    ]
Ejemplo n.º 16
0
class ListEntry(MemStruct):
    fields = [
        ("flink", Ptr("<I", Void())),
        ("blink", Ptr("<I", Void())),
    ]
Ejemplo n.º 17
0
class B(MemStruct):
    fields = [
        ("a", Ptr("I", A)),
    ]
Ejemplo n.º 18
0
raw_miams_array = [ord(c) for c in raw_miams]
assert list(data.array)[:len(raw_miams_array)] == raw_miams_array
assert data.array.cast(Str("utf16")) == memstr
# Default is "ansi"
assert data.array.cast(Str()) != memstr
assert data.array.cast(Str("utf16")).val == memstr.val

print "See that the original array has been modified:"
print repr(data)
print

# Some type manipulation examples, for example let's construct an argv for
# a program:
# Let's say that we have two arguments, +1 for the program name and +1 for the
# final null ptr in argv, the array has 4 elements:
argv_t = Array(Ptr("<I", Str()), 4)
print "3 arguments argv type:", argv_t

# alloc argv somewhere
argv = argv_t.lval(vm)

# Auto alloc with the MemStr.from_str helper
MemStrAnsi = Str().lval
argv[0].val = MemStrAnsi.from_str(vm, "./my-program").get_addr()
argv[1].val = MemStrAnsi.from_str(vm, "arg1").get_addr()
argv[2].val = MemStrAnsi.from_str(vm, "27").get_addr()
argv[3].val = 0

# If you changed your mind on the second arg, you could do:
argv[2].deref.val = "42"