系统DLL的副本不起作用

Art*_*tem 1 c dll winapi

我有Windows 8.1.我从E:\文件夹中的C:\ Windows\System32复制了User32.dll.首先,我已经提到,如果你只是复制粘贴,原始User32.dll的内容和User32.dll的副本是不一样的!我发现它,使用WinMerge程序.所以,我在C上写了我的程序,像这样:

void copy(FILE* input_dll)
{
    FILE* f = fopen("E:\\user32.dll", "wb");
    int size_of_base_input_dll_file;
   // Get the Size of base_file 
    fseek(input_dll, 0, SEEK_END);
    size_of_base_input_dll_file = ftell(input_dll);
    //move on a begin of dll
    fseek(input_dll, 0, SEEK_SET);
    for (int i = 0; i < size_of_base_input_dll_file; ++i)
    {
        char symbol = fgetc(input_dll);
        fputc(symbol, f);
    }
}

int main()
 {
       FILE* user32 = fopen("C:\\Windows\\System32\\user32.dll","rb");
       copy(user32);
 }
Run Code Online (Sandbox Code Playgroud)

现在WinMerge显示C:\ Windows\System32\user32.dll和E:\ user32.dll的内容相同,但文件C:\ Windows\System32\user32.dll大于E:\ user32.dll on 100 KB !!! 它怎么样?

当我尝试使用WinApi LoadLibraryA函数加载user32.dll(E:\ user32.dll)的副本时,无论是否使用我的函数副本获得user32.dll(E:\ user32.dll)的副本,它都返回NULL或者使用复制粘贴.

所以我的问题:

  1. 为什么dll的内容相同,但dll的大小不同?
  2. 为什么dll的内容相同,但是我无法使用LoadLibraryA加载E:\ user32.dll并且可以使用LoadLibraryA加载C:\ Windows\System32\user32.dll?
  3. 为什么复制粘贴制作错误的副本?

Dav*_*nan 5

您正在WOW64模拟器下运行32位进程.这意味着您需要进行文件系统重定向.系统重定向system32syswow64.

这意味着您没有复制您希望复制的文件.在资源管理器中复制时,您将从64位系统文件夹(system32)进行复制,因此复制64位DLL.当您复制32位程序时,您正在从32位系统文件夹(syswow64)复制,因此复制32位DLL.

在资源管理器中复制时,复制的文件因此是64位DLL,因此无法加载到您的进程中.当您复制32位程序时,复制的文件是32位DLL,因此可以加载到您的进程中.

您的WinMerge是一个32位程序,因此它也被重定向到32位系统目录,syswow64.

您可以使用以下方法之一访问64位system32目录:

  1. 切换到64位进程.
  2. 使用 sysnative别名从WOW64内部访问64位系统目录.
  3. 禁用文件系统重定向.

最后的选择绝对是不鼓励的,因为它会产生许多意想不到的后果.

无论你真正想做什么,将系统目录复制到其他文件夹肯定不是你的问题的解决方案.

更多细节:文件系统重定向器.

  • @FUZxxl不是.这是MS试图保持大量二进制兼容性的结果.如果他们没有这样做,他们就会破坏很多程序. (2认同)