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())))), ]
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"))), ]
## Same stuff for Ptr to MemField alloc_addr = my_heap.vm_alloc(jitter.vm, mstruct.get_type().get_field_type("i") .dst_type.size) mstruct.i = alloc_addr mstruct.i.deref.val = 8 assert mstruct.i.deref.val == 8 assert mstruct.i.val == alloc_addr memval = struct.unpack("I", jitter.vm.get_mem(alloc_addr, 4))[0] assert memval == 8 # Str tests ## Basic tests memstr = Str().lval(jitter.vm, addr_str) memstr.val = "" assert memstr.val == "" assert jitter.vm.get_mem(memstr.get_addr(), 1) == b'\x00' memstr.val = "lala" assert jitter.vm.get_mem(memstr.get_addr(), memstr.get_size()) == b'lala\x00' jitter.vm.set_mem(memstr.get_addr(), b'MIAMs\x00') assert memstr.val == 'MIAMs' ## Ptr(Str()) manipulations mstruct.s.val = memstr.get_addr() assert mstruct.s.val == addr_str assert mstruct.s.deref == memstr assert mstruct.s.deref.val == 'MIAMs' mstruct.s.deref.val = "That's all folks!" assert mstruct.s.deref.val == "That's all folks!"
class DataStr(MemStruct): fields = [ ("valshort", Num("<H")), # Pointer to an utf16 null terminated string ("data", Ptr("<I", Str("utf16"))), ]
assert data.val1 == 0x22 and data.val2 == 0x11 # Let's play with strings memstr = datastr.data.deref # Note that memstr is Str("utf16") memstr.val = 'Miams' print("Cast data.array to MemStr and set the string value:") print(repr(memstr)) print() # If you followed, memstr and data.array point to the same object, so: raw_miams = 'Miams'.encode('utf-16le') + b'\x00' * 2 raw_miams_array = [ord(c) for c in iterbytes(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)
class UnicodeString(MemStruct): fields = [ ("length", Num("H")), ("maxlength", Num("H")), ("data", Ptr("<I", Str("utf16"))), ]
assert other == other2 # But same value ## Same stuff for Ptr to MemField alloc_addr = my_heap.vm_alloc( jitter.vm, mstruct.get_type().get_field_type("i").dst_type.size) mstruct.i = alloc_addr mstruct.i.deref.val = 8 assert mstruct.i.deref.val == 8 assert mstruct.i.val == alloc_addr memval = struct.unpack("I", jitter.vm.get_mem(alloc_addr, 4))[0] assert memval == 8 # Str tests ## Basic tests memstr = Str().lval(jitter.vm, addr_str) memstr.val = "" assert memstr.val == "" assert jitter.vm.get_mem(memstr.get_addr(), 1) == b'\x00' memstr.val = "lala" assert jitter.vm.get_mem(memstr.get_addr(), memstr.get_size()) == b'lala\x00' jitter.vm.set_mem(memstr.get_addr(), b'MIAMs\x00') assert memstr.val == 'MIAMs' ## Ptr(Str()) manipulations mstruct.s.val = memstr.get_addr() assert mstruct.s.val == addr_str assert mstruct.s.deref == memstr assert mstruct.s.deref.val == 'MIAMs' mstruct.s.deref.val = "That's all folks!" assert mstruct.s.deref.val == "That's all folks!"
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" print("An argv instance:", repr(argv)) print("argv values:", repr([val.deref.val for val in argv[:-1]])) print() print("See test/core/types.py and the miasm.core.types module doc for ") print("more information.")