Discussion:
standard file search strategy
(too old to reply)
Boba
2010-08-27 03:38:24 UTC
Permalink
Dear All; here is what I can't figure out and need your
helpful advice on: when my user application starts, it
dependants (system DLLs) get loaded (if needed) and they
get mapped in. When this takes place, how do I control the
standard sequence of the file search used by the loader?
For instance, if a copy of some system DLL happens to exist
in my application's folder or in the current directory (both
differ from %windir%\system32), the loader will pick that
copy, but I want it to load the one from %windir%\system32
instead. Thank you in advance. Boba.
rogero
2010-08-27 15:11:19 UTC
Permalink
Post by Boba
Dear All; here is what I can't figure out and need your
helpful advice on: when my user application starts, it
dependants (system DLLs) get loaded (if needed) and they
get mapped in. When this takes place, how do I control the
standard sequence of the file search used by the loader?
For instance, if a copy of some system DLL happens to exist
in my application's folder or in the current directory (both
differ from %windir%\system32), the loader will pick that
copy, but I want it to load the one from %windir%\system32
instead. Thank you in advance.                       Boba.
I'd start with reading up about LoadLibraryEx:
http://msdn.microsoft.com/en-us/library/ms684179%28v=VS.85%29.aspx
This may give you the pointers you need.

Roger.
Boba
2010-08-27 16:48:32 UTC
Permalink
i don't see how the link could help me.
Pavel A.
2010-08-27 18:01:57 UTC
Permalink
Post by Boba
Dear All; here is what I can't figure out and need your
helpful advice on: when my user application starts, it
dependants (system DLLs) get loaded (if needed) and they
get mapped in. When this takes place, how do I control the
standard sequence of the file search used by the loader?
For instance, if a copy of some system DLL happens to exist
in my application's folder or in the current directory (both
differ from %windir%\system32), the loader will pick that
copy, but I want it to load the one from %windir%\system32
instead. Thank you in advance. Boba.
Don't put copies of system DLLs in your app folder.

Re. current directory: Looking in current directory is considered non-safe
and is disabled by defaut.

See http://msdn.microsoft.com/en-us/library/ms682586(VS.85).aspx,
"Standard Search Order".

Regards,
--pa
Leo Davidson
2010-08-27 18:41:00 UTC
Permalink
Post by Pavel A.
Re. current directory: Looking in current directory is considered non-safe
and is disabled by defaut.
While it is unsafe it's also, unfortunately, *enabled* by default.
(The page you linked confirms it.)

(It's the cause of all the "binary planting" exploits which have been
revealed recently.)

Going back to the root question, are we talking about automatic
dependency loading done by the OS before your code starts to run, or
calls to LoadLibrary from within your code?
Pavel A.
2010-08-27 19:14:28 UTC
Permalink
Post by Leo Davidson
Post by Pavel A.
Re. current directory: Looking in current directory is considered non-safe
and is disabled by defaut.
While it is unsafe it's also, unfortunately, *enabled* by default.
(The page you linked confirms it.)
(It's the cause of all the "binary planting" exploits which have been
revealed recently.)
Apologies. I should write, it is enabled by default in *current* OS
versions.
These who use outdated and unsupported systems, obviously have this problem
(among of many others.)

I've just checked several XP machines installed orginally with SP1, then
updated to SP2 and SP3.
On all of them the SafeDllSearchMode registry value is not present.

--pa
Post by Leo Davidson
Going back to the root question, are we talking about automatic
dependency loading done by the OS before your code starts to run, or
calls to LoadLibrary from within your code?
Leo Davidson
2010-08-27 21:44:25 UTC
Permalink
Post by Pavel A.
Apologies. I should write, it is enabled by default in *current* OS
versions.
These who use outdated and unsupported systems, obviously have this problem
(among of many others.)
I've just checked several XP  machines installed orginally with SP1, then
updated to SP2 and SP3.
On all of them the SafeDllSearchMode registry value is not present.
The current directory is still searched by default even on Windows 7.
SafeDllSearchMode affects which order the directories are searched
but, unfortunately, it does not prevent the current directory from
being searched at all (unless the DLL in question is found somewhere
else first).

There is another registry setting which can disable lookup in the CWD
entirely but it's not set by default on any versions of Windows that
exist today, AFAIK.
Boba
2010-08-28 00:25:19 UTC
Permalink
Post by Leo Davidson
...
The current directory is still searched by default even on Windows 7.
and on all previous versions as well.
Post by Leo Davidson
SafeDllSearchMode affects which order the directories are searched
but, unfortunately, it does not prevent the current directory from
being searched at all (unless the DLL in question is found somewhere
else first).
nope. if "the DLL in question is found somewhere else first" then it
is not the application's directory that is being searched.
Post by Leo Davidson
There is another registry setting which can disable lookup in the CWD
entirely but it's not set by default on any versions of Windows that
exist today, AFAIK.
CWD is not a problem, it is under control.

thank ya'll for your time. again, my problem is: i'm too lazy to scan
for all the loaded modules at start up and unmap+[re-load]+re-map those
which are not loaded from the system dir. @Pavel, i'm afraid you are
right regarding not having those dlls in the app's folder at load time,
but users are also clients and i'm trying to put as few restrictions on
them as possible.
if any of you ever faced this situation, you'd know that what causes it
is a problem w/windows itself: unfortunately, some system dlls' behavior
depends on where the lib was loded from.
Boba
2010-08-28 00:35:21 UTC
Permalink
Post by Boba
...
nope. if "the DLL in question is found somewhere else first" then it
is not the application's directory that is being searched.
i mean the case when cwd == app's dir
Pavel A.
2010-08-28 21:29:54 UTC
Permalink
"Boba" <***@somewhere.net> wrote in message news:***@TK2MSFTNGP02.phx.gbl...
..........
Post by Boba
again, my problem is: i'm too lazy to scan
for all the loaded modules at start up and unmap+[re-load]+re-map those
right regarding not having those dlls in the app's folder at load time,
but users are also clients and i'm trying to put as few restrictions on
them as possible.
if any of you ever faced this situation, you'd know that what causes it
is a problem w/windows itself: unfortunately, some system dlls' behavior
depends on where the lib was loded from.
How about a small "bootstrap" app that will check the Windows version, check
that there are no evil twins of system DLLs in the app directory,
and when everything is clear will start the main app?
It may even delete or rename the offending DLLs.

-- pa
Boba
2010-08-29 08:37:13 UTC
Permalink
...
How about a small "bootstrap" app ...
won't help either: the "evil twins of system DLLs" may
appear after the boot completes.
... and when everything is clear will start the main app?
as i already said, this is a 3rd party application that starts
on user demand.
Hector Santos
2010-08-29 10:29:39 UTC
Permalink
Post by Boba
...
How about a small "bootstrap" app ...
won't help either: the "evil twins of system DLLs" may
appear after the boot completes.
... and when everything is clear will start the main app?
as i already said, this is a 3rd party application that starts
on user demand.
Maybe you don't have a programmatic solution here and have to resort
to just technical support. It sounds very similar to our framework
with all the loading DLLs and version control issues, ours or 3rd
party loaded.

You can do only so much and like Pavel indicated, a 'boot strap'
version checking concept is a good idea. We do that and it solves 99%
of the problems. The user/operator gets a Message "Version Mismatch
Problem."

We have the issue because people copy DLLs to where they are needed on
desktop machines, away from th main server installation. For many,
networking shared drives is allowed, for others it is not allowed, so
they need to copy DLLs over. Come automated update time at the
installed location on the server, they can get DLL mismatch problems
if they don't remember to update other machines local copies.

There is is nothing you can do here but DOCUMENT the potential issue
with updates and 3rd party installations of software and beyond that -
wait for a tech support call.

I suspect this isn't a big deal for you, but you came across it and as
its the nature of software people, we want to automate the WORLD even
for the most trivial or low occurrence issue! :)
--
HLS
m
2010-08-30 23:49:31 UTC
Permalink
If the bootstrap program is launched instead of the main app, and then
launches it if the checks are okay, then you will get some comfort.

but the basic problem is that any determined attack can bypass all
countermeasures that you (the app) implement because its implementation of
the APIs that you use to check for the attack can return the result you
expect. For example, GetModuleFileName might indicate that you have loaded
c:\Windows\System32\advapi.dll, but malicious code in c:\program files\your
app\advapi.dll may have modified the memory where GetModuleFileName is
implemented to redirect the call, or change the output, to prevent your from
detecting the true path. This is the same problem encountered with root-kit
detection, but on a per-process rather than a system wide basis.

The short answer is that there is no in-process solution to this problem.
You can implement checks for file location and version, but they are only as
reliable as the OS that you are running on. The responsibility for this
kind of checking lies squarely with the OS because only the OS has protected
knowledge of the true location of these system DLLs. However, because
hackers rarely are able to take an exploit to its penultimate advantage,
simple checks can often yield tangible results (IMHO this is the basis of
the entire AV industry), so you can try the following

- GetModuleFileName
- GetFileVersionInfo (check major & minor version against OS, revision is
volatile with Windows update)
- WinVerifyTrust
- VirtualQuery

You can also check if a core DLL has been patched after being loaded by
rechecking the checksum against the PE header + relocations, but this is
more complicated, but does offer the potential to detect nearly all attempts
to hijack your process address space. The exception is if a hack is
specifically targeted to your app and rewrites the code bytes on your binary
to falsely pass this check.
Post by Boba
...
How about a small "bootstrap" app ...
won't help either: the "evil twins of system DLLs" may
appear after the boot completes.
... and when everything is clear will start the main app?
as i already said, this is a 3rd party application that starts
on user demand.
Boba
2010-08-31 22:03:39 UTC
Permalink
...
there's absolutely no need for what you're talking about:
the computer is 100% free of viruses, but it suffers from
minor glitches in the os itself.
Pavel A.
2010-08-28 21:37:15 UTC
Permalink
Yes, it looks so :(

http://www.reuters.com/article/idUS2168761020100825?loomia_ow=t0:s0:a49:g43:r4:c0.067109:b36892454:z0

- pa
Boba
2010-08-28 00:03:37 UTC
Permalink
Post by Pavel A.
...
I've just checked several XP machines installed orginally with SP1, then
updated to SP2 and SP3.
On all of them the SafeDllSearchMode registry value is not present.
it matters not: the directory from which the application
loaded is still #0 on the search list.
Boba
2010-08-28 00:01:04 UTC
Permalink
Post by Leo Davidson
...
Going back to the root question, are we talking about automatic
dependency loading done by the OS before your code starts to run,
yes.
Post by Leo Davidson
or calls to LoadLibrary from within your code?
no.
Tim Roberts
2010-08-28 04:37:56 UTC
Permalink
Post by Leo Davidson
Going back to the root question, are we talking about automatic
dependency loading done by the OS before your code starts to run,
yes.
Then you are sunk. The search order is what it is. It is not
customizable. If you have a conflict, you need to move the EXE or the
conflicting DLL.
--
Tim Roberts, ***@probo.com
Providenza & Boekelheide, Inc.
Boba
2010-08-28 05:07:56 UTC
Permalink
Post by Tim Roberts
...
Then you are sunk. The search order is what it is. It is not
customizable.
so, you're saying my only choice is to reload those dlls. right?
Post by Tim Roberts
If you have a conflict, you need to move the EXE or the
conflicting DLL.
i can't move the dlls: they are in use. i can move the application,
but the situation may repeat itself next time the app loads; i can
not prevent system dlls from re-appearing in the app's folder. i can
hope that one day all bugs in all system dlls will be fixed by ms.
Leo Davidson
2010-08-28 13:47:18 UTC
Permalink
Post by Boba
Then you are sunk.  The search order is what it is.  It is not
customizable.
so, you're saying my only choice is to reload those dlls. right?
I'd be surprised if you didn't run into problems unloading and then re-
loading different versions of system DLLs. e.g. If anything else in
your process has a reference to the DLL you are trying to unload then
it won't actually be unloaded; you'll just reduce the refcount and
then increase it again when you try to load a different version of the
DLL (which won't be loaded because a DLL with that name is already/
still loaded). Or it may pull objects/handles/data out from under
things that are using them.

I guess it might work, if you do it really early in the process's
life, and don't have any static init code/objects that use any of the
DLLs, and know none of the other DLLs do (naughty) things in their
process/thread-attach that may reference the other DLLs. It still
seems like asking for trouble to me, though.

IMO, your only choice is to tell people to stop doing completely
stupid things like copying system DLLs to programs' directories.
That's not something anyone should have to code around; that is people
breaking their computers, and they should just be told not to do that
because it's completely stupid.

Actually, there is another option which doesn't involve any kludges:
Don't make those DLLs a dependency at all, so they are not loaded at
process startup. Instead, construct the full path to them and load
them using LoadLibrary once the process is running. (But if any other
DLL or static-init code/object causes those DLLs to be loaded before
your code gets control then you'll still have the same problem.)
Boba
2010-08-28 18:14:44 UTC
Permalink
"Leo Davidson" <***@gmail.com> wrote in message news:15aed19f-a7eb-4880-a640-***@z7g2000yqg.googlegroups.com...

Hi, Leo;
Post by Leo Davidson
I'd be surprised if you didn't run into problems unloading and then
re-loading different versions of system DLLs. e.g.
the problem i'm having is with the same versions (for now at least.)
Post by Leo Davidson
If anything else in your process has a reference to the DLL you are
trying to unload then it won't actually be unloaded; you'll just
reduce the refcount and then increase it again when you try to load
a different version of the DLL (which won't be loaded because a DLL
with that name is already/still loaded). Or it may pull objects/
handles/data out from under things that are using them.
this is not a problem: i'll do it at the first load of a questionable
dll at process startup.
Post by Leo Davidson
I guess it might work, if you do it really early in the process's
life, and don't have any static init code/objects that use any of the
DLLs, and know none of the other DLLs do (naughty) things in their
process/thread-attach that may reference the other DLLs. It still
seems like asking for trouble to me, though.
it has to be done before any init.code runs; i mean any code of appli-
cation, not the dll attachment code.
Post by Leo Davidson
IMO, your only choice is to tell people to stop doing completely
stupid things like copying system DLLs to programs' directories.
That's not something anyone should have to code around; that is people
breaking their computers, and they should just be told not to do that
because it's completely stupid.
agree, but often times bug fixing is just finding a way around stupidity
of others :)
Post by Leo Davidson
Don't make those DLLs a dependency at all, so they are not loaded at
process startup. Instead, construct the full path to them and load
them using LoadLibrary once the process is running. (But if any other
DLL or static-init code/object causes those DLLs to be loaded before
your code gets control then you'll still have the same problem.)
i'm fixing a 3rd party application; if i only had a source code...
thank you, Leo, for your comments. Boba TC.
Tim Roberts
2010-08-30 02:00:10 UTC
Permalink
Post by Boba
i can't move the dlls: they are in use. i can move the application,
but the situation may repeat itself next time the app loads; i can
not prevent system dlls from re-appearing in the app's folder.
How can that possibly happen? DLLs do not magically appear in random
folders. What kind of Frankenstein application are you working with here?
How can it possibly be so out of control of itself?
--
Tim Roberts, ***@probo.com
Providenza & Boekelheide, Inc.
Boba
2010-08-30 08:14:22 UTC
Permalink
Post by Tim Roberts
...
Post by Boba
but the situation may repeat itself next time the app loads; i can
not prevent system dlls from re-appearing in the app's folder.
How can that possibly happen?
it wasn't me who wrote that package and its users are people who are
free to do whatever they want to. are they stupid? - i do not know,
but i got busy for almost 3 days... (took me ~2 days to figure out).
Boba
2010-08-27 23:59:36 UTC
Permalink
Post by Pavel A.
...
Don't put copies of system DLLs in your app folder.
i do not. others do.
Post by Pavel A.
Re. current directory: Looking in current directory is considered non-safe
and is disabled by defaut.
no it is not.
Hector Santos
2010-08-29 10:51:55 UTC
Permalink
Post by Boba
Dear All; here is what I can't figure out and need your
helpful advice on: when my user application starts, it
dependants (system DLLs) get loaded (if needed) and they
get mapped in. When this takes place, how do I control the
standard sequence of the file search used by the loader?
For instance, if a copy of some system DLL happens to exist
in my application's folder or in the current directory (both
differ from %windir%\system32), the loader will pick that
copy, but I want it to load the one from %windir%\system32
instead. Thank you in advance. Boba.
Boba, this is really a follow up to my last post. Based on your own
follow up responses, you have the same situation we have and no matter
how much you do, you will always run into one or few people that have
a issue and need your help to resolve it.

For example, we have RPC client/server system with many static dlls,
pluggable, etc. What is common for all clients are:

wcsrv2.dll RPC client server API interface
wcsrv.dll Original, now a backward compatibility module.

We have 3rd party developers and many have written products over the
years that many customers still use that the old WCSRV.DLL interface.
Many install their products on different folders and either:

1) Have the operator put the main product directory on the PATH
2) Automatically copy WCSRV.DLL from the main product directory,
3) Or install an WCSRV.DLL copy they had during production.

Because these older 3rd party products are still useful with the
wcsrv.dll compatibility module that loads the current WCSRV2.dll, if
they have an older WCSRV.DLL, they got a POPUP message saying
SERVER/CLIENT version mismatch problem. Thats because this version
checking was always done since the original version. That logic never
changed.

The support buck is passed to us when the 3rd party vendor is no
longer around or hasn't updated his software to link with WCSRV2.DLL.

It doesn't matter, you can try to hook into LoadLibraryEx() and take
control but I don't think that will always solve this.

Honestly, is this a big deal and worth it? No matter what you do,
someone will have mismatched problem.

We should take a lesson from Microsoft when they tried to DO US A
FAVOR by taking control of this issue with the manifest and SxS crap.
That created more problems than it was worth and thank god now got
out of our WAY and don't require it for ISVs :)
--
HLS
Boba
2010-08-30 08:17:57 UTC
Permalink
thank you, Hector, for your concern. BTC.
Chris Becke
2010-08-30 12:29:20 UTC
Permalink
Post by Boba
Dear All; here is what I can't figure out and need your
helpful advice on: when my user application starts, it
dependants (system DLLs) get loaded (if needed) and they
get mapped in. When this takes place, how do I control the
standard sequence of the file search used by the loader?
For instance, if a copy of some system DLL happens to exist
in my application's folder or in the current directory (both
differ from %windir%\system32), the loader will pick that
copy, but I want it to load the one from %windir%\system32
instead. Thank you in advance. Boba.
When your application starts, the dlls that get loaded are the EXEs
imported dll's for which the system is, rather loosely, going to use the
following search order:

1. If the Dll is in the KnownDLL's key - and exists in System32 - then
the System32 version will be loaded.
2. If there is an application manifest that references an assembly that
references the dll, then the dll will be loaded from either the shared
assembly or private assembly.
3. Then the system searches the EXEs folder.
4. The current working folder on systems pre SafeDllSearchPath
5. C:\Windows\System32, C:\Windows\System, C:\Windows
6. The current working directory on SafeDllSearchPath systems
7. %PATH%

The only way to force the version in System32 to be used, it to ensure
its a registered KnownDll.

For Dlls that are loaded after application start, either directly or
indirectly via calls to LoadLibraryEx, the SetDllDirectory and
ALTERED_SEARCH_PATH flags will substitute for the current working
directory, and exe folder respectivley.

Best solution: If you are responsible for distributing the Dll, turn it
into a versioned assembly, install it into WinSxS and all these problems
go away - consumers will always get the exact dll they need to get
regardless of trojan copies anywhere else on the hdd.

Next Best Solution: Add the dll to the KnownDLLs registry key and ensure
that the correct version is in System32 - and guarded with
windows-file-protection.

3rd best solution: Refactor your program to load the dll dynamically at
runtime and always specify the fully qualified path the to the correct
version.
Boba
2010-08-30 17:15:25 UTC
Permalink
Hi Chris;
Post by Chris Becke
...
When your application starts, the dlls that get loaded are the EXEs
imported dll's for which the system is, rather loosely, going to use the
following search order: ...
the question was not about the order, i was wondering how i could control
that order at load time.
Post by Chris Becke
The only way to force the version in System32 to be used, it to ensure its
a registered KnownDll.
not applicable for 2 reasons.
Post by Chris Becke
For Dlls that are loaded after application start, either directly or
indirectly via calls to LoadLibraryEx, the SetDllDirectory and
ALTERED_SEARCH_PATH flags will substitute for the current working
directory, and exe folder respectivley.
i was talking about the os loader.
Post by Chris Becke
Best solution: If you are responsible for distributing the Dll,
no, it is ms that distributes'em.
Post by Chris Becke
Next Best Solution: Add the dll to the KnownDLLs registry key ...
na, requires restart.
Post by Chris Becke
3rd best solution: Refactor your program to load the dll dynamically
na, i was patching a 3rd party package. thanx for your time.
Chris Becke
2010-09-01 12:36:34 UTC
Permalink
Post by Boba
na, i was patching a 3rd party package. thanx for your time.
What DLL is this anyway?
Anyway, if KnownDLLs is unacceptable, and the other methods don't apply
- then the appropriate way to deal with illegitimate copies of system
dlls in the wrong place - is to just delete them.
Boba
2010-09-01 18:45:59 UTC
Permalink
Post by Chris Becke
...
What DLL is this anyway?
there are several.
Post by Chris Becke
Anyway, if KnownDLLs is unacceptable, and the other methods don't apply -
then the appropriate way to deal with illegitimate copies of system dlls
in the wrong place - is to just delete them.
deleting is not a solution because other parts of the package
will require those files to be present where they are - this is
why copies were made to begin with; the next application run may
recreate the copies. re-loading those dlls from their original
location (system area) during app start up works (for now).
m
2010-09-01 23:10:17 UTC
Permalink
I suggest that you try to install these applications in separate folders. I
expect that that will be the easiest way to handle your problem until you
can fix whatever is wrong with your code that requires private versions of
OS components.

In my experience, only dbghelp.dll and msvcrt.dll have had private builds
that need side-by-side installation. Microsoft has attempted to fix this
thru manifests, with some success, so, depending on what the DLLs are, it is
likely that on modern versions of Windows, you don't really need these extra
DLLs
Post by Boba
Post by Chris Becke
...
What DLL is this anyway?
there are several.
Post by Chris Becke
Anyway, if KnownDLLs is unacceptable, and the other methods don't apply -
then the appropriate way to deal with illegitimate copies of system dlls
in the wrong place - is to just delete them.
deleting is not a solution because other parts of the package
will require those files to be present where they are - this is
why copies were made to begin with; the next application run may
recreate the copies. re-loading those dlls from their original
location (system area) during app start up works (for now).
Boba
2010-09-05 03:34:10 UTC
Permalink
Post by m
I suggest that you try to install these applications in separate folders.
that missbehaved application is a 3rd party tool, and the 'bad system dll'
is copied into app's folder after app.installation.
Post by m
I expect that that will be the easiest way to handle your problem until
you can fix whatever is wrong with your code that requires private
versions of OS components.
who told you there's something wrong with my code? did you read my question
before you're trying to answer it?
Post by m
In my experience, only dbghelp.dll and msvcrt.dll have had private builds
that need side-by-side installation. Microsoft has attempted to fix this
thru manifests, with some success, so, depending on what the DLLs are, it
is likely that on modern versions of Windows, you don't really need these
extra DLLs
again, it is not me who creates those copies. and btw, there are more that 2
system dlls that have bugs.

Loading...