2013-02-20 29 views
2

我試圖通過它們的絕對路徑(在別處確定,以編程方式)打開幾個不同的文件,所以我可以得到它們的SHA1哈希*,其中一些是核心Windows文件。 fopen()函數是在一些返回NULL(但不是全部)的文件,當我試圖打開它們如下(通常文件名是通過QueryFullProcessImageName得到,但我硬編碼以防萬一):在Windows核心文件上調用fopen返回NULL指針

char * filename = "c:\\windows\\system32\\spoolsv.exe"; 
FILE * currFileRead = fopen(filename, "rb"); 
if (currFileRead == NULL) 
{ 
    printf("Failed to open %s, error %s\n", filename, strerror(errno)); 
} 
else 
{ 
    //hashing code 
} 

報告的錯誤是2:「沒有這樣的文件或目錄」,但顯然他們在那裏。它也只是失敗的一些進程,如spoolsv.exe或winlogon.exe,而svchost.exe和wininint.exe似乎打開很好。

我的程序具有管理權限,我無法弄清楚爲什麼某些進程會失敗,而其他進程卻無故打開?

*我正在使用來自LibTomCrypt(http://libtom.org/?page=features)的方法,該方法是具有許可許可的開源代碼。對sha1_process的調用需要一個hash_state(庫內部),一個unsigned char緩衝區以及緩衝區的長度。我需要用fopen讀取文件以將文件存入內存進行散列。

+0

想看看GetLastError()說什麼。你可以使用GetLastError()和FormatMessage()(或手動查找)嗎? – 2013-02-20 21:58:17

+1

在64位操作系統上將其更改爲sysnative而不是system32。或者建立一個64位的程序,這樣文件重定向不會成爲字節。 Fwiw在計算可能由Windows Update更新的文件上的哈希值可能不明智。 – 2013-02-20 22:05:17

+0

RonBurk GetLastError也報告2,它(每個MSDN)是ERROR_FILE_NOT_FOUND - 即同樣的問題。 HansPassant - 我的程序需要在32位和64位主機上運行。所以我不能只製作一個64位版本。你是什​​麼意思將它改爲系統性的? – user2093082 2013-02-20 22:10:29

回答

3

由於您的程序是32位進程,因此當您嘗試打開c:\windows\system32時,實際上得到的是c:\windows\syswow64,它不包含所有相同的文件。

您可以使用IsWow64Process來確定您是否在64位系統上運行。如果是這樣,除非需要支持Windows 2003或Windows XP,否則可以用路徑中的sysnative代替system32以打開實際文件。根據您的具體情況,您可能需要應對Windows文件夾不是c:\windows和/或其他文件夾名稱爲system32的可能性。

總的來說,如果您的應用程序具有單獨的32位和64位版本,或者可能只是展示該問題的特定部分,則會更加穩健。如果您不能讓用戶安裝適當的版本,安裝程序可以決定要安裝哪個版本,或者您可以隨時安裝兩者,並且在64位版本上運行時使32位版本自動啓動64位版本位系統。

+0

這就是解決方案(Hans Passant給了我足夠的朝這個方向移動,儘管IsWow64Process是我沒有找到的東西)。 鑑於我在EnumProcessModules與32位和64位二進制文​​件之間存在的問題,我將致力於編寫兩個單獨的二進制文件。 謝謝你們 – user2093082 2013-02-27 22:22:14

0

擁有管理權限並不總是足夠的,因爲如果要打開的文件正在使用中並且正在使用它的程序已將其鎖定,則無法打開並讀取該文件。

+0

所以,我的理解是,我應該能夠打開它在幾乎所有情況下閱讀。例如,我可以在記事本中打開這些.exe文件之一(儘管顯然結果是垃圾),沒有任何問題。我似乎無法在c中打開它。 – user2093082 2013-02-20 22:08:29