I am just doing some experiment and trying to understand why i can not do the following:
(1) I copy kernel32.dll / user32.dll and rename both to some fabricated name (x.dll and y.dll), trying to load in my program x.dll or y.dll will result in an error 1114 dynamic link library (DLL) intialization routine failed.
But when i try to do the same with my other dlls, e.g. Test.dll renaming to w.dll and then loading both, it succeeds and both are loaded.
I know that both kernel32.dll and user32.dll have reloc section therefore they should be able to relocate (re-base) automatically when the image base address already occupied, why then it fails?
I am working under Windows 7. debugging in visual studio 2014 (configured 32bit in configuration manager)
These DLLs are special and there is hardcoded behaviors in them. You can’t load them twice.
-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@gmail.com
Sent: Tuesday, August 26, 2014 12:18 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] Loading duplicate DLL with different filename
Hi,
I am just doing some experiment and trying to understand why i can not do the following:
(1) I copy kernel32.dll / user32.dll and rename both to some fabricated name (x.dll and y.dll), trying to load in my program x.dll or y.dll will result in an error 1114 dynamic link library (DLL) intialization routine failed.
But when i try to do the same with my other dlls, e.g. Test.dll renaming to w.dll and then loading both, it succeeds and both are loaded.
I know that both kernel32.dll and user32.dll have reloc section therefore they should be able to relocate (re-base) automatically when the image base address already occupied, why then it fails?
I am working under Windows 7. debugging in visual studio 2014 (configured 32bit in configuration manager)
I know they are special system dlls, i am interested what is the hard-coded behavior which doesn’t allow me to load them twice (i can’t find any documented reason), i am debugging few hours in ollyDbg to try and find our the reason , till far without luck.
-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@gmail.com
Sent: Tuesday, August 26, 2014 12:32 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Loading duplicate DLL with different filename
I know they are special system dlls, i am interested what is the hard-coded behavior which doesn’t allow me to load them twice (i can’t find any documented reason), i am debugging few hours in ollyDbg to try and find our the reason , till far without luck.
I know they are special system dlls, i am interested what is the
hard-coded behavior which doesn’t allow me to load them twice (i
can’t find any
documented reason),
i am debugging few hours in ollyDbg to try and find our the reason
, till far without luck.
Have you looked in DllMain, if it’s there (I conclude it’s there
reading the original post)?
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.22 (GNU/Linux)
I know they are special system dlls, i am interested what is the hard-coded behavior which doesn’t allow me to load them twice (i can’t find any documented reason), i am debugging few hours in ollyDbg to try and find our the reason , till far without luck.
You seem to be thinking that the system is doing something special to
prevent the DLLs from loading. I think the explanation is much
simpler. The DLLs are being loaded, their DllInit routine is being
called, DllInit discovers that their initialization has already been
done, and DllInit fails.
–
Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.
How they know that it is already initialized if I loading it with different names, and why then two simple dlls with different names are loaded successfully.
And I don’t want to change nothing undocumented , I am just trying to understand
– gg
How they know that it is already initialized if I loading it with different names, and why then two simple dlls with different names are loaded successfully.
And I don’t want to change nothing undocumented , I am just trying to understand
Ok, knowing that user32 and kernel32 are special system things,
imagine that during their init they set some undocumented variables in
the process private data area.
On the 2nd attempt they check these fields and see that they are already
not 0 or whatever…
– pa
How they know that it is already initialized if I loading it with different names, and why then two simple dlls with different names are loaded successfully.
These DLLs both have a job to do, and they’re all sharing the same
address space. Kernel32.dll is setting up the process and its address
space to prepare it for execution, including calling in to the kernel to
configure things. Maybe kernel32 tries to initialize a thread table,
and when it does it sees that someone else already set it up.
The POINT here is that you certainly can load a given DLL twice with
different names, UNLESS the DLL itself has code that depends on being
initialized only once per process. These DLLs apparently have such
code. It’s not a system policy, it’s a policy with these specific DLLs.
–
Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.
well i faintly remebered loading ntdll via loadlib so just to confirm
if i was remembering wrong i rigged a twoliner and it seems i can load
renamed ntdll via loadlib without problems in an xpsp2 dont have a
win7 rig handy to check if the behaviour has changed
dupnt:\>dir /b
dupnt:\>copy con dupntdll.cpp #include <windows.h> #include <stdio.h> int main (void) { HMODULE hMod = LoadLibraryA(“dupntdll.dll”); printf(“%x\n”, hMod); return 0; }^Z 1 file(s) copied.
dupnt:>dir /b dupntdll.cpp
dupnt:>“c:\Program Files\Microsoft Visual Studio 10.0\vc\compile.bat” dupntdll.cpp Setting environment for using Microsoft Visual Studio 2010 x86 tools. dupntdll.cpp c:\codesnips\dupntdll\dupntdll.cpp(6) : warning C6273: Non-integer passed as par ameter ‘2’ when integer is required in call to ‘printf’: if a pointer value is b eing passed, %p should be used Press any key to continue . . .
On 8/27/14, Tim Roberts wrote: > xxxxx@gmail.com wrote: >> How they know that it is already initialized if I loading it with >> different names, and why then two simple dlls with different names are >> loaded successfully. > > These DLLs both have a job to do, and they’re all sharing the same > address space. Kernel32.dll is setting up the process and its address > space to prepare it for execution, including calling in to the kernel to > configure things. Maybe kernel32 tries to initialize a thread table, > and when it does it sees that someone else already set it up. > > The POINT here is that you certainly can load a given DLL twice with > different names, UNLESS the DLL itself has code that depends on being > initialized only once per process. These DLLs apparently have such > code. It’s not a system policy, it’s a policy with these specific DLLs. > > – > Tim Roberts, xxxxx@probo.com > Providenza & Boekelheide, Inc. > > > — > NTDEV is sponsored by OSR > > Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev > > OSR is HIRING!! See http://www.osr.com/careers > > For our schedule of WDF, WDM, debugging and other seminars visit: > http://www.osr.com/seminars > > To unsubscribe, visit the List Server section of OSR Online at > http://www.osronline.com/page.cfm?name=ListServer ></stdio.h></windows.h>
i was overwhelmed with the amount of answers and suggestions.
Till now i debugged carefully User32.dll second loading and found the reason inside ntdll.RtlInitializeNtUserPfn(), there is one variable which is initialized once as you all said, on second try of loading User32.dll this variable is checked.
I assume that if zero this variable everything should succeed, although i really wouldn’t like to hack with kernel process space.
I must say it was really interesting and exciting reverse engineering work