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与兼容模式的更多相关文章
- Win64 驱动内核编程-3.内核里使用内存
内核里使用内存 内存使用,无非就是申请.复制.设置.释放.在 C 语言里,它们对应的函数是:malloc.memcpy.memset.free:在内核编程里,他们分别对应 ExAllocatePool ...
- Win64 驱动内核编程-8.内核里的其他常用
内核里的其他常用 1.遍历链表.内核里有很多数据结构,但它们并不是孤立的,内核使用双向链表把它们像糖 葫芦一样给串了起来.所以遍历双向链表能获得很多重要的内核数据.举个简单的例子,驱 动对象 Driv ...
- Win64 驱动内核编程-7.内核里操作进程
在内核里操作进程 在内核里操作进程,相信是很多对 WINDOWS 内核编程感兴趣的朋友第一个学习的知识点.但在这里,我要让大家失望了,在内核里操作进程没什么特别的,就标准方法而言,还是调用那几个和进程 ...
- Win64 驱动内核编程-2.基本框架(安装.通讯.HelloWorld)
驱动安装,通讯,Hello World 开发驱动的简单流程是这样,开发驱动安装程序,开发驱动程序,然后安装程序(或者其他程序)通过通讯给驱动传命令,驱动接到之后进行解析并且执行,然后把执行结果返回. ...
- Win64 驱动内核编程-18.SSDT
SSDT 学习资料:http://blog.csdn.net/zfdyq0/article/details/26515019 学习资料:WIN64内核编程基础 胡文亮 SSDT(系统服务描述表),刚开 ...
- Win64 驱动内核编程-11.回调监控进线程句柄操作
无HOOK监控进线程句柄操作 在 NT5 平台下,要监控进线程句柄的操作. 通常要挂钩三个API:NtOpenProcess.NtOpenThread.NtDuplicateObject.但是在 VI ...
- Win64 驱动内核编程-10.突破WIN7的PatchGuard
突破WIN7的PatchGuard WIN64 有两个内核保护机制,KPP 和 DSE.KPP 阻止我们 PATCH 内核,DSE 拦截我们加载驱动.当然 KPP 和 DSE 并不是不可战胜的,WIN ...
- Win64 驱动内核编程-28.枚举消息钩子
枚举消息钩子 简单粘贴点百度的解释,科普下消息钩子: 钩子是WINDOWS中消息处理机制的一个要点,通过安装各种钩子,应用程序能够设置相应的子例程来监视系统里的消息传递以及在这些消息到达目标窗口程序之 ...
- Win64 驱动内核编程-25.X64枚举和隐藏内核模块
X64枚举和隐藏内核模块 在 WIN64 上枚举内核模块的人方法:使用 ZwQuerySystemInformation 的第 11 号功能和枚举 KLDR_DATA_TABLE_ENTRY 中的 I ...
随机推荐
- 【Arduino学习笔记05】Arduino数字输入、输出和脉冲宽带调制 -- 小项目:彩色小台灯
基本功能: 长按控制按钮开机,长按控制按钮关机(>3s) 通过三个调节按钮调节灯的颜色,每一个按钮分别对应R,G,B值 模式切换:短按控制按钮切换模式(长亮模式/闪烁模式) 元器件清单: Ard ...
- 在Linux中安装MariaDB并添加远程访问
在Linux中安装MariaDB并添加远程访问 最近学习到了数据库部分,因为有一台台式机一台笔记本换着用,就没有把数据库安装在本机,本来打算用之前买的虚拟空间的数据库的,结果速度太慢用起来太难受了,就 ...
- WPF 基础 - 资源
为了避免丢失和损坏,编译器允许我们把外部文件编译进程序主体.成为程序主体不可分割的一部分,这就是传统意义上的程序资源,即二进制资源: WPF 的四个等级资源: 数据库里的数据 (仓库) 资源文件 (行 ...
- 攻防世界 reverser secret-galaxy-300
secret-galaxy-300 school-ctf-winter-2015 运行程序 完全没有flag的身影呀 ida查看字符串 也没有相关信息 动态调试,看运行后内存信息 发现了一串字符 al ...
- 此博客使用的CSS样式详解!
此博客使用的CSS样式详解! 页面使用的博客园模板为:LuxInteriorLight,可以在博客皮肤里找到. 页首屏蔽广告代码 <script>console.log("顶部标 ...
- k8s删除节点
k8s 删除节点 线上环境 # ctl get nodes NAME STATUS ROLES AGE VERSION 10.0.0.123 Ready <none> 104d v1.20 ...
- ECharts绘制折线图
首先看实现好的页面 实现 首先引入echarts工具 // vue文件中引入echarts工具 let echarts = require('echarts/lib/echarts') require ...
- 使用SignalR ASP.NET Core来简单实现一个后台实时推送数据给Echarts展示图表的功能
什么是 SignalR ASP.NET Core ASP.NET Core SignalR 是一种开放源代码库,可简化将实时 web 功能添加到应用程序的功能. 实时 web 功能使服务器端代码可以立 ...
- Recoil 中多级数据联动及数据重置的合理做法
前情回顾 书接上回,前面引出了在数据存在级联的情况下,各下拉框之间的默认值及值变化的处理.简单回顾一下: 场景是: 地域下拉决定可选的可用区 默认选中第一个地域,通过设置 atom 的 default ...
- MySQL-索引简介
一.索引是什么? 索引是本质是一种数据结构,索引的目的在于提高查询效率.[排好序的快速查找的数据结构] 每个节点包含索引键值和一个指向对应数据记录物理地址的指针. 索引往往以索引文件的形式存储在磁盘. ...