是否可以在 Windows 中使用 python 来写入原始设备?
这是 这个问题。我想知道您是否可以在写入模式下访问原始设备(即 \\.\PhysicalDriveN
),如果是这种情况,如何访问。
使用 Linux,可以通过使用例如 open("/dev/sdd", "w+")
来简单地实现写访问(前提是脚本以 root 权限运行)。我假设 Mac OS 的行为类似(使用 /dev/diskN
作为输入文件)。
在 Windows 下尝试相同的命令(使用相应的路径)时,它会失败并出现以下错误:
IOError: [Errno 22] invalid mode ('w+') or filename: '\\\\.\\PhysicalDrive3'
但是,当尝试从物理驱动器读取时,它确实有效(甚至读取正确的数据)。 shell 在 Windows 7 下以管理员权限运行。
是否有其他方法可以使用 python 完成此任务,同时仍然保持脚本尽可能独立于平台?
编辑:
我进一步研究了 python 提供的文件处理方法,并偶然发现了 os .打开。使用 os.open(drive_string, os.O_WRONLY|os.O_BINARY) 打开 PhysicalDrive 不会返回任何错误。到目前为止,一切都很好。现在我可以选择使用 os.write< 直接写入此文件描述符/a>,或使用 os.fdopen 获取文件对象并以常规方式写入。 遗憾的是,这些可能性都行不通。在第一种情况下(os.write()
),我得到:
>>> os.write(os.open("\\\\.\\PhysicalDrive3", os.O_WRONLY|os.O_BINARY), "test")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OSError: [Errno 22] Invalid argument
在第二种情况下,我可以创建具有写入权限的文件对象,但写入本身失败(好吧,在使用 .flush()
强制执行之后):
>>> g = os.fdopen(os.open("\\\\.\\PhysicalDrive3", os.O_WRONLY|os.O_BINARY), "wb")
>>> g.write("test")
>>> g.flush()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IOError: [Errno 22] Invalid argument
This is sort of a follow-up to this question. I want to know if you can access raw devices (i.e. \\.\PhysicalDriveN
) in writing mode and if this should be the case, how.
Using Linux, write access can simply be achieved by using e.g. open("/dev/sdd", "w+")
(provided that the script is running with root permissions). I assume that Mac OS behaves similar (with /dev/diskN
as input file).
When trying the same command under Windows (with the corresponding path), it fails with the following error:
IOError: [Errno 22] invalid mode ('w+') or filename: '\\\\.\\PhysicalDrive3'
However, when trying to read from the PhysicalDrive, it does work (even the correct data is read). The shell is running with administrator permissions under Windows 7.
Is there any other way to accomplish this task using python while still keeping the script as platform-independent as possible?
Edit:
I looked a bit further into what methods python provides for file handling and stumbled across os.open. Opening the PhysicalDrive using os.open(drive_string, os.O_WRONLY|os.O_BINARY)
returns no error. So far, so good. Now I have either the choice to write directly to this file-descriptor using os.write, or use os.fdopen to get a file-object and write to it in the regular way.
Sadly, none of these possibilities works. In the first case (os.write()
), I get this:
>>> os.write(os.open("\\\\.\\PhysicalDrive3", os.O_WRONLY|os.O_BINARY), "test")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OSError: [Errno 22] Invalid argument
In the second case, I can create a file object with write permissions, but the writing itself fails (well, after enforcing its execution using .flush()
):
>>> g = os.fdopen(os.open("\\\\.\\PhysicalDrive3", os.O_WRONLY|os.O_BINARY), "wb")
>>> g.write("test")
>>> g.flush()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IOError: [Errno 22] Invalid argument
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
作为 eryksun 和 agf 在评论中指出(但一开始我并没有真正明白),解决方案相当简单:你必须以
rb+
模式打开设备,该模式打开设备为 <一个href="http://docs.python.org/library/functions.html#open" rel="noreferrer">更新(正如我现在发现的..),而不尝试用新的替换它文件(这不起作用,因为该文件实际上是物理驱动器)。写入时,必须一次写入整个扇区(即 512 字节的倍数),否则会失败。
此外,
.seek()
命令也只能按扇区跳转。如果您尝试在扇区内查找位置(例如位置621
),文件对象将跳转到您请求的位置所在扇区的开头(即第二个扇区的开头,字节512
)。As eryksun and agf pointed out in the comments (but I didn't really get it at first), the solution is rather simple: you have to open the device in the
rb+
mode, which opens the device for updating (as I have found out now..) without trying to replace it with a new file (which wouldn't work because the file is in fact a physical drive).When writing, you have to write always a whole sector at a time (i.e. multiples of 512-byte), otherwise it fails.
In addition, the
.seek()
command can also jump only sector-wise. If you try to seek a position inside a sector (e.g. position621
), the file object will jump to the beginning of the sector where your requested position is (i.e. to the beginning of the second sector, byte512
).在 Win 7 中你不必这样做;使用“rb+”模式打开和写入效果很好。
In Win 7 you don't have to do that; opening and writing with 'rb+' mode works fine.