加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

用c语言如何进入ring0??

(2007-02-25 16:00:18)
分类: 操作系统
我用c语言写一个程序,需要直接操纵硬件,如何进入ring0??  
 
 
2K/XP下:  
http://www.xfocus.net/articles/200306/562.html  
9x下:  
令Win32应用程序跳入系统零层  
   
东南大学卢威(luwei@126.com)    
   周昊理(moses@263.net)  
   
---  众  所  周  知,  在Windows95/98  的Win32  on  Intel  x86  体  系  中  利  用  了  处  理  器  的  三  环  保  护  模  型  中  的  零  环(Ring0,  最  高  权  限  级  别)  和  三  环(Ring3,  最  低  权  限  级  别)。  一  般  应  用  程  序  都  运  行  在Ring3  下,  受  到  严  格  的"  保  护",  只  能  规  矩  地  使  用Win32API。  如  果  我  们  想  进  行  一  些  系  统  级  的  操  作,  例  如  在  嵌  入  汇  编  中  使  用  诸  如"Mov  EAX,CR0",  或  像  在DOS  下  那  样  调  用  一  些  必  不  可  少  的  系  统  服  务(  如BIOS,DPMI  服  务)  而  用"Int  xx",  都  会  导  致"  非  法  操  作"。  但  这  种  能  力  有  时  是  必  不  可  少  的,  一  到  这  种  时  候Microsoft  就  "  建  议  编  写  一  个VxD"。VxD  大  家  早  有  所  闻  了,  在VxD  里,  不  但  可  以  执  行CPU  的  所  有  指  令,  而  且  可  以  调  用VMM(  虚  拟  机  管  理  器)  和  其  他VxD  提  供  的  上  千  个  系  统  级  服  务。  获  得  这  一  能  力  的  最  本  质  原  因  在  于  它  运  行  在Ring0,  与  系  统  内  核  同  一  级  别。  但  是  它  体  系  的  复  杂  性、  开  发  工  具  的  不  易  获  得、  帮  助  文  档  的  不  完  备,  使Microsoft  排  除  了  一  大  批  程  序  员  和  竞  争  对  手。  而  将  在Windows2000(Windows98  也  开  始  支  持)  中  取  代VxD  的WDM  对Win95  程  序  员  也  是  个  噩  梦,  它  需  要  了  解Windows  NT  核  心  驱  动  模  型。    
 
----有  没  有  简  单  一  些  的  办  法  呢  ?  我  们  可  以  令  一  个  普  通Win32  应  用  程  序  运  行  在Ring0  下,  从  而  获  得VxD  的  能  力  吗  ?  答  案  是  肯  定  的。  下  面  我  们  就  简  述  一  下  这  一  技  巧,  有  关Intel  x86  保  护  模  式  的  基  础  知  识  请  大  家  看  有  关  书  籍。    
 
----首  先  此  技  巧  基  于  以  下  理  论  根  据:    
 
----一、SIDT  指  令(  将  中  断  描  述  符  表  寄  存  器  IDTR  -  -64  位  宽,16  ~47Bit  存  有  中  断  描  述  符  表IDT  基  地  址  -  -  的  内  容  存  入  指  定  地  址  单  元)  不  是  特  权  指  令,  就  是  说  我  们  可  以  在Ring3  下  执  行  该  指  令,  获  得IDT  的  基  地  址,  从  而  修  改IDT,  增  加  一  个  中  断  门  安  置  我  们  的  中  断  服  务,  一  旦Ring3  程  序  中  产  生  此  中  断,VMM  就  会  调  用  此  中  断  服  务  程  序,  而  此  中  断  服  务  程  序  就  运  行  在Ring0  下  了。  这  一  点  与  在DOS  下  非  常  相  似。    
 
----二、Windows95  Win32  应  用  程  序  运  行  一  个  映  射  到  全  部4G  内  存  的  段  中,  选  择  子  为0137h,Ring0  中  的VxD  运  行  在  另  一  个  映  射  到  全  部4G  内  存  的  段  中,  选  择  子028h,  这  两  个  段  除  了  选  择  子  决  定  的  访  问  权  限  不  同  外,  没  什  么  不  同,  各  自  段  中  相  同  的  偏  移  量  对  应  了  相  同  的  线  性  地  址。  所  以  我  们  放  在Win32  应  用  程  序  中  的  中  断  服  务  程  序  可  以  以Ring3  的  段  偏  移  量  被Ring0  中  的VMM  寻  址。    
 
----下  面  我  们  以  具  体  例  子  进  一  步  说  明,  程  序  中  有  详  细  注  释。    
 
----这  是  一  个Win32  Console  Program(  控  制  台  应  用  程  序),  虽  然  运  行  中  看  起  来  很  像DOS  筐  中  运  行  的  实  模  式DOS  程  序,  但  它  是  货  真  价  实  的  运  行  在Ring3  下  的Win32  程  序。  用Visual  C  +  +  5.0  AppWizard  创  建  一  个Win32  Console  Program  项  目,  添  加  以  下.CPP  文  件,  编  译  即  可。    
 
 #include  
 #include  
 #include  
 #include    
   //  若  无DDK  带  下  划  线  的  可  略  去,  
   这  些  语  句  演  示  了  调  用VMM/VXD  服  务  
DWORDLONG  IDTR,SavedGate;  
WORD  OurGate[4]={0,0x0028,0xee00,0x0000};  
//  中  断  门  描  述  符  格  式  如  下:  
 
 
 
 
DWORD  _eax,_ecx,_cr0;  
WORD  vmmver;  
HVM  sysvm;  
 
void  nothing()  
{  
           //Used  to  test  call  in  Ring0  
           sysvm=Get_Sys_VM_Handle();  
}  
 
void  __declspec(  naked  )  Ring0Proc(void)  
   //  中  断  例  程,  运  行  在Ring0  
{  
           _asm{  
                       mov      _eax,eax        //  
                       mov      _ecx,ecx        //  
                       mov      eax,  CR0          
     //  测  试Ring3  中  不  能  执  行  的  特  权  指  令  
                       mov      _cr0,eax        //  
           }  
                       VMMCall(Get_VMM_Version);    
   //  调  用VMM  服  务  
           _asm{  
                       mov  vmmver,ax  
           }  
           nothing();      
   //  测  试  在  运  行  于Ring0  的    
       中  断  例  程  中  调  用  子  
         _asm    iretd        
   //  中  断  返  回,  与  在  实  模  式    
       编  程  无  本  质  区  别  
}  
void  main()  //  主  程  序  
{  
           _asm{  
           mov      eax,  offset  Ring0Proc  
           mov      [OurGate],  ax    //  将  中  断  函  数  的  地  址  
           shr      eax,  16      //  填  入  新  造  的  中  断  门  
           mov      [OurGate  +6],  ax  //  描  述  符  
 
           sidt    fword  ptr  IDTR          
   //  将  中  断  描  述  符  表  寄  存  器(IDTR)  
         的  内  容  取  出  
           mov      ebx,  dword  ptr  [IDTR  +2]  
   //  取  出  中  断  描  述  符  表(IDT)  基  地  址  
           add      ebx,  8  *9      
     //  计  算Int  9  的  描  述  符  应  放  置  的  地  址  选  用  
       Int9  是  因  为  它  在Win32  保  护  模  式  下  未  占  用  
 
           mov            edi,  offset  SavedGate  
           mov            esi,  ebx  
           movsd      //  保  存  原  来  的Int  9  描  述  符  到  
           movsd    //SavedGate  以  便  恢  复  
 
           mov            edi,  ebx  
           mov            esi,  offset  OurGate  
           movsd    //  替  换  原  来  的  中  断  门  描  述  符  
           movsd    //  以  安  装  中  断  服  务  例  程  
 
           mov      eax,0x6200    
     //  用  以  测  试  放  在EAX  中  的  数  据  
         能  否  正  确  传  到Ring0  中  断  
           mov      ecx,0    
     //  用  以  测  试  放  在ECX  中  的  数  据    
         能  否  正  确  传  到Ring0  中  断  
           mov      ecx,0    
     //  用  以  测  试  放  在ECX  中  的  数  据    
         能  否  正  确  传  到Ring0  中  断  
                             //  因  为  很  多VxD  服  务  都  用  
                                 此  二  寄  存  器  传  递  参  数  
           int    9h      
         //  人  为  触  发  中  断,  平  时  会  出  现  
             保  护  错  误  蓝  屏  或  非  法  操  
                         //  作  对  话  框,  现  在  安  装  了  
                         //  中  断  服  务  例  程  后,  就  会  通  过  
                         //VMM  在Ring0  调  用  中  断  服  务  例  程  
                               -  -Ring0Proc  
 
           mov        edi,  ebx  
           mov        esi,  offset  SavedGate  
           movsd  //  恢  复  原  来  的  中  断  门  描  述  符  
           movsd  
           }  
           cout<<"CR0="<<_cr0<  
   
运  行  结  果:    
 
 
----此  方  法  的  好  处  一  是  回  避  了  奇  特  的VxD  文  件  格  式,  不  用  使  用  汇  编  语  言  编  程,  二  是  应  用  程  序  不  用  带  一  个  单  独  的VxD  文  件,  干  净  利  索。    
 
----值  得  一  提  的  是,  许  多  文  章  描  述  著  名  的  CIH  病  毒  都  说  其  利  用  了VxD  技  术,  是  说  它  带  一  个  单  独  的VxD  文  件  吗  ?  显  然  不  可  能,  实  际  上CIH  病  毒  使  用  的  就  是  以  上  技  巧,  进  入Ring0  后  调  用VMM  服  务  分  配  一  块  内  存,  把  自  身  拷  贝  进  去,  然  后  用IFS  VxD  的  IFSMgr_InstallFileSystemApiHook  服  务  安  装  文  件  系  统  监  视  以  感  染  其  他  文  件,  只  不  过CIH  病  毒  安  装  的  是Int  3  中  断,  这  跟  在DOS  下  没  什  么  两  样。  我  们  也  可  以  对  此  了  解  以  更  好  地  防  范CIH  病  毒。    
 
----最  后  还  要  指  出  其  缺  陷,  这  个  技  巧  仅  能  用  在Windows95/97/98  下,  在Windows  NT  下  行  不  通。  不  过  听  说CIH  病  毒  的  作  者  已  经  开  发  了NT  版  的CIH  病  毒,  说  明NT  中  也  有  类  似  的"  后  门"。    

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有