2014-02-08 81 views
1

我一直在探索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()。同上。 我高度懷疑我遇到了一些未公開的安全功能。

+2

如果你打開文件爲'binary',爲什麼要分配一個'wchar_t * buffer'?您正在嘗試複製**二進制字節**,而不是**寬字符**。難怪文件不匹配(或散列相同)。 –

+0

請注意,文件可以包含備用數據流,但在檢查文件大小時不會看到它。文件大小隻適用於正常的數據流。請參閱[NTFS中的備用數據流](https://blogs.technet.com/b/askcore/archive/2013/03/24/alternate-data-streams-in-ntfs.aspx) – wimh

+1

優秀點@Ken White,然而請注意,將緩衝區更改爲char *而不是wchar_t *僅具有這樣的效果,即我不會將緩衝區分配爲其所需大小的兩倍。由於所有IO都是二進制模式,所以wchar_t沒有任何作用(除了需要的兩倍)。兩個版本之間的結果校驗和是相同的。然而,我會更新顯示的代碼來反映你的bug,因爲它可以分散你手頭的問題。 – user3288203

回答

4

您可能正在運行64位版本的Windows,並且您的程序是32位。當您在c:\Windows\System32中打開文件時,它將被重定向到C:\Windows\SysWOW64。所以你不是複製c:\windows\system32\calc.exe,而是C:\Windows\SysWOW64\calc.exe。我推斷calc.exe的文件大小爲798720.

另請參閱File System Redirector

+0

優秀答案@Wimmel!這似乎是這種情況。對不起,我沒有要點票給你。 – user3288203