看过以前有童鞋写过的清空 cmos 的小程序挺好用的,但是方法介绍的不是很详 细,这篇文章主要从端口读写入手,详细阐述在windows系统下如何操纵端口。操纵端口无 非有这么几种用途,操纵PC SPEAKER发声,清空CMOS,读写硬盘端口穿透还原系统,高校 里面经常用来做的采集数据的项目从端口读写PCI卡。 我先列一下端口读写的几种方法吧。 1. 六个宏定义 READ_PORT_UCHAR READ_PORT_USHORT READ_PORT_ULONG WRITE_PORT_UCHAR WRITE_PORT_USHORT WRITE_PORT_ULONG 2.内嵌汇编In和 Out 特权指令的使用 3.Native API NtSystemDebugControl的使用 4.使用函数Ke386QueryAccessMap Ke386SetIoAccessMap Ke386IoSetAccessProcess 5.WinIO 的使用 第一种方法(需要驱动),使用六个宏定义 他们分别是 READ_PORT_UCHAR READ_PORT_USHORT READ_PORT_ULONG WRITE_PORT_UCHAR WRITE_PORT_USHORT WRITE_PORT_ULONG 这也是非常稳定的一种方法,是微软推荐的一种做法,宏定义大家都知道,在根据 OS 版本的不同下调用不同的函数,这六个函数类似于 dos 下 debug 命令中的 IN 和 OUT 并且 在 WinIo 中作者也是用了着六个函数来进行端口的读写。R3 下主要代码如下。我们使用 CreateFile打开我们在驱动中创建的"\\??\\CMOS"这个符号链接。注意C++中\要表示成\\, 然后向 70和 71端口写入垃圾数据,所以代码如图1: ![]() 图 1 测试程序都是 CUI 程序,成功后在 CMD 窗口中打印出 success, 截图测试程序在虚拟机中如图 2: ![]() 测试的时候首先在VMware安装的XP SP3 启动的时候设置CMOS密码,然后用驱动加载工 具加载我们的驱动,将测试程序拖入cmd中查看是否成功。如图3: ![]() 这时候重启虚拟机,会发现CMOS 已经被清空,说明我们的端口读写成功。 第二种方法(需要驱动) 内嵌汇编In 和 Out特权指令的使用 大家可能都试过从光驱启动,很多优化版本的 XP 光盘往往集成了很多工具,其中进入 dos 输入一个命令就可以清空 CMOS。 的确在 dos下这样的命令就可以清空CMOS. -o 70 xx(回车) (xx位 00-99之间的任意数值) -o 71 xx(回车) -q (回车) Dos 下只是用了CPU的实模式,但是windows下充分利用了CPU 的保护模式,不挂驱动 想要进入 R0 是不容易做到的,当然调用Native API可以不挂驱动做到很多需要挂驱动才能 做到的事情,Native API 的缺点就是因 OS 的版本号 Native API 的某些功能号不同或者干 脆被微软和谐了,这个后面我们在 NtSystemDebugControl 里面细说。第二种方法的关键就 在于对于六个函数的封装。这个代码比较多截图如图4。关键就在于着六个函数的封装。 ![]() 看出点门道来了吧,其实和六个宏定义是差不多的,然后 R3 程序中我们依然用 CreateFile 打开我们创建的符号链接"\\.??\\CMOSASM"测试方法和以前一样,屏幕依旧输 出 success。如图 5 ![]()
第三种方法(不需要驱动) NtSystemDebugControl 这个方法是比较好也是比较简洁的一个方法。但是缺点也是致命的,无法在 WIN7 下使 用,为什么呢,WIN7 下把 NtSystemDebugControl 的很多功能给和谐了。 我先把代码贴出来然后说一下原理吧。 #include <windows.h> #include <stdio.h> #pragma comment(lib, "advapi32") #define NTAPI stdcall #define FCHK(a) if (!(a)) {printf(#a " failed\n"); return 0;} // |