Win64 驱动内核编程-9.系统调用、WOW64与兼容模式
系統(tǒng)調(diào)用、WOW64與兼容模式
? ? 這種東西都是偏向于概念的,我就把資料上的東西整理下粘貼過(guò)來(lái),資料來(lái)源于胡文亮,感謝這位前輩。
? ? WIN64?的系統(tǒng)調(diào)用比?WIN32?要復(fù)雜很多,原因很簡(jiǎn)單,因?yàn)?WIN64?系統(tǒng)可以運(yùn)行兩種?EXE,而且?WIN32EXE?的執(zhí)行效率并不差(據(jù)我本人用?3DMARK06?實(shí)測(cè),在一臺(tái)電腦上分別安裝?WIN7X86?和WIN7X64,使用同樣版本的顯卡驅(qū)動(dòng),3DMARK06在?WIN7X86?的系統(tǒng)得分比在?WIN7X64?系統(tǒng)的得分高?3%左右,性能損失還算少),因此判斷出?WIN32EXE?在?WIN64?系統(tǒng)上絕對(duì)不是模擬執(zhí)行的,而是經(jīng)過(guò)了某種轉(zhuǎn)換后直接執(zhí)行。在本文中,先講解?WIN64?進(jìn)程(或稱(chēng)?64?位進(jìn)程)的系統(tǒng)函數(shù)的執(zhí)行過(guò)程,再講解?WOW64?進(jìn)程(或稱(chēng)?32?位進(jìn)程)的系統(tǒng)函數(shù)的執(zhí)行過(guò)程。
?
W?W4?IN64??進(jìn)程?的?系統(tǒng)?函數(shù)執(zhí)行?流程、W?W?OW4?64??進(jìn)程的系統(tǒng)?函數(shù)執(zhí)行?流程。
接下來(lái)說(shuō)說(shuō)?32?位程序怎么檢測(cè)自己是否運(yùn)行在?WIN64?系統(tǒng)上。微軟的官方
方案是使用?kernel32!IsWow64Process(這個(gè)函數(shù)在?XP?SP2?以后才有):
//代碼來(lái)自: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位下運(yùn)行32位程序會(huì)輸出:he?process?is?running?under?WOW64.
64位下運(yùn)行64位程序會(huì)輸出:he?process?is?not?running?under?WOW64.
32位下運(yùn)行32位程序會(huì)輸出:he?process?is?not?running?under?WOW64.
兼容模式
????兼容模式與?WOW64?不是一回事,但有點(diǎn)類(lèi)似,兼容模式是關(guān)于舊?WINDOWS?程
序在新?WINDOWS?平臺(tái)上運(yùn)行的。通過(guò)兼容模式,十幾年前的?OFFICE97?可以在
WINDOWS?7?上運(yùn)行(但反過(guò)來(lái)?OFFICE2007?不能在?WINDOWS?97?上運(yùn)行)。可以想
象,如果沒(méi)有兼容模式,將會(huì)有多少舊程序無(wú)法在新系統(tǒng)上運(yùn)行,而新系統(tǒng)又會(huì)
損失多少用戶(hù)。
????先說(shuō)說(shuō)兼容模式的實(shí)現(xiàn)。當(dāng)一個(gè)程序運(yùn)行在兼容模式時(shí),系統(tǒng)就會(huì)給它加載
不同的?DLL,保證此程序的正常運(yùn)行。隨便運(yùn)行一個(gè)應(yīng)用程序,在兼容模式與非
兼容模式下,會(huì)有不同的?DLL?加載。
????要設(shè)置某個(gè)程序的兼容性,就打開(kāi)此程序文件的“屬性”對(duì)話框,切換到“兼
容性”選項(xiàng)卡,勾選“用兼容模式運(yùn)行這個(gè)程序”復(fù)選框并選擇系統(tǒng)版本即可。
實(shí)際上,設(shè)置程序兼容性就是在注冊(cè)表的[HKCU/Software/Microsoft/Windows
NT/CurrentVersion/AppCompatFlags/Layers]下面建立一個(gè)鍵值。新建這個(gè)鍵值
會(huì)使?kernel32!GetVersionEx?和?ntdll!RtlGetVersion?獲得兼容模式中設(shè)置的
系統(tǒng)的版本號(hào)。比如說(shuō)某程序明明是在?WIN7?下運(yùn)行的,但是設(shè)置了在?XP?的兼容
模式下運(yùn)行,結(jié)果調(diào)用?kernel32!GetVersionEx?和?ntdll!RtlGetVersion?都會(huì)得
到版本號(hào)為?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;
}
???設(shè)置程序兼容性能對(duì)抗不少安全類(lèi)軟件,因?yàn)椴煌南到y(tǒng)有不同的硬編碼,
所以安全類(lèi)軟件啟動(dòng)后的第一件事就是獲取?Build?Number?來(lái)判定該使用哪一套
硬編碼,如果?Build?Number?不是任何已知的?Build?Number,就退出程序。
總結(jié)
以上是生活随笔為你收集整理的Win64 驱动内核编程-9.系统调用、WOW64与兼容模式的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 10.PHP加密相关
- 下一篇: Win64 驱动内核编程-10.突破WI