我一直在探索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
这很有趣,因为找位于C :\ windows \ system32 \ calc.exe给我...
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
为了您的观赏乐趣, “copyit”节目我在C++中写道:
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;
}
如果我在应用程序中设置断点并检查大小可变的所以tellg()调用之后我 看到798720.
???
请注意,生成的calc.exe不会在我的测试目录中运行,但如果我降低我的 UAC安全设置,它将运行。
有什么可以解释这种尺寸差异?一些软件与 system32 \ calc.exe捆绑的元数据?如果是这样,为什么我的小复制程序只复制 ,因为它在同一个文件中? Microsoft是否将TrustedInstaller 的某些证书捆绑使用?如果是这样,那么为什么我的小应用程序没有复制?
如果我用peexplorer看这两个文件...他们看起来正好是一样。与使用hexeditor的 相同。
使用Cywin的md5sum,这些文件导致不同的散列。
在其他非MS系统可执行文件上运行我的应用程序会产生完美副本,无论大小还是 哈希和可执行文件运行都不会触及UAC控件。
我重写了copyit使用CopyFile API ...相同的结果。还有_fopen()。同上。 我高度怀疑我遇到了一些未公开的安全功能。
如果你打开文件为'binary',为什么要分配一个'wchar_t * buffer'?您正在尝试复制**二进制字节**,而不是**宽字符**。难怪文件不匹配(或散列相同)。 –
请注意,文件可以包含备用数据流,但在检查文件大小时不会看到它。文件大小只适用于正常的数据流。请参阅[NTFS中的备用数据流](https://blogs.technet.com/b/askcore/archive/2013/03/24/alternate-data-streams-in-ntfs.aspx) – wimh
优秀点@Ken White,然而请注意,将缓冲区更改为char *而不是wchar_t *仅具有这样的效果,即我不会将缓冲区分配为其所需大小的两倍。由于所有IO都是二进制模式,所以wchar_t没有任何作用(除了需要的两倍)。两个版本之间的结果校验和是相同的。然而,我会更新显示的代码来反映你的bug,因为它可以分散你手头的问题。 – user3288203