def unlink(engine: Engine): try: name = engine.read_string() os_.unlink(name) engine.write_int(0) except OSError as e: engine.write_int(map_errno(int(str(e)), errno, Flags))
def fstat(engine: Engine): try: fd = engine.read_int() st = os_.fstat(fd) engine.write_int(0) write_stat(engine, st) except OSError as e: engine.write_int(map_errno(int(str(e)), errno, Flags))
def stat_(engine: Engine): try: file = engine.read_string() st = os_.stat(file) engine.write_int(0) write_stat(engine, st) except OSError as e: engine.write_int(map_errno(int(str(e)), errno, Flags))
def open_unchecked(engine: Engine): file = engine.read_string() try: flags = map_open_flags(engine.read_int(), Flags, os_) mode = map_file_mode(engine.read_int(), Flags, os_) target_fd = engine.read_int() unchecked_map[target_fd] = os_.open(file, flags, mode) except OSError as e: print("Error opening file {} : {}".format(file, e), file=sys.stderr)
def invoke(self, engine: Engine, macro_expansion: MacroExpansion): engine.write_int(len(self.argv)) data = b'\0'.join(arg.encode() for arg in self.argv) + b'\0' res = engine.write_memory(data) if res != len(data): print( "***metal.serial***: Couldn't write all of argv, buffer size was {}" .format(res), file=sys.stderr)
def open_full(engine: Engine): try: file = engine.read_string() flags = map_open_flags(engine.read_int(), Flags, os_) mode = map_file_mode(engine.read_int(), Flags, os_) engine.write_int(os_.open(file, flags, mode)) except OSError as e: engine.write_int(-1) engine.write_int(map_errno(int(str(e)), errno, Flags))
def lseek(engine: Engine): try: file = engine.read_int() ptr = engine.read_int() dir_ = engine.read_int() engine.write_int(os_.lseek(file, ptr, dir_)) except OSError as e: engine.write_int(-1) engine.write_int(map_errno(int(str(e)), errno, Flags))
def write_full(engine: Engine): try: fd = engine.read_int() dt = engine.read_memory() engine.write_int(os_.write(fd, dt)) except OSError as e: engine.write_int(-1) engine.write_int(map_errno(int(str(e)), errno, Flags))
def read_full(engine: Engine): try: fd = engine.read_int() len_ = engine.read_int() buf = os_.read(fd, len_) engine.write_int(0) engine.write_memory(buf) except OSError as e: engine.write_int(map_errno(int(str(e)), errno, Flags))
def test_args(argv, argv_ex=None): if argv_ex is None: argv_ex = argv p = Popen(args.binary, stdin=PIPE, stdout=PIPE, close_fds=True) engine = Engine(input=p.stdout, output=p.stdin, serial_info=serial_info, macro_hooks=[Exit, build_argv_hook(argv), ArgvTest]) print('testing with ', argv) assert engine.init_marker.file.endswith('argv.c') assert engine.run() == 0 print('received ', argv_) print('expected ', argv_ex) assert argv_ == argv_ex
def close_unchecked(engine: Engine): target_fd = engine.read_int() try: os_.close(unchecked_map[target_fd]) except OSError as e: print("Error closing file {} : {}".format(target_fd, e), file=sys.stderr) except KeyError: pass
def close_full(engine: Engine): try: fd = engine.read_int() os_.close(fd) engine.write_int(0) except OSError as e: engine.write_int(-1) engine.write_int(map_errno(int(str(e)), errno, Flags))
def isatty(engine: Engine): try: fd = engine.read_int() isatty_ = os_.isatty(fd) engine.write_int(0) engine.write_int(isatty_) except OSError as e: engine.write_int(map_errno(int(str(e)), errno, Flags))
def invoke(self, engine: Engine, macro_expansion: MacroExpansion): file = macro_expansion.file line = macro_expansion.line type_and_level = engine.read_byte() args = macro_expansion.args[3:] level = level_t[(type_and_level[0] & 0b11100000) >> 5] type_ = type_t[type_and_level[0] & 0b11111] cond_or_length = engine.read_int() condition = bool(cond_or_length) func = getattr(self.reporter, type_) if type_ == "checkpoint": func(file, line) elif type_ == "log": func(file, line, args[0]) elif type_ in ["message", "plain"]: func(file, line, level, condition, args[0]) elif type_ in ["equal", "not_equal", "ge", "le", "greater", "lesser"]: func(file, line, level, condition, args[0], args[1]) elif type_ in ["close", "close_relative"]: func(file, line, level, condition, args[0], args[1], args[2]) elif type_ in ["close", "close_relative"]: func(file, line, level, condition, args[0], args[1], args[2]) elif type_ == "report": func(file, line, condition) elif type_ == "critical": func(file, line, level) elif type_ == "call": name = args[1][3:-8] if args[1] else args[0] func(file, line, level, condition, name) elif type_ == 'loop': func(file, line, level) elif type_ == 'ranged': func(file, line, level, cond_or_length, args) elif type_ == 'predicate': args_a = [arg.strip() for arg in str(args[1][2:-2]).split(',') ] if args else None func(file, line, level, cond_or_length, args[0], args_a) else: raise Exception("Unknown check type {}".format(type_))
def symlink(engine: Engine): try: existing = engine.read_string() _new = engine.read_string() os_.symlink(existing, _new) engine.write_int(0) except OSError as e: engine.write_int(map_errno(int(str(e)), errno, Flags))
def read_buffered(engine: Engine): try: fd = engine.read_int() len_ = engine.read_int() cur = os_.lseek(fd, 0, os_.SEEK_CUR) end = os_.lseek(fd, 0, os_.SEEK_END) available = end - cur read_len = min(available, len_) buf = os_.read(fd, read_len) engine.write_int(0) engine.write_memory(buf) except OSError as e: engine.write_int(map_errno(int(str(e)), errno, Flags))
def main(): parser = argparse.ArgumentParser() parser.add_argument('-S', '--serial-info', required=True, help='The serial information perviously generated') parser.add_argument('-I', '--input', help="The file for input data, defaults to stdin") parser.add_argument('-O', '--output', help="The output ,defaults to null.") args = parser.parse_args() serial_info = SerialInfo.from_dict(json.load(open(args.serial_info))) engine = Engine(input=open(args.input, 'rb') if args.input else sys.stdin, output=open(args.output, 'wb') if args.output else None, serial_info=serial_info)
'--define', nargs='+', help="Defines for the preprocessor", default=[]) args = parser.parse_args() serial_info = generate(args.binary, args.define, args.include) p = Popen(args.binary, stdin=PIPE, stdout=PIPE, stderr=sys.stdout.buffer, close_fds=True) engine = Engine(input=p.stdout, output=p.stdin, serial_info=serial_info) assert engine.init_marker.file.endswith('write.c') assert engine.init_marker.line == 25 engine.write_byte(b'0') assert engine.read_byte() == b'9' engine.write_int(22) assert engine.read_int() == 44 assert engine.write_string("str") == 3 assert engine.read_string() == "tr" engine.write_int(11) assert engine.read_int() == 33
return 0 def symlink(self, existing, new): assert existing.endswith("doesn't exist") assert new.endswith('lib/syscalls.h') raise OSError(errno.ENOENT) def unlink(self, existing): assert existing.endswith('syscalls.h') return 0 def lseek(self, fd, ptr, dir): assert fd in [0, 3] assert ptr == 0 if dir == os_stub.SEEK_CUR: return 0 if dir == os_stub.SEEK_END: return 5 oss = os_stub() engine = Engine(input=p.stdout, output=p.stdin, serial_info=serial_info, macro_hooks=[Exit, build_newlib_hook(oss)]) assert engine.init_marker.file.endswith('newlib_full.c') assert engine.run() == 0 assert oss.write_cnt == 3 assert oss.open_cnt == 1
parser = argparse.ArgumentParser() parser.add_argument('binary', help='The binary that runs on target') parser.add_argument('-S', '--source-dir', required=True, help='The root of the source directory') parser.add_argument('-I', '--include', nargs='+', help="Include folders for the preprocessor", default=[]) parser.add_argument('-D', '--define', nargs='+', help="Defines for the preprocessor", default=[]) args = parser.parse_args() serial_info = generate(args.binary, args.define, args.include) p = Popen(args.binary, stdin=PIPE, stdout=PIPE, close_fds=True) engine = Engine(input=p.stdout, output=p.stdin, serial_info=serial_info, macro_hooks=[Exit, Unit]) assert engine.init_marker.file.endswith('unit.c') assert engine.run() == 0
def invoke(self, engine: Engine, macro_expansion: MacroExpansion): l = engine.read_int() global argv_ argv_ = [engine.read_string() for i in range(l)]
def write_stat(engine: Engine, st: os_.stat_result): engine.write_int(st.st_dev) engine.write_int(st.st_ino) engine.write_int(map_file_mode(st.st_mode, Flags, os_)) engine.write_int(st.st_nlink) engine.write_int(st.st_uid) engine.write_int(st.st_gid) if hasattr(st, 'st_rdev'): engine.write_int(getattr(st, 'st_rdev') or 0) else: engine.write_int(0) engine.write_int(st.st_size) if hasattr(st, 'st_blksize'): engine.write_int(getattr(st, 'st_blksize') or 0) else: engine.write_int(0) if hasattr(st, 'st_blocks'): engine.write_int(getattr(st, 'st_blocks') or 0) else: engine.write_int(0) engine.write_int(int(st.st_atime)) engine.write_int( (st.st_atime_ns or int(st.st_atime * 1000000000)) % 1000000000) engine.write_int(int(st.st_mtime)) engine.write_int( (st.st_mtime_ns or int(st.st_mtime * 1000000000)) % 1000000000) engine.write_int(int(st.st_ctime)) engine.write_int( (st.st_ctime_ns or int(st.st_ctime * 1000000000)) % 1000000000)
'--include', nargs='+', help="Include folders for the preprocessor", default=[]) parser.add_argument('-D', '--define', nargs='+', help="Defines for the preprocessor", default=[]) args = parser.parse_args() serial_info = generate(args.binary, args.define, args.include) p = Popen(args.binary, stdin=PIPE, stdout=PIPE, close_fds=True) engine = Engine(input=p.stdout, output=p.stdin, serial_info=serial_info) assert engine.init_marker.file.endswith('read.c') assert engine.init_marker.line == 22 assert engine.read_byte() == b'a' assert engine.read_int() == 42 assert engine.read_string() == "test-string" main_ptr = engine.read_int() - engine.base_pointer assert [sym.address for sym in serial_info.symbols if sym.name == 'main'][0] == main_ptr assert int.from_bytes(engine.read_memory(), engine.endianness) == 42 assert engine.read_int() == 1234
def write_unchecked(engine: Engine): fd = engine.read_int() dt = engine.read_memory() os_.write(fd, dt)