def int21(self): ah = self.ql.reg.ah # exit if ah == 0x4C: self.ql.nprint("[+] Emulation Stop") self.ql.uc.emu_stop() # character output elif ah == 0x2 or ah == 0x6: ch = chr(self.ql.reg.dl) self.ql.reg.al = self.ql.reg.dl self.ql.nprint(ch) # write to screen elif ah == 0x9: s = self.read_dos_string_from_ds_dx() self.ql.nprint(s) elif ah == 0xC: # Clear input buffer pass # create a new file (or truncate existing file) elif ah == 0x25: # Set interrupt vector pass elif ah == 0x26: # Create PSP pass elif ah == 0x30: # Get DOS version, return DOS version 7.0 self.ql.reg.ax = self.dos_ver elif ah == 0x33: # Get or set Ctrl-Break pass elif ah == 0x35: # Get interrupt vector pass elif ah == 0x3C: # fileattr ignored fname = self.read_dos_string_from_ds_dx() f = open(PathUtils.convert_for_native_os(self.ql.rootfs, self.ql.cur_path, fname), "wb") self.dos_handles[self.handle_next] = f self.ql.reg.ax = self.handle_next self.handle_next += 1 self.clear_cf() elif ah == 0x3d: fname = self.read_dos_string_from_ds_dx() f = open(PathUtils.convert_for_native_os(self.ql.rootfs, self.ql.cur_path, fname), "rb") self.dos_handles[self.handle_next] = f self.ql.reg.ax = self.handle_next self.handle_next += 1 self.clear_cf() elif ah == 0x3e: hd = self.ql.reg.bx if hd not in self.dos_handles: self.ql.reg.ax = 0x6 self.set_cf() else: f = self.dos_handles[hd] f.close() del self.dos_handles[hd] self.clear_cf() elif ah == 0x3f: hd = self.ql.reg.bx if hd not in self.dos_handles: self.ql.reg.ax = 0x6 self.set_cf() else: f = self.dos_handles[hd] buffer = self.calculate_address(self.ql.reg.ds, self.ql.reg.dx) sz = self.ql.reg.cx rd = f.read(sz) self.ql.mem.write(buffer, rd) self.clear_cf() self.ql.reg.ax = len(rd) elif ah == 0x40: hd = self.ql.reg.bx if hd not in self.dos_handles: self.ql.reg.ax = 0x6 self.set_cf() else: f = self.dos_handles[hd] buffer = self.calculate_address(self.ql.reg.ds, self.ql.reg.dx) sz = self.ql.reg.cx rd = self.ql.mem.read(buffer, sz) f.write(bytes(rd)) self.clear_cf() self.ql.reg.ax = len(rd) elif ah == 0x41: fname = self.read_dos_string_from_ds_dx() real_path = PathUtils.convert_for_native_os(self.ql.rootfs, self.ql.cur_path, fname) try: os.remove(real_path) self.clear_cf() except OSError: self.ql.reg.ax = 0x5 self.set_cf() elif ah == 0x43: self.ql.reg.cx = 0xFFFF self.clear_cf() else: self.ql.nprint("Exception: int 21h syscall Not Found, ah: %s" % hex(ah)) raise NotImplementedError()
def test_convert_for_native_os(self): ql = Qiling(["../examples/rootfs/x8664_linux/bin/x8664_hello_static"], "../examples/rootfs/x8664_linux", output="debug") if ql.platform == QL_OS.WINDOWS: rootfs = pathlib.Path("../examples/rootfs/x8664_windows").resolve() self.assertEqual( str(rootfs / "test"), str( PathUtils.convert_for_native_os( rootfs, "/", "\\\\.\\PhysicalDrive0\\test"))) self.assertEqual( str(rootfs / "test"), str( PathUtils.convert_for_native_os( rootfs, "/", "\\\\.\\PhysicalDrive0\\..\\test"))) self.assertEqual( str(rootfs / "test"), str( PathUtils.convert_for_native_os( rootfs, "/", "\\\\.\\PhysicalDrive0\\..\\..\\test"))) self.assertEqual( str(rootfs / "test"), str( PathUtils.convert_for_native_os( rootfs, "/", "\\\\.\\PhysicalDrive0\\..\\xxxx\\..\\test"))) self.assertEqual( str(rootfs / "test"), str( PathUtils.convert_for_native_os( rootfs, "/", "\\\\hostname\\share\\test"))) self.assertEqual( str(rootfs / "test"), str( PathUtils.convert_for_native_os( rootfs, "/", "\\\\hostname\\share\\..\\test"))) self.assertEqual( str(rootfs / "test"), str( PathUtils.convert_for_native_os( rootfs, "/", "\\\\hostname\\share\\..\\..\\test"))) self.assertEqual( str(rootfs / "test"), str( PathUtils.convert_for_native_os( rootfs, "/", "\\\\hostname\\share\\..\\xxxx\\..\\test"))) self.assertEqual( str(rootfs / "test"), str( PathUtils.convert_for_native_os( rootfs, "/", "\\\\.\\BootPartition\\test"))) self.assertEqual( str(rootfs / "test"), str( PathUtils.convert_for_native_os( rootfs, "/", "\\\\.\\BootPartition\\..\\test"))) self.assertEqual( str(rootfs / "test"), str( PathUtils.convert_for_native_os( rootfs, "/", "\\\\.\\BootPartition\\..\\..\\test"))) self.assertEqual( str(rootfs / "test"), str( PathUtils.convert_for_native_os( rootfs, "/", "\\\\.\\BootPartition\\..\\xxxx\\..\\test"))) self.assertEqual( str(rootfs / "test"), str(PathUtils.convert_for_native_os(rootfs, "/", "C:\\test"))) self.assertEqual( str(rootfs / "test"), str( PathUtils.convert_for_native_os(rootfs, "/", "C:\\..\\test"))) self.assertEqual( str(rootfs / "test"), str( PathUtils.convert_for_native_os(rootfs, "/", "C:\\..\\..\\test"))) self.assertEqual( str(rootfs / "test"), str( PathUtils.convert_for_native_os(rootfs, "/", "C:\\..\\xxxx\\..\\test"))) self.assertEqual( str(rootfs / "test"), str(PathUtils.convert_for_native_os(rootfs, "/", "\\test"))) self.assertEqual( str(rootfs / "test"), str(PathUtils.convert_for_native_os(rootfs, "/", "\\..\\test"))) self.assertEqual( str(rootfs / "test"), str( PathUtils.convert_for_native_os(rootfs, "/", "\\..\\..\\test"))) self.assertEqual( str(rootfs / "test"), str( PathUtils.convert_for_native_os(rootfs, "/", "\\..\\xxxx\\..\\test"))) self.assertEqual( str(rootfs / "test"), str(PathUtils.convert_for_native_os(rootfs, "/", "test"))) self.assertEqual( str(rootfs / "test"), str(PathUtils.convert_for_native_os(rootfs, "/", "..\\test"))) self.assertEqual( str(rootfs / "test"), str( PathUtils.convert_for_native_os(rootfs, "/", "..\\..\\test"))) self.assertEqual( str(rootfs / "test"), str( PathUtils.convert_for_native_os(rootfs, "/", "..\\xxxx\\..\\test"))) self.assertEqual( str(rootfs / "xxxx" / "test"), str(PathUtils.convert_for_native_os(rootfs, "/xxxx", "test"))) self.assertEqual( str(rootfs / "xxxx" / "test"), str( PathUtils.convert_for_native_os(rootfs, "/xxxx/yyyy", "..\\test"))) self.assertEqual( str(rootfs / "xxxx" / "test"), str( PathUtils.convert_for_native_os(rootfs, "/xxxx/yyyy/zzzz", "..\\..\\test"))) self.assertEqual( str(rootfs / "xxxx" / "test"), str( PathUtils.convert_for_native_os(rootfs, "/xxxx/yyyy", "..\\xxxx\\..\\test"))) else: rootfs = pathlib.Path("../examples/rootfs/x8664_linux").resolve() self.assertEqual( str(rootfs / "test"), str(PathUtils.convert_for_native_os(rootfs, "/", "/test"))) self.assertEqual( str(rootfs / "test"), str(PathUtils.convert_for_native_os(rootfs, "/", "/../test"))) self.assertEqual( str(rootfs / "test"), str(PathUtils.convert_for_native_os(rootfs, "/", "/../../test"))) self.assertEqual( str(rootfs / "test"), str( PathUtils.convert_for_native_os(rootfs, "/", "/../xxxx/../test"))) self.assertEqual( str(rootfs / "test"), str(PathUtils.convert_for_native_os(rootfs, "/", "test"))) self.assertEqual( str(rootfs / "test"), str(PathUtils.convert_for_native_os(rootfs, "/", "../test"))) self.assertEqual( str(rootfs / "test"), str(PathUtils.convert_for_native_os(rootfs, "/", "../../test"))) self.assertEqual( str(rootfs / "test"), str( PathUtils.convert_for_native_os(rootfs, "/", "../xxxx/../test"))) self.assertEqual( str(rootfs / "xxxx" / "test"), str(PathUtils.convert_for_native_os(rootfs, "/xxxx", "test"))) self.assertEqual( str(rootfs / "xxxx" / "test"), str( PathUtils.convert_for_native_os(rootfs, "/xxxx/yyyy", "../test"))) self.assertEqual( str(rootfs / "xxxx" / "test"), str( PathUtils.convert_for_native_os(rootfs, "/xxxx/yyyy/zzzz", "../../test"))) self.assertEqual( str(rootfs / "xxxx" / "test"), str( PathUtils.convert_for_native_os(rootfs, "/xxxx/yyyy", "../xxxx/../test"))) del ql
def test_convert_win32_to_posix(self): rootfs = pathlib.Path("../examples/rootfs/x8664_windows").resolve() self.assertEqual( str(rootfs / "test"), str( PathUtils.convert_win32_to_posix( rootfs, "/", "\\\\.\\PhysicalDrive0\\test"))) self.assertEqual( str(rootfs / "test"), str( PathUtils.convert_win32_to_posix( rootfs, "/", "\\\\.\\PhysicalDrive0\\..\\test"))) self.assertEqual( str(rootfs / "test"), str( PathUtils.convert_win32_to_posix( rootfs, "/", "\\\\.\\PhysicalDrive0\\..\\..\\test"))) self.assertEqual( str(rootfs / "test"), str( PathUtils.convert_win32_to_posix( rootfs, "/", "\\\\.\\PhysicalDrive0\\..\\xxxx\\..\\test"))) self.assertEqual( str(rootfs / "test"), str( PathUtils.convert_win32_to_posix(rootfs, "/", "\\\\hostname\\share\\test"))) self.assertEqual( str(rootfs / "test"), str( PathUtils.convert_win32_to_posix( rootfs, "/", "\\\\hostname\\share\\..\\test"))) self.assertEqual( str(rootfs / "test"), str( PathUtils.convert_win32_to_posix( rootfs, "/", "\\\\hostname\\share\\..\\..\\test"))) self.assertEqual( str(rootfs / "test"), str( PathUtils.convert_win32_to_posix( rootfs, "/", "\\\\hostname\\share\\..\\xxxx\\..\\test"))) self.assertEqual( str(rootfs / "test"), str( PathUtils.convert_win32_to_posix( rootfs, "/", "\\\\.\\BootPartition\\test"))) self.assertEqual( str(rootfs / "test"), str( PathUtils.convert_win32_to_posix( rootfs, "/", "\\\\.\\BootPartition\\..\\test"))) self.assertEqual( str(rootfs / "test"), str( PathUtils.convert_win32_to_posix( rootfs, "/", "\\\\.\\BootPartition\\..\\..\\test"))) self.assertEqual( str(rootfs / "test"), str( PathUtils.convert_win32_to_posix( rootfs, "/", "\\\\.\\BootPartition\\..\\xxxx\\..\\test"))) self.assertEqual( str(rootfs / "test"), str(PathUtils.convert_win32_to_posix(rootfs, "/", "C:\\test"))) self.assertEqual( str(rootfs / "test"), str(PathUtils.convert_win32_to_posix(rootfs, "/", "C:\\..\\test"))) self.assertEqual( str(rootfs / "test"), str( PathUtils.convert_win32_to_posix(rootfs, "/", "C:\\..\\..\\test"))) self.assertEqual( str(rootfs / "test"), str( PathUtils.convert_win32_to_posix(rootfs, "/", "C:\\..\\xxxx\\..\\test"))) self.assertEqual( str(rootfs / "test"), str(PathUtils.convert_win32_to_posix(rootfs, "/", "\\test"))) self.assertEqual( str(rootfs / "test"), str(PathUtils.convert_win32_to_posix(rootfs, "/", "\\..\\test"))) self.assertEqual( str(rootfs / "test"), str(PathUtils.convert_win32_to_posix(rootfs, "/", "\\..\\..\\test"))) self.assertEqual( str(rootfs / "test"), str( PathUtils.convert_win32_to_posix(rootfs, "/", "\\..\\xxxx\\..\\test"))) self.assertEqual( str(rootfs / "test"), str(PathUtils.convert_win32_to_posix(rootfs, "/", "test"))) self.assertEqual( str(rootfs / "test"), str(PathUtils.convert_win32_to_posix(rootfs, "/", "..\\test"))) self.assertEqual( str(rootfs / "test"), str(PathUtils.convert_win32_to_posix(rootfs, "/", "..\\..\\test"))) self.assertEqual( str(rootfs / "test"), str( PathUtils.convert_win32_to_posix(rootfs, "/", "..\\xxxx\\..\\test"))) self.assertEqual( str(rootfs / "xxxx" / "test"), str(PathUtils.convert_win32_to_posix(rootfs, "/xxxx", "test"))) self.assertEqual( str(rootfs / "xxxx" / "test"), str( PathUtils.convert_win32_to_posix(rootfs, "/xxxx/yyyy", "..\\test"))) self.assertEqual( str(rootfs / "xxxx" / "test"), str( PathUtils.convert_win32_to_posix(rootfs, "/xxxx/yyyy/zzzz", "..\\..\\test"))) self.assertEqual( str(rootfs / "xxxx" / "test"), str( PathUtils.convert_win32_to_posix(rootfs, "/xxxx/yyyy", "..\\xxxx\\..\\test")))
def test_convert_posix_to_win32(self): rootfs = pathlib.Path("../examples/rootfs/x8664_linux").resolve() self.assertEqual( str(rootfs / "test"), str(PathUtils.convert_posix_to_win32(rootfs, "/", "/test"))) self.assertEqual( str(rootfs / "test"), str(PathUtils.convert_posix_to_win32(rootfs, "/", "/../test"))) self.assertEqual( str(rootfs / "test"), str(PathUtils.convert_posix_to_win32(rootfs, "/", "/../../test"))) self.assertEqual( str(rootfs / "test"), str( PathUtils.convert_posix_to_win32(rootfs, "/", "/../xxxx/../test"))) self.assertEqual( str(rootfs / "test"), str(PathUtils.convert_posix_to_win32(rootfs, "/", "test"))) self.assertEqual( str(rootfs / "test"), str(PathUtils.convert_posix_to_win32(rootfs, "/", "../test"))) self.assertEqual( str(rootfs / "test"), str(PathUtils.convert_posix_to_win32(rootfs, "/", "../../test"))) self.assertEqual( str(rootfs / "test"), str( PathUtils.convert_posix_to_win32(rootfs, "/", "../xxxx/../test"))) self.assertEqual( str(rootfs / "xxxx" / "test"), str(PathUtils.convert_posix_to_win32(rootfs, "/xxxx", "test"))) self.assertEqual( str(rootfs / "xxxx" / "test"), str( PathUtils.convert_posix_to_win32(rootfs, "/xxxx/yyyy", "../test"))) self.assertEqual( str(rootfs / "xxxx" / "test"), str( PathUtils.convert_posix_to_win32(rootfs, "/xxxx/yyyy/zzzz", "../../test"))) self.assertEqual( str(rootfs / "xxxx" / "test"), str( PathUtils.convert_posix_to_win32(rootfs, "/xxxx/yyyy", "../xxxx/../test")))
def cb(ql, intno, user_data=None): ah = self.ql.reg.ah # http://spike.scu.edu.au/~barry/interrupts.html # http://www2.ift.ulaval.ca/~marchand/ift17583/dosints.pdf if intno == 0x21: if ah == 0x4C: self.ql.uc.emu_stop() elif ah == 0x2 or ah == 0x6: ch = chr(self.ql.reg.dl) self.ql.reg.al = self.ql.reg.dl ql.nprint(ch) elif ah == 0x9: s = self.read_dos_string_from_ds_dx() ql.nprint(s) elif ah == 0x3C: # fileattr ignored fname = self.read_dos_string_from_ds_dx() f = open( PathUtils.convert_for_native_os( self.ql.rootfs, self.ql.cur_path, fname), "wb") self.dos_handles[self.handle_next] = f self.ql.reg.ax = self.handle_next self.handle_next += 1 self.clear_cf() elif ah == 0x3d: fname = self.read_dos_string_from_ds_dx() f = open( PathUtils.convert_for_native_os( self.ql.rootfs, self.ql.cur_path, fname), "rb") self.dos_handles[self.handle_next] = f self.ql.reg.ax = self.handle_next self.handle_next += 1 self.clear_cf() elif ah == 0x3e: hd = self.ql.reg.bx if hd not in self.dos_handles: self.ql.reg.ax = 0x6 self.set_cf() else: f = self.dos_handles[hd] f.close() del self.dos_handles[hd] self.clear_cf() elif ah == 0x3f: hd = self.ql.reg.bx if hd not in self.dos_handles: self.ql.reg.ax = 0x6 self.set_cf() else: f = self.dos_handles[hd] buffer = self.calculate_address( self.ql.reg.ds, self.ql.reg.dx) sz = self.ql.reg.cx rd = f.read(sz) ql.mem.write(buffer, rd) self.clear_cf() self.ql.reg.ax = len(rd) elif ah == 0x40: hd = self.ql.reg.bx if hd not in self.dos_handles: self.ql.reg.ax = 0x6 self.set_cf() else: f = self.dos_handles[hd] buffer = self.calculate_address( self.ql.reg.ds, self.ql.reg.dx) sz = self.ql.reg.cx rd = self.ql.mem.read(buffer, sz) f.write(bytes(rd)) self.clear_cf() self.ql.reg.ax = len(rd) elif ah == 0x41: fname = self.read_dos_string_from_ds_dx() real_path = PathUtils.convert_for_native_os( self.ql.rootfs, self.ql.cur_path, fname) try: os.remove(real_path) self.clear_cf() except OSError: self.ql.reg.ax = 0x5 self.set_cf() elif ah == 0x43: self.ql.reg.cx = 0xFFFF self.clear_cf() else: raise NotImplementedError() else: raise NotImplementedError()