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)

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)


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

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.

The behavior isn’t documented

d

-----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.


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

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

On 08/26/14 11:32, xxxxx@gmail.com wrote:

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)

iQEcBAEBCAAGBQJT/DuTAAoJEK64IL1uI2ha8bgH+QFlCoaNjNuXC+gOTX9qidWL
YFx+rOo0iwNfsYT65jxxIORNQIf4vJ2aWYsZ4o7DCf65NAa7oEmyLAhoEtE1dHzB
Rk7sXWHYSNGNe+gJ8OWdM7Tuo5GydWVAZWzfJxXLUmUoI7Z/AwofzMiHrsUEL/Oq
Mry5mVXfYHrWzvVXZHFk1z549pZEFLEpgDICFY3/buRBD1DxuJex6n3hQaPvidE5
8BQYG0y6FYREmXkLi+d4jQRbjJ0jxFEqYSaKA8iBn3eGSjoa9sCv7gGYFj5P6qMV
PQBxc1vRMTeuhHze4i0DJ1pXZbn1saI2gE0nnO942O8FZT/+wrLTxmDr6b83ISg=
=3xSy
-----END PGP SIGNATURE-----

xxxxx@gmail.com wrote:

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.

Tim,

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

On 26-Aug-2014 21:22, 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.
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

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.

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:&gt;dir /b
dupntdll.cpp

dupnt:&gt;“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 . . .

dupnt:&gt;dir /b
dupntdll.cpp
dupntdll.exe
dupntdll.obj
dupntdll.pdb
vc100.pdb

dupnt:&gt;dupntdll.exe
0

dupnt:&gt;copy c:\WINDOWS\system32\ntdll.dll dupntdll.dll
1 file(s) copied.

dupnt:&gt;dupntdll.exe
420000

dupnt:&gt;

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>

> Ok, knowing that user32 and kernel32 are special system things,

imagine that during their init they set some undocumented variables in

I would also expect user32 (or even kernel32) to connect to csrss.exe via an LPC port in its DllMain.


Maxim S. Shatskih
Microsoft MVP on File System And Storage
xxxxx@storagecraft.com
http://www.storagecraft.com

Hi Guys,

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 :wink: