home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS 1992 September
/
Simtel20_Sept92.cdr
/
msdos
/
pcmag
/
vol9n03.arc
/
CHKBOOT.ASM
< prev
next >
Wrap
Assembly Source File
|
1990-01-05
|
62KB
|
1,099 lines
PAGE 60,132
TITLE CHKboot - High performance boot sector checker
; SUBTTL General program description and use of common storage
; ----------------------------------------------------------------------------;
; CHKboot - check DOS boot record and partition table boot for changes.;
; ----------------------------------------------------------------------------;
; CHKBOOT 1.0 ■ PCDATA TOOLKIT Copyright (c) 1990 Ziff Communications Co. ;
; PC Magazine ■ Wolfgang Stiller ;
; ;
;-----------------------------------------------------------------------------;
;Purpose: ;
;CHKBOOT checks the integrity of DOS boot sectors and hard disk ;
;partition tables (sectors). On first execution, or with the "/I" ;
;parameter, CHKBOOT writes check values to the parameter file and ;
;creates reload files for the boot and partition sectors. All files ;
;written contain self check information. CHKBOOT subsequently will ;
;check the DOS boot record and/or the partition sector for any changes ;
;by using information recorded on the parameter file. ;
; ;
; ----------------------------------------------------------------------------;
;Format: ;
; ;
;CHKBOOT [filespec] [/B] [/H] [/I] [/P] [/2] ;
; ;
;"filespec" is optional file specification for the parameter file. If not ;
; specified, "CHKBOOT.PRM" will be used as the parameter file. ;
;"/H" Presents extensive detailed help information. ;
;"/B" Checks boot record on current DOS disk for any changes. ;
;"/P" Checks partition sector on first physical hard disk for any changes. ;
;"/2" Checks partition sector on second physical hard disk. ;
; /P and /2 may not be specified together. ;
;"/I" Force initialization. Attempts read of current boot sector and ;
; partition sector on 1st hard drive (Include /2 for 2nd partition ;
; sector). CHKBOOT then writes the parameter file so that any ;
; changes to these sectors can be detected on subsequent ;
; executions. The boot and partition sectors are copied to files ;
; @@BOOT.SCT and @@PARTIT.SCT for LODboot reload. ;
; ;
; At least one of the parameters, /B /P /2 or /I must be entered. ;
; If /I is entered then /B and /P are ignored if entered (/2 is ;
; honored). ;
; ;
;Note, If the parameter file does not exist, then CHKBOOT will ;
; automatically initialize and create the file. ;
; ;
;Example: "CHKBOOT /B /F" will read both the DOS boot sector and the ;
; partition sector on the 1st hard drive and compare the ;
; cryptographic checksums from a prior execution. ;
;-----------------------------------------------------------------------------;
;Remarks: ;
; It is safest to keep CHKBOOT and all its files off-line on a floppy. ;
; This floppy should be bootable (created with FORMAT d:/S). In order ;
; to check hard disk partition sectors, CHKBOOT can be executed ;
; directly from anywhere. To check a DOS boot sector, you must be ;
; logged on to the DOS drive you wish to check. If for example, your ;
; floppy is drive A, and C is your default drive, then ;
; A:CHKBOOT A:CHKBOOT.PRM/B/P ;
; will cause the program and the parameter file (CHKBOOT.PRM) to both ;
; be utilized from floppy. The DOS boot sector from drive C and the ;
; hard disk partition sector from the first physical disk will be ;
; checked. ;
; ;
; All files created by CHKBOOT contain validity check data embedded. ;
; Any change to any of the files will be detected whenever the file is ;
; processed. If CHKBOOT finds corruption to either the parameter file ;
; or the sectors it is checking, it will produce an error message, beep, ;
; and force the user to acknowledge with a key press. Other serious ;
; errors detected are also handled in this way. ;
; ;
; The following DOS errorlevels will be returned on termination. ;
; ;
; 00 - Compare of boot and/or partition records successful. ;
; 02 - Compare of boot sector failed. ;
; 04 - Compare of partition sector failed. ;
; 06 - Compare of both boot and partition boot sectors failed. ;
; 16 - Initialization occurred. No compare done. ;
; 32 - Corruption of the parameter file detected (CHKBOOT.PRM). ;
; 64 - Program failure (usually due to disk problems or lack of space on disk);
;128 - Syntax error on invoking CHKBOOT. ;
; ;
;-----------------------------------------------------------------------------;
;---------------------------------------------------------------;
; Constants: ;
;---------------------------------------------------------------;
BOX EQU 254 ;Small box character code
CR EQU 0Dh
LF EQU 0Ah
CRLF EQU 0A0Dh ;Carriage return line feed.
Boot_type EQU 0FFh ;Indicator of a boot sector (.PRM)
Part_type EQU 055h ;Indicator of a partition sector(.PRM)
; Double line drawing character definitions
Horizontal EQU 205 ;Horizontal double line
Vertical EQU 186 ;Vertical double line
UPRT_corner EQU 187 ;Upper righthand corner
UPLT_corner EQU 201 ;Upper lefthand corner
LWLT_corner EQU 200 ;Lower lefthand corner
LWRT_corner EQU 188 ;Lower righthand corner
CSEG SEGMENT
ASSUME CS:CSEG, DS:CSEG, ES:CSEG, SS:CSEG
SUBTTL Main program
;******************************************************************************;
;** Main program begins here -CHKBOOT- **;
;******************************************************************************;
ORG 100H ; THIS IS A COM TYPE PROGRAM
CHKBOOT:
CALL Parse_parms ;Parse cmdline paramters
MOV DX, offset Header_Msg ;Put out title display
MOV AH,09H ;DOS display string function
INT 21H
; Check system sector size
MOV AH,36h ;Check sector size and free space
XOR DL,DL ;Check current disk (DL=0 is current)
INT 21h
MOV Sector_Size,CX ;Save # of bytes per sector
CMP CX,512 ;Is this a standard size sector
JE Continue_main_process ; If so, continue
MOV DX, OFFSET Non_STD_Msg ; Else put out message warning user
MOV AH,09h ; DOS display function
INT 21h
Continue_main_process:
XOR BP,BP ;Zero out highest error level code
CMP Initialize_Mode,'Y' ;Has init mode been requested?
JE Initialize_all_files ; If so, then initialize this program
CALL Open_and_Read_PARM_file ;Open and verify existance of parmfile
; If open fails, set initialize flag
CMP Initialize_Mode,'Y' ;Check again if INIT is requested...
JE Initialize_all_files ; If so, then initialize this program
CALL Validate_Parm_File ;Make sure its a valid parm file
CMP Boot_wanted,'Y' ;Does user want BOOT rec checked?
JNE No_Boot ; If not skip checking the boot rec
CALL Read_Boot_Sector ;Do actual read of sector 0 (DOS)
; --------- Calculate cryptographic check/XOR sums for disk sector -----------
MOV SI,offset BUFFER ;Point SI to buffer containing sector
MOV CX,Sector_Size ;Process all bytes in a sector
CALL Calc_Sums ;Calculate CHK and XOR sums
; On return: DI - Contains checksum for this file
; DX - XOR sum
; -----------------------------------------------------------------------------
CALL Compare_Boot_Sums ;See if any changes to the sector
NO_BOOT:
CMP Partition_wanted,'Y' ;Does user want Partition checked?
JNE End_Execution ; If not skip checking the Partition
CALL Read_Part_Sector ;Do actual read of sector 0 (BIOS)
; --------- Calculate cryptographic check/XOR sums for disk sector -----------
MOV SI,offset BUFFER ;Point SI to buffer containing sector
MOV CX,Sector_Size ;Process all bytes in a sector
CALL Calc_Sums ;Calculate CHK and XOR sums
; On return: DI - Contains checksum for this file
; DX - XOR sum
; -----------------------------------------------------------------------------
CALL Compare_Part_Sums ;Any changes to partition sector?
End_Execution: ;Successful termination of program
MOV AX,BP ;BP contains highest error level
MOV AH,4Ch ;DOS terminate with errorlevel funct
INT 21h
;---------------------------------------------------------------------;
; Initialize all files-initialize this program - writing "PARM_File" ;
;---------------------------------------------------------------------;
; This procedure will read both boot and partition records calculate ;
; the check sums (XOR and CHK). These will be recorded on "PARM_FILE".;
;---------------------------------------------------------------------;
Initialize_all_files:
CALL Create_PARM_file ;Create and open the parameter file
MOV DX,offset Init_Msg ;Explain that we are intializing
MOV AH,09H ;DOS display string function
INT 21H
CALL Read_Boot_Sector ;Do actual read of sector 0 (DOS)
; --------- Calculate cryptographic check/XOR sums for disk sector -----------
MOV SI,offset BUFFER ;Point SI to buffer containing sector
MOV CX,Sector_Size ;Process all bytes in a sector
CALL Calc_Sums ;Calculate CHK and XOR sums
; On return: DI - Contains checksum for this file
; DX - XOR sum
; -----------------------------------------------------------------------------
MOV Boot_XOR_Sum,DX ;Copy XOR sum into PARM buffer
MOV SCT_XOR,DX ;Copy XOR sum to reloadable file
MOV Boot_CHK_SUM,DI ;Copy CHK sum into Parm buffer
MOV SCT_CHK,DI ;Copy CHK sum to reloadable file
MOV BYTE PTR[SCT_Type],Boot_type ;Set sector type indicator to BOOT
CALL Write_Boot_Sector ;Create a reloadable copy of partition
CALL Read_Part_Sector ;Do actual read of sector 0 (BIOS)
CMP Partition_wanted,'X' ;Read failed (no longer wanted)?
JE Encrypt_Parm_File ; If so, skip writing PARM file
; --------- Calculate cryptographic check/XOR sums for disk sector -----------
MOV SI,offset BUFFER ;Point SI to buffer containing sector
MOV CX,Sector_Size ;Process all bytes in a sector
CALL Calc_Sums ;Calculate CHK and XOR sums
; -----------------------------------------------------------------------------
MOV Part_XOR_Sum,DX ;Copy XOR sum into memory
MOV SCT_XOR,DX ;Copy XOR sum to reloadable file
MOV Part_CHK_SUM,DI ;Copy CHK sum into mem
MOV SCT_CHK,DI ;Copy CHK sum to reloadable file
MOV BYTE PTR[SCT_Type],PART_type ;Set sector type indicator to Part
CALL Write_Part_Sector ;Create a reloadable copy of partition
Encrypt_Parm_File:
; --------- Calculate cryptographic XOR sum for the PARM file ---------------
MOV SI,offset PARM_BUFFER ;Point SI to buffer containing sector
MOV CX,41 ;Check 1st 41 characters parm_file
CALL Calc_Sums ;Calculate CHK and XOR sums
; -----------------------------------------------------------------------------
MOV PARM_XOR_Sum,DX ;Copy XOR sum into memory
MOV PARM_CHK_SUM,DI ;Copy CHK sum into mem
CALL Write_Parm_File ;Write records to parmfile
MOV AX,4C10h ;DOS terminate with 16 error level
INT 21h
;---------------------------------------------------;
; C O M P A R E B O O T S U M S - any changes?;
;---------------------------------------------------;
;Register conventions: ;
; ;
; DI - Contains checksum for this file ;
; DX - XOR sum ;
;---------------------------------------------------;
Compare_Boot_Sums: ;See if any changes to the sector
CMP Boot_XOR_SUM,DX ;Any change to XOR sum?
JNE Boot_change_detected ; If not =, report the change
CMP BOOT_CHK_SUM,DI ;Is the checksum OK?
JNE Boot_change_detected ; If not, report the change
; ELSE all is OK with boot sector
MOV DX,offset Boot_Msg ;Display message about boot record
MOV AH,09H ;DOS display string function
INT 21H
MOV DX,offset OK_Msg ;Explain that all is well
MOV AH,09H ;DOS display string function
INT 21h
RET
Boot_Change_detected: ;Report problem with boot record
ADD BP,2 ;Adjust DOS error lvl to ind prblm
MOV DX,offset Boot_Msg ;Display message about boot record
MOV AH,09H ;DOS display string function
INT 21H
MOV DX,offset Bad_Sector_Msg ;Explain that its bad
MOV AH,09H ;DOS display string function
INT 21H
CALL Send_Beep ;Wake up user!
CALL Wait_For_Key ;Beep and force user to hit a key
RET
;---------------------------------------------------;
; C O M P A R E P A R T S U M S - any changes?;
;---------------------------------------------------;
;Register conventions: ;
; ;
; DI - Contains checksum for this file ;
; DX - XOR sum ;
;---------------------------------------------------;
Compare_Part_Sums: ;See if any changes to the sector
CMP Part_XOR_SUM,DX ;Any change to XOR sum?
JNE Part_change_detected ; If not =, report the change
CMP Part_CHK_SUM,DI ;Is the checksum OK?
JNE Part_change_detected ; If not, report the change
; ELSE all is OK with Part sector
MOV DX,offset Part_Msg ;Display message about Partition sect
MOV AH,09H ;DOS display string function
INT 21H
MOV DX,offset OK_Msg ;Explain that all is well
MOV AH,09H ;DOS display string function
INT 21h
RET
Part_Change_detected: ;Report problem with Partition sector
ADD BP,2 ;Adjust DOS error lvl to ind prblm
MOV DX,offset Part_Msg ;Display message about Partition sect
MOV AH,09H ;DOS display string function
INT 21H
MOV DX,offset Bad_Sector_Msg ;Explain that its bad
MOV AH,09H ;DOS display string function
INT 21H
CALL Send_Beep ;Wake up user!
CALL Wait_For_Key ;Beep and force user to hit a key
RET
;---------------------------------------------------;
; R E A D B O O T S E C T O R ;
;---------------------------------------------------;
;Read the DOS boot sector using DOS I/O requests. ;
;---------------------------------------------------;
Read_Boot_Sector:
PUSH BP ;Save all current registers
Try_boot_read_again: ;Come here to retry the extended
;form of the read if normal int 25h failed. Note, it is NOT an error
;that we re-execute the 19h function...some systems require this
MOV AH,19h ;DOS get current disk drive function
INT 21h ;Get current disk drive in AL (0=A)
CMP DOS_Version,4 ;Are we running under DOS 4.x?
JNE Old_DOS ;If not, do normal int 25 call
; Process DOS 4.0 disks using extended format of INT25 (handles disks > 32mb)
MOV CX,-1 ;Set indicator to handle >32 mb disks
MOV BX,Offset INT25_Parms ;Point to 10 byte parameter block
MOV Buffer_Segment,DS ;Segment address in parameter block
JMP SHORT DOS_Abs_Read ;Do DOS Absolute sector read
Old_DOS:
MOV CX,1 ;Read just one sector
XOR DX,DX ;DX=0 to read DOS logical sector 0
MOV BX,Offset buffer ;Place to put the sector
DOS_Abs_Read:
INT 25h ;DOS absolute disk read function
JNC Boot_read_OK ;If I/O was successful
;Else we had an I/O error
;
; Since some OEM versions of DOS such as COMPAQ 3.31 also support the extended
; format of the int 25h call for disks > 32mb we will lie and say this is
; DOS 4.x and try the interrupt 4.0 using the extended format call.
POPF ;Remove flags from stack
CMP DOS_Version,4 ;Did we already try DOS 4.x type int?
JE Boot_Read_Failed ; If so, then boot read failed
; otherwise try extended int 25h
MOV DOS_Version,4 ; Force extended int 25h use (lie)
JMP SHORT Try_Boot_Read_Again ; do func 19h and then extd int 25h
Boot_Read_Failed:
MOV DX,offset Boot_Msg ;Display message about boot record
MOV AH,09H ;DOS display string function
INT 21H
Unrecoverable_IO_Error: ;Exit here if I/O has failed
MOV DX,offset IO_Err_Msg ;Explain that input/output failed
MOV AH,09H ;DOS display string function
INT 21H
CALL Send_Beep ;Wake up user!
CALL Wait_For_Key ;Beep and force user to hit a key
MOV AX,4C40h ; terminate with 64 DOS ERRORLEVEL
INT 21h
Boot_read_OK:
POPF ;restore flags pushed by INT 25h
POP BP ;Restore active registers
RET
;---------------------------------------------------;
; R E A D P A R T S E C T O R ;
;---------------------------------------------------;
;Read the partition sector using BIOS I/O request ;
;---------------------------------------------------;
Read_part_Sector:
MOV AH,02 ;BIOS floppy read function of INT 13h
MOV DL,BYTE PTR[Drive_number] ;Drive 80 (1st) or 81 (2nd) hard drive
MOV AL,1 ;Read only 1 sector
MOV CX,1 ;Read (CH) track 0, (CL) sector 1
XOR DH,DH ;Read head number zero
MOV BX,Offset buffer ;Place to put the sector
INT 13h ;BIOS absolute (floppy) disk read
JNC Part_Read_OK ;If I/O was successful
;Else the we had an I/O error
MOV DX,offset No_HardDisk_MSG ;Display message about missing part
MOV AH,09H ;DOS display string function
INT 21H
CMP Partition_wanted,'Y' ;Did user ask to read this partition?
MOV Partition_wanted,'X' ;Turn off partn checking (stop write)
JNE Part_Read_OK ; If user did NOT ask for read,its OK
; Otherwise, its a fatal error
JMP SHORT Unrecoverable_IO_Error
Part_Read_OK:
RET
;---------------------------------------------------------------------------;
; Open_and_read_parm_file: ;
; Open the parameter(CHKBOOT.PRM) file which contains the cryptographic ;
; XOR and checksums for the boot and partition records. ;
; If Open fails, set a flag to indicate this, (intialize_mode=Y) ;
;---------------------------------------------------------------------------;
Open_and_Read_Parm_File:
MOV AX,3D00h ;Open file for read function
MOV DX,offset Parm_File_Name ;Name of the parameter file:ASCIIZ
INT 21h ;Do open for read
JNC File_found ;If open went OK..
MOV Initialize_mode,'Y' ; If not, force initialization
MOV DX,offset Missing_Msg ;Explain that PARM file is missing
MOV AH,09H ;DOS display string function
INT 21H
CALL Send_Beep ;Wake up user!
CALL Wait_For_Key ;Beep and force user to hit a key
RET
File_found:
MOV BX,AX ;File handle in BX
MOV CX,45 ;Read 45 bytes from disk
MOV DX,OFFSET PARM_buffer ;Data to write to disk
MOV AH,3FH ;DOS read function
INT 21H ;Call DOS
JNC Close_Parm_file ;If no error, continue + close file
JMP Bad_Parm_file ; else Report that we have a bad file
Close_Parm_file:
MOV AH,3Eh ;DOS close file function code
INT 21h ;Close the file
RET
;---------------------------------------------------;
; C R E A T E P A R M F I L E ;
; Does an open create/truncate on the "PARM_file" ;
; Returns file handle in Parm_handle ;
;---------------------------------------------------;
Create_PARM_file: ;Create and open the parameter file
MOV AH,3Ch ;DOS create file function
MOV DX,Offset PARM_File_Name
XOR CX,CX ;Set CX (file attribute=normal) = 0
INT 21h
JNC Create_Parm_Exit ;IF all went OK then return
JMP Unrecoverable_IO_Error
Create_Parm_Exit:
MOV Parm_Handle,AX ;Save file handle
RET
;---------------------------------------------------;
; W R I T E P A R M F I L E ;
;---------------------------------------------------;
;Write the parameter file out to disk. ;
;This is called only during intialization. ;
;---------------------------------------------------;
Write_PARM_File:
MOV DX,offset PW_Msg ;Display message about write parm rec
MOV AH,09H ;DOS display string function
INT 21H
MOV AH,40h ;DOS WRITE function code
MOV BX,PARM_Handle ;Handle for parm_file
MOV CX,45 ;Write 45 bytes to disk
MOV DX,OFFSET PARM_buffer ;Data to write to disk
INT 21h ;Do the I/O
JNC PARM_write_OK ;If I/O was successful
;Else the we had an I/O error
JMP Unrecoverable_IO_Error
PARM_write_OK: ;Write of Parm_file worked ok
MOV AH,3Eh ;DOS close file function code
INT 21h ;Close the file
RET
;---------------------------------------------------;
; W R I T E B O O T S E C T O R (F I L E) ;
;---------------------------------------------------;
;Write a reloadable version of the boot sector to ;
;DISK. This is done during intialization. ;
;---------------------------------------------------;
Write_Boot_Sector:
MOV DX,offset BootW_MSG ;Display msg about writing boot file
MOV AH,09H ;DOS display string function
INT 21H
MOV AH,3Ch ;DOS create file function
MOV DX,Offset Boot_File_Name
XOR CX,CX ;Set CX (file attribute=normal) = 0
INT 21h
JNC Create_boot_OK ;IF all went OK then return
Boot_Write_Error:
JMP Unrecoverable_IO_Error
Create_Boot_OK:
MOV BX,AX ;Handle for Boot sector file
MOV AH,40h ;DOS WRITE function code
MOV CX,69 ;Length of reload sector prefix
ADD CX,Sector_Size ;Write 1 sector + 69 bytes
MOV DX,OFFSET Write_buffer ;Data to write to disk
INT 21h ;Do the I/O
JNC Boot_write_OK ;If I/O was successful
;Else the we had an I/O error
JMP Unrecoverable_IO_Error
Boot_write_OK: ;Write of Parm_file worked ok
MOV AH,3Eh ;DOS close file function code
INT 21h ;Close the file
RET
;---------------------------------------------------;
; W R I T E P A R T S E C T O R (F I L E) ;
;---------------------------------------------------;
;Write a reloadable version of the partition sector ;
;to disk. This is done during initialize processing.;
;---------------------------------------------------;
Write_Part_Sector:
MOV DX,offset PartW_MSG ;Display msg about writing Part file
MOV AH,09H ;DOS display string function
INT 21H
MOV AH,3Ch ;DOS create file function
MOV DX,Offset Part_File_Name
XOR CX,CX ;Set CX (file attribute=normal) = 0
INT 21h
JNC Create_Part_OK ;IF all went OK then return
Part_Write_Error:
JMP Unrecoverable_IO_Error
Create_Part_OK:
MOV BX,AX ;Handle for Part sector file
MOV AH,40h ;DOS WRITE function code
MOV CX,69 ;Length of reload sector prefix
ADD CX,Sector_Size ;Write 1 sector + 69 bytes to disk
MOV DX,OFFSET Write_buffer ;Data to write to disk
INT 21h ;Do the I/O
JNC Part_write_OK ;If I/O was successful
;Else the we had an I/O error
JMP Unrecoverable_IO_Error
Part_write_OK: ;Write of Parm_file worked ok
MOV AH,3Eh ;DOS close file function code
INT 21h ;Close the file
RET
;---------------------------------------------------;
; V A L I D A T E P A R M F I L E ;
;---------------------------------------------------;
;Check that the parameter file itself has not been ;
;corrupted in some way. ;
;---------------------------------------------------;
Validate_Parm_File: ; make sure its a valid parm file
; --------- Calculate cryptographic XOR sum for the PARM file ---------------
MOV SI,offset PARM_BUFFER ;Point SI to buffer containing sector
MOV CX,41 ;Check 1st 41 characters in buffer
CALL Calc_Sums ;Calculate CHK and XOR sums
; -----------------------------------------------------------------------------
; Compare the calculated with the recorded check/XOR sums
CMP PARM_XOR_Sum,DX ;Compare XOR sum
JNE Bad_Parm_File ;If parm file corrupted..
CMP PARM_CHK_SUM,DI ;Compare CHK sum
JNE Bad_Parm_File ;If parm file corrupted..
RET ;Otherwise return..all is well so far
Bad_Parm_file:
MOV DX,offset BadP_MSG ;Explain that Parm file is corrupted
MOV AH,09H ;DOS display string function
INT 21H
CALL Send_Beep ;Wake up user!
CALL Wait_For_Key ;Beep and force user to hit a key
MOV AX,4C20h ; terminate with 32 DOS ERRORLEVEL
INT 21h
SUBTTL General Purpose subroutines
PAGE
;******************************************************************************;
;** General purpose subroutines follow **;
;******************************************************************************;
SUBTTL General purpose subroutines
PAGE
;---------------------------------------------------;
; C A L C S U M S - Calculate XOR + CHK sums ;
;---------------------------------------------------;
; INPUT: SI = pointer to file BUFFER to scan ;
; CX = # of characters to read ;
; ;
;Register conventions: ;
; ;
; AL - Each new character read into this register ;
; CX - number of chars read in -decreasing counter ;
; DI - Contains checksum for this file ;
; DX - XOR sum ;
; SI - index pointing into file BUFFER ;
; --------------------------------------------------;
Calc_Sums:
XOR DX,DX ;Zero XOR sum
XOR DI,DI ;Zero CHK sum
XOR AH,AH ;Zero upper part of AX for addition
; Innermost char loop - keep this fast!
NEXT_CHAR:
LODSB ;Get char into AL
XOR DL,AL ;cumulative XOR into DX
ROL DX,1 ;Keep shifting to XOR sum to left
ADD DI,AX ;cumulative check sum
LOOP NEXT_CHAR ;CONTINUE SCANNING CHARS UNTIL EOB
RET ;All done calculating sums!
;---------------------------------------------------;
; D I S P L A Y M A X H E L P - Display adv help;
;---------------------------------------------------;
; 1) Clear the screen ;
; 2) Send message pointed to by DS:DX ;
; 3) Beep and wait for any key press ;
; --------------------------------------------------;
Display_Max_Help:
CALL Clear_Screen ;Clear screen and set cursor to top
MOV AH,09H ;DOS display string function
INT 21H
CALL Pos_Cursor_Line25 ;Go to last line of screen
CALL Wait_for_key ;Wait for key press
RET
;---------------------------------------------------;
; C L E A R S C R E E N - Erase contents of screen;
; and position cursor at top of screen. Maintain ;
; user's current screen attributes (colors). ;
; ;
; Entry: Current_Screen_atr contains current screen ;
; attribute. (Set by routine: Get_Screen_Atr);
;---------------------------------------------------;
Clear_Screen:
PUSH BP ;Save registers
PUSH DX
; Clear the screen using the BIOS scroll screen function
MOV AX,0600h ;06=scroll function.
;00=lines to scroll = clear screen
MOV BH,Current_Screen_Atr ;Attribute byte to fill screen
MOV CX,00 ;upper left corner is (0,0) = (y,x)
MOV DX,184Fh ;Lower rt corner=(y,x)=(24,79)
INT 10h ;Call BIOS video services
; Position cursor to line 00 column 00
MOV AH,02 ;BIOS int 10h set cursor position func
XOR BH,BH ;Set page to zero
MOV DX,0000h ;Set cusor to row 00 and column 00
INT 10h ;BIOS video services
POP DX
POP BP ;Restore registers
RET
;---------------------------------------------------;
; S E N D B E E P ;
;---------------------------------------------------;
; Cause the PC to put out a BEEP sound. ;
;This is used to alert user to an error condition. ;
;---------------------------------------------------;
Send_Beep:
PUSH BP ;Save all vulnarable registers
PUSH DX
; Produce a beep to alert the user: (use BIOS TTY func to write an ASCII BELL)
MOV AX,0E07H ;BIOS func (0Eh) to write (07H) beep
XOR BH,BH ;Select page zero for output
INT 10H ;BIOS video function (0Eh=write char)
POP DX
POP BP ;Restore registers
RET
;---------------------------------------------------;
; G E T C U R R E N T S C R E E N A T R ribute;
;---------------------------------------------------;
;Determine forground and background colors in use ;
;and save for use by other BIOS video functions. ;
; Save it in: "Current_Screen_Atr" ;
;---------------------------------------------------;
Get_Current_Screen_Atr:
PUSH BP ;Save all vulnarable registers
PUSH DX
;Find out what attribute is being used for display
MOV AH,08h ;read attrib + char function
INT 10h ;Call BIOS video services
MOV Current_Screen_Atr,AH ;Save AH=attribute byte
POP DX
POP BP ;Restore registers
RET
;---------------------------------------------------;
; P O S C U R S O R on L I N E 2 5 ;
;---------------------------------------------------;
;Move cursor position to line 25 (BIOS line 24) ;
;the last line on the screen. . ;
;---------------------------------------------------;
Pos_Cursor_Line25:
PUSH BP ;Save all vulnarable registers
PUSH DX
; Position cursor to line 25 and column 01: (TO BIOS col 00 + row 24)
MOV AH,02 ;BIOS int 10h set cursor position func
XOR BH,BH ;Set page to zero
MOV DX,1800h ;DH = row 24; DL = col 00
INT 10h ;BIOS video services
POP DX
POP BP ;Restore registers
RET
;---------------------------------------------------;
; W A I T F O R K E Y ;
;---------------------------------------------------;
; 1) Put out message to hit any key on current line.;
; 2) Wait for any key press ;
; 3) Erase message using current screen attribute ;
; 4) Position currsor back at start of current line.;
; --------------------------------------------------;
Wait_For_Key:
PUSH BP ;Save all corrupted registers
PUSH DX
;Find out what line the cursor is on
MOV AH,03h ;Read cursor position function
INT 10h ;BIOS video services
PUSH DX ;DH contains row (line #) Save it!
; Position cursor to current line + column 28: (TO BIOS row 27)
MOV AH,02 ;BIOS int 10h set cursor position func
XOR BH,BH ;Set page to zero
;DH contains current row
MOV DL,1Bh ;Set cusor current row and col 27
INT 10h ;BIOS video services
; Put -Hit any key- message out with inverse video attribute type on
; XOR BH,BH ;Set page to zero (BH is still 0)
MOV BL,0F0h ;Inverse video attribute
MOV CX,1 ;Character count
MOV SI,offset Hit_Key_Msg ;The hit-any-key message
Display_next_video_char:
MOV AH,09H ;BIOS int 10h write attrib + char func
LODSB ;Get next character for output
PUSH SI ;Save SI (int 10h may corrupt it)
INT 10h ;Put character and attribute out
INC DX ;Advance cursor position
MOV AH,02 ;Adv cursor function
INT 10h ; advance the cursor (BIOS)
POP SI ;Restore saved SI
CMP SI,offset Hit_key_Msg_end ;are we at end of message?
JB Display_next_video_char ; If not get next char for display
; Else, wait for key press by user
; Wait for user to hit any key
XOR AX,AX
INT 16h ;Wait for user to hit a key
; Erase HIT ANY KEY message
POP DX ;DH=current line number
MOV BH,Current_Screen_Atr ;AH=user's screen attribute
MOV AH,06h ;INIT window function
XOR AL,AL ;Zero AL to clear window
MOV CH,DH ;Current row (y coor upr lft)
MOV CL,00 ;Start in first char position
MOV DL,79 ;Last char pos - blank entire line
INT 10h ;Blank out line
; Position cursor to start of blanked line
MOV AH,02 ;BIOS int 10h set cursor position func
XOR DL,DL ;DH=cur line, DL=0: first char pos
XOR BX,BX ;Use video page zero
INT 10h ;BIOS video services
POP DX
POP BP
RET ;Return to caller
; ----------------------------------------------------------------------------;
; Initialization code - parse parms + put out msgs ;
; ----------------------------------------------------------------------------;
Parse_parms: ;Parse input parameters
MOV AH,30h ;Check DOS version
INT 21h ; Ask DOS: "who are you?"
OR AL,AL ;Check if before DOS 2.x (AL=0)
JNE DOS_is_OK ;If good DOS vers, then continue
MOV DX, OFFSET Bad_DOS_Msg ; ELSE Send MSG that
MOV AH,09h ; DOS version is too low.
INT 21h
INT 20h ; Old style DOS terminate interupt
DOS_is_OK:
MOV DOS_Version,AL ;Save major DOS version number (0-4)
MOV SI,80H ;Parameter area in PSP
MOV CL,[SI] ;Get # of chars in input parm
XOR CH,CH ;CLEAR UPPER BYTE OF CHR COUNT
OR CL,CL ;CHECK FOR 0 CHARS (NO INPUT)
MOV DX, OFFSET Explanation ;Give user full explanation of prgm
JNZ Continue_parse ;If some parameters keep going
JMP Help_display ; Else, give user some help info
Continue_parse:
INC SI ;POINT TO FIRST CHARACTER
CLD ;FORWARD DIRECTION
DEL_SPACES:
LODSB ;Get byte at DS:SI and inc SI
CMP AL,'/' ;Is it a "/"
JE Scan_for_parms ;If so, we have a parameter
CMP AL,' ' ;Is it a space?
JNE Scan_Filespec ;If not we have a filespec
LOOP DEL_SPACES ;CONT CHECKING UNTIL LAST CHAR
JMP Help_Display
;---------------------------------------------------------------------------;
; Conventions for command line parsing: ;
; SI points to next char to be checked in the parm field at DS:80 ;
; CX is count of characters left to be scanned ;
;---------------------------------------------------------------------------;
Scan_Filespec: ;Parse user override to parameter file
;----------------------------------------;
; Parse filespec + xfer to Parm_FIle_Name;
;----------------------------------------;
DEC SI ;point back to 1ST letter of filespec
MOV DI, offset Parm_File_Name ;prep to transfer file name to msg
Scan_To_File_Spec_End:
; start scanning the file specification and transfer into output field
LODSB ;Get next char of file spec
CMP AL,' ' ;check valid separator character
JBE file_spec_end_found
CMP AL,'/' ;check for valid separator
JE file_spec_end_found
STOSB ;Store char as part of User_file_spec
LOOP Scan_To_File_Spec_End
JMP Help_Display ;There must be at least on /x parm
;So give user HELP with CHKBOOT
File_Spec_End_Found:
;SI = next char loc after filespec
PUSH AX ;Save last char examined
MOV AL,00 ;Zero terminate the filespec
STOSB ; combination as a single word
POP AX ;Restore last character examined
Scan_for_parms:
CMP CX,01 ;Check if we out of chars to scan
JA Parm_Scan ;If some are left, check parameters
JMP Help_display ;If so, user needs HELP
Check_parm_chars_left: ;Check if enough chars left for a parm
CMP CX,01 ;Check if we out of chars to scan
JA Parm_Scan ; if not continue chcking for /parms
RET ; If so, return
Parm_Scan: ;Check for presence of a /_ parm
CMP AL,'/' ;check for "/" parm character
JE Parm_found
CMP AL,' ' ;check for blanks
JNE Unrecog_parm ;If other than blank its illegal...
LODSB ;Keep checking next character
LOOP Parm_Scan
RET ;All done
Parm_Found: ;Check if parm is valid
DEC CX ;Adjust chars remaining counter
JCXZ Unrecog_parm ;IF no chars left then parm is invalid
LODSB ;Get next char
DEC CX ;Adjust chars remaining counter
CMP AL,'2' ;Is it the Initialize parm?
JE Two_parm ;2 parm detected..
AND AL,5Fh ;Capitalize char
CMP AL,'P' ;Is it Partition table parm?
JE P_parm ;P parameter detected
CMP AL,'B' ;Is it the Boot record parm?
JE B_parm ;I parm detected..
CMP AL,'I' ;Is it the Initialize parm?
JE I_parm ;I parm detected..
CMP AL,'H' ;Is it the Initialize parm?
JE H_parm ;I parm detected..
Unrecog_parm: ; an illegal paramter:
MOV DX, offset Bad_Parm_Msg ;indicate illegal parm was found
MOV AH,09H ;DOS display string function
INT 21H
JMP SHORT ERR_Exit ;terminate with error level set
Illegal_P_2_Parms: ;User has entered both /P + /2
MOV DX, offset Bad_P_2_Msg ;indicate use of /P+/2 found
MOV AH,09H ;DOS display string function
INT 21H
JMP SHORT ERR_Exit ;terminate with error level set
P_parm:
CMP Partition2_wanted,'Y' ;Has user already selected /2
JE Illegal_P_2_Parms ; If so, give error message
MOV Partition_wanted,'Y' ;Indicate user wants partition table
LODSB ;Keep checking next character
JMP SHORT Check_Parm_chars_left ;Check for additional parms
B_parm:
MOV Boot_wanted,'Y' ;Indicate user wants boot record
LODSB ;Keep checking next character
JMP SHORT Check_Parm_chars_left ;Check for additional parms
I_parm:
MOV Initialize_mode,'Y' ;Force intialization mode
LODSB ;Keep checking next character
JMP SHORT Check_Parm_chars_left ;Check for additional parms
Two_parm: ;/2 parm (read partition on 2nd disk)
CMP Partition_wanted,'Y' ;Has user already selected /P
JE Illegal_P_2_Parms ; If so, give error message
MOV Partition_wanted,'Y' ;Indicate user wants a partition table
MOV Partition2_wanted,'Y' ;Indicate user wants 2nd partit table
INC Drive_number ;Read drive number 81 (2nd hard drive)
LODSB ;Keep checking next character
JMP SHORT Check_Parm_chars_left ;Check for additional parms
H_parm: ;Handle HELP request
CALL Get_Current_Screen_Atr ;Use user's choice of screen colors
MOV DX, offset Max_Help1 ;Give user detailed help information
CALL Display_Max_Help ;Clear screen/Displ HELP/wait for key
MOV DX, offset Max_Help2 ;Give user Help page 2
CALL Display_Max_Help
MOV DX, offset Max_Help3 ;Help page 3
CALL Display_Max_Help
CALL Clear_Screen
JMP SHORT Syntax_msg_only ;Give syntax summary
Err_Exit:
CALL Send_Beep ;Alert user to serious error!
CALL Wait_For_Key ;Beep and force user to hit a key
Syntax_msg_only:
MOV DX, offset Syntax_Msg ;show user correct syntax
Help_Display:
MOV AH,09H ;DOS display string function
INT 21H
MOV AX,4C80h ; terminate with 128 DOS ERRORLEVEL
INT 21h
SUBTTL Definition of Data structures
PAGE
;******************************************************************************;
;** Definition of Data areas follow **;
;******************************************************************************;
Boot_wanted DB 'N' ;Read DOS boot sector Y or N?
partition_wanted DB 'N' ;Read any Partition sector Y or N?
partition2_wanted DB 'N' ;Read part on 2nd disk Y or N?
Initialize_Mode DB 'N' ;Read DOS boot sector Y or N?
Current_Screen_Atr DB 07 ;Screen attribute to use for BIOS I/O
DOS_Version DB 00 ;Major version of DOS used (0 - 4)
Sector_Size DW 00 ;Number of bytes per sector
INT25_Parms LABEL BYTE ;DOS 4.0 INT25/26 parameter block
Sector_Number DD 00 ;DOS logical sector number to read
Sector_Count DW 01 ;Read 1 sector
Buffer_Offset DW OFFSET Buffer ;Buffer address - offset
Buffer_Segment DW 0 ; segment - set at run time
Missing_Msg DB 'Parameter file is missing. Creating a new copy...',CR,LF,'$'
PW_MSG DB 'Writing the parameter file.',CR,LF,'$'
BootW_MSG DB 'Writing "@@BOOT.SCT."',CR,LF,'$'
PartW_MSG DB 'Writing "@@PARTIT.SCT".',CR,LF,'$'
Init_Msg DB 'Executing in initialization mode. New files will be '
DB 'created. (.PRM + .SCT)',CR,LF,'$'
IO_ERR_Msg DB 'I/O error',CR,LF,'$'
No_hardDisk_MSG DB 'Partition sector not processed. Hard disk not found.'
DB CR,LF,'$'
BAD_Sector_Msg DB 'modification (system corruption) detected.',CR,LF,'$'
BadP_MSG DB 'Parameter file has been corrupted.',CR,LF,'$'
DB CR,LF,'$'
Part_Msg DB 'Partition sector ','$'
Boot_Msg DB 'DOS Boot sector ','$'
OK_Msg DB 'OK.',CR,LF,'$'
Parm_File_name DB 'CHKBOOT.PRM' ;ASCIIZ string of parameter file name
DB 64 DUP (0) ;Include space to handle path on file
Boot_File_name DB '@@BOOT.SCT',00 ;ASCIIZ string of boot sector file
Part_File_name DB '@@PARTIT.SCT',00 ;ASCIIZ string of partition file
Drive_number DW 80h ;Drive number for BIOS hard disk read
Parm_handle DW 00h ;File handle for parameter file
Parm_Buffer Label byte
Parm_header DB 'CHKBOOT-Author: Wolfgang Stiller:'
Boot_XOR_Sum DW 0000h ;Boot record exclusive or sum
Boot_CHK_Sum DW 0000h ;Boot record check sum
Part_XOR_Sum DW 0000h ;Partition record exclusive or sum
Part_CHK_Sum DW 0000h ;Partition record check sum
PARM_XOR_Sum DW 0000h ;Validity check for PARM_file itself
PARM_CHK_Sum DW 0000h ;Validity check for PARM_file itself
Hit_Key_MSG DB '-Hit any key-'
Hit_Key_MSG_end EQU $
Explanation LABEL BYTE
DB 'CHKBOOT will check the DOS boot record and/or the partition sector for '
DB 'any ',CR,LF
DB 'changes by using information recorded on the parameter file. On first'
DB CR,LF
DB 'execution, or with the "/I" parameter, CHKBOOT writes cryptographic '
DB 'check',CR,LF
DB 'values to the parameter file and creates reload files for the boot '
DB 'and',CR,LF
DB 'partition sectors. All files written contain self check information.'
DB CR,LF,LF
Syntax_Msg LABEL BYTE
DB 'Syntax is: CHKBOOT [filespec] [/B] [/H] [/I] [/P] [/2]',CR,LF
DB '"filespec" is optional file specification for the parameter file. If not'
DB CR,LF
DB ' specified, "CHKBOOT.PRM" will be used as the parameter file.'
DB CR,LF
DB ' "/H" Presents extensive detailed Help information.',CR,LF
DB ' "/B" Checks boot record on current DOS disk for any changes.',CR,LF
DB ' "/P" Checks partition sector on first physical hard disk for any '
DB 'changes.',CR,LF
DB ' "/2" Checks partition sector on second physical hard disk.'
DB CR,LF
DB ' /P and /2 may not be specified together.'
DB CR,LF
DB ' "/I" Force initialization. Attempts read of current boot sector and '
DB 'partition',CR,LF
DB ' sector on 1st hard drive (Include /2 for 2nd partition sector). '
DB 'CHKBOOT',CR,LF
DB ' then writes the parameter file so that any changes to these '
DB 'sectors can',CR,LF
DB ' be detected on subsequent executions. The boot and partition '
DB 'sectors are',CR,LF
DB ' copied to files: "@@BOOT.SCT" and "@@PARTIT.SCT" for "LODboot" '
DB 'reload.',CR,LF
Header_msg LABEL BYTE
DB UPLT_Corner,76 DUP(Horizontal),UPRT_Corner,CR,LF
DB vertical," CHKBOOT 1.0 ■ PCDATA TOOLKIT Copyright (c) 1990 Ziff "
DB "Communications Co. ",vertical,CR,LF
DB Vertical," PC Magazine ■ Wolfgang Stiller "
DB " ",vertical,CR,LF
DB LWLT_Corner,76 DUP(Horizontal),LWRT_Corner,CR,LF,'$'
Write_Buffer DB 'LODboot reload file. Copy me to a floppy.'
DB 'By Wolfgang Stiller',CR,LF
DW 0FFFFh ;Special boot/partition indicator
SCT_TYPE DB 0FFh ;Indicate if this is boot or part rec
; FF=Boot and 55=Partition sector
SCT_CHK DW 00h ;CHK SUM(boot when used for parm file
SCT_XOR DW 00h ;XOR SUM
Buffer label byte ;All storage + code following is in
; the input file buffer.
Bad_P_2_Msg DB '***SORRY***, /P may not be used with /2.',cr,lf,lf,'$'
Bad_Parm_Msg DB 'Unrecognized parameter detected.',cr,lf,'$'
Bad_DOS_MSG DB 'DOS 2.x or higher required.',CR,LF,'$'
Non_Std_Msg DB 'Note, sectors on this disk are not 512 bytes.',CR,LF,'$'
Max_Help1 DB 'The most difficult to detect type of damage (such as virus '
DB 'infection) is',CR,LF
DB 'corruption of either your DOS boot sector or the partition sector. '
DB 'CHKBOOT',CR,LF
DB 'will detect such damage if it happens, and give you the means to fix it'
DB CR,LF
DB 'with program LODboot.'
DB CR,LF,LF
DB 'What is a boot sector?'
DB CR,LF
DB 'The boot sector is sector 0 on a bootable DOS disk(ette). This sector '
DB 'contains',CR,LF
DB 'the initial program executed when DOS is first started or booted by '
DB 'the ',CR,LF
DB 'CNTL/ALT/DEL key combination. If this sector is damaged, you will have'
DB CR,LF
DB 'an unreliable or non-functioning operating system.'
DB CR,LF,LF
DB 'What is a partition sector (AKA: partition table)?'
DB CR,LF
DB 'If you have a hard (fixed) disk, each physical disk drive can be '
DB 'partitioned',CR,LF
DB 'into multiple logical disks. A table on the first sector of the disk '
DB 'contains',CR,LF
DB 'information on how the disk is partitioned. If the hard disk is '
DB 'bootable, then',CR,LF
DB 'the partition sector also contains a program that loads and executes '
DB 'the DOS',CR,LF
DB 'boot sector. If the partition sector is damaged, your hard disk '
DB 'may be unusable.$'
Max_Help2 DB 'What does CHKBOOT do?'
DB CR,LF,LF
DB '1)During initialization, it will read the boot record on '
DB 'the current disk and',CR,LF
DB ' attempt to read the partition record on the first hard disk ('
DB 'or the second',CR,LF
DB ' hard disk if "/2" is specified). Copies of these sectors will '
DB 'be written to',CR,LF
DB ' files: @@BOOT.SCT and @@PARTIT.SCT. CHKBOOT will use 2 '
DB 'different algorithms',CR,LF
DB ' to compute 32 bit cryptographic check signatures which uniquely '
DB CR,LF
DB ' characterize each sector. These cryptographic signatures will '
DB 'be further',CR,LF
DB ' encrypted and recorded on the parameter file.'
DB CR,LF,LF
DB '2)In normal use, CHKBOOT will read the parameter file and verify '
DB 'its integrity.',CR,LF
DB ' It will then read the boot and/or the partition sectors. '
DB 'The cryptographic',CR,LF
DB ' signatures will be calculated and compared with information '
DB 'stored on the',CR,LF
DB ' parameter file. If a change to the boot or partition sectors '
DB 'is detected,',CR,LF
DB ' the user will be notified.'
DB '$'
Max_Help3 DB 'How do you use CHKBOOT?'
DB CR,LF,LF
DB '1) Enter "CHKBOOT /I", in the root directory on any disks from '
DB 'which you boot',CR,LF
DB ' your PC. This forces initialization of the parameter file '
DB '("CHKBOOT.PRM")',CR,LF
DB ' and creates copies of the boot and partition sectors. If you '
DB 'boot from your',CR,LF
DB ' second hard disk, enter: "CHKBOOT /I/2".'
DB CR,LF,LF
DB '2) Create a bootable floppy (FORMAT A:/S), then copy '
DB '@@BOOT.SCT, @@PARTIT.SCT,',CR,LF
DB ' CHKBOOT.PRM, CHKBOOT.COM and LODBOOT.COM to it.',CR,LF,LF
DB '3) Modify your AUTOEXEC.BAT file to include:'
DB CR,LF
DB ' "CHKBOOT /B" - for floppy only systems or'
DB CR,LF
DB ' "CHKBOOT /B/P" for systems where you boot from the first '
DB 'hard drive or',CR,LF
DB ' "CHKBOOT /B/2" for systems where you boot from hard drive #2.'
DB CR,LF
DB ' If any changes are detected, CHKBOOT will beep, display a '
DB 'message and wait',CR,LF
DB ' for a key press. Program LODboot can be used to restore.'
DB CR,LF,LF
DB '4) Checking in the AUTOEXEC file may not be effective if a '
DB 'virus is already in',CR,LF
DB ' control, so also periodically issue the above command '
DB 'after booting from',CR,LF
DB ' the floppy created in step 2 above. For example, on the disk'
DB ' being checked,'
DB CR,LF
DB ' type:',CR,LF
DB ' "a:CHKBOOT a:CHKBOOT.PRM/B/P"',CR,LF
DB ' where "a:" is the floppy drive with the .PRM file.'
DB '$'
CSEG EndS
END CHKBOOT