def test_basic_types(self): # struct a - basic types offset = self.offsets['struct_a'][0] m = self.memory_handler.get_mapping_for_address(offset) my_ctypes = self.memory_handler.get_target_platform( ).get_target_ctypes() ret, validated = api.load_record(self.memory_handler, self.ctypes5_gen32.struct_a, offset) self.assertTrue(validated) self.assertEquals(int(self.sizes['struct_a']), my_ctypes.sizeof(ret)) parser = python.PythonOutputter(self.memory_handler) a = parser.parse(ret) self.assertEquals(int(self.values['struct_a.a']), a.a) self.assertEquals(int(self.values['struct_a.b']), a.b) self.assertEquals(int(self.values['struct_a.c']), a.c) self.assertEquals(int(self.values['struct_a.d']), a.d) self.assertEquals(int(self.values['struct_a.e']), a.e) self.assertEquals(float(self.values['struct_a.f']), a.f) self.assertEquals(float(self.values['struct_a.g']), a.g) self.assertEquals(float(self.values['struct_a.h']), a.h) offset = self.offsets['union_au'][0] m = self.memory_handler.get_mapping_for_address(offset) au, validated = api.load_record(self.memory_handler, self.ctypes5_gen32.union_au, offset) self.assertTrue(validated) au = parser.parse(au) self.assertEquals(int(self.values['union_au.d']), au.d) self.assertEquals(float(self.values['union_au.g']), au.g) self.assertEquals(float(self.values['union_au.h']), au.h) return
def test_basic_types(self): # struct a - basic types offset = self.offsets['struct_a'][0] m = self.memory_handler.get_mapping_for_address(offset) my_ctypes = self.memory_handler.get_target_platform().get_target_ctypes() ret, validated = api.load_record(self.memory_handler, self.ctypes5_gen32.struct_a, offset) self.assertTrue(validated) self.assertEqual(int(self.sizes['struct_a']), my_ctypes.sizeof(ret)) parser = python.PythonOutputter(self.memory_handler) a = parser.parse(ret) self.assertEqual(int(self.values['struct_a.a']), a.a) self.assertEqual(int(self.values['struct_a.b']), a.b) self.assertEqual(int(self.values['struct_a.c']), a.c) self.assertEqual(int(self.values['struct_a.d']), a.d) self.assertEqual(int(self.values['struct_a.e']), a.e) self.assertEqual(float(self.values['struct_a.f']), a.f) self.assertEqual(float(self.values['struct_a.g']), a.g) self.assertEqual(float(self.values['struct_a.h']), a.h) offset = self.offsets['union_au'][0] m = self.memory_handler.get_mapping_for_address(offset) au, validated = api.load_record(self.memory_handler, self.ctypes5_gen32.union_au, offset) self.assertTrue(validated) au = parser.parse(au) self.assertEqual(int(self.values['union_au.d']), au.d) self.assertEqual(float(self.values['union_au.g']), au.g) self.assertEqual(float(self.values['union_au.h']), au.h) return
def watch(args): """ structname watch vaddr [refreshrate] [varname] :param opt: :return: """ memory_address = args.addr refresh = args.refresh_rate varname = args.varname # we need an int # get the memory handler adequate for the type requested memory_handler = _get_memory_handler(args) # check the validity of the address heap = memory_handler.is_valid_address_value(memory_address) if not heap: log.error("the address is not accessible in the memoryMap") raise ValueError("the address is not accessible in the memoryMap") # get the structure name modulename, sep, classname = args.struct_name.rpartition('.') module = memory_handler.get_model().import_module(modulename) struct_type = getattr(module, classname) # verify target fieldcompliance if varname is not None: varname = varname.split('.') if not check_varname_for_type(memory_handler, varname, struct_type): return False # load the record result = api.load_record(memory_handler, struct_type, memory_address) results = [result] # output handling output = api.output_to_python(memory_handler, results) py_obj = output[0][0] # print pyObj # print as asked every n secs. while True: # clear terminal print chr(27) + "[2J" # if varname is None: print py_obj else: print get_varname_value(varname, py_obj) if refresh == 0: break time.sleep(refresh) result = api.load_record(memory_handler, struct_type, memory_address) results = [result] # output handling output = api.output_to_python(memory_handler, results) py_obj = output[0][0]
def watch(args): """Cast the bytes at this address into a record_type and refresh regularly. """ memory_address = args.addr refresh = args.refresh_rate varname = args.varname # get the memory handler adequate for the type requested memory_handler = get_memory_handler(args) # check the validity of the address heap = memory_handler.is_valid_address_value(memory_address) if not heap: log.error("the address is not accessible in the memoryMap") raise ValueError("the address is not accessible in the memoryMap") # get the structure name modulename, sep, classname = args.record_type_name.rpartition('.') module = None try: module = memory_handler.get_model().import_module(modulename) except ImportError as e: log.error('sys.path is %s', sys.path) raise e record_type = getattr(module, classname) # verify target fieldcompliance if varname is not None: varname = varname.split('.') if not check_varname_for_type(memory_handler, varname, record_type): return False # load the record result = api.load_record(memory_handler, record_type, memory_address) results = [result] # output handling output = api.output_to_python(memory_handler, results) # _get_output(memory_handler, results, rtype): # Conflicts with varname py_obj = output[0][0] # print pyObj # print as asked every n secs. while True: # clear terminal print chr(27) + "[2J" # if varname is None: print py_obj else: print get_varname_value(varname, py_obj) if refresh == 0: break time.sleep(refresh) result = api.load_record(memory_handler, record_type, memory_address) results = [result] # output handling output = api.output_to_python(memory_handler, results) py_obj = output[0][0]
def watch(args): """Cast the bytes at this address into a record_type and refresh regularly. """ memory_address = args.addr refresh = args.refresh_rate varname = args.varname # get the memory handler adequate for the type requested memory_handler = get_memory_handler(args) # check the validity of the address heap = memory_handler.is_valid_address_value(memory_address) if not heap: log.error("the address is not accessible in the memoryMap") raise ValueError("the address is not accessible in the memoryMap") # get the structure name modulename, sep, classname = args.record_type_name.rpartition('.') module = None try: module = memory_handler.get_model().import_module(modulename) except ImportError as e: log.error('sys.path is %s', sys.path) raise e record_type = getattr(module, classname) # verify target fieldcompliance if varname is not None: varname = varname.split('.') if not check_varname_for_type(memory_handler, varname, record_type): return False # load the record result = api.load_record(memory_handler, record_type, memory_address) results = [result] # output handling output = api.output_to_python(memory_handler, results) # _get_output(memory_handler, results, rtype): # Conflicts with varname py_obj = output[0][0] # print pyObj # print as asked every n secs. while True: # clear terminal print(chr(27) + "[2J") # if varname is None: print(py_obj) else: print(get_varname_value(varname, py_obj)) if refresh == 0: break time.sleep(refresh) result = api.load_record(memory_handler, record_type, memory_address) results = [result] # output handling output = api.output_to_python(memory_handler, results) py_obj = output[0][0]
def test_complex_text(self): # struct a - basic types offset = self.offsets['struct_d'][0] m = self.memory_handler.get_mapping_for_address(offset) # d = m.read_struct(offset, self.ctypes5_gen32.struct_d) results, validated = api.load_record(self.memory_handler, self.ctypes5_gen32.struct_d, offset) self.assertTrue(results) parser = text.RecursiveTextOutputter(self.memory_handler) out = parser.parse(results) # should not fail x = eval(out) self.assertEquals(len(x.keys()), 15) # 14 + padding self.assertEquals(self.values['struct_d.a'], hex(x['a'])) self.assertEquals(len(x['b'].keys()), 9) self.assertEquals(len(x['b2'].keys()), 8) self.assertEquals(int(self.values['struct_d.b.e']), x['b']['e']) self.assertEquals(int(self.values['struct_d.b2.e']), x['b2']['e']) for i in range(9): self.assertEquals( int(self.values['struct_d.c[%d].a' % (i)]), x['c'][i]['a']) self.assertEquals( int(self.values['struct_d.f[%d]' % (i)]), x['f'][i]) self.assertEquals(int(self.values['struct_d.e']), x['e']) self.assertEquals(str(self.values['struct_d.i']), x['i']) return
def test_complex_text(self): # struct a - basic types offset = self.offsets['struct_d'][0] m = self.memory_handler.get_mapping_for_address(offset) # d = m.read_struct(offset, self.ctypes5_gen32.struct_d) results, validated = api.load_record(self.memory_handler, self.ctypes5_gen32.struct_d, offset) self.assertTrue(results) parser = text.RecursiveTextOutputter(self.memory_handler) out = parser.parse(results) # should not fail x = eval(out) self.assertEqual(len(x.keys()), 15) # 14 + padding # its an byte string, that is a hex value. self.assertEqual(self.values['struct_d.a'], hex(x['a']).encode()) self.assertEqual(len(x['b'].keys()), 9) self.assertEqual(len(x['b2'].keys()), 8) self.assertEqual(int(self.values['struct_d.b.e']), x['b']['e']) self.assertEqual(int(self.values['struct_d.b2.e']), x['b2']['e']) for i in range(9): self.assertEqual(int(self.values['struct_d.c[%d].a' % (i)]), x['c'][i]['a']) self.assertEqual(int(self.values['struct_d.f[%d]' % (i)]), x['f'][i]) self.assertEqual(int(self.values['struct_d.e']), x['e']) self.assertEqual(self.values['struct_d.i'], x['i']) return
def test_complex(self): # struct a - basic types offset = self.offsets['struct_d'][0] m = self.memory_handler.get_mapping_for_address(offset) my_ctypes = self.memory_handler.get_target_platform().get_target_ctypes() d, validated = api.load_record(self.memory_handler, self.ctypes5_gen32.struct_d, offset) self.assertTrue(validated) self.assertEqual(int(self.sizes['struct_d']), my_ctypes.sizeof(d)) parser = python.PythonOutputter(self.memory_handler) obj = parser.parse(d) # check Ctypes values too self.assertEqual(d.a.value, self.offsets['struct_d'][0]) self.assertEqual(d.b.value, self.offsets['struct_d.b'][0]) self.assertEqual(d.b2.value, self.offsets['struct_d.b2'][0]) # check python calues for i in range(9): self.assertEqual( int(self.values['struct_d.c[%d].a' % i]), obj.c[i].a) self.assertEqual( int(self.values['struct_d.f[%d]' % i]), obj.f[i]) self.assertEqual(int(self.values['struct_d.e']), obj.e) self.assertEqual(self.values['struct_d.i'], obj.i) return
def test_complex(self): # struct a - basic types offset = self.offsets['struct_d'][0] m = self.memory_handler.get_mapping_for_address(offset) my_ctypes = self.memory_handler.get_target_platform( ).get_target_ctypes() d, validated = api.load_record(self.memory_handler, self.ctypes5_gen32.struct_d, offset) self.assertTrue(validated) self.assertEquals(int(self.sizes['struct_d']), my_ctypes.sizeof(d)) parser = python.PythonOutputter(self.memory_handler) obj = parser.parse(d) # check Ctypes values too self.assertEquals(d.a.value, self.offsets['struct_d'][0]) self.assertEquals(d.b.value, self.offsets['struct_d.b'][0]) self.assertEquals(d.b2.value, self.offsets['struct_d.b2'][0]) # check python calues for i in range(9): self.assertEquals(int(self.values['struct_d.c[%d].a' % i]), obj.c[i].a) self.assertEquals(int(self.values['struct_d.f[%d]' % i]), obj.f[i]) self.assertEquals(int(self.values['struct_d.e']), obj.e) self.assertEquals(str(self.values['struct_d.i']), obj.i) return
def test_bitfield(self): # struct a - basic types offset = self.offsets['struct_c'][0] m = self.memory_handler.get_mapping_for_address(offset) my_ctypes = self.memory_handler.get_target_platform().get_target_ctypes() c, validated = api.load_record(self.memory_handler, self.ctypes5_gen32.struct_c, offset) self.assertTrue(validated) self.assertEqual(int(self.sizes['struct_c']), my_ctypes.sizeof(c)) parser = python.PythonOutputter(self.memory_handler) c = parser.parse(c) self.assertEqual(int(self.values['struct_c.a1']), c.a1) self.assertEqual(int(self.values['struct_c.b1']), c.b1) self.assertEqual(int(self.values['struct_c.c1']), c.c1) self.assertEqual(int(self.values['struct_c.d1']), c.d1) # should be 'A' but is 65 because of bitfield #self.assertEqual(self.values['struct_c.a2'], c.a2) self.assertEqual(ord(self.values['struct_c.a2']), c.a2) self.assertEqual(int(self.values['struct_c.b2']), c.b2) self.assertEqual(int(self.values['struct_c.c2']), c.c2) self.assertEqual(int(self.values['struct_c.d2']), c.d2) self.assertEqual(int(self.values['struct_c.h']), c.h) return
def test_bitfield(self): # struct a - basic types offset = self.offsets['struct_c'][0] m = self.memory_handler.get_mapping_for_address(offset) my_ctypes = self.memory_handler.get_target_platform( ).get_target_ctypes() c, validated = api.load_record(self.memory_handler, self.ctypes5_gen32.struct_c, offset) self.assertTrue(validated) self.assertEquals(int(self.sizes['struct_c']), my_ctypes.sizeof(c)) parser = python.PythonOutputter(self.memory_handler) c = parser.parse(c) self.assertEquals(int(self.values['struct_c.a1']), c.a1) self.assertEquals(int(self.values['struct_c.b1']), c.b1) self.assertEquals(int(self.values['struct_c.c1']), c.c1) self.assertEquals(int(self.values['struct_c.d1']), c.d1) self.assertEquals(str(self.values['struct_c.a2']), c.a2) self.assertEquals(int(self.values['struct_c.b2']), c.b2) self.assertEquals(int(self.values['struct_c.c2']), c.c2) self.assertEquals(int(self.values['struct_c.d2']), c.d2) self.assertEquals(int(self.values['struct_c.h']), c.h) return
def test_load(self): valid = self.offsets['test3'] for x in valid: instance, validated = api.load_record(self.memory_handler, self.ctypes3.struct_test3, x) self.assertTrue(validated) self.assertEqual(instance.val1, 0xdeadbeef) self.assertEqual(instance.val1b, 0xdeadbeef) self.assertEqual(instance.val2, 0x10101010) self.assertEqual(instance.val2b, 0x10101010) self.assertEqual(self.my_utils.get_pointee_address(instance.me), x) valid = self.offsets['test1'] for x in valid: instance, validated = api.load_record(self.memory_handler, self.ctypes3.struct_Node, x) self.assertTrue(validated) self.assertEqual(instance.val1, 0xdeadbeef) self.assertEqual(self.my_utils.get_pointee_address(instance.ptr1), x) self.assertEqual(self.my_utils.get_pointee_address(instance.ptr2), x)
def refresh(args): """ Default function for the refresh command line option. Try to map a Structure from a specific offset in memory. Returns it in pickled or text format. See the command line --help . """ # we need an int memory_address = args.addr # get the memory handler adequate for the type requested memory_handler = _get_memory_handler(args) # print output on stdout rtype = _get_output_style(args) # check the validity of the address heap = memory_handler.is_valid_address_value(memory_address) if not heap: log.error("the address is not accessible in the memoryMap") raise ValueError("the address is not accessible in the memoryMap") # get the structure name modulename, sep, classname = args.struct_name.rpartition('.') module = memory_handler.get_model().import_module(modulename) struct_type = getattr(module, classname) # load the record result = api.load_record(memory_handler, struct_type, memory_address) results = [result] if args.validate: my_constraints = None if args.constraints_file: handler = constraints.ConstraintsConfigHandler() my_constraints = handler.read(args.constraints_file.name) validation = api.validate_record(memory_handler, result[0], my_constraints) if args.interactive: import code code.interact(local=locals()) # output handling ret = None if rtype == 'string': ret = api.output_to_string(memory_handler, results) elif rtype == 'python': ret = api.output_to_python(memory_handler, results) elif rtype == 'json': ret = api.output_to_json(memory_handler, results) elif rtype == 'pickled': ret = api.output_to_pickle(memory_handler, results) else: raise ValueError('unknown output format') print ret if args.validate: print 'Validated', validation return
def show_cmdline(args): """Cast the bytes at this address into a record_type. """ # we need an int memory_address = args.address # get the memory handler adequate for the type requested memory_handler = get_memory_handler(args) # check the validity of the address heap = memory_handler.is_valid_address_value(memory_address) if not heap: log.error("the address is not accessible in the memoryMap") raise ValueError("the address is not accessible in the memoryMap") # get the structure name modulename, sep, classname = args.record_type_name.rpartition('.') module = None try: module = memory_handler.get_model().import_module(modulename) except ImportError as e: log.error('sys.path is %s', sys.path) raise e record_type = getattr(module, classname) # load the record result = api.load_record(memory_handler, record_type, memory_address) results = [result] # validate if required validation = None if args.constraints_file: handler = constraints.ConstraintsConfigHandler() my_constraints = handler.read(args.constraints_file.name) validation = api.validate_record(memory_handler, result[0], my_constraints) # output handling ret = None try: ret = get_output(memory_handler, results, args.output) # print output on stdout print ret if args.constraints_file: print 'Validated', validation except Exception as e: log.error(e) finally: if args.interactive: print 'results are local variable "results"' import code code.interact(local=locals()) return
def test_basic_signed_types(self): # union b - basic types offset = self.offsets['union_b'][0] m = self.memory_handler.get_mapping_for_address(offset) my_ctypes = self.memory_handler.get_target_platform().get_target_ctypes() ret, validated = api.load_record(self.memory_handler, self.ctypes5_gen32.union_b, offset) self.assertTrue(ret) parser = python.PythonOutputter(self.memory_handler) b = parser.parse(ret) self.assertEqual(int(self.values['union_b.a']), b.a) self.assertEqual(int(self.values['union_b.b']), b.b) self.assertEqual(int(self.values['union_b.c']), b.c) self.assertEqual(int(self.values['union_b.d']), b.d) self.assertEqual(int(self.values['union_b.e']), b.e) # char 251 self.assertEqual((self.values['union_b.g']), b.g) return
def test_weird_py3_bug(self): # RESULT: PY3 pickling works if model includes all pythoned module hierachy results, validated = api.load_record(self.memory_handler, self.usual, self.address1) # check the string output retstr = api.output_to_string(self.memory_handler, [(results, validated)]) self.assertTrue(isinstance(retstr, str)) ret = api.output_to_python(self.memory_handler, [(results, validated)]) # check subclass in model module x = pickle.dumps(ret) # Python 2 # self.assertIn(b'test.src.ctypes6_gen32.struct_usual_py', x) # Python 3 self.assertIn(b'struct_usual_py', x) # TODO TEST really, you should be able to load the pickled code as long as haystack.outputters.python is there # and still be able to load the object graph. obj = pickle.loads(x) self.assertEqual(obj[0][0].root.blink, obj[0][0].root.flink) self.assertEqual(obj[0][0].root.blink.flink, obj[0][0].root.flink.flink) return
def test_basic_signed_types(self): # union b - basic types offset = self.offsets['union_b'][0] m = self.memory_handler.get_mapping_for_address(offset) my_ctypes = self.memory_handler.get_target_platform( ).get_target_ctypes() ret, validated = api.load_record(self.memory_handler, self.ctypes5_gen32.union_b, offset) self.assertTrue(ret) parser = python.PythonOutputter(self.memory_handler) b = parser.parse(ret) self.assertEquals(int(self.values['union_b.a']), b.a) self.assertEquals(int(self.values['union_b.b']), b.b) self.assertEquals(int(self.values['union_b.c']), b.c) self.assertEquals(int(self.values['union_b.d']), b.d) self.assertEquals(int(self.values['union_b.e']), b.e) # char 251 self.assertEquals((self.values['union_b.g']), b.g) return
def test_refresh(self): #handler = constraints.ConstraintsConfigHandler() #my_constraints = handler.read('test/src/ctypes6.constraints') #results = api.search_record(self.memory_handler, self.usual_structname, my_constraints) # search struct_usual with constraints results, validated = api.load_record(self.memory_handler, self.usual, self.address1) # check the string output retstr = api.output_to_string(self.memory_handler, [(results, validated)]) self.assertTrue(isinstance(retstr, str)) # string #retstr = api.show_dumpname(self.usual_structname, self.memdumpname, # self.address1, rtype='string') self.assertIn(str(0x0aaaaaaa), retstr) # 0xaaaaaaa/178956970L self.assertIn(str(0x0ffffff0), retstr) self.assertIn('"val2b": 0', retstr) self.assertIn('"val1b": 0', retstr) # usual->root.{f,b}link = &node1->list; # offset list is (wordsize) bytes ## TU results based on __book node1_list_addr = hex(self.address2 + self.my_target.get_word_size()) self.assertIn('"flink": { # <struct_entry at %s' % node1_list_addr, retstr) self.assertIn('"blink": { # <struct_entry at %s' % node1_list_addr, retstr) ## TU results based on direct access #node1_list_addr = self.address2 + self.my_target.get_word_size() #self.assertIn('"flink": 0x%0.8x' % node1_list_addr, retstr) #self.assertIn('"blink": 0x%0.8x' % node1_list_addr, retstr) # python usuals = api.output_to_python(self.memory_handler, [(results, validated)]) usual, validated = usuals[0] self.assertEqual(validated, True) self.assertEqual(usual.val1, 0x0aaaaaaa) self.assertEqual(usual.val2, 0x0ffffff0) self.assertEqual(usual.txt, b'This a string with a test this is a test string') # so now we got python objects # that is node 1 self.assertIsNotNone(usual.root.flink) self.assertEqual(usual.root.flink, usual.root.blink) #print usual.root.flink # that is node2 self.assertEqual(usual.root.blink.flink, usual.root.flink.flink) # that is None (root.flink = root.blink) self.assertIsNone(usual.root.blink.blink) self.assertIsNone(usual.root.flink.blink) # that is None per design UT self.assertIsNone(usual.root.blink.flink.flink) # python 2 struct Node results, validated = api.load_record(self.memory_handler, self.node, self.address2) node1s = api.output_to_python(self.memory_handler, [(results, validated)]) node1, validated = node1s[0] self.assertEqual(validated, True) self.assertEqual(node1.val1, 0xdeadbeef) self.assertEqual(node1.val2, 0xffffffff) results, validated = api.load_record(self.memory_handler, self.node, self.address3) node2s = api.output_to_python(self.memory_handler, [(results, validated)]) node2, validated = node2s[0] self.assertEqual(validated, True) self.assertEqual(node2.val1, 0xdeadbabe) self.assertEqual(node2.val2, 0xffffffff) self.assertIsNotNone(usual.root.flink) # FIXME this was assertNotEquals. Why would the python obj be equals now ? # but we have different instances/references between calls to # show_dumpname self.assertEqual(usual.root.flink, node1.list) self.assertEqual(usual.root.blink.flink, node2.list)