NtCreateFile 返回 STATUS_OBJECT_NAME_NOT_FOUND 即使该文件存在于目录中
NtCreateFile returning STATUS_OBJECT_NAME_NOT_FOUND even if the file exists in the directory
我一直在尝试使用 NtCreateFile 打开一个现有文件,尽管它找不到我正在寻找的文件,即使它存在于我试图打开文件的目录中。
NtCreateFile returns 错误代码 0x34,又名 STATUS_OBJECT_NAME_NOT_FOUND。
我三次检查路径格式是否正确,我还确保 UNICODE_STRING 的长度和最大长度都是偶数而不是奇数,因为它会导致 NtCreateFile 抛出错误代码 0x33 (更多信息在这里:NtOpenFile returns STATUS_OBJECT_NAME_INVALID).
我注意到,尽管同一文件夹中的另一个 .png 文件工作正常,但我可以成功获取该文件的句柄,使用不同的标志 FILE_DIRECTORY_FILE 而不是 FILE_NON_DIRECTORY_FILE。
代码如下:
#define DLL_FILE_OPEN 1
#define DLL_NON_DIRECTORY_FILE 0x40
#define DLL_OPEN_BY_FILE_ID 0x2000
#define DLL_DIRECTORY_FILE 1
#define DLL_FILE_OPENED 1
#define DLL_SYNCRONIZE 0x00100000L
#define DLL_FILE_READ_ATTRIBUTES 0x0080
#define DLL_FILE_OPEN_FOR_BACKUP_INTENT 0x00004000
#define OBJ_CASE_INSENSITIVE 0x00000040L
void main()
{
OBJECT_ATTRIBUTES oa;
IO_STATUS_BLOCK isb;
UNICODE_STRING NtPath;
HANDLE FileHandle;
NTSTATUS status;
ULONG FileAttributes, Flags = 0;
PVOID EaBuffer = 0;
ULONG EaLength = 0;
Flags |= DLL_NON_DIRECTORY_FILE;
Flags |= DLL_FILE_OPEN_FOR_BACKUP_INTENT;
NtPath.Buffer = (PWSTR)L"\??\C:\Users\MyUsername\Downloads\verifica.txt";
NtPath.Length = (USHORT)(wcslen(NtPath.Buffer) + 1); // +1 to avoid it being an odd value.
NtPath.MaximumLength = (USHORT)(sizeof(PWSTR) + 1);
InitializeObjectAttributes(&oa, &NtPath, OBJ_CASE_INSENSITIVE, 0, 0);
status = NewNtCreateFile(&FileHandle, FILE_GENERIC_READ, &oa, &isb, NULL, NULL, FILE_SHARE_READ, DLL_FILE_OPEN, Flags, EaBuffer, EaLength);
if (status != 0)
printf("status: 0x%08X\n", status);
else
if (!FileHandle || FileHandle == INVALID_HANDLE_VALUE)
printf("Invalid handle.\n");
else
printf("file opened successfully\n");
return;
}```
NtPath.Length = (USHORT)(wcslen(NtPath.Buffer));
没有。该字段是以字节为单位的长度。
NtPath.Length = (USHORT)(wcslen(NtPath.Buffer)) << 1;
此外,由于您没有将字符串传递给将写入它的内容,我建议将 NtPath.MaximumLength
设置为与 Length
相同。
如果您继续使用这些 API,请注意一点,默认情况下文件句柄是异步打开的,并且 IO_STATUS_BLOCK
结构需要 16 字节对齐。
我一直在尝试使用 NtCreateFile 打开一个现有文件,尽管它找不到我正在寻找的文件,即使它存在于我试图打开文件的目录中。
NtCreateFile returns 错误代码 0x34,又名 STATUS_OBJECT_NAME_NOT_FOUND。
我三次检查路径格式是否正确,我还确保 UNICODE_STRING 的长度和最大长度都是偶数而不是奇数,因为它会导致 NtCreateFile 抛出错误代码 0x33 (更多信息在这里:NtOpenFile returns STATUS_OBJECT_NAME_INVALID).
我注意到,尽管同一文件夹中的另一个 .png 文件工作正常,但我可以成功获取该文件的句柄,使用不同的标志 FILE_DIRECTORY_FILE 而不是 FILE_NON_DIRECTORY_FILE。
代码如下:
#define DLL_FILE_OPEN 1
#define DLL_NON_DIRECTORY_FILE 0x40
#define DLL_OPEN_BY_FILE_ID 0x2000
#define DLL_DIRECTORY_FILE 1
#define DLL_FILE_OPENED 1
#define DLL_SYNCRONIZE 0x00100000L
#define DLL_FILE_READ_ATTRIBUTES 0x0080
#define DLL_FILE_OPEN_FOR_BACKUP_INTENT 0x00004000
#define OBJ_CASE_INSENSITIVE 0x00000040L
void main()
{
OBJECT_ATTRIBUTES oa;
IO_STATUS_BLOCK isb;
UNICODE_STRING NtPath;
HANDLE FileHandle;
NTSTATUS status;
ULONG FileAttributes, Flags = 0;
PVOID EaBuffer = 0;
ULONG EaLength = 0;
Flags |= DLL_NON_DIRECTORY_FILE;
Flags |= DLL_FILE_OPEN_FOR_BACKUP_INTENT;
NtPath.Buffer = (PWSTR)L"\??\C:\Users\MyUsername\Downloads\verifica.txt";
NtPath.Length = (USHORT)(wcslen(NtPath.Buffer) + 1); // +1 to avoid it being an odd value.
NtPath.MaximumLength = (USHORT)(sizeof(PWSTR) + 1);
InitializeObjectAttributes(&oa, &NtPath, OBJ_CASE_INSENSITIVE, 0, 0);
status = NewNtCreateFile(&FileHandle, FILE_GENERIC_READ, &oa, &isb, NULL, NULL, FILE_SHARE_READ, DLL_FILE_OPEN, Flags, EaBuffer, EaLength);
if (status != 0)
printf("status: 0x%08X\n", status);
else
if (!FileHandle || FileHandle == INVALID_HANDLE_VALUE)
printf("Invalid handle.\n");
else
printf("file opened successfully\n");
return;
}```
NtPath.Length = (USHORT)(wcslen(NtPath.Buffer));
没有。该字段是以字节为单位的长度。
NtPath.Length = (USHORT)(wcslen(NtPath.Buffer)) << 1;
此外,由于您没有将字符串传递给将写入它的内容,我建议将 NtPath.MaximumLength
设置为与 Length
相同。
如果您继续使用这些 API,请注意一点,默认情况下文件句柄是异步打开的,并且 IO_STATUS_BLOCK
结构需要 16 字节对齐。