【发布时间】: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() 来研究这里访问函数指针的行为。