Win64 驱动内核编程-9.系统调用、WOW64与兼容模式
系統調用、WOW64與兼容模式
? ? 這種東西都是偏向于概念的,我就把資料上的東西整理下粘貼過來,資料來源于胡文亮,感謝這位前輩。
? ? WIN64?的系統調用比?WIN32?要復雜很多,原因很簡單,因為?WIN64?系統可以運行兩種?EXE,而且?WIN32EXE?的執行效率并不差(據我本人用?3DMARK06?實測,在一臺電腦上分別安裝?WIN7X86?和WIN7X64,使用同樣版本的顯卡驅動,3DMARK06在?WIN7X86?的系統得分比在?WIN7X64?系統的得分高?3%左右,性能損失還算少),因此判斷出?WIN32EXE?在?WIN64?系統上絕對不是模擬執行的,而是經過了某種轉換后直接執行。在本文中,先講解?WIN64?進程(或稱?64?位進程)的系統函數的執行過程,再講解?WOW64?進程(或稱?32?位進程)的系統函數的執行過程。
?
W?W4?IN64??進程?的?系統?函數執行?流程、W?W?OW4?64??進程的系統?函數執行?流程。
接下來說說?32?位程序怎么檢測自己是否運行在?WIN64?系統上。微軟的官方
方案是使用?kernel32!IsWow64Process(這個函數在?XP?SP2?以后才有):
//代碼來自:http://msdn.microsoft.com/en-us/library/ms684139(VS.85).aspx
#include?<windows.h>
#include?<tchar.h>
typedef?BOOL(WINAPI?*LPFN_ISWOW64PROCESS)?(HANDLE,?PBOOL);
LPFN_ISWOW64PROCESS?fnIsWow64Process;
BOOL?IsWow64()
{
BOOL?bIsWow64?=?FALSE;
//IsWow64Process?is?not?available?on?all?supported?versions?of?Windows.
//Use?GetModuleHandle?to?get?a?handle?to?the?DLL?that?contains?the?function
//and?GetProcAddress?to?get?a?pointer?to?the?function?if?available.
fnIsWow64Process?=?(LPFN_ISWOW64PROCESS)GetProcAddress(
GetModuleHandle(TEXT("kernel32")),?"IsWow64Process");
if?(NULL?!=?fnIsWow64Process)
{
if?(!fnIsWow64Process(GetCurrentProcess(),?&bIsWow64))
{
//handle?error
}
}
return?bIsWow64;
}
int?main(void)
{
if?(IsWow64())
_tprintf(TEXT("The?process?is?running?under?WOW64.\n"));
else
_tprintf(TEXT("The?process?is?not?running?under?WOW64.\n"));
return?0;
}
?
64位下運行32位程序會輸出:he?process?is?running?under?WOW64.
64位下運行64位程序會輸出:he?process?is?not?running?under?WOW64.
32位下運行32位程序會輸出:he?process?is?not?running?under?WOW64.
兼容模式
????兼容模式與?WOW64?不是一回事,但有點類似,兼容模式是關于舊?WINDOWS?程
序在新?WINDOWS?平臺上運行的。通過兼容模式,十幾年前的?OFFICE97?可以在
WINDOWS?7?上運行(但反過來?OFFICE2007?不能在?WINDOWS?97?上運行)。可以想
象,如果沒有兼容模式,將會有多少舊程序無法在新系統上運行,而新系統又會
損失多少用戶。
????先說說兼容模式的實現。當一個程序運行在兼容模式時,系統就會給它加載
不同的?DLL,保證此程序的正常運行。隨便運行一個應用程序,在兼容模式與非
兼容模式下,會有不同的?DLL?加載。
????要設置某個程序的兼容性,就打開此程序文件的“屬性”對話框,切換到“兼
容性”選項卡,勾選“用兼容模式運行這個程序”復選框并選擇系統版本即可。
實際上,設置程序兼容性就是在注冊表的[HKCU/Software/Microsoft/Windows
NT/CurrentVersion/AppCompatFlags/Layers]下面建立一個鍵值。新建這個鍵值
會使?kernel32!GetVersionEx?和?ntdll!RtlGetVersion?獲得兼容模式中設置的
系統的版本號。比如說某程序明明是在?WIN7?下運行的,但是設置了在?XP?的兼容
模式下運行,結果調用?kernel32!GetVersionEx?和?ntdll!RtlGetVersion?都會得
到版本號為?2600?而不是?7600。
?
#include?<stdio.h>
#include?<windows.h>
typedef?long(__stdcall?*RTLGETVERSION)(POSVERSIONINFO);
int?main()
{
RTLGETVERSION
RtlGetVersion?=?(RTLGETVERSION)GetProcAddress(LoadLibrary(L"ntdll.dll"),?"RtlGetVersion");
OSVERSIONINFO?osv1?=?{?0?},?osv2?=?{?0?};
//way?1
osv1.dwOSVersionInfoSize?=?sizeof(OSVERSIONINFO);
GetVersionEx(&osv1);
printf("Get?Build?Number?by?GetVersionEx:?%ld\n",?osv1.dwBuildNumber);
//way?2
osv2.dwOSVersionInfoSize?=?sizeof(OSVERSIONINFO);
RtlGetVersion(&osv2);
printf("Get?Build?Number?by?RtlGetVersion:?%ld\n",?osv2.dwBuildNumber);
//show?info
getchar();
return?0;
}
???設置程序兼容性能對抗不少安全類軟件,因為不同的系統有不同的硬編碼,
所以安全類軟件啟動后的第一件事就是獲取?Build?Number?來判定該使用哪一套
硬編碼,如果?Build?Number?不是任何已知的?Build?Number,就退出程序。
總結
以上是生活随笔為你收集整理的Win64 驱动内核编程-9.系统调用、WOW64与兼容模式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 10.PHP加密相关
- 下一篇: Win64 驱动内核编程-10.突破WI