坑啊坑,十一七天却只能有两天时间用来搞程序,苦逼了高三狗。。。
这几天搞的放在 https://github.com/Mighten/Win32-Drivers/tree/master/MSR
主题:获取更加详细的处理器信息
实现:使用NT驱动程序在Ring 0权限上运行“读MSR”(RDMSR)指令。
想法来源: 最初是来自看完张帆写的书的IO控制(DeviceIoControl)那一章节后手痒,想做个东西练练手,后来一个偶然的机会看到邓志大叔x86/x64那本详细介绍处理器架构的书里面有介绍通过读写MSR获取更加详细的处理器信息。
开始日期: 2015年08月28日 下午05时33分
中间的测试版本: 2015年10月02日 下午01时43分
总的来说呢,还是比较不简单的,也有了一些心得,分享一下:
1. 考虑到一个基本的现实问题,人不可能什么不干连续40多小时写程序,还是分模块写好,每一个测试稳定的模块组装在一起就是一个比较稳定的大块头。。。千万别像我这样急于求成最后搞得“吃不了兜着走”
2. 由于RDMSR指令需要的参数放在寄存器里面,所以只能用C/C++内联汇编的语法,而内联汇编最重要的一部分是把寄存器里面的数值通过变量读写保存下来。
MOV 寄存器名, [指针变量]
这种格式很容易误导人,因为看上去是对的,但实际上微软的编译器偏爱于解释为
MOV 寄存器名, 指针变量内部的值
而不是指针变量存储的值所指向的单元。
就是在这段代码,特别是在操作指针变量的时候,,,,走了很多弯路,后来个人弱弱地提出一种较为低级的解决办法: 现用LEA指令吧:
LEA EAX, 指针变量名称
MOV ESI, [EAX]
MOV EAX, [ESI]
这样就取到了指针变量所指向单元内部的数值且存入了EAX寄存器。
3. 不管做什么,不管希望多么渺茫,只要肯伏下身子去一点点有耐心地去做,最后肯定希望越来越大。
4. 可能影响系统稳定性的指令一定要谨慎,最好先注释掉,模拟其返回值,等待测试稳定后再脱掉注释符。这几天测试很幸运的是,没有因为这个问题让我的机器"蓝屏死机"(术语BSOD)
这个东西虽说完成了测试版,但离着能拿出台面还远呢,
1. 只是模拟了RDMSR的返回值,还没有脱去注释符,
2. 对MSR这一庞大的家伙所知甚少,不敢轻举妄动,还没有正八经地用实际的MSR地址(索引值,可能会更好理解)测试一番,也就是说,这个版本只是个“意淫版”
3. MSR在具体处理机上实现方式很不一样,要CPUID等指令的辅助才可真枪实弹地干一架,比如AMD与Intel部分实现方式很不一样,而且同一品牌的新旧版本还要判断, 在外部调用时要完成检测工作——这,其实是一个体力活 。
4. 前边我做的一个用DLL封装的对CPUID操作现在可能要用到,但是那个DLL是在我所知甚少的情况下做的,概念性的错误很多,需要重新查阅Intel与AMD两家巨头的开发人员文档增补修改。。
————最后我的目标是,把那个DLL与这个SYS整合成一个比较综合的模块,名称仍为“处理器的功能检测与信息获取”
我不知道以后有什么更大的难题等待我去解决,或许超乎我的想想,也许小菜一碟,但不管怎样,客观上来说,只要我不轻易放弃,那一定是我一个千载难逢的成长与成熟的机会