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,641 of 21,759   
   Ben Collver to All   
   The DOS 3.3 SYS.COM Bug Hunt (2/3)   
   24 Feb 25 01:03:51   
   
   [continued from previous message]   
      
   I tried it again, this time with a diskette image mounted using   
   NetDrive, and it did everything perfectly. Which implies that the   
   problem is not in NetDrive, but in the difference between hard drive   
   images and floppy disk images.   
      
   So the DOS 3.3 SYS command added the boot code and updated the FAT   
   correctly, but it clobbered the BPB. But only on the NetDrive hard   
   drive image. Why?   
      
   DOS 3.2 added a function called "Generic IOCTL" which allows DOS to   
   query a device to get its geometry, write a track, read a track,   
   format a track, etc It also added code to handle these additional   
   calls for the devices supported by the BIOS. For example, here is a   
   call to "Get Device Parameters" (Generic IOCTL, sub function 0x60)   
   for drive C:   
      
       C:\DOS>debug   
       -a   
       18CE:0100 mov ax,440d   
       18CE:0103 mov bl,03   
       18CE:0105 mov cx,0860   
       18CE:0108 mov dx,0400   
       18CE:010B int 21   
       18CE:010D int 20   
       18CE:010F   
       -g=100 10d   
      
       AX=0001  BX=0003  CX=0860  DX=0400  SP=FFEE  BP=0000  SI=0000  DI=0000   
       DS=18CE  ES=18CE  SS=18CE  CS=18CE  IP=010D   NV UP EI PL NZ NA PO NC   
       18CE:010D CD20          INT     20   
       -g   
      
       Program terminated normally   
       -d 400 l 30   
       18CE:0400 89 05 01 00 41 00 00 00-02 04 01 00 02 00 02 B1 ....A...........   
       18CE:0410 FF F8 40 00 3F 00 10 00-3F 00 FA 89 45 06 8B 46 ..@.?...?...E..F   
       18CE:0420 FC 89 05 8B 46 EC 89 EC-5D 5F 5E C3 51 56 55 89 ....F...]_^.QVU.   
       -   
      
   Note that at the first breakpoint (after the IOCTL call) the Carry   
   Flag (NC) is not set. This means the call was successful and the data   
   returned is reliable.   
      
   The documentation says that the DEVICEPARAMS data structure has a BPB   
   starting at offset 0x06, which here shows:   
      
       Offset  Bytes  Description   
       ------  -----  ------------------------------------   
       0x06    00 02  Bytes per sector (512)   
       0x08    04     Sectors per cluster (8)   
       0x09    01 00  Reserved sectors (1)   
       0x0B    02     Number of File Allocation Tables (2)   
       0x0C    00 02  Root directory entries (512)   
       0x0E    B1 FF  Sectors (65457)   
       0x10    F8     Media Descriptor (hard drive)   
       0x11    40 00  Sectors per fat (4)   
      
   That makes sense for a 32MB C: drive.   
      
   Let's run that code again against the NetDrive drive image, with the   
   boot sector returned to what it was before it was corrupted:   
      
       DS=18CE  ES=18CE  SS=18CE  CS=18CE  IP=010D  NV UP EI PL NZ NA PO NC   
       18CE:010D CD20          INT     20   
       -g   
      
       Program terminated normally   
       -d 400 l 30   
       18CE:0400 89 05 01 00 41 00 00 00-02 04 01 00 02 00 02 B1 ....A...........   
       18CE:0410 FF F8 40 00 3F 00 10 00-3F 00 FA 89 45 06 8B 46 ..@.?...?...E..F   
       18CE:0420 FC 89 05 8B 46 EC 89 EC-5D 5F 5E C3 51 56 55 89 ....F...]_^.QVU.   
       -a 103   
       18CE:0103 mv bl,05   
       18CE:0105   
       -g=100 10d   
      
       AX=0001  BX=0005  CX=0860  DX=0400  SP=FFEE  BP=0000  SI=0000  DI=0000   
       DS=18CE  ES=18CE  SS=18CE  CS=18CE  IP=010D   NV UP EI PL NZ NA PO CY   
       18CE:010D CD20          INT     20   
       -g   
      
       Program terminated normally   
       -d 400 l 30   
       18CE:0400 89 05 01 00 41 00 00 00-02 04 01 00 02 00 02 B1 ....A...........   
       18CE:0410 FF F8 40 00 3F 00 10 00-3F 00 FA 89 45 06 8B 46 ..@.?...?...E..F   
       18CE:0420 FC 89 05 8B 46 EC 89 EC-5D 5F 5E C3 51 56 55 89 ....F...]_^.QVU.   
       -_   
      
   I changed one instruction to change to the NetDrive drive number and   
   ran the code again, but this time at the first breakpoint the Carry   
   Flag (CY) is set. This means there was an error, and AX holds the   
   error code. Value 0x0001 means "ERROR_INVALID_FUNCTION" which makes   
   sense because the NetDrive device driver doesn't support this   
   function. (It is not required to be supported.)   
      
   If we dig around inside of SYS.COM we can see a call to Generic IOCTL:   
      
       C:\DOS>debug sys.com   
       -u 9a5   
       18EC:09A5 8A1E2209      MOV     BL,[0922]   
       18EC:09A9 BAC003        MOV     DX,03C0   
       18EC:09AC B444          MOV     AH,44   
       18EC:09AE B00D          MOV     AL,0D   
       18EC:09B0 B508          MOV     CH,08   
       18EC:09B2 B160          MOV     CL,70   
       18EC:09B4 CD21          INT     21   
       18EC:09B6 8BDA          MOV     BX,DX   
       18EC:09B8 8D7707        LEA     SI,[BX+07]   
       18EC:09BB 46            INC     SI   
       18EC:09BC 46            INC     SI   
       18EC:09BD 83FEFF        CMP     SI,-01   
       18EC:09C0 7445          JZ      0A07   
       18EC:09C2 83FEFE        CMP     SI,-02   
       -   
      
   Here we see it getting the drive number from storage, setting AX to   
   0x440D, setting CH to 0x08 (a block device) and CL to 0x60 (get   
   device parameters). DS:DX will be the pointer to the parameter block   
   to fill in.   
      
   Let's run the code!   
      
       C:\DOS\>debug sys.com e:   
       -u 9a5   
       18EC:09A5 8A1E2209      MOV     BL,[0922]   
       18EC:09A9 BAC003        MOV     DX,03C0   
       18EC:09AC B444          MOV     AH,44   
       18EC:09AE B00D          MOV     AL,0D   
       18EC:09B0 B508          MOV     CH,08   
       18EC:09B2 B160          MOV     CL,70   
       18EC:09B4 CD21          INT     21   
       18EC:09B6 8BDA          MOV     BX,DX   
       18EC:09B8 8D7707        LEA     SI,[BX+07]   
       18EC:09BB 46            INC     SI   
       18EC:09BC 46            INC     SI   
       18EC:09BD 83FEFF        CMP     SI,-01   
       18EC:09C0 7445          JZ      0A07   
       18EC:09C2 83FEFE        CMP     SI,-02   
       -g 9b6   
      
       AX=0001  BX=0005  CX=0860  DX=03C0  SP=0192  BP=0000  SI=0000  DI=0001   
       DS=1923  ES=1923  SS=1994  CS=1923  IP=0436   NV UP EI PL ZR NA PE CY   
       1923:0436 CC            INT     3   
       -   
      
   At the breakpoint after the Generic IOCTL we see that the Carry Flag   
   (CY) is set and the error code is set to ERROR_INVALID_FUNCTION, just   
   as it was above. And here is the bug ... nothing is checking the   
   Carry Flag to see if there was an error after the Generic IOCTL call.   
      
   The Generic IOCTL writes DEVICEPARAMS structure at DS:DX, assuming   
   the call did not fail. If the call fails, as it does here, we'll just   
   see whatever was already in that storage. As before, the BPB   
   structure will be at offset 0x06. Here is what we got back in that   
   data structure:   
      
       18EC:09B0 B508          MOV     CH,08   
       18EC:09B2 B160          MOV     CL,70   
       18EC:09B4 CD21          INT     21   
       18EC:09B6 8BDA          MOV     BX,DX   
       18EC:09B8 8D7707        LEA     SI,[BX+07]   
       18EC:09BB 46            INC     SI   
       18EC:09BC 46            INC     SI   
       18EC:09BD 83FEFF        CMP     SI,-01   
       18EC:09C0 7445          JZ      0A07   
       18EC:09C2 83FEFE        CMP     SI,-02   
       -g 9b6   
      
       AX=0001  BX=0005  CX=0860  DX=03C0  SP=0192  BP=0000  SI=0000  DI=0001   
       DS=1923  ES=1923  SS=1994  CS=1923  IP=0436   NV UP EI PL ZR NA PE CY   
       1923:0436 CC            INT     3   
       -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...   
       -_   
      
   (Note that the segment registers changed causing the instruction   
   pointer to shift ... we are still in the same code though, just using   
      
   [continued in next message]   
      
   --- 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