如何使用文件句柄写入特定的偏移量

时间:2019-03-11 17:26:17

标签: c++ winapi

我正在将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解决方法?

1 个答案:

答案 0 :(得分:2)

要通过WriteFile写入特定偏移,我们需要在OVERLAPPED内设置此偏移:

  

此偏移量是通过设置 Offset OffsetHigh 来指定的   OVERLAPPED结构的成员。

这是一个非常常见的错误,假设我们只能将OVERLAPPED与异步文件句柄一起使用(如果hFile是用 FILE_FLAG_OVERLAPPED 打开的)。但这不是真的。我们可以始终使用指向OVERLAPPEDWriteFile的指针作为参数。仅下一个不同-如果异步文件句柄是强制参数,否则为可选

  如果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,就可以正常工作。否则,您将收到下一个状态错误: hEventSTATUS_INVALID_HANDLE内部的随机值根本无效),hEvent(句柄有效但不是事件),STATUS_OBJECT_TYPE_MISMATCH(句柄没有STATUS_ACCESS_DENIED

但是我确定EVENT_MODIFY_STATE不会返回错误WriteFile。只有ERROR_ALREADY_EXISTS会转换为此错误,并且我看不到STATUS_OBJECT_NAME_COLLISION如何返回此状态的任何地方。我绝对确定您没有收到此错误,但是有另一个错误。在这种情况下,最好总是打电话给NtWriteFile(而不是RtlGetLastNtStatus();)(或与GetLastError()联系)

相关问题