Does kernel32 always load from System32?
This seems to contradict what I've always thought is the default behaviour of DLLs, that is to load from the local application directory first and if it's not there load from the PATH environment variable. However, for certain DLLs like ntdll or kernel32, Windows always seems to check System32 first. Is this expected behaviour? Can it be overridden?
(I'm aware that overriding this would be bad practice, but want to know if it's actually possible, for science!)
The KnownDLLs feature in Windows is supposed to help loading common DLLs faster but it also forces all DLLs on the list to load from system32.
On top of this, kernel32.dll and ntdll.dll are given special treatment in most versions of Windows and are loaded early inside CreateProcess because the real entry point of a usermode process is in one of those modules.
You can use .local and manifest redirection to override some of these.
After more research, I found that the reason certain DLLs such as kernel32.dll or user32.dll cannot be overridden normally is because they are Known DLLs - Windows has a list of commonly used DLLs like these which automatically default to the System32 versions, rather than the default behaviour of checking the folder of the application first.
If you want to work around this, for example to make a proxy DLL, you need to include two files in the application directory: applicationName.exe.local and applicationName.exe.manifest where applicationName is the name of your EXE file.
These need to be the contents of the manifest file:
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity version="1.0.0.0" name="redirector" type="win32" />
<file name="kernel32.dll" />
</assembly>
The assemblyIdentity tag is intended to give information about your application's version number and name, but we can basically just ignore it. The important part is the file tag which specifies a file to load locally. Replace kernel32.dll
with DLL you'd like to load locally.
Also, Windows only refreshes the contents of .manifest files either upon restart, or when the EXE file is modified, so you could just open the EXE file in some hex editor, erase the first character and add it back and save... etc. to refresh the manifest file. Do this if you manifest file seems to be ignored.
上一篇: 加载程序集并调用一个方法(如果存在的话)