Hello,

do kernel32.dll, user32.dll and ntdll.dll always get loaded at their preferred base/load address on NT/w2k/w2k3/XP systems??? Does this mean that in theory functions exported from these DLLs could be called using hardcoded addresses (no static linking or GetProcAddress calling)???


yaa
Posted on 2004-02-04 12:59:49 by yaa
Yes and no. Since these system DLLs are loaded very early, they will always get their preferred base address - at least I cannot think of anything that would cause them not to. But they do have relocations presentm, and as such *can* be relocated (or rebased, by paranoid people).

But you cannot depend on these base addresses, and even less on hardcoded function offsets. Even base addresses tend to change between service packs, and it takes even less modifications to the source to have a lot of export addresses jumping around.

Furthermore, you'll still need to have imports from a DLL to be sure it's mapped in your process. Also, some versions of NT (win2k, for instance) requires that your applications imports from kernel32.dll, or at least imports from some other DLL so that kernel32.dll ends up *somewhere* in the import chain.

Btw, what you're referring to is not called static linking - static linking is when you're directly linking in code from a static library. I don't know if there's an official term for "using import libraries", but "implicit dynamic linkage" should suffice ^_^
Posted on 2004-02-04 13:17:46 by f0dder
f0dder,

sorry, when I say statically linking I was meaning to "statically" link the corresponding DLL import library.
I don't think those 3 DLLs can be relocated ... I remember once having read about someone having created an executable voluntarily setting its preferred load address to clash with one of those DLLs load address just to prove that those DLLs must be loaded at their preferred base addresses.


yaa
Posted on 2004-02-04 14:16:41 by yaa

sorry, when I say statically linking I was meaning to "statically" link the corresponding DLL import library.

Yep, I know, just a bad idea using the word "static linkage" because it could confuse people - especially if the context isn't entirely clear.


I remember once having read about someone having created an executable voluntarily setting its preferred load address to clash with one of those DLLs load address just to prove that those DLLs must be loaded at their preferred base addresses.

Well, unless he found a way to get his DLL loaded before those DLLs, it will be his own DLL that will be force to relocate...

It would be interesting to use rebase on, say, kernel32.dll (and test both with and without the strip-relocs flag), then boot into recovery console and copy over this kernel32.dll , see what happens.
Posted on 2004-02-04 15:06:44 by f0dder
WinXP running under vmware, I copied kernel32.dll to my win2k, rebased it, and used ERC Commander 2002 to copy it back... didn't strip relocs, but since the rebase obviously worked, you should be able to do that if you want to :)



Command line: listdlls.exe -d kernel32

Base Size Version Path
0x42420000 0xe5000 5.01.2600.0000 C:\WINDOWS\system32\kernel32.dll
Posted on 2004-02-04 15:40:29 by f0dder
f0dder,

I was not talking of having another DLL "steal" the preferred load address of kernel32.dll, user32.dll or ntdll.dll but of having an executable itself (the one that also makes use of those 3 DLLS) being set to have the same load address (so to "steal" it).
I'm sure the article said that no one (the exe or another dll) can be loaded at the preferred address of one of those 3 DLL without having the executable using them crash.


yaa
Posted on 2004-02-04 15:51:53 by yaa
Obviously you cannot load at one of those addresses when it is used by a DLL :) - this is especially true since you *have* to end up importing from kernel32 to work on all versions of windows, you'll always end up pulling in from ntdll.dll, and very likely also from user32 or gdi32.

If you rebase those DLLs, however, you should be able to use one of those 'system addresses' for your own applications - as long as your entire image is below 0x80000000, I guess.
Posted on 2004-02-04 15:57:35 by f0dder
mmmhhh, any other DLL would handle not finding its preferred base address available ... this does not happen with those 3 DLLs.

yaa
Posted on 2004-02-05 05:15:36 by yaa

mmmhhh, any other DLL would handle not finding its preferred base address available ... this does not happen with those 3 DLLs.

Dunno... try rebasing all of ntdll,kernel32,user32 to the same address - after all, they do have a .reloc section.

Also "handling not having base address available" has nothing to do with whether you can create an app using this base address or not...
Posted on 2004-02-05 05:18:53 by f0dder
Creating an executable that occupies one those base address was just a way to verify if the involved DLL can handle being loaded at a different base address.

yaa
Posted on 2004-02-05 05:22:17 by yaa
Hrm, I wouldn't say so... this might work with a 'normal' DLL (ie, do a DLL with base address 0x00600000, load it from an app with base addr 0x00400000, then load it from an app with base addr 0x00600000 before terminating the first app). However, especially kernel32 is treated a bit specially by some windows versions (like, pe loader silently refusing to execute your app if you don't end up importing from kernel32) - it could be that kernel32 is mapped in your process before your own image, and thus can't be relocated?
Posted on 2004-02-05 05:52:34 by f0dder