怎样判定应用程序自身运行在“兼容模式”下?
来源:互联网 发布:linux vi 加行号 编辑:程序博客网 时间:2024/06/16 06:40
怎样判定应用程序自身运行在“兼容模式”下?
我们的程序有时候需要精确的判定当前运行在哪个系统下面,也就是说程序的某个功能可能需要知道当前运行在哪个真正的操作系统下,而操作系统提供了一个兼容模式功能,就是用户可以设置某个程序运行在某个模拟的更低的版本的操作系统下面,这是有好处的,因为某些程序在某些更高版本的操作系统下面可能发生兼容性问题而无法运行。在设置兼容模式运行后,程序里面调用ring3层的GetVersionEx得到的将是模拟的的操作系统版本,而不是真正的操作系统版本。
由此而引发两个问题:
1、怎么判定当前程序(自己)运行在兼容模式下了呢?
2、如果有一个需求,在安装时,怎么设置一个程序运行在某个低版本的操作系统兼容模式下呢?
先看下第2个问题,首先看一下在设置了兼容模式运行后,系统做了些什么事情?很容易做到,使用注册表工具对explorer.exe进行监控,在设置兼容模式应用或者确定后,发现系统在注册表 [HKCU/Software/Microsoft/Windows NT/CurrentVersion/AppCompatFlags/Layers] 写下了如下一些东东:
系统把需要进行兼容模式运行的程序路径记录在这个下面,具体兼容哪个环境则由属性的值来确定,譬如WIN2000, NT4SP5, WIN95, WIN98, WINXPSP2, WINXPSP3, WINSRV03SP1, WINSRV08SP1, VISTARTM, VISTASP1, VISTASP2等等(不要在低版本的操作系统下兼容更高版本的操作系统,不会出问题,而是毫无意义,系统直接忽略)。有了这个就可以做到把某个程序写入兼容模式运行中。也可以保护这个注册表位置防止别人来使用兼容模式运行你的程序。
再看看第一个问题,研究下了微软实现兼容模式的原理,网上的资料很少,但是大概就是使用HOOK的原理,windows发现该程序需要进行兼容模式运行(通过查注册表啦,还有一些系统默认以兼容模式运行的程序,应该是记录在其他地方,没有深究),就会加载一些不同的系统DLL(在win32下一个应用程序想跑起来,是需要很多系统的DLL的)来进行程序的运行,大概情况如下,左边是非兼容模式运行时加载的一些DLL,右边是运行在兼容模式环境下后加载的一些DLL:
这是否就给了我们一些思路?可以检测当前程序加载的模块,如果有这些AcGenral.dll之类的模块存在,就认为是运行在兼容模式下呢?这个我没有去试过,但是我觉得可行。o(∩_∩)o
另外一种方法是从原理是来绕过,GetVersionEx这个API来之kernel32.dll,而kernel32.dll又调用了ntdll.dll里面的RtlGetVersion这个函数,如果我们直接调用呢?试了下也是有一定可行性的。不过悲剧的是,这个方法在vista及以上系统就无效了,可能是因为微软在实现兼容模式时,hook得更加深了。
360也有个兼容模式检测功能,去看了下他的实现,还不错。
然后去研究了下,发现很有道理,360的方式是先调用 GetVersionEx 得到一个版本号,譬如是5.0(2000系统),然后算出一个值50(5*10 + 0);然后调用文件版本API,取出文件ntoskrnl.exe的版本号,譬如是5.1.2600.5938,然后算出一个值52(5*10 + 1),对比前后两个值,如果不相等则认为自身运行在兼容模式下。具体分析可以见调试结果(call 0042980是去取ntoskrnl.exe是版本)。
下面是IDA反编译的结果:
还不错哦。
[END]
- 怎样判定应用程序自身运行在“兼容模式”下?
- 怎样判定应用程序自身运行在“兼容模式”下?
- win8/10上的应用程序怎样以兼容模式运行?
- 同时在手机和平板下兼容运行Android应用程序
- 让网站在IE8的兼容模式下运行
- 在win7下如何以兼容模式运行matlab
- 程序检测自身是否运行在虚拟机下
- 通过代码将程序在Win7/Win8下设置成以兼容模式运行
- 巧妙解决程序运行在兼容模式下时window版本欺诈问题
- C#自身包含其他应用程序(或者文件)并在运行时调用
- C#自身包含其他应用程序(或者文件)并在运行时调用
- (九)Spark应用程序在不同部署模式下的运行方式
- vs2015在Debug模式下运行出现"应用程序无法正常启动(0x000007b)"的错误解决方法
- 在高优先级下运行应用程序
- ADF11g-037:解决IE8兼容模式下运行时弹窗问题
- 解决IE8兼容模式下运行时弹窗问题
- 争论:DirectX 10能兼容运行在XP下?
- 怎样让程序每次运行后改变自身图标?
- 高效地显示Bitmap图片 3 - 两种缓存Bitmap的方式
- 高效地显示Bitmap图片 4 - 使用ViewPager与GridView显示图片
- 改变datagridview行头图标
- ARM汇编的SWI指令软中断
- sharepoint 2010 用timer job 实现列表评论次数
- 怎样判定应用程序自身运行在“兼容模式”下?
- 我的vim配置文件.vimrc(一)(最后一行的配置会方便很多)
- Java与C#交互DES算法加密解密数据
- java定时器
- android 之 SQLite
- 防黑必学cmd命令集合
- delegate传值-demo
- sip协议中重要名词Session(会话)、dialog(对话)、transaction(事务)的理解
- My97DatePicker使用说明文档