庞大资源库的计算机教程网站!
设为首页
加入收藏
总编信箱
投稿或申请专栏请先 [登 陆]
首页 操作系统 程序设计 图形图像 媒体动画 机械电子 WEB开发 数 据 库 办公系列 路由技术 网络原理 网络应用
认证考试 安全技术
首页>程序设计>汇编语言>技巧教程>正文
资料搜索
Google搜索
Google
返回上级列表

推荐文章

快速保存网页中所有图片的方法
Windows中让光驱巧妙“隐身”技
防范非法用户入侵Win 2000/XP系
两款比较典型的ASP木马防范方法
有关表格边框的css语法整理
Windows XP中可以被禁用的服务
SQL Server导出导入数据方法
Javascript所有对象的属性的获
网页(HTML)中的特殊字符
与篮球共舞,尽显模式本色
QQ病毒的手工清除方法
Photoshop为极品美女打造性感睫
天衣无缝:IIS与PHP水火也相容
SQL Server存储过程编写和优化

仿FDISK及PQMAGIC列出分区逻辑盘符的prw.asm实现(2)

 作者:本站收集   日期:2005-8-1 15:50:27
字号选择〖 〗/ 双击滚屏 单击停止   
  
          mul s1track
          mov     s1cyl,ax    ;每柱面扇数
  
          mov ax,cx
          mov cl,6
          shr al,cl
          xchg al,ah
          inc ax
  
          mov     media_c,ax  ;柱面数
  
  h_geo2:    ret
  h_geo endp
  
  chain     proc                ;处理链
  chain0: mov ax,201h
          Call rw1sec
  
          mov al,buf[1beh+4]
          call pri_non
  
          test buf[1beh+16+4],255         ;0,5,0fh之1
          je chain1
  
          mov ax,word ptr buf[1beh+16+8]
          Add ax,entrydi                 ;加基址entrydi
          mov lbal,ax
  
          mov ax,word ptr buf[1beh+16+10]
          adc ax,entryes                 ;加基址entryes
          mov lbah,ax
  
          jmp chain0
  chain1: ret
  chain   endp
  
  nondos   proc                查未占过盘符的DOS主分区及非DOS分区
  nondos0:cmp dl,mod_p
          je nondos4
  
          mov ax,201h
          mov cx,1
          int 13h
  
          mov bp,dx
          sub bp,80h        
      
       mov al,fcbsz[bp]    取已占分区表号
       mul extblk
       mov fcbdat,ax
  
          xor     bp,bp
  nondos1:cmp bp,4*16
          je nondos3
  
       cmp bp,fcbdat
          je nondos2              ;已占
  
          mov al,buf[1beh+bp+4]
  
          test al,255        不理闲置分区
          jz nondos2
  
          mov cx,extmksz          ;不理扩展分区
          lea di,extmk
          repne scasb
          jz nondos2
  
          call pri_non
  
  nondos2:Add bp,16
          jmp nondos1
        
  nondos3:inc dl
          jmp nondos0
        
  nondos4:ret
  nondos endp
  
  show    proc    ;分区信息
  
          mov al,dl            取硬盘编号
          lea di,from80
          alasc
  
          mov al,buf[1beh+bp]    ;取BootON
          lea di,Boot
      alasc
  
          mov al,buf[1beh+bp+4]  ;取volume
          lea di,volume
          alasc
  
          mov     ax,word ptr buf[1beh+bp+8]   ;取Front low
          Add ax,lbal                    ;为chain而加
          pushf
  
          lea di,Front_l
          axasc
  
          mov     ax,word ptr buf[1beh+bp+10]  ;Front high
  
          popf
          adc ax,lbah                    ;为chain而加
          lea di,Front_h
          axasc
  
          mov     ax,word ptr buf[1beh+bp+12]  ;取In low
          lea di,In_l
          axasc
  
          push dx
  
          mov     dx,word ptr buf[1beh+bp+14]  ;In high
          mov        ax,dx
          lea di,In_h
          axasc
  
          mov     ax,word ptr buf[1beh+bp+12]
  
      rept    11    In扇转为M
      shr    dx,1
      rcr    ax,1
      endm
  
          lea di,MB[4]
          axasc
  
          mov     ax,dx
          lea di,MB
          axasc
  
          mov ah,9
          lea dx,.from80
          int 21h
  
          pop dx
          ret
  Show endp
  
  rw1sec proc            读/写1扇
          test dl,80h
          jz rw1sec1
  
          test    drv_p,1
          jz rw1sec1
  
       xor     al,al        不校验写
          or     ah,40h
          lea     si,extblk   ;扩展块
          jmp rw1sec2
  
  rw1sec1:push ax
          push dx
          call lba2chs
          pop dx
          pop ax
  
          call cxdh
  
  rw1sec2:cmp cmd_p,'v'
          je rw1sec3
  
      int    13h          
      ret            遗c
  
  rw1sec3:Call [entry]
  
          cmp    bp,4096    VxD按(8.3)返bp值
          jae     rw1sec4
  
          push bx
  
          add     bx,bp       ;使bx,bx+511在4k内
      mov    buf_off,bx    扩展i13
  
          push cx
      push si
  
          lea     si,buf511    ;原buf尾
  
          mov di,si
          add     di,bp       ;新buf尾
  
          std                 ;从后向前移1扇
          mov cx,256
          rep movsw
          cld
  
      pop si
          pop cx
  
          Call [entry]
  
          pop bx
      mov    buf_off,bx    扩展i13
  
      cmp     bp,4096
  rw1sec4:je    rw1sec5
  
      cmp    bp,1010h
      jne    rw1sec6
  
      xor ah,ah
          Call [entry]        释它页
  
  rw1sec5:clc
      ret
  
  rw1sec6:stc
      ret
  
  rw1sec endp
  
  f_geo proc
          lea     bx,buf      ;缓区
          mov     cx,1        ;引导扇,在0:0:1(chs)
  
  f_geo0:      mov     ax,201h     ;读1扇
          int     13h         ;读11起的bios参数块
          jc        f_geo0     ;换盘
  
      mov     al,[bx+26]  ;偏移26:头数
          mov media_h,al
  
          mov     ah,[bx+24]  ;偏移24:每道扇数
          mov s1track,ah
  
          mul ah
          mov     s1cyl,ax    ;每柱面扇数
          
          mov     ax,[bx+19]  ;偏移19:总扇数
          xor     dx,dx       ;高字
  
          div s1cyl
  
          mov     media_c,ax  ;柱面数
      ret
  f_geo endp
  
  rng proc
          mov     ax,cyl      ;当前柱面
          lea di,cyl_p1
          axasc
  
          mov     al,hd       ;当前头
          lea di,hd_p1
          alasc
  
          mov     al,sec      ;当前扇号
          lea di,sec_p1
          alasc
  
          mov     ax,lbah     ;当前lba高字
          lea di,lbah_p1
          axasc
  
          mov     ax,lbal     ;当前lba低字
          lea di,lbal_p1
          axasc
  
          mov ah,9
          lea dx,cyl_p
          int     21h
  
          lea dx,hd_p
          int     21h
  
          lea dx,sec_p
          int     21h
  
          lea dx,lba_p
          int     21h
  
          ret
  rng endp
  
  scr proc
          xor     si,si
  
  scr1:   mov     ax,2    ;清屏
      int     10h
  
          mov     ax,In_h   ;当前扇号
          lea di,MB[4]
          mov dx,di
          axasc
  
          mov ah,9
          int 21h
  
          cmp     scr_p,'q'
          jne     scr2
          ret
  
  scr2:   mov ax,si
          lea di,stk1
          axasc
  
          lea bp,rowasc
  
  scr3:  mov al,[bx+si]
          mov di,bp
          alasc
  
          Add bp,2 + 2 - 1
  
          inc si
          test si,15
          jne scr3
  
          mov ah,9
          lea dx,stk1
          int     21h
  
          test si,255
          je scr4
          jmp scr2
  
  scr4:   mov ah,9
          lea dx,scr_p
          int     21h
  
          mov     ah,1        ;按1键
          int     21h
  
          cmp al,'q'
          je scr5
  
          test si,511
          je scr6
          jmp scr1
  
  scr5:   mov scr_p,al
  scr6:    ret
  scr     endp
  
  cxdh proc
          mov     dh,hd       ;头号
  
          mov     cx,cyl      ;柱面号
          xchg ch,cl
  
      rept 6
          shl cl,1
      endm
  
          or      cl,sec      ;低6位扇号
  
          ret
  cxdh endp
  
  lba2chs proc
          mov ax,lbal
          mov dx,lbah
  
          div     s1cyl       ;柱面号
          mov cyl,ax
  
          mov ax,dx
          div s1track
  
          mov     hd,al       ;头号
          inc ah
          mov     sec,ah      ;扇号
  
          ret
  lba2chs endp
  
  chs2lba proc
          mov     ax,cyl      ;柱面号
          mul s1cyl
  
          mov lbal,ax
          mov lbah,dx
  
          mov     al,s1track  ;每道扇数
          mul hd
  
          Add lbal,ax
          adc lbah,0
  
          mov     al,sec      ;此处,低6位扇号
          dec al
       cbw
  
          Add lbal,ax
          adc lbah,0
  
          ret
  chs2lba endp
  
  INnib   proc        ;kbd限长nib入kbd2.转后入stk1,低字还入bx
  INnib1: mov ah,9
          int 21h
  
          push dx
  
          inc ah      ;回车才收
          lea dx,kbd
          int 21h
  
          pop dx
  
          mov al,kbd
          dec al
  
          cmp al,kbd1 ;实长
          jnz INnib1
  
          xor bp,bp
  
          lea si,kbd2
  INnib2:lodsb
  
          mov cx,16
          lea di,hextbl
          repne scasb
  
          jnz INnib1
  
          dec kbd1
  
          inc cx          ;转'[0-9a-f]'为0~15
          sub cx,16
          neg cx
  
          rept 4
          shl bx,1        ;bx接收nibble
          endm
  
          and bl,240
          or bl,cl
  
          test kbd1,3     ;已收4个nibble
          jnz INnib2
  
          mov stk1[bp],bx
          add bp,TYPE stk1
  
          test kbd1,255
          jnz INnib2
  
          ret
  INnib endp
  
  c ends
          end     @
  
  (8) 论9x的V86下,直寻硬盘扇区,只能靠VxD
  
  VToolsD建的C级VxD,有读/写DOS分区的R0_ReadAbsoluteDisk/R0_Write...函数.
  
  例如,响应自32位C的W32_DEVICEIOCONTROL事件时,用格式R0_Read...(2,1,0,buf,&w),读相对DOS分区的逻辑扇号是0的分区引导扇区PBS,对80H硬盘,PBS位于第0柱,第1头,第1扇,即0:1:1(chs).这时,当前虚拟机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(硬盘主引导记录,0:0:1(chs)).
  
  笔者c.cpp,a.exe搭档,直读MBR连续5扇,启动config.sys,需rem dev=EMM386
  
  (8.1) 用QuickVxD,建C++级VxD,设备名=C,设备ID=0x3180,选动态安装
  选API页Standard App Entry Points框Real/V86 Mode,(8.3)是体
  选OnSysDynamicDeviceInit,OnSysDynamicDeviceExit,体返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) 如下装C.VxD,用Viewer验装,在DOS窗口A,运行a.exe,出兰屏后,在A,用debug,得0:1c8分区表首字,前2种装,重boot,启新VxD.
  
  静态装,置VxD于c:\windows\system,在c:\windows\system.ini中,对节[386Enh]加一行"device=C.VxD"
  
  4种动态装:
  
  置VxD于c:\windows\system\iosubsys
  用Loader
  用DriverMonitor,先Open,再Start
  在DOS窗口V,用笔者
  
  #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);
          }
      }
  }
  
  的vxd_load.exe,装参C.VxD,做完a.exe,在V,敲回车,卸VxD

上一篇:驻留exe文件    下一篇:仿FDISK及PQMAGIC列出分区逻辑盘符的prw.asm实现(1)  
[发送给好友]  [关闭窗口]  [返回顶部]   转载请注明来源:www.it00.com   
特别声明: 本站除部分特别声明禁止转载的专稿外的其他文章可以自由转载,但请务必注明出处和原始作者。文章版权归文章原始作者所有。对于被本站转载文章的个人和网站,我们表示深深的谢意。如果本站转载的文章有版权问题请联系编辑人员,我们尽快予以更正。
责任编辑: 原点 投稿作者: 本站收集
信息来源: 网络 录入时间: 2005-8-1 15:50:27
关于我们 - 广告服务 - 版权申明 - 网站地图 - 联系方式 - 总编信箱 - 会员投稿