Troubleshooting Missing or Corrupt Kernel Files

Materials:
Working complete PC
Blank Diskette
Student Diskette, "New Boot A Ver 2.0+"
Student CD-ROM, "Room 6359"
Objectives:
The student will become familiar with how to develop a complex batch file,
The student will learn how to build a batch file that can detect missing or corrupt files.
Competency:
The student will understand the nature and function of real mode batch files and batch file programming. In this exercise the student will develop a powerful set of batch files that can scan the entire Windows folder looking for missing or corrupted Windows kernel files and therefore once found be able to replace them and get Windows to boot up again.
Preparation
  1. Use Ghost to image the system with Windows 98. Boot to Command Prompt Only and change into the C:\WINDOWS\SYSTEM and do the following:

    C:\WINDOWS\SYSTEM>copy msgsrv32.exe msgsrv32.bak
     1 file(s) copied.
    C:\WINDOWS\SYSTEM>ren msgsrv32.exe msgsrv32.ex!
    C:\WINDOWS\SYSTEM>debug msgsrv32.ex!
    -f 100 110 0
    -w
     Writing 2E90 bytes
    -q
    C:\WINDOWS\SYSTEM>ren msgsrv32.ex! msgsrv32.exe
    C:\WINDOWS\SYSTEM>_
    

    At this point a core component of Windows has been corrupted. Launch Windows (by typing WIN[Enter]) and the system will respond with an infamous "Blue Screen of Death":





     Windows 

        A fatal exception 0D has occured at 0147:0000BC9D. The current
        application will be terminated.

        *  Press any key to terminate the current application.
        *  Press CTRL+ALT+DEL again to restart your computer. You will
           lose any unsaved information in all applications.

    Press any key to continue _




  2. Procedures
  3. Now that the system is trashed, a batch file will be developed that can check all system files by extracting the originals from the CABs and then it will perform binary comparisons between the originals from the CABs and the files that are currently part of the running operating system. Any discrepancies found would indicate a corrupted file. Some files get renamed during the installation and some files do not exist in the CABs and some do get modified by the Windows 98 installation. By accounting for all of these issues, if a file still slips through as changed then it would certainly be the strongest possible cause of the blue screen and would be replaced.

  4. First the batch file will have to be able list of all of the files in the operating system installation folder. The batch file does not have to check text files since the primary assumption is corrupted code. Therefore it will have to list only machine language files from the WINDOWS folder. Then it will have to extract these from the CABs and then finally it will have to perform the binary file comparison between the fresh one extracted from the CABs and the original copy on the hard drive. The batch file would then have to report any discrepancies.

  5. To make the batch file universal, it should be made on a bootable diskette. The image of which can be burned into a bootable CD-ROM as well. Copy CHOICE.COM, FC.EXE, FIND.EXE, HIMEM.SYS, SMARTDRV.EXE, OAKCDROM.SYS, MSCDEX.EXE and XMSDSK.EXE to the floppy. Setup the floppy to launch all drivers and an 8MB ramdrive and an 8MB smartdrv buffer: CONFIG.SYS:

    device=himem.sys
    device=oakcdrom.sys /d:CD01
    
    AUTOEXEC.BAT:
    mscdex.exe /d:CD01 /L:Q
    xmsdsk 8192 K: /y /t
    smartdrv 8192 C+ 
    set TMP=K:\
    set TEMP=K:\
    path=K:\
    copy . K:\
    
  6. Now the floppy can be used to access a Windows 98 OEM CD-ROM to perform the operation. The batch file will take two parameters: the location of the windows %systemroot% folder and the location of the installation CABs. Open EDIT.COM or Notepad and start the batch file with these lines:

    @echo off
    rem check for passed params:
    rem  param1 = Windows folder
    rem  param2 = Source CABs folder
    if %1z==z goto help
    if %2z==z goto help
    rem at this point the params will be checked for validity
    if not exist %1\WIN.COM goto help2
    if not exist %2\BASE4.CAB goto help2
    rem at this point the folders exist so proceed
    rem set environmental variables
    SET WINDIR=%1
    SET CABDIR=%2
    rem the following is needed to initialize the variable to nothing on a second run
    SET CURRDIR=
    rem create the working folders on the RAM drive
    MD K:\TEMP
    MD K:\CABS
    MD K:\RPTS
    
  7. Now for the working code. The batch file must change into the Windows directory and process every EXE by copying it to a temporary folder, then extract the original from the CABs then do the binary file comparison and then append a report file, then do the next task. The tasks are complicated enough that the best course of action in this case is to call another batch file that will handle this series of jobs. The other job handler looks like this:

    @echo off 
    rem Check for VMM32.VXD which can crash the commandline redirection and is known
    rem to be different from the one in the CABs anyway
    if %1z==VMM32.VXDz goto avoid
    echo Testing %WINDIR%%CURRDIR%\%1...
    K:
    cd \CABS
    extract /a %CABDIR%\BASE4.CAB %1 | find /c /i "no matching" | choice /n /c:01 > nul
    if errorlevel 2 goto notincab
    rem if it reaches here then the file was in the CABs
    copy %WINDIR%%CURRDIR%\%1 \TEMP > nul
    fc /b \TEMP\%1 %1 | find /c /i "no differences" | choice /n /c:01 > nul
    if errorlevel 2 goto end
    rem if it reaches here then the file is different
    echo %WINDIR%%CURRDIR%\%1 >> K:\RPTS\DIFF.RPT
    goto end
    :notincab
    echo %WINDIR%%CURRDIR%\%1 >> K:\RPTS\NOTINCAB.RPT
    :end
    if exist %1 del %1
    if exist \TEMP\%1 del \TEMP\%1
    :avoid
    C:
    cd %windir%%currdir%
    

    Save this file as JOB.BAT on the floppy. Now the loop operation can call this batch file to work on each machine language file one at a time looking for a corrupt file.

  8. Back in the original batch file add this code:

    @echo off
    rem check for passed params:
    rem  param1 = Windows folder
    rem  param2 = Source CABs folder
    if %1z==z goto help
    if %2z==z goto help
    rem at this point the params will be checked for validity
    if not exist %1\WIN.COM goto help2
    if not exist %2\BASE4.CAB goto help2
    rem at this point the folders exist so proceed
    rem set environmental variables
    SET WINDIR=%1
    SET CABDIR=%2
    rem the following is needed to initialize the variable to nothing on a second run
    SET CURRDIR=
    rem create the working folders on the RAM drive
    MD K:\TEMP
    MD K:\CABS
    MD K:\RPTS
    
    REM ADD THE FOLLOWING:
    
    C:
    cd %windir%
    echo Checking executable OS components in %windir%
    for %%I in (*.EXE) do call job %%I
    for %%I in (*.DLL) do call job %%I
    for %%I in (*.COM) do call job %%I
    for %%I in (*.SYS) do call job %%I
    for %%I in (*.386) do call job %%I
    for %%I in (*.VXD) do call job %%I
    for %%I in (*.PDR) do call job %%I
    for %%I in (*.DRV) do call job %%I
    echo Checking executable OS components in %windir%\SYSTEM
    cd %windir%\system
    set CURRDIR=\SYSTEM
    for %%I in (*.EXE) do call job %%I
    for %%I in (*.DLL) do call job %%I
    for %%I in (*.COM) do call job %%I
    for %%I in (*.SYS) do call job %%I
    for %%I in (*.386) do call job %%I
    for %%I in (*.VXD) do call job %%I
    for %%I in (*.PDR) do call job %%I
    for %%I in (*.DRV) do call job %%I
    echo Checking executable OS components in %windir%\SYSTEM32
    cd %windir%\system32
    set CURRDIR=\SYSTEM32
    for %%I in (*.EXE) do call job %%I
    for %%I in (*.DLL) do call job %%I
    for %%I in (*.COM) do call job %%I
    for %%I in (*.SYS) do call job %%I
    for %%I in (*.386) do call job %%I
    for %%I in (*.VXD) do call job %%I
    for %%I in (*.PDR) do call job %%I
    for %%I in (*.DRV) do call job %%I
    echo Checking executable OS components in %windir%\SYSTEM\IOSUBSYS
    cd %windir%\system\iosubsys
    set CURRDIR=\SYSTEM\IOSUBSYS
    for %%I in (*.EXE) do call job %%I
    for %%I in (*.DLL) do call job %%I
    for %%I in (*.COM) do call job %%I
    for %%I in (*.SYS) do call job %%I
    for %%I in (*.386) do call job %%I
    for %%I in (*.VXD) do call job %%I
    for %%I in (*.PDR) do call job %%I
    for %%I in (*.DRV) do call job %%I
    echo Checking executable OS components in %windir%\SYSTEM\VMM32
    cd %windir%\system\vmm32
    set CURRDIR=\SYSTEM\VMM32
    for %%I in (*.EXE) do call job %%I
    for %%I in (*.DLL) do call job %%I
    for %%I in (*.COM) do call job %%I
    for %%I in (*.SYS) do call job %%I
    for %%I in (*.386) do call job %%I
    for %%I in (*.VXD) do call job %%I
    for %%I in (*.PDR) do call job %%I
    for %%I in (*.DRV) do call job %%I
    echo Operation complete...
    K:
    pause
    echo Files in which differences were detected:
    type \RPTS\DIFF.RPT | more
    pause
    echo Files not found in the CABs:
    type \RPTS\NOTINCAB.RPT | more
    goto end
    :help
    echo SYNTAX:
    echo.
    echo FILECHK WINDIR CABDIR
    echo Where:
    echo  WINDIR location of Windows; must be a full absolute path
    echo  CABDIR location of the CABs; must be a full absolute path
    echo.
    echo EXAMPLE:
    echo.
    echo FILECHK C:\WINDOWS D:\WIN98
    goto end
    :help2
    echo Either %1\WIN.COM or %2\BASE4.CAB is missing.
    :end
    

    Save the batch file to the floppy and be sure that it is bootable and all of the above components are on the floppy as well. Boot to the floppy and then run FILECHK.BAT from the commandline. Even with smartdrv and a ram drive extract.exe grinds through the CABs very slowly and the batch file can take a very long time to process all of the files. When it is finished it will pause the process and then display the report files on screen.

  9. This file checker does not take into account service packs, files replaced by software, or Microsoft patches which all change the original files which will report differences. Over time these can range into the hundreds. By the way these "legitimate" changes can indeed be the cause of the blue screen!

  10. After running the file on the test system the contents of DIFF.RPT appear as follows:

    C:\WINDOWS\SETVER.EXE 
    C:\WINDOWS\SYSTEM\MSGSRV32.EXE 
    C:\WINDOWS\SYSTEM\USER.EXE 
    C:\WINDOWS\SYSTEM\MAPI32.DLL 
    
  11. Note that SETVER.EXE will always be different. It violates the #1 rule of good coding: it is a self-modifying program and stores the SETVER list within itself. MS saw the folly of their ways and never did this again. Programs save such information in *.INI files and then later the Registry. MAPI32.DLL is another mysterious file that ends up different. USER.EXE is a concern and of course MSGSRV32.EXE is the file that was damaged. Here is the list of files that are known to be modified from their originals in the CABs:

    C:\WINDOWS\SETVER.EXE 
    C:\WINDOWS\SYSTEM\VMM32.VXD 
    C:\WINDOWS\SYSTEM\MAPI32.DLL 
    

    NOTE: This list is preliminary (incomplete) at this time.

  12. Any file not in the CABs came from one of four possible places: 1) It is in the WIN98 folder uncompressed or 2) It was created by the installation routine like VMM32.VxD, 3) It is renamed during install and has a different name in the CABs, 4) It is a third party addition or a microsoft update (service pack, etc). JOB.BAT can be modified to account for the possibility that the file is in the CABs folder uncompressed:

    @echo off
    if %1z==VMM32.VXDz goto avoid
    echo Testing %WINDIR%%CURRDIR%\%1...
    K:
    cd \CABS
    extract /a %CABDIR%\BASE4.CAB %1 | find /c /i "no matching" | choice /n /c:01 > nul
    if errorlevel 2 goto notincab
    rem if it reaches here then the file was in the CABs
    copy %WINDIR%%CURRDIR%\%1 \TEMP\%1 > nul
    fc /b \TEMP\%1 %1 | find /c /i "no differences" | choice /n /c:01 > nul
    if errorlevel 2 goto end
    rem if it reaches here then the file is different
    :diff
    echo %WINDIR%%CURRDIR%\%1 >> K:\RPTS\DIFF.RPT
    goto end
    :notincab 
    if not exist %CABDIR%\%1 goto notncab2
    copy %WINDIR%%CURRDIR%\%1 \TEMP\%1 > nul
    copy %CABDIR%\%1 . > nul
    fc /b \TEMP\%1 %1 | find /c /i "no differences" | choice /n /c:01 > nul
    if errorlevel 2 goto end
    rem gets here then it was in CABDIR but different
    goto diff
    :notncab2
    echo %WINDIR%%CURRDIR%\%1 >> K:\RPTS\NOTINCAB.RPT
    :end
    if exist %1 del %1
    if exist \TEMP\%1 del \TEMP\%1
    :avoid
    C:
    cd %windir%%currdir%
    
  13. You can add other files to the avoid process of JOB.BAT. Here is SETVER.EXE and MAPI32.DLL being avoided:

    @echo off
    if %1z==VMM32.VXDz goto avoid
    if %1z==SETVER.EXEz goto avoid
    if %1z==MAPI32.DLLz goto avoid
    echo Testing %WINDIR%%CURRDIR%\%1...
    K:
    cd \CABS
    extract /a %CABDIR%\BASE4.CAB %1 | find /c /i "no matching" | choice /n /c:01 > nul
    if errorlevel 2 goto notincab
    rem if it reaches here then the file was in the CABs
    copy %WINDIR%%CURRDIR%\%1 \TEMP\%1 > nul
    fc /b \TEMP\%1 %1 | find /c /i "no differences" | choice /n /c:01 > nul
    if errorlevel 2 goto end
    rem if it reaches here then the file is different
    :diff
    echo %WINDIR%%CURRDIR%\%1 >> K:\RPTS\DIFF.RPT
    goto end
    :notincab 
    if not exist %CABDIR%\%1 goto notncab2
    copy %WINDIR%%CURRDIR%\%1 \TEMP\%1 > nul
    copy %CABDIR%\%1 . > nul
    fc /b \TEMP\%1 %1 | find /c /i "no differences" | choice /n /c:01 > nul
    if errorlevel 2 goto end
    rem gets here then it was in CABDIR but different
    goto diff
    :notncab2
    echo %WINDIR%%CURRDIR%\%1 >> K:\RPTS\NOTINCAB.RPT
    :end
    if exist %1 del %1
    if exist \TEMP\%1 del \TEMP\%1
    :avoid
    C:
    cd %windir%%currdir%
    
  14. All files that get listed in NOTINCAB.RPT at this point are either added to the system, created by setup, or have been renamed by setup. Here is the list of files that setup renames:

    In the CABs becomes this On the HDD
    SHELL.NEW   SHELL.DLL
    VER.NEW   VER.DLL

    NOTE: This list is preliminary (incomplete) at this time.

  15. The AUTOEXEC.BAT automatically copies all files from the floppy to the root of the RAM drive and sets the PATH to point there. This allows both batch files and all executables to run from the much faster RAM drive than from the very slow floppy disk. The reports are also stored in the RPTS directory of the RAM drive. Files are copied from the hard drive to the RAM drive and they are decompressed from the CABs to the RAM drive, then the copy of the original and the newly decompressed files are compared on the RAM drive. All of this has been done to make the tools work as fast as possible with the caveat that if the file is corrupt and cannot be copied to the RAM drive, then the problem has possibly been found, but these tools will not record that event. The technician will have to record the file names that fail to copy AND use the [F]ail choice when prompted with the "Abort, Retry, Fail?" choices. Also if the batch files crash at any point then the reports will be lost, but since this all runs many times faster than keeping the reports on the floppy, the risk is worth it. Change to the K: drive and type: FILECHK C:\WINDOWS Q:\WIN98SE if working with the lab systems. The process takes about 2 hours on the lab systems which have rather old and slow non-UDMA hard drives.

  16. Here is a file list from NOTINCAB.RPT run on a pristine installation of Windows 98 Second Edition with no other software installed:

    WSOCK32.DLL 
    CFGWIZ.DLL 
    CFGWIZ32.EXE 
    DINDI.DLL 
    DLCNDI.DLL 
    INFRARED.DLL 
    ISSETUP.DLL 
    MSTCP.DLL 
    NDSWAN16.DLL 
    NDSWAN32.DLL 
    NETAPI.DLL 
    NETDI.DLL 
    NETOS.DLL 
    NWNDS.DLL 
    PPPNDI.DLL 
    RNASETUP.DLL 
    DSKMAINT.DLL 
    COMMCTRL.DLL 
    LZEXPAND.DLL 
    MSPRINT.DLL 
    MSPRINT2.DLL 
    SYSDETMG.DLL 
    SUCATREG.EXE 
    SETUPX.DLL 
    COMMDLG.DLL 
    SHELL.DLL 
    VER.DLL 
    ICMFIL~1.DLL 
    MSJETO~1.DLL 
    MAPI32X.DLL 
    HWINFOD.VXD 
    
  17. How to find a file that is "not in the CAB's"

    This list will take a while to complete. In the meantime here is how to find the renamed files for yourself. The key is the file's size. It may not be unique because all of the components of Windows are aligned. However, here is how to search the CABs for a renamed file. First read NOTINCAB.RPT and choose one, in this example SHELL.DLL will be used. Now run DIR for the file to get its size:

    C:\>dir shell.dll /s
     Volume in drive C has no label
     Volume Serial Number is 0630-1AE0
    Directory of C:\WINDOWS\SYSTEM
    SHELL    DLL       126,704  01-07-98  8:11p
             1 file(s)        126,704 bytes
    Total files listed:
             1 file(s)        126,704 bytes
             0 dir(s)   1,698,824,192 bytes free
    C:|>_
    
  18. The file is 126,704 bytes in size. Now run extract so that it will display the contents of all of the CABs and PIPE the output through the FIND filter looking for this file size report text:

    C:\>extract /a /d c:\win98\base4.cab | find "126,704"
    04-23-1999 10:22:00p A---       126,704 shell.new
    C:\>_
    

    And there it has been revealed that the file SHELL.DLL is stored in the CABs under the alias SHELL.NEW.

  19. The modified file checker for the Windows NT Family will be included in a future module linked here.

Back to Page Top

Copyright©2000-2006 Brian Robinson ALL RIGHTS RESERVED