WEB开发网
开发学院软件开发汇编语言 汇编仿FDISK及PQMAGIC列出分区逻辑盘符的prw.asm实... 阅读

汇编仿FDISK及PQMAGIC列出分区逻辑盘符的prw.asm实现

 2007-11-13 09:31:21 来源:WEB开发网   
核心提示: (8) 论V86下,直寻硬盘扇区,只能靠VxDVToolsD建的C级VxD,有读/写DOS分区的R0_ReadAbsoluteDisk/R0_Write...函数.例如,响应自32位C的W32_DEVICEIOCONTROL事件时,用格式R0_Read...(2,1,0,buf,&w),读相对DOS分区的逻辑扇号是1

 
  (8) 论V86下,直寻硬盘扇区,只能靠VxD
 
 VToolsD建的C级VxD,有读/写DOS分区的R0_ReadAbsoluteDisk/R0_Write...函数.
 
 例如,响应自32位C的W32_DEVICEIOCONTROL事件时,用格式R0_Read...(2,1,0,buf,&w),读相对DOS分区的逻辑扇号是1的分区引导扇区PBS.这时,当前虚拟机hVM,是系统(证于Test_Sys_VM_Handle测事件实参IOCTLPARAMS.dioc_hvm).VxD不改hVM身份.
 
 又如,响应自16位ASM程序的V86_API_Entry入口调用时,同上,读PBS,这时,hVM是DOS(证于Test_...测入口实参VMHANDLE).
 
 均读PBS含"MSWIN4...".
 
 但VxD,也能在V86下,用Exec_Int(0x13),法如13h,直寻硬盘,如PBS之前MBR.
 
 笔者c.cpp+a.exe,直读MBR连续5扇.需cfg.sys,隐dev=EMM386
 
 (8.1) 用QuickVxD,建C++级VxD,设备名=C,设备ID=0x3180,选动态装
 
 选API页Standard App Entry Points框Real/V86 Mode.体,见(8.3).
 
 选OnSysDynamicDevice的Init及Exit.体中:
 
 选发SHELL_SYSMODAL_Message(Get_Cur_VM_Handle(),MB_SYSTEMMODAL,"m","cap")
 必发return(true)
 
 (8.2) 写a.asm,汇编时,/DNPAGE=5,指明5扇.读变写,需debug下,改r2w3处的2为3.
 
 VxD查客户这5扇缓区,囿V86空间1页(4K字节)的整体性,未全囿,bp返回<4k的修正量.
 
 IF2
     IF NPAGE LT 1 or NPAGE GT 8
          %OUT 0         .ERR
     ENDIF
 ENDIF
 
 d  segment
 buf   db  NPAGE*512*2-1 dup(9);留足修区
 entry  dd  0
 d  ends
 
 c  segment
     assume  cs:c,ds:d
 
 @:  mov   bp,d
     mov   ds,bp
 
     mov   ax,1684h  功能号
     mov   bx,3180h  接口ID
     int   2fh
 
     mov   ax,es  es/di=API_Entry入口段/偏移
     or   ax,di
     jz   @3     ;es及di全为零,失败
 
     mov   word ptr [entry],di
     mov   word ptr [entry+2],es
 
     mov   ax,ds  设exec_int参数
     mov   es,ax
 
     lea   bx,buf  es:bx,指向缓区首
 
 r2w3:  mov   ah,2    读80h硬盘MBR处NPAGE扇
     mov   al,NPAGE
     mov   cx,1    0:0:1(chs)
     mov   dx,128
 
     std        VxD出兰屏,写修
     call  [entry]
 
     cmp  bp,4096    VxD按(8.3)返bp值
     jae   @2
 
     add   bx,bp    修缓区首址
 
    test  ah,1    查读/写
   jz @1      此例ah=2,读盘
         
     lea   si,buf    写入时,从后向前,移NPAGE*256字
   add  si,NPAGE*512-1  si指向原缓区尾
 
     mov di, si
     add   di,bp    di指向新缓区尾
 
     mov cx, NPAGE*256
     rep movsw      ds:si所指cx字,移到es:di
 
     mov cx,1
 
 @1:  call  [entry]
   cmp   bp,4096
 
 @2:  je  @3
 
   cmp  bp,1010h
   jne  @3
 
     xor   ah,ah      ;释它页
   call  [entry]
 
 @3:   xor   ax,ax
     mov   es,ax
 
     mov   ax,[bx+1beh]  成功/失败,72h矢量=分区表首字/9
     mov   es:[1c8h],ax
 
     mov   ah,4ch
     int   21h
 
 c  ends
     end   @
 
 (8.3) ...V86_API_Entry(VMHANDLE hVM, CLIENT_STRUCT* pRegs)体
 
 DWORD h,t;
 CLIENT_STRUCT s;
 
     if(pRegs->CBRS.Client_AH){//2读3写
     h=(DWORD)Map_Flat(CLIENT_ES,CLIENT_BX);//h=客户缓区首es:bx的32位线性址
     t=h+pRegs->CBRS.Client_AL*512-1;//t=尾的线性址
 
     if((h>>12)!=(t>>12)){
       pRegs->CWRS.Client_BP=(4096-(h&4095));//首尾未囿同页,bp返客户增bx量
       return;
     }
 
     if((h>>12)<0x110)//缓区能被V86寻,bp返4096
       pRegs->CWRS.Client_BP=4096;
     else      
       if(LinMapIntoV86(h>>12,hVM,0x10,1,0,&t)){
         //缓区所在页,成功映入V86第0x10页,bp返0x1010
         pRegs->CWRS.Client_BP=0x1010;
         h=(16<<12)+(h&4095);//由t及偏移,得缓区V86址h
       }else{//无页等,bp返0x1110
         pRegs->CWRS.Client_BP=0x1110;
         return;
       }
       
     Save_Client_State(&s);//存reg
     Begin_Nest_V86_Exec();//当前虚拟机,能寻V86
 
     pRegs->CRS.Client_ES=(h>>4);//es=址h的段值
     pRegs->CRS.Client_EBX=(h&15);//bx=址h的偏移
 
     Exec_Int(0x13);
 
     End_Nest_Exec();//复原
     Restore_Client_State(&s);
 
     if(pRegs->CWRS.Client_Flags&1024){//方向,控兰屏
         sprintf((char*)s.CBRS.Client_res30,"%x",pRegs->CWRS.Client_BP);
     SHELL_SYSMODAL_Message(hVM,MB_SYSTEMMODAL,(char*)s.CBRS.Client_res30,"bp");
     }
 
   }else//知bp返0x1010时,客户释它页
     MapIntoV86(GetNulPageHandle(),hVM,16,1,0,0);
 
 (8.4) 装VxD法
 
 静态:
 放C.VXD于c:\windows\system,在c:\windows\system.ini的386Enh,写device=C.VxD,再reboot
 
 动态4法:
 用VxD_Loader,选C.VXD
 用DriverMonitor,先打开C.VXD,再Start
 放C.VXD于c:\windows\system\iosubsys,再reboot
 
 用笔者DOS窗口a的exe
 
 #include
 
 #define  pre  "\\\\.\\"
 
 main(int ac,char *av[]){
 char *vxd;
 HANDLE h;
 
   if (ac==1) printf("vxd_load ?.vxd\n");
   else{
     vxd=malloc(strlen(pre)+strlen(av[1]));
     sprintf(vxd,"%s%s",pre,av[1]);
 
     h=CreateFile(vxd,0,0,0,0,FILE_FLAG_DELETE_ON_CLOSE,0);
 
     if(h!=INVALID_HANDLE_VALUE){
       printf("To unload,hit Enter");
       getch();
       CloseHandle(h);
     }
   }
 }
 
 装C.VXD,事毕,敲回车到窗a,卸此VXD

上一页  1 2 3 4 

Tags:汇编 FDISK PQMAGIC

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接