zoukankan      html  css  js  c++  java
  • 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) (HANDLEPBOOL);

    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. "));

    else

    _tprintf(TEXT("The process is not running under WOW64. "));

    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 ", osv1.dwBuildNumber);

    //way 2

    osv2.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);

    RtlGetVersion(&osv2);

    printf("Get Build Number by RtlGetVersion: %ld ", osv2.dwBuildNumber);

    //show info

    getchar();

    return 0;

    }




       设置程序兼容性能对抗不少安全类软件,因为不同的系统有不同的硬编码,

    所以安全类软件启动后的第一件事就是获取 Build Number 来判定该使用哪一套

    硬编码,如果 Build Number 不是任何已知的 Build Number,就退出程序。

  • 相关阅读:
    新人手册
    使用koa-mysql-session时报错
    自建windows服务器如何部署egg应用
    mac os 10.15 virtualBox6.0.12崩溃
    thinkphp3.2 上传图片兼容小程序
    PHP版本微信支付开发
    php mysql 按照指定年月查找数据 数据库create_time为时间戳
    Mac OS 查看端口和杀死进程
    MAC PHP7 如何disable xdebug
    TCP为什么是三次握手,为什么不是两次或者四次 && TCP四次挥手
  • 原文地址:https://www.cnblogs.com/csnd/p/12062030.html
Copyright © 2011-2022 走看看