Cerbo Asked:2020-07-15 21:29:39 +0800 CST2020-07-15 21:29:39 +0800 CST 2020-07-15 21:29:39 +0800 CST 如何在仅给定内存映射句柄的情况下获取文件句柄 772 如何从内存映射对象的句柄中恢复文件句柄? c++ 1 个回答 Voted Best Answer nick_n_a 2020-07-30T15:44:37+08:002020-07-30T15:44:37+08:00 或许如果你深入Windows的内核,以了解如何“绕过”瓶颈,那就更容易了。我将简化文件一次映射一个文件。如果不是这种情况,那么程序需要稍微复杂一些。您还必须找出至少一个映射文件的位置。没有它就行不通。有两个函数以相同的格式返回名称GetMappedFileNameW和NtQueryObject. 通过它们,您可以简单地扫描手柄 HANDLE GetMemFileHandle(void *mem) { wchar_t name1[512] = {0,}; wchar_t name2[512] = {0,}; DWORD q1, q2; int HandleCount = 10000; //TODO: Подобрать/почитать // Вызов psapi.dll GetMappedFileNameW if ((q1=GetMappedFileNameW(GetCurrentProcess(),mem,name1,sizeof(name1)/2))== 0) return 0; for (int i=4;i<HandleCount;i+=4) { // TODO: проверить тип хандла // Узнаём имя обьекта 1=ObjectNameInformation if (NtQueryObject( (HANDLE)i,1,&name2,sizeof(name2),&q2)!=0) continue; // Длинна имени совпала? if (name2[0]/2 != q1) continue; // Имя совпало? if (lstrcmpW(name1,name2+4) != 0) continue; // Да совпало return (HANDLE)i; } return 0; } 获得一段记忆......很容易。可以这样吗 HANDLE GetFileMappingFileHanlde(HANDLE hMap){ HANDLE ret = 0; void *mem = MapViewOfFile(hMap,FILE_MAP_READ,0,0,1); if (mem == 0) return 0; ret = GetMemFileHandle(mem); UnmapViewOfFile(mem); return ret; } 为了不连接 psapi.dll,你也可以乱用NtQueryVirtualMemory(NtCurrentProcess(), File1MappedAsAnImage, MemoryMappedFilenameInformation, buf, cb, &rcb)它会得到与 .dll 相同的结果GetMappedFileNameW。 还有一个NtAreMappedFilesTheSame检查一对内存段是否对应一个文件的功能,不过这样比较麻烦。使用此功能添加检查将改进程序。 链接 http://docs.microsoft.com/en-us/windows/win32/api/winternl/nf-winterl-ntqueryobject http://docs.microsoft.com/en-us/windows/win32/api/psapi/nf-psapi-getmappedfilenamew http://docs.microsoft.com/en-us/windows/win32/memory/obtaining-a-file-name-from-a-file-handle https://docs.microsoft.com/en-us/windows/win32/sysinfo/handles-and-objects http://stackoverflow.com/questions/40368487/how-to-obtain-file-handle-to-the-current-executable-without-introducing-a-filesy
或许如果你深入Windows的内核,以了解如何“绕过”瓶颈,那就更容易了。我将简化文件一次映射一个文件。如果不是这种情况,那么程序需要稍微复杂一些。您还必须找出至少一个映射文件的位置。没有它就行不通。有两个函数以相同的格式返回名称
GetMappedFileNameW
和NtQueryObject
. 通过它们,您可以简单地扫描手柄获得一段记忆......很容易。可以这样吗
为了不连接 psapi.dll,你也可以乱用
NtQueryVirtualMemory(NtCurrentProcess(), File1MappedAsAnImage, MemoryMappedFilenameInformation, buf, cb, &rcb)
它会得到与 .dll 相同的结果GetMappedFileNameW
。还有一个
NtAreMappedFilesTheSame
检查一对内存段是否对应一个文件的功能,不过这样比较麻烦。使用此功能添加检查将改进程序。链接
http://docs.microsoft.com/en-us/windows/win32/api/winternl/nf-winterl-ntqueryobject
http://docs.microsoft.com/en-us/windows/win32/api/psapi/nf-psapi-getmappedfilenamew
http://docs.microsoft.com/en-us/windows/win32/memory/obtaining-a-file-name-from-a-file-handle