工具软件   办公软件   操作系统   网络安全   设计在线   程序开发   教程宝典   软件下载   软件论坛
您的位置:软件 > 开发者网络 > 开发工具 > 开发专栏 > VC > 正文
用Visual C++实现CPU特权指令操作
[文章信息]
作者:黄东
时间:2005-02-25
出处:天极网
责任编辑:方舟
[文章导读]
80x86系列CPU具有四级保护机制。在Windows 9X操作系统只使用0级和3级,以便于移植到精简指令集的计算机上
advertisement
热点推荐
· 设计欣赏:《夜精灵》之羡慕花朵
· 调整Word表格的列宽和行高
· 2月24日软件精选 突破防火墙的技术
· 对付网页恶意代码
· 入侵检测实战之全面问答(下)
[正文]
  一、引言

  80x86系列CPU具有四级保护机制。在Windows 9X操作系统只使用0级和3级,以便于移植到精简指令集的计算机上,如RS4000等,这些处理器一般只有两个特权级,即系统级和用户级。在Windows 9X系统环境,应用程序运行在Ring3(3级),如果要运行特权指令就必须进入Ring0(0级)。在同一任务内,实现特权级从外层到内层变换的普通途径是使用段间调用指令CALL,通过调用门进行转移;实现特权级从内层向外层变换的普通途径是使用段间返回指令RET。注意,不能用JMP指令实现任务内不同特权级的变换。调用门描述符转移的入口点包含目标地址的段及偏移量的48位全指针。在执行通过任务门的段间转移指令JMP或段间调用指令CALL时,指令所含指针内的选择子用于确定调用门,而偏移被丢弃;把调用门内的48位全指针作为目标地址指针进行转移。

  二、基本思路

  取得全局描述符表,搜索该表找到一个暂时为空的描述符,安装调用门,进行远程调用即可实现特权指令操作。

  三、所用到的数据结构

  ①全局描述符GDT的格式:


  在VC中定义全局描述符如下:

struct GDT_DESCRIPTOR{
 WORD LimitL;//段界限低16位
 WORD BaseL;//基地址低16位
 BYTE BaseM;//基地址中间8位
 BYTE AttriB;//段属性
 BYTE LimitH;//段界限的高4位(包括段属性的高4位)
 BYTE BaseH;//基地址的高8位
}

  ②门描述符的一般格式:


  当TYPE的低4位值为0xC时,这是一个386调用门(CallGate)。在VC中定义"门"如下:struct GATE{ //门结构类型定义

WORD OffsetL; // 32位偏移的低16位
WORD Selector; //选择子
BYTE Dcount; //双字计数字段
BYTE Gtype; //当低4位值为0xC是,这是一个调用门
WORD LimitH; //32位偏移的高16位
}

  ③全局描述符表寄存器GDTR

  GDTR长48位,其中高32位为基地址,低16位为界限,GDTR中的段界限以字节为单位。在VC中定义如下:

struct GDTR{
 WORD wGDTLimit;
 DWORD dwGDTBase;
};

  四、具体实现

  使用MFC AppWizard新建一个基于对话框的应用程序,工程名为MyRing0。在对话框中添加一个按钮,修改ID为ID_GETCR0,修改Caption为取CR0的值,同时添加该按钮的消息处理函数void CMyRing0Dlg::OnGetcr0()。新建一个头文件Ring0.h并添加到工程中,添加下面的代码到Ring0.h中。

#pragma pack(1)
struct GDT_DESCRIPTOR{
 WORD LimitL; //段界限低16位
 WORD BaseL; //基地址低16位
 BYTE BaseM; //基地址中间8位
 BYTE AttriB; //段属性
 BYTE LimitH; //段界限的高4位(包括段属性的高4位)
 BYTE BaseH; //基地址的高8位
};
struct GATE_DESCRIPTOR{
 WORD OffsetL; // 32位偏移的低16位
 WORD Selector; //选择子
 BYTE Dcount; //双字计数字段
 BYTE Gtype; //当低4位值为0xC是,这是一个调用门
 WORD LimitH; //32位偏移的高16位
};

struct GDTR{
 WORD wGDTLimit;
 DWORD dwGDTBase;
};
#pragma pack()

  在MyRing0Dlg.cpp中最后一个include语句后添加#include "Ring0.h",在按钮的消息处理函数void CMyRing0Dlg::OnGetcr0()前面添加下面两个函数:

__declspec(naked) void GetCR0_Ring0()
{
 _asm{
 mov ebx,cr0 //特权指令
 mov [EAX],ebx
 retf
}
}

bool CallRing0(PVOID pvRing0FuncAddr,PWORD pVal)
{
 struct GDT_DESCRIPTOR *pGDTDescriptor;
 struct GDTR gdtr;
 WORD CallgateAddr[3];
 WORD wGDTIndex = 1;
 //取得全局描述符表GDT
 _asm Sgdt [gdtr]

 // 空选择子有特殊用途,跳过它,从第二个选择子开始搜索
 pGDTDescriptor = (struct GDT_DESCRIPTOR *)(gdtr.dwGDTBase + 8);
 for (wGDTIndex = 1; wGDTIndex < (gdtr.wGDTLimit / 8); wGDTIndex++)
 {
  if (pGDTDescriptor->AttriB == 0)
  {
   struct GATE_DESCRIPTOR *pGate;

   pGate = (struct GATE_DESCRIPTOR *) pGDTDescriptor;
   pGate->OffsetL = LOWORD(pvRing0FuncAddr);
   //选择子0x28总是指向Ring0的代码段
   pGate->Selector = 0x28;
   pGate->Dcount = 0;
   pGate->Gtype = 0xEC;
   pGate->OffsetH = HIWORD(pvRing0FuncAddr);
   //准备远程调用参数
   CallgateAddr[0] = 0x0;
   CallgateAddr[1] = 0x0;
   CallgateAddr[2] = (wGDTIndex << 3) | 3;
   //进入Ring0
   _asm Mov EAX,[pVal]
   _asm call FWORD PTR [CallgateAddr]
   //归还刚才使用的全局描述符
   memset(pGDTDescriptor, 0, 8);
   return true;
  }
  //下一个全局描述符
  pGDTDescriptor++;
 }
 //没有空闲的全局描述符
 return false;
}

  为按钮的消息处理函数void CMyRing0Dlg::OnGetcr0()添加代码如下:

void CMyRing0Dlg::OnGetcr0()
{
 // TODO: Add your control notification handler code here
 WORD Val=0;
 char str[16];
 if(!CallRing0((PVOID)GetCR0_Ring0,&Val)){
  AfxMessageBox("系统资源不够!");
  return;
 };
 sprintf(str,"CR0=%3d",Val);
 AfxMessageBox(str);
}

  程序在VC6下编译通过,操作系统为Windows98。

发表评论推荐给朋友我想参加相关培训打印我对此感兴趣订阅电子杂志
相关内容焦点新闻
  • VC下用串口与电台通信需注意的问题
  • 剖析MFC六大关键技术之初始化过程
  • VC调用ACM音频编程接口压缩Wave音频
  • VC利用控件传递自定义struct解决方案
  • MFC程序员的WTL指南之包容ActiveX
  • 中国版3G预商用测试开锣 成品样机正式亮相
  • 丁磊揣23亿现金 谁将成为网易的“盘中餐”?
  • EVD苦熬半年终成国标 伪高清将面临双倍索赔
  • 陈天桥京城密会段永基 盛大收购新浪柳暗花明
  • 搜房网买下网易房产频道 双方下周二正式签约
  • AMD注1亿美元中国造芯片 3月2日正式投产
  • 陈天桥接受专访 盛大人员表示迟早要吃下新浪
  • 新浪股东中无日资背景 高层没有股票抛售行为
  • Advertisement

    天极无线


    奇妙科幻|美好风光|清风车影|漫画卡通|星座生肖|明星写真|动物世界
    老鼠爱大米
    挥着翅膀的女孩
    女人味
    栀子花开
    白月光
    刚刚好
    江南
    快乐崇拜
    亲爱的你怎么不在我身边
    小薇
    2002年的第一场雪
    有多少爱可以重来
    我的地盘
    七里香
    情人
     
    老鼠爱大米 老板电话
    冲动的惩罚 七里香
    我不是黄蓉 女生撒娇
    盛夏的果实 坚持到底
    孤单北半球 眉飞色舞
    挪威的森林 可爱女人
    最浪漫的事 老板电话

    CSEEK搜索