C++ Microsoft系统可执行副本差异

C++ Microsoft系统可执行副本差异,c++,windows,C++,Windows,我一直在探索Windows系统文件的来龙去脉,并注意到 奇怪的是:如果我执行Windows系统的低级按位复制 可执行文件到我的目标位置选择的结果文件小于 原著 我写了一个小程序来复制无处不在的calc.exe可执行文件 C:\test> copyit c:\windows\system32\calc.exe c:\test\calc.exe 这是生成的文件: C:\test>dir Volume in drive C is OS Volume Serial Number is

我一直在探索Windows系统文件的来龙去脉,并注意到 奇怪的是:如果我执行Windows系统的低级按位复制 可执行文件到我的目标位置选择的结果文件小于 原著

我写了一个小程序来复制无处不在的calc.exe可执行文件

C:\test> copyit c:\windows\system32\calc.exe c:\test\calc.exe
这是生成的文件:

C:\test>dir
 Volume in drive C is OS
 Volume Serial Number is DEAD-BEEF

 Directory of C:\test

02/08/2014  03:37 PM    <DIR>          .
02/08/2014  03:37 PM    <DIR>          ..
02/08/2014  03:37 PM           798,720 calc.exe
               1 File(s)        798,720 bytes
               2 Dir(s)  291,059,347,456 bytes free
如果我在应用程序中设置断点并在tellg()调用后检查size变量 见798720

请注意,生成的calc.exe将不会在我的测试目录中运行,但如果我降低 UAC安全设置它将运行

什么可以解释这种尺寸差异?一些软元数据与 system32\calc.exe?如果是这样的话,为什么我的小复制程序不能复制好的呢 因为它在同一个文件中?微软是否正在为可信安装商捆绑一些证书 使用?如果是这样的话,为什么我的小应用程序不复制它呢

如果我用peexplorer查看这两个文件。。。它们看起来完全一样。同 使用hexeditor

使用Cywin的md5sum,这些文件会产生不同的散列

在其他非MS系统可执行文件上运行我的应用程序会产生一个完美的副本,无论大小还是大小 哈希和可执行文件在不接触UAC控件的情况下运行

我用CopyFile API重写了copyit。。。同样的结果。也可以使用_fopen()。同上。
我高度怀疑我遇到了一些未记录的安全功能

您可能正在运行64位版本的windows,而您的程序是32位的。在
c:\Windows\System32
中打开文件时,它将被重定向到
c:\Windows\SysWOW64
。因此,您不是在复制
c:\windows\system32\calc.exe
,而是在复制
c:\windows\SysWOW64\calc.exe
。我估计calc.exe的文件大小为798720


另请参见。

您可能正在运行64位版本的windows,而您的程序是32位的。在
c:\Windows\System32
中打开文件时,它将被重定向到
c:\Windows\SysWOW64
。因此,您不是在复制
c:\windows\system32\calc.exe
,而是在复制
c:\windows\SysWOW64\calc.exe
。我估计calc.exe的文件大小为798720


另请参见。

如果您以二进制方式打开文件,为什么要分配
wchar\u*buffer
?您正在尝试复制二进制字节,而不是宽字符。难怪文件不匹配(或散列相同)。请注意,文件可以包含备用数据流,但在检查文件大小时不会看到它。文件大小仅适用于普通数据流。请参阅极好的一点@Ken White,但是请注意,将缓冲区更改为char*而不是wchar\u t*只会产生这样的效果,即我没有将缓冲区分配为需要的两倍大。由于所有IO都处于二进制模式,因此wchar__t没有任何影响(除了需要的两倍大)。两个版本之间的结果校验和是相同的。不过,我将更新显示的代码以反映您的错误捕获,因为它可能会分散您的注意力。@Wimmel我已经检查了是否有calc.exe包含使用sysinternal太“Streams”的广告。。。。找不到任何文件。如果您以
二进制文件
打开文件,为什么要分配
wchar\u t*缓冲区
?您正在尝试复制二进制字节,而不是宽字符。难怪文件不匹配(或散列相同)。请注意,文件可以包含备用数据流,但在检查文件大小时不会看到它。文件大小仅适用于普通数据流。请参阅极好的一点@Ken White,但是请注意,将缓冲区更改为char*而不是wchar\u t*只会产生这样的效果,即我没有将缓冲区分配为需要的两倍大。由于所有IO都处于二进制模式,因此wchar__t没有任何影响(除了需要的两倍大)。两个版本之间的结果校验和是相同的。不过,我将更新显示的代码以反映您的错误捕获,因为它可能会分散您的注意力。@Wimmel我已经检查了是否有calc.exe包含使用sysinternal太“Streams”的广告。。。。没有找到。回答得很好@Wimmel!情况似乎是这样。对不起,我没有投票给你的分数。回答得很好@Wimmel!情况似乎是这样。对不起,我没有投票支持你的理由。
C:\test>dir c:\Windows\System32\calc.exe
 Volume in drive C is OS
 Volume Serial Number is DEAD-BEEF

 Directory of c:\Windows\System32

08/22/2013  05:51 AM           922,112 calc.exe     <------Why is this larger?
               1 File(s)        922,112 bytes
               0 Dir(s)  291,059,322,880 bytes free
int main(int argc, char* argv[])
{  
    std::ifstream is( argv[0], std::ios::in | std::ios::binary );
    std::ofstream os( argv[1], std::ios::out| std::ios::binary );

    is.seekg(0, std::ios::end);
    std::streampos size = is.tellg();
    is.seekg(0);

    char* buffer = new char[(size_t)size];

    is.read(buffer, size);
    os.write(buffer, size);

    delete [] buffer;

    os.close();
    is.close();

    return 0;
}