我正在将DLL注入到进程中,检索文件句柄。
然后,我尝试使用WriteFile Winapi函数进行编写。效果很好,但是如果我要写入特定的偏移量(添加偏移量arg而不是NULL),
_OVERLAPPED offset;
offset.Offset = 0xFFFFFFFF;
offset.OffsetHigh = 0xFFFFFFFF;
if (!WriteFile(hFile, &buffer, 9, &written,&offset)) {
Debug(GetLastErrorStdStr());
}
然后我得到:
ERROR_ALREADY_EXISTS 183 该文件已存在时无法创建该文件。
这让我觉得不能,因为创建了HANDLE时没有FILE_FLAG_OVERLAPPED。难道这来自别的东西吗?
如果这确实是错误的原因,是否有hacky解决方法?
答案 0 :(得分:2)
要通过WriteFile
写入特定偏移,我们需要在OVERLAPPED
内设置此偏移:
此偏移量是通过设置 Offset 和 OffsetHigh 来指定的
OVERLAPPED
结构的成员。
这是一个非常常见的错误,假设我们只能将OVERLAPPED
与异步文件句柄一起使用(如果hFile
是用 FILE_FLAG_OVERLAPPED
打开的)。但这不是真的。我们可以始终使用指向OVERLAPPED
中WriteFile
的指针作为参数。仅下一个不同-如果异步文件句柄是强制参数,否则为可选
如果hFile参数为
OVERLAPPED
结构, 用FILE_FLAG_OVERLAPPED
打开,否则此参数可以 成为NULL
。
可以但不一定必须是
设置文件位置的另一种方法-使用SetFilePointer[Ex]
-已过时,效率不高,并且提出了提高条件的指针-此API的全部功能-在FILE_OBJECT
结构内设置CurrentByteOffset
。然后在WriteFile
中,如果我们不通过OVERLAPPED
提供显式偏移-使用隐式偏移FILE_OBJECT.CurrentByteOffset
。执行此操作(实际上并不需要对内核进行多次额外调用)-比较OVERLAPPED
上的显式文件偏移量非常不高效(并且当其他人同时使用文件时-可以在SetFilePointer[Ex]
和{之间更改此偏移量{1}}或WriteFile
通话)
也The old DOS SetFilePointer API is an anachronism. One should specify the file offset in the overlapped structure even for synchronous I/O.
但是当我们使用OVERLAPPED
结构时-我们必须必须将其ReadFile
成员初始化为0或使用hEvent
访问权限(以及该事件)将其初始化为有效的事件句柄每个I / O请求必须唯一-在另一个I / O请求中并发使用,直到尚未完成)。
因此,当您实际上未在SYNCHRONIZE|EVENT_MODIFY_STATE
内初始化hEvent
时,当前的代码是 UB 。一段时间后,如果_OVERLAPPED offset;
为随机0,就可以正常工作。否则,您将收到下一个状态错误:
hEvent
(STATUS_INVALID_HANDLE
内部的随机值根本无效),hEvent
(句柄有效但不是事件),STATUS_OBJECT_TYPE_MISMATCH
(句柄没有STATUS_ACCESS_DENIED
)
但是我确定EVENT_MODIFY_STATE
不会返回错误WriteFile
。只有ERROR_ALREADY_EXISTS
会转换为此错误,并且我看不到STATUS_OBJECT_NAME_COLLISION
如何返回此状态的任何地方。我绝对确定您没有收到此错误,但是有另一个错误。在这种情况下,最好总是打电话给NtWriteFile
(而不是RtlGetLastNtStatus();
)(或与GetLastError()
联系)