系统调用、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与兼容模式的更多相关文章

  1. Win64 驱动内核编程-3.内核里使用内存

    内核里使用内存 内存使用,无非就是申请.复制.设置.释放.在 C 语言里,它们对应的函数是:malloc.memcpy.memset.free:在内核编程里,他们分别对应 ExAllocatePool ...

  2. Win64 驱动内核编程-8.内核里的其他常用

    内核里的其他常用 1.遍历链表.内核里有很多数据结构,但它们并不是孤立的,内核使用双向链表把它们像糖 葫芦一样给串了起来.所以遍历双向链表能获得很多重要的内核数据.举个简单的例子,驱 动对象 Driv ...

  3. Win64 驱动内核编程-7.内核里操作进程

    在内核里操作进程 在内核里操作进程,相信是很多对 WINDOWS 内核编程感兴趣的朋友第一个学习的知识点.但在这里,我要让大家失望了,在内核里操作进程没什么特别的,就标准方法而言,还是调用那几个和进程 ...

  4. Win64 驱动内核编程-2.基本框架(安装.通讯.HelloWorld)

    驱动安装,通讯,Hello World 开发驱动的简单流程是这样,开发驱动安装程序,开发驱动程序,然后安装程序(或者其他程序)通过通讯给驱动传命令,驱动接到之后进行解析并且执行,然后把执行结果返回. ...

  5. Win64 驱动内核编程-18.SSDT

    SSDT 学习资料:http://blog.csdn.net/zfdyq0/article/details/26515019 学习资料:WIN64内核编程基础 胡文亮 SSDT(系统服务描述表),刚开 ...

  6. Win64 驱动内核编程-11.回调监控进线程句柄操作

    无HOOK监控进线程句柄操作 在 NT5 平台下,要监控进线程句柄的操作. 通常要挂钩三个API:NtOpenProcess.NtOpenThread.NtDuplicateObject.但是在 VI ...

  7. Win64 驱动内核编程-10.突破WIN7的PatchGuard

    突破WIN7的PatchGuard WIN64 有两个内核保护机制,KPP 和 DSE.KPP 阻止我们 PATCH 内核,DSE 拦截我们加载驱动.当然 KPP 和 DSE 并不是不可战胜的,WIN ...

  8. Win64 驱动内核编程-28.枚举消息钩子

    枚举消息钩子 简单粘贴点百度的解释,科普下消息钩子: 钩子是WINDOWS中消息处理机制的一个要点,通过安装各种钩子,应用程序能够设置相应的子例程来监视系统里的消息传递以及在这些消息到达目标窗口程序之 ...

  9. Win64 驱动内核编程-25.X64枚举和隐藏内核模块

    X64枚举和隐藏内核模块 在 WIN64 上枚举内核模块的人方法:使用 ZwQuerySystemInformation 的第 11 号功能和枚举 KLDR_DATA_TABLE_ENTRY 中的 I ...

随机推荐

  1. Educational Codeforces Round 69 (Rated for Div. 2) D. Yet Another Subarray Problem 【数学+分块】

    一.题目 D. Yet Another Subarray Problem 二.分析 公式的推导时参考的洛谷聚聚们的推导 重点是公式的推导,推导出公式后,分块是很容易想的.但是很容易写炸. 1 有些地方 ...

  2. 京东数科面试真题:常见的 IO 模型有哪些?Java 中的 BIO、NIO、AIO 有啥区别?

    本文节选自<Java面试进阶指北 打造个人的技术竞争力> 面试中经常喜欢问的一个问题,因为通过这个问题,面试官可以顺便了解一下你的操作系统的水平. IO 模型这块确实挺难理解的,需要太多计 ...

  3. Html5分页显示Table

    Html: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <met ...

  4. Git - 使用命令和P4Merge进行diff

    P4Merge P4Merge是Git的一个第三发Diff和Merge工具(可视化冲突解决工具). 下载地址: https://www.perforce.com/downloads/visual-me ...

  5. 用Python优雅的写出送给女儿的藏头诗

    2016年迎来了我的小土匪,忙活了一年,在17年的4月加班的夜里因思念以小土匪的名字写了一首藏头发了朋友圈,不温不火,最近在看python,那么如何用python优雅的用写出这首诗了? 执行 代码 i ...

  6. Elasticsearch优化 & filebeat配置文件优化 & logstash格式配置 & grok实践

    Elasticsearch优化 & filebeat配置文件优化 & logstash格式配置 & grok实践 编码转换问题(主要就是中文乱码) (1)input 中的cod ...

  7. HTTPS证书通过cert-manager自动获取,部署,续期

    HTTP-01验证和DNS-01验证 使用cert-manager给阿里云的DNS域名授权SSL证书 第一步:安装cert-manager 配置 CRD kubectl apply -f https: ...

  8. [GDKOI2021] 提高组 Day 1 总结

    [ G D K O I 2021 ]    提 高 组    D a y   1    总 结 [GDKOI2021]~~ 提高组~~ Day~1~~ 总结 [GDKOI2021]  提高组  Day ...

  9. 【10.5NOIP普及模拟】sum

    [10.5NOIP普及模拟]sum 文章目录 [10.5NOIP普及模拟]sum 题目描述 输入 输出 输入输出样例 样例输入 样例输出 解析 code 题目描述 小x有很多糖果,分成了 N 堆,排成 ...

  10. 201871030103-陈荟茹 实验二 个人项目―《D{0-1}KP问题》项目报告

    项目 内容 课程班级博客链接 班级博客链接 这个作业要求链接 作业要求链接 我的课程学习目标 1.理解掌握软件设计的过程中的各个环节2.掌握github的使用,将自己的项目上传至githu中 这个作业 ...