about summary refs log tree commit diff stats
path: root/example/jitter/memstruct.py
diff options
context:
space:
mode:
authorFlorent Monjalet <florent.monjalet@gmail.com>2015-11-30 15:25:27 +0100
committerFlorent Monjalet <florent.monjalet@gmail.com>2016-01-18 14:02:31 +0100
commit31650c36e3c079445fe6c26fc0a40c1bd19da57d (patch)
treeba83d10ec66a5ab61dc049a063a542a64aa3b450 /example/jitter/memstruct.py
parent3c8d4335d26a33d3e14be83ef8b1d7ceed3ad769 (diff)
downloadmiasm-31650c36e3c079445fe6c26fc0a40c1bd19da57d.tar.gz
miasm-31650c36e3c079445fe6c26fc0a40c1bd19da57d.zip
MemStruct: Global doc update
Diffstat (limited to '')
-rw-r--r--example/jitter/memstruct.py38
1 files changed, 22 insertions, 16 deletions
diff --git a/example/jitter/memstruct.py b/example/jitter/memstruct.py
index 3b6358cd..77d65d17 100644
--- a/example/jitter/memstruct.py
+++ b/example/jitter/memstruct.py
@@ -13,10 +13,11 @@ from miasm2.os_dep.common import heap
 # Instanciate a heap
 my_heap = heap()
 # And set it as the default memory allocator, to avoid manual allocation and
-# explicit address passing to the PinnedStruct constructor
+# explicit address passing to the PinnedType subclasses (like PinnedStruct)
+# constructor
 set_allocator(my_heap.vm_alloc)
 
-# Let's reimplement a simple C generic linked list mapped on a VmMngr!
+# Let's reimplement a simple C generic linked list mapped on a VmMngr.
 
 # All the structures and methods will use the python objects but all the data
 # is in fact stored in the VmMngr
@@ -24,14 +25,14 @@ set_allocator(my_heap.vm_alloc)
 class ListNode(PinnedStruct):
     fields = [
         # The "<I" is the struct-like format of the pointer in memory, in this
-        # case a Little Endian 32 bits unsigned int
+        # case a Little Endian 32 bits unsigned int.
         # One way to handle reference to ListNode in ListNode is to use the
-        # special marker PinnedSelf.
-        # You could also set or modify ListNode.fields after the class
-        # declaration and call ListNode.gen_fields()
+        # 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(_, PinnedVoid) is analogous to void*, PinnedVoid is just an empty
-        # PinnedStruct type
+        # Ptr(_, Void()) is analogous to void*, Void() is a kind of "empty type"
         ("data", Ptr("<I", Void())),
     ]
 
@@ -49,6 +50,8 @@ class ListNode(PinnedStruct):
 
 class LinkedList(PinnedStruct):
     fields = [
+        # For convenience, either a Type instance (like Self() or Num("I") or a
+        # PinnedStruct 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
@@ -63,11 +66,13 @@ class LinkedList(PinnedStruct):
         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 (PinnedType instance) to the linked list."""
         # Allocate a new node
         node = ListNode(self._vm)
 
@@ -90,6 +95,7 @@ class LinkedList(PinnedStruct):
         self.size += 1
 
     def pop(self, data_type=None):
+        """Pop one data from the LinkedList."""
         # Nothing to pop
         if self.head == 0:
             return None
@@ -106,6 +112,7 @@ class LinkedList(PinnedStruct):
         return node.get_data(data_type)
 
     def empty(self):
+        """True if the list is empty."""
         return self.head == 0
 
     def __iter__(self):
@@ -122,10 +129,9 @@ class DataArray(PinnedStruct):
     fields = [
         ("val1", Num("B")),
         ("val2", Num("B")),
-        # Ptr can also be instanciated with a PinnedField as an argument, a special
-        # PinnedStruct containing only one field named "val" will be created, so
-        # that Ptr can point to a PinnedStruct instance. Here,
-        # data_array.array.deref.val will allow to access an Array
+        # Ptr can also be instanciated with a Type instance as an argument, the
+        # corresponding Pinnedtype 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)),
@@ -133,7 +139,7 @@ class DataArray(PinnedStruct):
 
 class DataStr(PinnedStruct):
     fields = [
-        ("valshort", Num("H")),
+        ("valshort", Num("<H")),
         # Pointer to an utf16 null terminated string
         ("data", Ptr("<I", Str("utf16"))),
     ]
@@ -150,7 +156,8 @@ jitter = Machine("x86_32").jitter("python")
 vm = jitter.vm
 
 # Auto-allocated by my_heap. If you allocate memory at `addr`,
-# `link = LinkedList(vm, addr)` will use this allocation.
+# `link = LinkedList(vm, addr)` will use this allocation. If you just want
+# to read/modify existing struct, you may want to use the (vm, addr) syntax.
 link = LinkedList(vm)
 # memset the struct (with '\x00' by default)
 link.memset()
@@ -181,6 +188,7 @@ print
 data = link.pop(DataArray)
 assert link.size == 2
 # Make the Array Ptr point to the data's array field
+# Note: this is equivalent to data.arrayptr.val = ...
 data.arrayptr = data.get_addr("array")
 # Now the pointer dereference is equal to the array field's value
 assert data.arrayptr.deref == data.array
@@ -193,10 +201,8 @@ print repr(datastr)
 print
 
 # data and datastr really share the same memory:
-# Set these fields for later
 data.val1 = 0x34
 data.val2 = 0x12
-
 assert datastr.valshort == 0x1234
 datastr.valshort = 0x1122
 assert data.val1 == 0x22 and data.val2 == 0x11