Does kernel32 always load from System32?

  • Copy kernel32.dll from System32 (or SysWOW64 if you're testing with a 32-bit application) to the directory containing your EXE file
  • Run the EXE file
  • Process Monitor shows it doesn't even bother to check the local folder for kernel32.dll first
  • 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.

  • On Windows 2000 and below, adding a .local file will be enough to convince it to load the local version of kernel32.dll .
  • On Windows XP and above, you need to use the .manifest file.
  • It's possible for an application to have a .manifest file embedded within it. In this case, you can delete the resource with a tool like Stud_PE.
  • 链接地址: http://www.djcxy.com/p/44478.html

    上一篇: 加载程序集并调用一个方法(如果存在的话)

    下一篇: kernel32是否总是从System32加载?