|
|
/*++
Copyright (c) 1993 Microsoft Corporation
Module Name:
verfix.c
Abstract:
This module fixes updates the major and minor subsystem version numbers in an executable and recomputes the checksum.
Author:
Robert Reichel (robertre) 2-May-1993
Revision History:
--*/
#include <private.h>
#define NEW_MAJOR_VERSION 3
#define NEW_MINOR_VERSION 10
void Usage() { fputs( "usage: VERFIX [-?] [-v] [-q] image-names...\n" " [-?] display this message\n" " [-n #.#] Subsystem Major.Minor versions (default to 3.10)\n" " [-q] quiet on failure\n" " [-v] verbose output\n", stderr); exit( 1 ); }
int __cdecl main( int argc, char *argv[] ) { HANDLE FileHandle; HANDLE MappingHandle; PIMAGE_NT_HEADERS NtHeaders; PVOID BaseAddress; ULONG CheckSum; ULONG FileLength; ULONG HeaderSum; ULONG OldCheckSum; USHORT MajorSubsystemVersion; USHORT MinorSubsystemVersion; ULONG NewMajorSubsystemVersion = NEW_MAJOR_VERSION; ULONG NewMinorSubsystemVersion = NEW_MINOR_VERSION; LPSTR ImageName; BOOLEAN fVerbose = FALSE; BOOLEAN fQuiet = FALSE; LPSTR s; UCHAR c;
if (argc <= 1) { Usage(); }
--argc; while (argc) { s = *++argv; if ( *s == '-' ) { while (c=*++s) { switch (c) { case 'q': case 'Q': fQuiet = TRUE; break;
case 'v': case 'V': fVerbose=TRUE; break;
case 'n': case 'N': s = *++argv; --argc; sscanf(s, "%d.%d", &NewMajorSubsystemVersion, &NewMinorSubsystemVersion); goto NextArgument; break;
case 'h': case 'H': case '?': Usage();
default: fprintf( stderr, "VERFIX: illegal option /%c\n", c ); Usage(); } } } else { ImageName = s; FileHandle = CreateFile( ImageName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL ); if (FileHandle == INVALID_HANDLE_VALUE) { if (!fQuiet) { fprintf( stderr, "VERFIX: Unable to open %s (%u) - skipping\n", ImageName, GetLastError() ); goto NextArgument; } }
MappingHandle = CreateFileMapping( FileHandle, NULL, PAGE_READWRITE, 0, 0, NULL ); if (MappingHandle == NULL) { CloseHandle( FileHandle ); if (!fQuiet) { fprintf( stderr, "VERFIX: Unable to create mapping object for file %s (%u) - skipping\n", ImageName, GetLastError() ); } } else { BaseAddress = MapViewOfFile( MappingHandle, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0 ); CloseHandle( MappingHandle ); if (BaseAddress == NULL) { CloseHandle( FileHandle ); if (!fQuiet ) { fprintf( stderr, "VERFIX: Unable to map view of file %s (%u) - skipping\n", ImageName, GetLastError() ); } } else { //
// Get the length of the file in bytes and compute the checksum.
//
FileLength = GetFileSize( FileHandle, NULL );
//
// Obtain a pointer to the header information.
//
NtHeaders = ImageNtHeader( BaseAddress ); if (NtHeaders == NULL) { CloseHandle( FileHandle ); UnmapViewOfFile( BaseAddress ); if (!fQuiet) { fprintf( stderr, "VERFIX: %s is not a valid image file - skipping\n", ImageName, GetLastError() ); } } else { //
// Write the information to the file. Update the
// SubsystemVersion major and minor codes.
//
MajorSubsystemVersion = NtHeaders->OptionalHeader.MajorSubsystemVersion; MinorSubsystemVersion = NtHeaders->OptionalHeader.MinorSubsystemVersion; OldCheckSum = NtHeaders->OptionalHeader.CheckSum;
NtHeaders->OptionalHeader.MajorSubsystemVersion = (USHORT)NewMajorSubsystemVersion; NtHeaders->OptionalHeader.MinorSubsystemVersion = (USHORT)NewMinorSubsystemVersion;
//
// Recompute and reset the checksum of the modified file.
//
(VOID) CheckSumMappedFile( BaseAddress, FileLength, &HeaderSum, &CheckSum );
NtHeaders->OptionalHeader.CheckSum = CheckSum;
if (fVerbose) { printf( "%s - Old version: %u.%u Old Checksum: %x", ImageName, MajorSubsystemVersion, MinorSubsystemVersion, OldCheckSum );
printf( " New version: %u.%u New Checksum: %x\n", NtHeaders->OptionalHeader.MajorSubsystemVersion, NtHeaders->OptionalHeader.MinorSubsystemVersion, NtHeaders->OptionalHeader.CheckSum ); }
if (!FlushViewOfFile( BaseAddress, FileLength )) { if (!fQuiet) { fprintf( stderr, "VERFIX: Flush of %s failed (%u)\n", ImageName, GetLastError() ); } }
UnmapViewOfFile( BaseAddress ); if (!TouchFileTimes( FileHandle, NULL )) { if (!fQuiet) { fprintf( stderr, "VERFIX: Unable to touch file %s (%u)\n", ImageName, GetLastError() ); } }
CloseHandle( FileHandle ); } } } } NextArgument: --argc; }
return 0; }
|