C++ Microsoft系统可执行副本差异
我一直在探索Windows系统文件的来龙去脉,并注意到 奇怪的是:如果我执行Windows系统的低级按位复制 可执行文件到我的目标位置选择的结果文件小于 原著 我写了一个小程序来复制无处不在的calc.exe可执行文件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
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;
}