【问题标题】:reasons for STATUS_ACCESS_VIOLATION for a user mode call in ntdll.dll library functionntdll.dll 库函数中用户模式调用的 STATUS_ACCESS_VIOLATION 原因
【发布时间】:2020-10-20 12:56:14
【问题描述】:

是否可以从用户模式访问 ntdll.dll 上的函数?我使用LoadLibrary()GetProcAddress()成功获取了NtOpenFile()的函数地址。但我在调用NtOpenFile 时收到STATUS_ACCESS_VIOLATION 错误。我知道这是因为内存相关问题。我应该为UNICODE_STRING 结构虚拟分配内存吗?我是 WinApi 编程的新手。我正在使用来自here的示例

int main() {
    typedef NTSTATUS(__stdcall* NT_OPEN_FILE)(OUT PHANDLE FileHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK IoStatusBlock, IN ULONG ShareAccess, IN ULONG OpenOptions);
    NT_OPEN_FILE NtOpenFileStruct;

    /* load the ntdll.dll */
    PVOID Info;
    HMODULE hModule = LoadLibrary(L"ntdll.dll");
    NtOpenFileStruct = (NT_OPEN_FILE)GetProcAddress(hModule, "NtOpenFile");
    if (NtOpenFileStruct == NULL) {
        printf("Error: could not find the function NtOpenFile in library ntdll.dll.");
        exit(-1);
    }
    printf("NtOpenFile is located at 0x%08x in ntdll.dll.\n", (unsigned int)NtOpenFileStruct);

    /* create the string in the right format */
    UNICODE_STRING filename;
    RtlInitUnicodeString(&filename, L"C:\\temp.txt" );
    /* initialize OBJECT_ATTRIBUTES */
    OBJECT_ATTRIBUTES obja;
    InitializeObjectAttributes(&obja, &filename, OBJ_CASE_INSENSITIVE, NULL, NULL);

    /* call NtOpenFile */
    IO_STATUS_BLOCK iostatusblock;
    HANDLE file = NULL;
    NTSTATUS stat = NtOpenFileStruct(&file, FILE_WRITE_DATA, &obja, NULL, NULL, NULL);
    if (NT_SUCCESS(stat)) {
        printf("File successfully opened.\n");
    }
    else {
        printf("File could not be opened.\n");
    }
    printf("Error = %x", stat);

    return 0;
}

【问题讨论】:

  • 在使用 Windows API 时,您有很多机会探索未定义的行为。无需下拉到 Native API。至于这个问题:Stack Overflow 提倡每个问题发布一个问题。
  • 和指向 &iostatusblock 你忘记通行证的指针。而且您不需要GetProcAddress,只需按原样调用NtOpenFile
  • 注意:NtOpenFileStruct 不是一个结构体,所以我不知道你为什么叫它结构体
  • 是否有可能您传递的参数无效?
  • @RbMm 我正在尝试实现 NtQueryLicenseValue() 未记录的 api,所以我使用 NtOpenFile() 来研究这里访问函数指针的行为。

标签: c++ windows winapi kernel


【解决方案1】:

正如评论所指出的,您需要将IO_STATUS_BLOCK (&iostatusblock) 的指针传递给第四个参数。

NTSTATUS stat = NtOpenFileStruct(&file, FILE_WRITE_DATA, &obja, &iostatusblock, NULL, NULL);

然后,示例仍然会得到错误STATUS_OBJECT_PATH_SYNTAX_BAD(0xC000003B):对象路径组件不是目录对象。

改用L"\\??\\C:\\temp.txt 之类的路径。

【讨论】:

  • 嗨,@Mohan,这能回答你的问题吗?如果您有任何问题,请随时告诉我,如果有帮助,请接受。
猜你喜欢
  • 2012-10-16
  • 1970-01-01
  • 2016-06-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-03
  • 2012-04-21
  • 1970-01-01
相关资源
最近更新 更多