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 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)), ]
class ContextException(MemStruct): fields = [ ("ContextFlags", Num("<I")), ("dr0", Num("<I")), ("dr1", Num("<I")), ("dr2", Num("<I")), ("dr3", Num("<I")), ("dr4", Num("<I")), ("dr5", Num("<I")), ("Float", Array(Num("B"), 112)), ("gs", Num("<I")), ("fs", Num("<I")), ("es", Num("<I")), ("ds", Num("<I")), ("edi", Num("<I")), ("esi", Num("<I")), ("ebx", Num("<I")), ("edx", Num("<I")), ("ecx", Num("<I")), ("eax", Num("<I")), ("ebp", Num("<I")), ("eip", Num("<I")), ("cs", Num("<I")), ("eflags", Num("<I")), ("esp", Num("<I")), ("ss", Num("<I")), ]
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())), ]
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")), ]
class MyStruct2(MemStruct): fields = [ ("s1", RawStruct("=BI")), ("s2", Array(Num("B"), 10)), ]
memstr2.val = "That's all folks!" assert memstr2.get_addr() != memstr.get_addr() assert memstr2 == memstr ## Same value, other encoding memstr3 = Str("utf16").lval(jitter.vm, addr_str3) memstr3.val = "That's all folks!" assert memstr3.get_addr() != memstr.get_addr() assert memstr3.get_size() != memstr.get_size() # Size is different assert str(memstr3) != str(memstr) # Mem representation is different assert memstr3 != memstr # Encoding is different, so they are not eq assert memstr3.val == memstr.val # But the python value is the same # Array tests # Construction methods assert Array(MyStruct) == Array(MyStruct.get_type()) assert Array(MyStruct, 10) == Array(MyStruct.get_type(), 10) # Allocate buffer manually, since memarray is unsized alloc_addr = my_heap.vm_alloc(jitter.vm, 0x100) memarray = Array(Num("I")).lval(jitter.vm, alloc_addr) memarray[0] = 0x02 assert memarray[0] == 0x02 assert jitter.vm.get_mem(memarray.get_addr(), Num("I").size) == '\x02\x00\x00\x00' memarray[2] = 0xbbbbbbbb assert memarray[2] == 0xbbbbbbbb assert jitter.vm.get_mem(memarray.get_addr() + 2 * Num("I").size, Num("I").size) == '\xbb\xbb\xbb\xbb' try: s = str(memarray) assert False, "Should raise"
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"
memstr3 = Str("utf16").lval(jitter.vm, addr_str3) memstr3.val = "That's all folks!" assert memstr3.get_addr() != memstr.get_addr() assert memstr3.get_size() != memstr.get_size() # Size is different assert str(memstr3) != str(memstr) # Mem representation is different assert memstr3 != memstr # Encoding is different, so they are not eq assert memstr3.val == memstr.val # But the python value is the same # Array tests # Construction methods assert Array(MyStruct) == Array(MyStruct.get_type()) assert Array(MyStruct, 10) == Array(MyStruct.get_type(), 10) # Allocate buffer manually, since memarray is unsized alloc_addr = my_heap.vm_alloc(jitter.vm, 0x100) memarray = Array(Num("I")).lval(jitter.vm, alloc_addr) memarray[0] = 0x02 assert memarray[0] == 0x02 assert jitter.vm.get_mem(memarray.get_addr(), Num("I").size) == '\x02\x00\x00\x00' memarray[2] = 0xbbbbbbbb assert memarray[2] == 0xbbbbbbbb assert jitter.vm.get_mem(memarray.get_addr() + 2 * Num("I").size, Num("I").size) == '\xbb\xbb\xbb\xbb' try: s = str(memarray) assert False, "Should raise" except (NotImplementedError, ValueError): pass try: s = len(memarray)
argzero_addr = 0x141166 sb.jitter.vm.add_memory_page(passwd_addr,PAGE_READ | PAGE_WRITE,ascii_letters[:30] + '\x00','required input') sb.jitter.vm.add_memory_page(argzero_addr,PAGE_READ,'reverseMe\x00','argv[0] -> program path') sb.jitter.push_uint32_t(passwd_addr) #argv[1] sb.jitter.push_uint32_t(argzero_addr) #argv[0] sb.jitter.push_uint32_t(0x2) #argc ''' #Set default allocator from class heap() set_allocator(heap().vm_alloc) #implementing argv[] array busing core types of miasm2 argv_t = Array(Ptr("<I",Str()),3) argv = argv_t.lval(sb.jitter.vm) MemStrAnsi = Str().lval argv[0].val = MemStrAnsi.from_str(sb.jitter.vm, "./reverseMe").get_addr() argv[1].val = MemStrAnsi.from_str(sb.jitter.vm, ascii_letters[:28]).get_addr() argv[2].val = 0 sb.jitter.push_uint32_t(argv[2].val) #argv[2] sb.jitter.push_uint32_t(argv[1].val) #argv[1] sb.jitter.push_uint32_t(argv[0].val) #argv[0] sb.jitter.push_uint32_t(0x2) #argc #Handle INT \x80 exception and dump memory region def dump(jitter):