gpt4 book ai didi

c++ - 当使用 LOAD_LIBRARY_AS_DATAFILE 调用 LoadLibraryEx 时,具有独占访问权限的 CreateFileW 成功

转载 作者:行者123 更新时间:2023-11-28 04:58:06 25 4
gpt4 key购买 nike

我假设如果您使用 CreateFileW 请求独占访问,如果它已经打开,我应该收到共享冲突。但是,我遇到了一个情况并非如此的例子。如果调用 LoadLibraryEx 以加载设置了 LOAD_LIBRARY_AS_DATAFILE 标志的 DLL,则 CreateFileW 会成功返回。但是有些操作将被拒绝(例如设置文件结尾等属性)。有没有更好的方法来检测这些文件是否打开?我是否错误地使用了 CreateFileW?在没有 LOAD_LIBRARY_AS_DATAFILE 标志的情况下加载 DLL 会导致 CreateFileW 失败,表明它无法访问该文件,因为它正被另一个进程使用。

HMODULE hModule = LoadLibraryEx(L"\\Pathto\\module.dll", NULL, NULL);
DWORD access = GENERIC_READ | GENERIC_WRITE | WRITE_OWNER | WRITE_DAC | ACCESS_SYSTEM_SECURITY;
DWORD creation = OPEN_EXISTING;
DWORD flags = FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT;
HANDLE file = CreateFileW(L"\\Pathto\\module.dll", access, 0, NULL, creation, flags, 0);

以上将导致 CreateFileW 失败,错误代码为 32(无法访问,因为它正在被另一个进程使用),这是预期的结果。如果我将标志添加到 LoadLibraryEx:

HMODULE hModule = LoadLibraryEx(name, NULL, LOAD_LIBRARY_AS_DATAFILE);    

然后对 CreateFileW 使用完全相同的调用,然后我被告知它成功了,尽管我稍后在尝试设置文件结尾时会遇到问题(作为示例)。此外,删除文件将失败并出现拒绝访问错误(没有应用程序或任何其他具有打开句柄的应用程序)。

其他奇怪的行为涉及与已加载库的硬链接(hard link)。如果我生成一个新的硬链接(hard link)到加载的模块,并尝试删除备用的新创建的硬链接(hard link),它也会失败(没有打开的文件句柄,只是加载的模块)。为什么?它不应该只是删除链接并取消引用链接计数,或者在模块关闭时安排删除,因为我之前可以获得独占访问权吗?

另外值得注意的是,该进程本身在启用了以下附加权限的特权用户帐户中运行:SE_SECURITY_NAME、SE_BACKUP_NAME、SE_RESTORE_NAME、SE_TAKE_OWNERSHIP_NAME

当加载库时,如何确定您是否真的拥有对文件的独占访问权?

编辑:为了仔细检查,除了通过 SysInternals 工具“句柄”加载模块外,我没有验证其他打开的句柄。

最佳答案

你的案例可以在下一次测试中显示得更清楚

ULONG TestImageAccess(PCWSTR name, BOOL bImage, BOOL bRequestWriteAccess)
{
SetLastError(0);

HANDLE hFile = CreateFileW(name, GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0);

if (hFile != INVALID_HANDLE_VALUE)
{
HANDLE hSection = CreateFileMappingW(hFile, 0,
bImage ? PAGE_READONLY|SEC_IMAGE : PAGE_READONLY|SEC_COMMIT, 0, 0, 0);

CloseHandle(hFile);

if (hSection)
{
hFile = CreateFileW(name,
bRequestWriteAccess ? GENERIC_WRITE : GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0);

CloseHandle(hSection);

if (hFile != INVALID_HANDLE_VALUE)
{
CloseHandle(hFile);
}
}
}

return GetLastError();
}

void TestImageAccess(PCWSTR filename)
{
TestImageAccess(filename, TRUE, TRUE); // ERROR_SHARING_VIOLATION
TestImageAccess(filename, FALSE, TRUE); // NOERROR
TestImageAccess(filename, TRUE, FALSE); // NOERROR
TestImageAccess(filename, FALSE, FALSE);// NOERROR
}

当我们请求对文件和文件映射为图像写权限时,我们得到了ERROR_SHARING_VIOLATION

此案例在 Executable Images 中有描述:

If the user wants write access to the file, make sure there is not a process mapping this file as an image

使用 MmFlushForWrite 调用 MmFlushImageSection 失败,您得到了 STATUS_SHARING_VIOLATION - 就在这一行。

LoadLibraryEx 带有标志 LOAD_LIBRARY_AS_DATAFILE 当标志为 0 时使用 SEC_COMMIT 在文件上创建部分 - 使用 SEC_IMAGE -所以作为图像部分

这里的权限绝对不相关

How would one determine if you truly have exclusive access to a file when libraries are loaded?

只需打开具有您需要的访问权限的文件,然后执行您需要的操作。是的,当您尝试截断映射文件时,您可能会遇到错误 ERROR_USER_MAPPED_FILE。但这里无能为力。示例 2

ULONG TestImage2(PCWSTR name)
{
HANDLE hFile = CreateFileW(name, GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0);

if (hFile != INVALID_HANDLE_VALUE)
{
HANDLE hSection = CreateFileMappingW(hFile, 0, PAGE_READONLY|SEC_COMMIT, 0, 0, 0);

CloseHandle(hFile);

if (hSection)
{
PVOID pv = MapViewOfFile(hSection, FILE_MAP_READ, 0, 0, 0);

CloseHandle(hSection);

if (pv)
{
hFile = CreateFileW(name,GENERIC_WRITE|GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0);

if (hFile != INVALID_HANDLE_VALUE)
{
FILE_END_OF_FILE_INFO eof = { };
// ERROR_USER_MAPPED_FILE will be here
SetFileInformationByHandle(hFile, FileEndOfFileInfo, &eof, sizeof(eof));
CloseHandle(hFile);
}

UnmapViewOfFile(pv);
}
}
}

return GetLastError();
}

关于c++ - 当使用 LOAD_LIBRARY_AS_DATAFILE 调用 LoadLibraryEx 时,具有独占访问权限的 CreateFileW 成功,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46734341/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com