Announcement

Collapse

Forum Guidelines

This forum is for finished source code that is working properly. If you have questions about this or any other source code, please post it in one of the Discussion Forums, not here.
See more
See less

PBCC and PBDLL: Rebase EXEs and DLLs

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • PBCC and PBDLL: Rebase EXEs and DLLs

    [UPDATED 11-Sep-2000 - see change history in code]
    [UPDATED 08-Jul-2000 - see change history in code]
    [UPDATED 07-Jul-2000 - see change history in code]

    Hi

    I know that this issue has been thrashed out a few times but I've
    got an application suite which consists of an executable and
    any number of plugins (dlls) which are dynamically loaded
    at the start.

    I was not so concerned about load times but I was concerned that
    with all my dlls based at the same address as the executable
    (0x00400000) that this might increase page faults at run-time.

    So I put together a rebase utility which also serves as a basic
    example of using the VERY useful imagehlp.dll.

    The utility accepts either a "batch file" consisting of names
    of dlls to rebase or the name of an excutable or dll to rebase.
    Additionally you can specify the start address on the command line
    (see usage for details).

    The way I use it is to rebase all dlls (not the executable) in my
    application suite using a simple algorithm based on the first letter
    of the dll. If there is a conflict with a couple of rebased dlls
    I rebase the dll individually, specifying a new start address
    offset.

    Disclaimer: this code requires the imagehlp.dll which comes with
    the SDK or WinNt. It's probably included with Win98 and is available
    as a redistributable download for Win95 from Microsoft (don't know
    the address). THIS CODE HAS ONLY BEEN TESTED ON NT - USE AT YOUR
    OWN RISK. YMMV

    Code:
    #IF 0
    ************************************************************************************
    * ' REBASE.BAS: A PB rebasing tool - reads a file comprised of a list of files
    * '            to rebase and attempts to rebase them according to a simple
    * '            algorithm based on filenames. It logs all successful rebases
    * '            to rebase.log - to view usage enter run rebase.exe without
    * '            parameters.
    * '
    * '            Rebase.exe logs output to rebase.log
    * '
    * '            The structure of the file passed should look like (1 line per file):
    * '
    * '            c:\pbdll60\talkbox.dll
    * '            c:\pbdll60\helper.dll
    * '            c:\pbdll60\mem.dll
    * '
    * ' Note        : This file uses the imagehlp.dll to retrieve information and
    * '               rebase files. The imagehlp.dll comes with NT and probably
    * '               Win98 - it is available as a redistributable file for Win95
    * '
    * ' Written     : Florent Heyworth
    * ' Date        : 07-Jul-2000
    * ' Last edit   : 11-Sep-2000
    * ' Version     : 0.0.2
    * '
    * ' Change history (most recent change last):
    * '                 + 07-Jul-2000: added test for location of input "batch" file
    * '                 + 07-Jul-2000: added TRIM$() to command line option tests
    * '                 + 08-Jul-2000: changed return for RebaseImage, MapAndLoad
    * '                   to LONGs and GetFileTitle to INTEGER. The return types for
    * '                   RebaseImage and MapAndLoad were defined as BOOL (LONG) and
    * '                   not BOOLEAN (BYTE). This is for correctness - the functions
    * '                   were working fine before
    * '                 + 11-Sep-2000: update declaration for T_LOADED_IMAGE since the
    * '                   tLinks entry was incorrectly defined. While the rebasing worked
    * '                   fine the code didn't report the file size correctly due to the
    * '                   invalid size of the T_LOADED_IMAGE.tLinks entry (redefined as a pointer)
    * '                   to a tLinks structure
    ************************************************************************************
    #ENDIF
    
     
    #IF NOT %DEF(%WINAPI)
    #INCLUDE "win32api.inc"
    #ENDIF
    
     
    %FROM_ADDR = &H60000000& 'Start of user application address space
    %MAX_ADDR = &H68000000&   'End of user application address space
    %MIN_ADDR = &H10000000&
    %INCR_BY = &H1000000& 'increment by
     
    'START of imagehlp.dll declares (incomplete)
    %IMAGE_SIZEOF_SHORT_NAME = 8
    %IMAGE_NUMBEROF_DIRECTORY_ENTRIES = 16
     
    %IMAGE_DOS_SIGNATURE = &H5A4D ' MZ
    %IMAGE_OS2_SIGNATURE = &H454E ' NE
    %IMAGE_OS2_SIGNATURE_LE = &H454C ' LE
    %IMAGE_VXD_SIGNATURE = &H454C ' LE
    %IMAGE_NT_SIGNATURE = &H00004550 ' PE00
     
    %SYMNONE    = 0
    %SYMCOFF    = 1
    %SYSCV      = 2
    %SYMPDB     = 3
    %SYMEXPORT  = 4
    %SYMDEFERRED= 5
    %SYSSYM     = 6
     
    %IMAGE_FILE_RELOCS_STRIPPED           = &H0001  ' Relocation info stripped FROM file.
    %IMAGE_FILE_EXECUTABLE_IMAGE          = &H0002  ' File is executable  (i.e. no unresolved externel references).
    %IMAGE_FILE_LINE_NUMS_STRIPPED        = &H0004  ' LINE nunbers stripped FROM file.
    %IMAGE_FILE_LOCAL_SYMS_STRIPPED       = &H0008  ' LOCAL symbols stripped FROM file.
    %IMAGE_FILE_AGGRESIVE_WS_TRIM         = &H0010  ' Agressively trim working SET
    %IMAGE_FILE_LARGE_ADDRESS_AWARE       = &H0020  ' App can HANDLE >2gb addresses
    %IMAGE_FILE_BYTES_REVERSED_LO         = &H0080  ' Bytes OF machine WORD are reversed.
    %IMAGE_FILE_32BIT_MACHINE             = &H0100  ' 32 BIT WORD machine.
    %IMAGE_FILE_DEBUG_STRIPPED            = &H0200  ' Debugging info stripped FROM file IN .DBG file
    %IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP   = &H0400  ' IF Image is ON removable media, copy AND run FROM the SWAP file.
    %IMAGE_FILE_NET_RUN_FROM_SWAP         = &H0800  ' IF Image is ON Net, copy AND run FROM the SWAP file.
    %IMAGE_FILE_SYSTEM                    = &H1000  ' System File.
    %IMAGE_FILE_DLL                       = &H2000  ' File is a DLL.
    %IMAGE_FILE_UP_SYSTEM_ONLY            = &H4000  ' File should only be run ON a UP machine
    %IMAGE_FILE_BYTES_REVERSED_HI         = &H8000  ' Bytes OF machine WORD are reversed.
     
    %IMAGE_FILE_MACHINE_UNKNOWN           = 0
    %IMAGE_FILE_MACHINE_I386              = &H014c  ' Intel 386.
    %IMAGE_FILE_MACHINE_R3000             = &H0162  ' MIPS little-endian, = &H160 big-endian
    %IMAGE_FILE_MACHINE_R4000             = &H0166  ' MIPS little-endian
    %IMAGE_FILE_MACHINE_R10000            = &H0168  ' MIPS little-endian
    %IMAGE_FILE_MACHINE_WCEMIPSV2         = &H0169  ' MIPS little-endian WCE v2
    %IMAGE_FILE_MACHINE_ALPHA             = &H0184  ' Alpha_AXP
    %IMAGE_FILE_MACHINE_POWERPC           = &H01F0  ' IBM PowerPC Little-Endian
    %IMAGE_FILE_MACHINE_SH3               = &H01a2  ' SH3 little-endian
    %IMAGE_FILE_MACHINE_SH3E              = &H01a4  ' SH3E little-endian
    %IMAGE_FILE_MACHINE_SH4               = &H01a6  ' SH4 little-endian
    %IMAGE_FILE_MACHINE_ARM               = &H01c0  ' ARM Little-Endian
    %IMAGE_FILE_MACHINE_THUMB             = &H01c2
    %IMAGE_FILE_MACHINE_IA64              = &H0200  ' Intel 64
    %IMAGE_FILE_MACHINE_MIPS16            = &H0266  ' MIPS
    %IMAGE_FILE_MACHINE_MIPSFPU           = &H0366  ' MIPS
    %IMAGE_FILE_MACHINE_MIPSFPU16         = &H0466  ' MIPS
    %IMAGE_FILE_MACHINE_ALPHA64           = &H0284  ' ALPHA64
    %IMAGE_FILE_MACHINE_AXP64             = %IMAGE_FILE_MACHINE_ALPHA64
    
     
    TYPE T_IMAGEHLP_MODULE
         dwSizeOfStruct AS DWORD 'Set to SIZEOF(T_IMAGEHLP_MODULE)
         dwBaseOfImage AS DWORD
         dwImageSize AS DWORD
         dwCheckSum AS DWORD
         lSymType AS LONG
         szModuleName AS ASCIIZ * 32
         szImageName AS ASCIIZ * %MAX_PATH
         szLoadedImageName AS ASCIIZ * %MAX_PATH
    END TYPE
     
    TYPE T_IMAGE_DATA_DIRECTORY
         dwVirtualAddress AS DWORD
         dwSize AS DWORD
    END TYPE
     
    TYPE T_IMAGE_OPTIONAL_HEADER32
         'Standard fields
         wMagic AS WORD
         bMajorLinkerVersion AS BYTE
         bMinorLinkerVersion AS BYTE
         dwSizeOfCode AS DWORD
         dwSizeOfInitializedData AS DWORD
         dwSizeOfUninitializedData AS DWORD
         dwAddressOfEntryPoint AS DWORD
         dwBaseOfCode AS DWORD
         dwBaseOfData AS DWORD
         'Nt optional fields
         dwImageBase AS DWORD
         dwSectionAlignement AS DWORD
         dwFileAlignment AS DWORD
         wMajorOperatingSystemVersion AS WORD
         wMinorOperatingSystemVersion AS WORD
         wMajorImageVersion AS WORD
         wMinorImageVersion AS WORD
         wMajorSubsystemVersion AS WORD
         wMinorSubsystemVersion AS WORD
         dwWin32VersionValue AS DWORD
         dwSizeOfImage AS DWORD
         dwSizeOfHeader AS DWORD
         dwCheckSum AS DWORD
         wSubsystem AS WORD
         wDllCharacteristics AS WORD
         dwSizeOfStackReserve AS DWORD
         dwSizeOfStackCommit AS DWORD
         dwSizeOfHeapReserve AS DWORD
         dwSizeOfHeapCommit AS DWORD
         dwLoaderFlags AS DWORD
         dwNumberOfRvaAndSizes AS DWORD
         tDataDirectory(%IMAGE_NUMBEROF_DIRECTORY_ENTRIES) AS T_IMAGE_DATA_DIRECTORY
    END TYPE
     
    TYPE T_IMAGE_FILE_HEADER
         wMachine AS WORD
         wNumberOfSections AS WORD
         dwTimeDateStamp AS DWORD
         dwPointerToSymbolsTable AS DWORD
         dwNumberOfSymbols AS DWORD
         wSizeOfOptionalHeader AS WORD
         wCharacteristics AS WORD
    END TYPE
     
    TYPE T_IMAGE_NT_HEADERS
         dwSignature AS DWORD
         tImageFileHeader AS T_IMAGE_FILE_HEADER
         tOptionalHeader AS T_IMAGE_OPTIONAL_HEADER32
    END TYPE
     
    UNION U_VT_ADDRESS
         dwPhysicalAddress AS DWORD
         dwVirtualSize AS DWORD
    END UNION
     
    TYPE T_IMAGE_SECTION_HEADER
         pszName AS ASCIIZ PTR
         uMisc AS U_VT_ADDRESS
         dwVirtualAddress AS DWORD
         dwPointerToRawData AS DWORD
         dwPointerToRelocations AS DWORD
         dwNumberOfRelocations AS DWORD
         dwNumberOfLineNumbers AS DWORD
         dwCharacteristics AS DWORD
    END TYPE
     
    TYPE T_LIST_ENTRY
         tFlink AS T_LIST_ENTRY PTR
         tBlink AS T_LIST_ENTRY PTR
    END TYPE
     
    TYPE T_LOADED_IMAGE
         pszModuleName AS ASCIIZ PTR
         lFileHandle AS LONG
         dwMappedAddress AS DWORD
         tFileHeader AS T_IMAGE_NT_HEADERS PTR
         tLastRvaSection AS T_IMAGE_SECTION_HEADER PTR
         dwNumberOfSections AS DWORD
         tSections AS T_IMAGE_SECTION_HEADER PTR
         dwCharacteristics AS DWORD
         lfSystemImage AS LONG
         lfDOSImage AS LONG
         tLinks AS T_LIST_ENTRY PTR
         dwSizeOfImage AS DWORD
    END TYPE
    
    
     
    DECLARE FUNCTION ReBaseImage LIB "imagehlp.dll" ALIAS "ReBaseImage" ( szCurrentImageName AS ASCIIZ, _
                                                                          szSymbolPath AS ASCIIZ, _
                                                                          BYVAL bfRebase AS BYTE, _
                                                                          BYVAL bfRebaseSysfileOk AS BYTE, _
                                                                          BYVAL bfGoingDown AS BYTE, _
                                                                          BYVAL dwCheckImageSize AS DWORD, _
                                                                          BYVAL pdwOldImageSize AS DWORD, _
                                                                          BYVAL pdwOldImageBase AS DWORD, _
                                                                          BYVAL pdwNewImageSize AS DWORD, _
                                                                          BYVAL pdwNewImageBase AS DWORD, _
                                                                          BYVAL dwTimeStamp AS DWORD  ) AS LONG
     
    DECLARE FUNCTION MapAndLoad LIB "imagehlp.dll" ALIAS "MapAndLoad" ( szImageName AS ASCIIZ, _
                                                                        szDllPath AS ASCIIZ, _
                                                                        tLoadedImage AS T_LOADED_IMAGE, _
                                                                        BYVAL bfDotDll AS BYTE, _
                                                                        BYVAL bfReadOnly AS BYTE ) AS LONG
     
    DECLARE FUNCTION UnMapAndLoad LIB "imagehlp.dll" ALIAS "UnMapAndLoad" ( tLoadedImage AS T_LOADED_IMAGE ) AS LONG
    'END of imagehlp.dll declares (incomplete)
     
    'not part of imagehlp.dll
    DECLARE FUNCTION GetFileTitle LIB "comdlg32.dll" ALIAS "GetFileTitleA" ( szFilePath AS ASCIIZ, _
                                                                            szFileName AS ASCIIZ, _
                                                                            BYVAL dwSize AS WORD ) AS INTEGER
     
    SUB tell ( szMessage AS ASCIIZ )
     
       #IF %DEF(%pb_cc32)
       STDOUT szMessage
       #ELSEIF %DEF(%pb_dll32)
       IF LEN(szMessage) > 0 THEN
          MSGBOX szMessage
       END IF
       #ENDIF
     
    END SUB
     
    SUB logfile( BYVAL lFileHandle AS LONG, szMessage AS ASCIIZ )
     
       PRINT #lFileHandle, szMessage
     
    END SUB
     
    FUNCTION rebase( BYVAL lFileHandle AS LONG, BYVAL dwFromAddr AS DWORD, szFilePath AS ASCIIZ ) AS LONG
       'Returns %FALSE on failure, %TRUE if successful
       LOCAL lResult AS LONG
       LOCAL lHandle AS LONG
       LOCAL dwOldImageSize AS DWORD
       LOCAL dwOldImageBase AS DWORD
       LOCAL dwNewImageSize AS DWORD
       LOCAL dwNewImageBase AS DWORD
       LOCAL dwCompare AS DWORD
       LOCAL iResult AS INTEGER
       LOCAL sDebugInfo AS STRING
       LOCAL tLoadedImage AS T_LOADED_IMAGE
       LOCAL tFindData AS WIN32_FIND_DATA
       LOCAL szBuffer AS ASCIIZ * %MAX_PATH
     
       lHandle = FindFirstFile( szFilePath, tFindData )
       IF lHandle = %INVALID_HANDLE_VALUE THEN
          CALL tell( "Could not locate " + szFilePath )
          CALL logfile( lFileHandle, "Could not locate " + szFilePath )
          FUNCTION = %FALSE
          EXIT FUNCTION
       END IF
       CALL FindClose( lHandle )
     
       lResult = MapAndLoad( szFilePath, _
                              BYVAL %NULL, _
                              tLoadedImage, _
                              %FALSE, _
                              %TRUE )
     
       IF ISFALSE(lResult) OR [email protected] <> %IMAGE_NT_SIGNATURE THEN
          CALL tell( szFilePath + " is not a valid PE file" )
          FUNCTION = %FALSE
          GOTO Unload
       END IF
     
       CALL logfile( lFileHandle, STRING$( LEN([email protected]), "-" ) )
       CALL logfile( lFileHandle, [email protected] + $CRLF + STRING$( LEN([email protected]), "-" ) )
       CALL logfile( lFileHandle, "Load Address             : 0x" + HEX$([email protected] , 8) )
       CALL logfile( lFileHandle, "File Size                : " + FORMAT$(tLoadedImage.dwSizeOfImage) )
       CALL logfile( lFileHandle, "Timestamp                : 0x" + HEX$([email protected], 8) )
       CALL logfile( lFileHandle, "Checksum                 : 0x" + HEX$([email protected], 8) )
       CALL logfile( lFileHandle, "Symbol count             : " + FORMAT$([email protected]) )
     
       'Get image characteristics
       IF %IMAGE_FILE_DEBUG_STRIPPED = (%IMAGE_FILE_DEBUG_STRIPPED AND tLoadedImage.dwCharacteristics ) THEN
          sDebugInfo = "Yes"
       ELSE
          sDebugInfo = "No"
       END IF
       IF %IMAGE_FILE_32BIT_MACHINE = (%IMAGE_FILE_32BIT_MACHINE AND tLoadedImage.dwCharacteristics) THEN
          CALL logfile( lFileHandle, "32 Bit machine           : Yes" )
       END IF
       CALL logfile( lFileHandle, "File debug info stripped : " + sDebugInfo )
       IF %IMAGE_FILE_DLL = (%IMAGE_FILE_DLL AND tLoadedImage.dwCharacteristics) THEN
          CALL logfile( lFileHandle, "File is a                : Dll" )
       END IF
       IF %IMAGE_FILE_EXECUTABLE_IMAGE = (%IMAGE_FILE_EXECUTABLE_IMAGE AND tLoadedImage.dwCharacteristics) THEN
          CALL logfile( lFileHandle, "File is executable       : Yes")
       END IF
     
       'Get file name from path
       iResult = GetFileTitle( szFilePath, szBuffer, SIZEOF(szBuffer) )
       IF iResult <> 0 THEN
          CALL tell( "Could not retrieve file name for : " + szFilePath )
       END IF
     
       IF dwFromAddr = 0 THEN
          dwFromaddr = %FROM_ADDR
       END IF
     
       SELECT CASE ASC(MID$(LCASE$(szBuffer), 1, 1))
              CASE 97 TO 99
                   dwNewImageBase = dwFromaddr
              CASE 100 TO 102
                   dwNewImageBase = dwFromaddr + %INCR_BY * 1
              CASE 103 TO 105
                   dwNewImageBase = dwFromaddr + %INCR_BY * 2
              CASE 106 TO 108
                   dwNewImageBase = dwFromaddr + %INCR_BY * 3
              CASE 109 TO 111
                   dwNewImageBase = dwFromaddr + %INCR_BY * 4
              CASE 112 TO 114
                   dwNewImageBase = dwFromaddr + %INCR_BY * 5
              CASE 115 TO 117
                   dwNewImageBase = dwFromaddr + %INCR_BY * 6
              CASE 118 TO 120
                   dwNewImageBase = dwFromaddr + %INCR_BY * 7
              CASE 121 TO 122
                   dwNewImageBase = dwFromaddr + %INCR_BY * 8
       END SELECT
       dwCompare = dwNewImageBase
     
       'Rebase the file
       lResult = ReBaseImage( szFilePath, _
                              BYVAL %NULL, _
                              %TRUE, _
                              %FALSE, _
                              %FALSE, _
                              0???, _
                              VARPTR(dwOldImageSize), _
                              VARPTR(dwOldImageBase), _
                              VARPTR(dwNewImageSize), _
                              VARPTR(dwNewImageBase), _
                              [email protected]  )
     
       IF ISTRUE(lResult) AND dwOldImageBase <> dwCompare THEN
     
          'unload and re-map to see effective changes as dwNewAddress returns an offset from asked for address
          CALL UnMapAndLoad( tLoadedImage )
          lResult = MapAndLoad( szFilePath, _
                              BYVAL %NULL, _
                              tLoadedImage, _
                              %TRUE, _
                              %TRUE )
     
          IF ISFALSE(lResult) OR [email protected] <> %IMAGE_NT_SIGNATURE THEN
             CALL tell( szFilePath + " is not a valid PE file" )
             CALL logfile( lFileHandle, szFilePath + " is not a valid PE file" )
             GOTO Unload
          END IF
     
          CALL logfile( lFileHandle, "Successfully rebased file: " + szBuffer )
          CALL logfile( lFileHandle, "Old base address         : 0x" + HEX$(dwOldImageBase, 8) )
          CALL logfile( lFileHandle, "New base address         : 0x" + HEX$([email protected], 8) )
     
          FUNCTION = %TRUE
       ELSE
          CALL tell( "Could not rebase file: " + szBuffer )
          CALL logfile( lFileHandle, "Could not rebase file: " + szBuffer )
          IF dwOldImageBase = dwCompare THEN
             CALL tell( "Reason: " + szBuffer + " is already based at 0x" + HEX$(dwCompare, 8) )
             CALL logfile( lFileHandle, "Reason: " + szBuffer + " is already based at 0x" + HEX$(dwCompare, 8) )
          END IF
          FUNCTION = %FALSE
       END IF
     
       FLUSH #lFileHandle
     
       'MUST UnMapAndLoad
    Unload:
       CALL UnMapAndLoad( tLoadedImage )
     
    END FUNCTION
     
    SUB usage()
       CALL tell( "Valid parameters are: " + $CRLF _
                + "-b<input_file_to_read_from> [-s<hex_start_address>]"  + $CRLF _
                + "-f<name_of_dll_or_exe> [-s<hex_start_address>]" + $CRLF _
                + "as in : rebase.exe -brebase.txt -s12000000" + $CRLF _
                + "or    : rebase.exe -fmydll.dll" )
     
    END SUB
     
    FUNCTION PBMAIN() AS LONG
       'command line switches - batch input file -binput_file_path.txt or command line -fname_of_file_to_rebase
       'as in rebase -btorebase.txt to read from a batch input file or -ftalkbox.dll
       'accepts an optional switch -sbase_address_in_hex as in -s600000000
       '
       'example calls:
       'rebase -binput_file.txt -> attempts to rebase all files in input_file.txt - defaults to pre-defined range
       'rebase -binput_file.txt -s600000000 -> ditto but starts at range specified in -s switch
       'rebase -fname_of_dll_or_exe -> attempts to rebase file specified on command line
       'rebase -fname_of_dll_or_exe -s600000000 -> ditto but starts at range specified in -s switch
       LOCAL lResult AS LONG
       LOCAL lHandle AS LONG
       LOCAL lReadHandle AS LONG
       LOCAL lFindHandle AS LONG
       LOCAL lParamCount AS LONG
       LOCAL lRebaseCount AS LONG
       LOCAL lBatch AS LONG
       LOCAL lValid AS LONG
       LOCAL i AS LONG
       LOCAL dwStartAddress AS DWORD
       LOCAL szFile AS ASCIIZ * %MAX_PATH
       LOCAL szBatchFile AS ASCIIZ * %MAX_PATH
       LOCAL sValue AS STRING
       LOCAL sStartAddress AS STRING
       LOCAL tFindData AS WIN32_FIND_DATA
     
       IF LEN(COMMAND$) = 0 THEN
          CALL tell( "No command line parameters were specified" + $CRLF )
          CALL usage()
          EXIT FUNCTION
       END IF
     
       'check command line parameters
       lParamCount = PARSECOUNT(COMMAND$, "-")
       IF lParamCount = 0 THEN
          CALL tell( "Invalid command line parameters" )
          CALL usage()
          EXIT FUNCTION
       END IF
     
       FOR i = 1 TO lParamCount
           sValue = TRIM$(PARSE$(COMMAND$, "-", i))
           SELECT CASE MID$(LCASE$(sValue), 1, 1)
                  CASE "b"
                       szFile = TRIM$(MID$( sValue, 2 ))
                       lBatch = %TRUE
                       IF lValid = %TRUE THEN
                          lValid = %FALSE
                       ELSE
                          lValid = %TRUE
                       END IF
                  CASE "f"
                       szFile = TRIM$(MID$( sValue, 2))
                       IF lValid = %TRUE THEN
                          lValid = %FALSE
                       ELSE
                          lValid = %TRUE
                       END IF
                  CASE "s"
                       sStartAddress = TRIM$(UCASE$(MID$(sValue, 2)))
                       IF LEFT$(sStartAddress, 2) = "0X" OR LEFT$(sStartAddress, 2) = "&H" THEN
                          sStartAddress = MID$( sStartAddress, 3 )
                       END IF
                       dwStartAddress = VAL( "&H" + STRING$(8 -LEN(sStartAddress), "0") + sStartAddress )
                       IF dwStartAddress < %MIN_ADDR OR dwStartAddress > %MAX_ADDR THEN
                          CALL tell( "Invalid start address - valid range is 0x" + HEX$(%MIN_ADDR) + " to 0x" + HEX$(%MAX_ADDR) )
                          EXIT FUNCTION
                       END IF
           END SELECT
       NEXT
     
       IF ISFALSE( lValid ) THEN
          CALL tell( "Invalid or missing command line parameters" )
          CALL usage()
          EXIT FUNCTION
       END IF
     
       'open the log file
       lHandle = FREEFILE
       OPEN CURDIR$ + "\rebase.log" FOR OUTPUT AS lHandle
    
     
       IF ISTRUE( lBatch ) THEN
          lFindHandle = FindFirstFile( szFile, tFindData )
          IF lFindHandle = %INVALID_HANDLE_VALUE THEN
             CALL tell( "Unable to locate input file " + szFile + " - exiting")
             EXIT FUNCTION
          END IF
          CALL FindClose( lFindHandle )
     
          lReadHandle = FREEFILE
          OPEN szFile FOR INPUT AS lReadHandle
          DO WHILE ISFALSE( EOF(lReadHandle) )
             LINE INPUT #lReadHandle, szBatchFile
             IF ISTRUE( rebase( lHandle, dwStartAddress, szBatchFile) ) THEN
                INCR lRebaseCount
             END IF
             szBatchFile = ""
          LOOP
          CLOSE #lReadHandle
       ELSE
          IF ISTRUE( rebase( lHandle, dwStartAddress, szFile ) ) THEN
             INCR lRebaseCount
          END IF
       END IF
     
       CLOSE #lHandle
       CALL tell( "" )
       CALL tell( "Successfully rebased: " + FORMAT$(lRebaseCount) + " files. See rebase.log for details" )
    
      
    END FUNCTION


    [This message has been edited by Florent Heyworth (edited September 10, 2000).]

  • #2
    Updated the T_LOADED_IMAGE type declaration - see source comments
    for changes. Updated 11-Sep-2000

    Florent

    ------------------

    Comment

    Working...
    X