home bbs files messages ]

Forums before death by AOL, social media and spammers... "We can't have nice things"

   comp.misc      General topics about computers not cover      21,759 messages   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]

   Message 20,642 of 21,759   
   Ben Collver to All   
   The DOS 3.3 SYS.COM Bug Hunt (3/3)   
   24 Feb 25 01:03:51   
   
   [continued from previous message]   
      
   aliased memory locations. Thanks segmented x86!)   
      
   IOCTL BPB:   
       72 E4 3B C1 75 1A 8B 16 DC 09 8B 0E DE 09 2B CA 74 D4 8B 1E 19 09 B4 40 CD   
      
   Corrupted BPB:   
       00 02 3B C1 75 1A 8B 16 DC 09 8B 0E DE 09 2B CA 74 D4 8B 1E 00 00 00 00 00   
      
   Except for the first two bytes (the sector size) and the last four   
   bytes (dpHugeSectors) that lines up perfectly. So the failure to   
   check the Carry Flag wound up causing bad BPB data to be written to   
   the volume boot record.   
      
   So what are those bytes? It looks like code to me, and we can confirm   
   that by just disassembling it:   
      
       -d ds:3c0   
       1923:03C0 1E 09 09 B4 40 CD 21 72-E4 3B C1 75 1A 8B 16 DC ....@.!r.;.u....   
       1923:03D0 09 8B 0E DE 09 2B CA 74-D4 8B 1E 19 09 B4 40 CD .....+.t......@.   
       1923:03E0 21 72 CA 3B C1 74 C6 F9-C3 B8 23 19 8E D8 A0 22 !r.;.t....#...."   
       1923:03F0 09 FE C8 BA 00 00 E8 90-00 72 0E 81 3E 82 0F 55 .........r..>..U   
       1923:0400 AA 75 06 BE 91 0D EB 57-90 B4 32 8A 16 22 09 CD .u.....W..2.."..   
       1923:0410 21 8A 47 16 0E 1F 2C F8-98 8B D8 D1 E3 8B B7 E7 !.G...,.........   
       1923:0420 0B 0B F6 75 18 8A 1E 22-09 BA C0 03 B4 44 B0 0D ...u...".....D..   
       1923:0430 B5 08 B1 60 CD 21 CC DA-8D 77 07 46 46 83 FE FF ...`.!...w.FF...   
       -u 3c0   
       1923:03C0 1E           PUSH    DS   
       1923:03C1 0909         OR      [BX+DI],CX   
       1923:03C3 B440         MOV     AH,40   
       1923:03C5 CD21         INT     21   
       1923:03C7 72E4         JB      03E7   
       1923:03C9 3BC1         CMP     AX,CX   
       1923:03CB 751A         JNZ     03E7   
       1923:03CD 8B16DC09     MOV     DX,[09DC]   
       1923:03D1 8B0EDE09     MOV     CX,[09DE]   
       1923:03D5 2BCA         SUB     CX,DX   
       1923:03D7 74D4         JZ      03AD   
       1923:03D9 8B1E1909     MOV     BX,[0919]   
       1923:03DD B440         MOV     AH,40   
       1923:03DF CD21         INT     21   
       -   
      
   Great, where did it come from? Using the search feature of DEBUG.COM   
   we can find those bytes, and they appear right before the suspect   
   code:   
      
       C:\DOS>debug sys.com e   
       -r   
       AX=0000  BX=0000  CX=129E  DX=0000  SP=FFFE  BP=0000  SI=0000  DI=0000   
       DS=18EC  ES=18EC  SS=18EC  CS=18EC  IP=0100   NV UP EI PL NZ NA PO NC   
       18EC:0100 E90912        JMP     130C   
       -s cs:100 129e 09 09 b4 40 cd 21 72 e4   
       18EC:0940   
       -u cs:940   
       18EC:0940 1E         PUSH    DS   
       18EC:0941 0909       OR      [BX+DI],CX   
       18EC:0943 B440       MOV     AH,40   
       18EC:0945 CD21       INT     21   
       18EC:0947 72E4       JB      092D   
       18EC:0949 3BC1       CMP     AX,CX   
       18EC:094B 751A       JNZ     0967   
       18EC:094D 8B16DC09   MOV     DX,[09DC]   
       18EC:0951 8B0EDE09   MOV     CX,[09DE]   
       18EC:0955 2BCA       SUB     CX,DX   
       18EC:0957 74D4       JZ      092D   
       18EC:0959 8B1E1909   MOV     BX,[0919]   
       18EC:095D B440       MOV     AH,40   
       18EC:095F CD21       INT 21   
       -   
      
   I am a little bit freaked out by that because the pointer to the   
   buffer is set before the IOCTL call; the code knowingly sets a   
   pointer to a buffer into what looks like its code area. Let's hope   
   they knew they were done with that part of the code, or it's just   
   another interesting bug to dissect.   
      
   So SYS.COM clearly doesn't work on hard drive images mounted with   
   NetDrive, but it did work on a floppy image. What is the difference   
   and why did it work?   
      
   The answer requires us to look inside of the BPB again. The BPB has a   
   field called the "media descriptor byte" which is used to describe   
   the layout of the image. This single byte has a limited range of   
   valid values:   
      
       Value  Description   
       -----  -------------------------------------------------------------   
       F0     3.5 inch, 2 sides, 18 sectors per track, 80 tracks, 1440KB or   
              3.5 inch, 2 sides, 36 sectors per track, 80 tracks, 2880KB or   
              5.25 inch, 2 sides, 15 sectors per track, 80 tracks, 1.2MB   
       F8     Hard disk, any geometry   
       F9     3.5 inch, 2 sides, 9 sectors per track, 80 tracks, 720KB or   
              5.25 inch, 2 sides, 15 sectors per track, 80 tracks, 1220KB   
       FA     5.25 inch, 1 side, 8 sectors per track, 40 tracks, 160KB   
       FB     3.5 inch, 2 sides, 8 sectors per track, 80 tracks, 640KB   
       FC     5.25 inch, 1 side, 9 sectors per track, 40 tracks, 180KB   
       FD     5.25 inch, 2 sides, 9 sectors per track, 80 tracks, 360KB or   
              8 inch, 2 sides, single density, 500KB   
       FE     5.25 inch, 1 side, 8 sectors per track, 40 tracks, 160KB or   
              8 inch, 1 side, single density, 250KB or   
              8 inch, 2 sides, double density, 1220KB or   
       FF     5.25 inch, 2 sides, 8 sectors per track, 40 tracks, 320KB.   
      
   You can tell this wasn't well thought out. The media descriptor byte   
   is often not enough to tell you what you are working with; you need   
   to combine it with knowledge of the physical drive type too.   
      
   When I run SYS.COM against a floppy image mounted using netdrive the   
   breakpoint after the Generic IOCTL call does not even get hit:   
      
       Server ip address is: 192.168.2.101   
       Next hop address: 98:90:96:C3:14:70   
       Session (52981) started, virtual hard drive opened: floppy.dsk   
       Packet driver connected at interrupt: 0x63   
       NetDrive packet driver shim connected at: 0x65   
      
       Drive size: 368640, Media descriptor byte from FAT: FD   
      
       C:\MTCP>   
       C:\MTCP>debug sys e:   
       File not found   
       -q   
      
       C:\MTCP>cd \dos   
      
       C:\DOS>debug sys.com e:   
       -r   
       AX=0000  BX=0000  CX=129E  DX=0000  SP=FFFE  BP=0000  SI=0000  DI=0000   
       DS=18EC  ES=18EC  SS=18EC  CS=18EC  IP=0100   NV UP EI PL NZ NA PO NC   
       18EC:0100 E90912        JMP     130C   
       -g 9b6   
       System transferred   
      
       Program terminated normally   
       -   
      
   I am pretty certain that it used the media descriptor byte from the   
   BPB and did not bother making the Generic IOCTL call. I used a 360KB   
   disk image with a media descriptor byte of FD, which is very common.   
   And no IBM PC ever shipped from the factory with an 8 inch drive so   
   it is not ambiguous. So as an experiment I used a 2880KB disk image   
   which has a media descriptor byte of F0, which is also shared with   
   1440KB diskettes. Sure enough SYS.COM tried to make the Generic IOCTL   
   call on that image, failed, and corrupted that BPB.   
      
   So in short:   
      
   * DOS block device drivers do not need to implement the Generic IOCTL   
     call.   
   * DOS 3.3 SYS.COM will work correctly with a device driver that does   
     not implement Generic IOCTL if you are using a media type where   
     there is no ambiguity about what the media actually is. (Example, a   
     360KB disk image that is 2 sided, 40 tracks, and 9 sectors per track.)   
   * When in doubt about what it is working with (which is always true   
     of a hard drive) DOS 3.3 SYS.COM will try to use the Generic IOCTL   
     call to get the BPB of the device instead of just reading it   
     directly from the first sector.   
   * DOS 3.3 SYS.COM has a bug where it fails to check the return code   
     from Generic IOCTL. This causes it to write garbage to the BPB of   
     the media when it happens.   
      
   The bug was probably introduced in DOS 3.2. I'm pretty sure that it   
   is still present in DOS 4.0, as the code is still not checking the   
   Carry Flag after the Generic IOCTL call.   
      
   SYS1.ASM from DOS 4.0 code   
      
      
   Created February 23rd, 2025   
   (C)opyright Michael Brutman, mbbrutman at gmail dot com   
      
   From:   
      
      
   --- SoupGate-DOS v1.05   
    * Origin: you cannot sedate... all the things you hate (1:229/2)   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]


(c) 1994,  bbs@darkrealms.ca