The only way I know how to do this is to map a SEC_IMAGE view of the DLL
that you want to check if matches the currently loaded DLL and then use the
(undocumented) NtAreMappedFilesTheSame. Internally this seems to compare
PSECTION_OBJECT_POINTERS->ImageSectionObject, such that that will be
different if the files were renamed on disk but had the same filename when
they were mapped. Note that you need to map the file as an image section
(SEC_IMAGE), like the loader does when mapping DLLs, for this to work.
NT_SUCCESS(NtAreMappedFilesTheSame(…)) will be true if the DLL was the
same.
Obviously not preferable to rely on undocumentedness though. Also, if
someone switches the DLLs back after you perform the NtAreMappedFilesTheSame
check, you’ll obviously get confused as well. Also, might be a bit hard to
work into how you need it to work in any case (this won’t give you a “new”
filename, just tell you that somebody swapped it, and you’ll need to keep a
file mapping pointer around to do the check), even if you can stomach the
undocumentedness…
Why does your coworker need this information at all, if I might ask? Seems
like a pretty weird situation to be into in the first place. Might be a
better way to accomplish it and circumvent this entire requirement, which
would be much preferable.
FYI, here’s a simple test app for demonstrating what I was speaking of
(error checking omitted - beware):
–
NTSYSAPI
NTSTATUS
NTAPI
NtAreMappedFilesTheSame(
IN PVOID Address1,
IN PVOID Address2
);
int
__cdecl
wmain(
int ac,
wchar_t **av
)
{
HMODULE hmod;
HMODULE hmod2;
hmod = LoadLibrary(L"dll.dll");
wprintf(L"%p\n", hmod);
getc(stdin); // swap dll.dll while we’re waiting on input
hmod2 = LoadLibrary(L"dll.dll");
wprintf(L"%p\n", hmod2);
HANDLE h;
HANDLE hs;
PVOID p;
h = CreateFile(L"dll.dll", GENERIC_READ, FILE_SHARE_READ |
FILE_SHARE_DELETE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
hs = CreateFileMapping(h, 0, PAGE_READONLY | SEC_IMAGE, 0, 0, 0);
p = MapViewOfFile(hs, FILE_MAP_READ, 0, 0, 0);
wprintf(L"%p\n", p);
wprintf(L"%x\n", NtAreMappedFilesTheSame(p, hmod));
return 0;
}
–
Ken Johnson (Skywing)
Windows SDK MVP
http://www.nynaeve.net
“Michal Vodicka” wrote in message
news:xxxxx@ntdev…
It is an user mode question but it is related to OS behaviour so it isn’t
hopefully much OT. My coworker asked me about following scenario:
1. a process has loaded a DLL using LoadLibrary()
2. the DLL is renamed/moved to the different directory
3. new DLL with the same name is copied to the original directory
Now, the process calls LoadLibrary() for the same DLL name again.
LoadLibrary internally increments the count of loaded original DLL and
returns its handle. That’s all expected but he’d like to distinguish this
case from the case when point #1 wasn’t performed and the new DLL is loaded,
instead.
Please note it is simplified scenario and obvious approaches can’t be used
(installer is involved and so on). It’d be sufficient if he can find
LoadLibrary() returns the handle of a DLL from different directory than
caller asked. I recommended him to try GetModuleFileName() but I’m affraid
it’ll return the original name of the DLL. Using GetModuleHandle() to find
if module was loaded before can’t be used because it is allowed case;
process can already have new DLL loaded or no executed points #2 and #3.
We’d just need a way how to find current name of loaded DLL after its move
or rename.
Best regards,
Michal Vodicka
UPEK, Inc.
[xxxxx@upek.com, http://www.upek.com]