SYMEDIT.C
资源名称:MSDN_VC98.zip [点击查看]
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:31k
源码类别:
Windows编程
开发平台:
Visual C++
- /*++
- Copyright 1996 - 1997 Microsoft Corporation
- Module Name:
- symedit.c
- Abstract:
- Author:
- Wesley A. Witt (wesw) 19-April-1993
- Environment:
- Win32, User Mode
- --*/
- #include <windows.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include "symcvt.h"
- #include "cv.h"
- #include "strings.h"
- #include <imagehlp.h>
- // prototypes for this module
- BOOL CalculateOutputFilePointers( PIMAGEPOINTERS pi, PIMAGEPOINTERS po );
- void ProcessCommandLineArgs( int argc, char *argv[] );
- void PrintCopyright( void );
- void PrintUsage( void );
- void FatalError( int, ... );
- BOOL MapOutputFile ( PPOINTERS p, char *fname, int );
- void ComputeChecksum( char *szExeFile );
- void ReadDebugInfo( PPOINTERS p );
- void WriteDebugInfo( PPOINTERS p, BOOL);
- void MungeDebugHeadersCoffToCv( PPOINTERS p, BOOL fAddCV );
- void MungeExeName( PPOINTERS p, char * szExeName );
- void DoCoffToCv(char *, char *, BOOL);
- void DoSymToCv(char *, char *, char *, char *);
- void DoNameChange(char *, char *, char *);
- void DoExtract(char *, char *, char *);
- void DoStrip(char *, char *);
- IMAGE_DEBUG_DIRECTORY DbgDirSpare;
- #define AdjustPtr(ptr) (((ptr) != NULL) ?
- ((DWORD)ptr - (DWORD)pi->fptr + (DWORD)po->fptr) :
- ((DWORD)(ptr)))
- int _CRTAPI1
- main(
- int argc,
- char * argv[]
- )
- /*++
- Routine Description:
- Shell for this utility.
- Arguments:
- argc - argument count
- argv - argument pointers
- Return Value:
- 0 - image was converted
- >0 - image could not be converted
- --*/
- {
- // Scan the command line and check what operations we are doing
- ProcessCommandLineArgs( argc, argv );
- return 0;
- }
- __inline void PrintCopyright( void )
- {
- puts( "nMicrosoft(R) Windows NT SymEdit Version 1.0n"
- "(C) 1989-1995 Microsoft Corp. All rights reserved.n");
- }
- __inline void PrintUsage( void )
- {
- PrintCopyright();
- puts ("nUsage: SYMEDIT <OPERATION> -q -o<file out> <file in>nn"
- "t<OPERATION> is:n"
- "tCtModify CodeView symbol informationn"
- "tNtEdit name fieldn"
- "tXtExtract debug informationn"
- "tStStrip all debug informationnn"
- "Options:n"
- "t-attAdd CodeView debug info to filen"
- "t-n<name>tName to change ton"
- "t-o<file>tspecify output filen"
- "t-qttquiet moden"
- "t-rttReplace COFF debug info with CV infon"
- "t-s<file>tSym file source");
- }
- void
- ProcessCommandLineArgs(
- int argc,
- char *argv[]
- )
- /*++
- Routine Description:
- Processes the command line arguments and sets global flags to
- indicate the user's desired behavior.
- Arguments:
- argc - argument count
- argv - argument pointers
- Return Value:
- void
- --*/
- {
- int i;
- BOOL fQuiet = FALSE;
- BOOL fSilent = FALSE;
- char * szOutputFile = NULL;
- char * szInputFile = NULL;
- char * szExeName = NULL;
- char * szDbgFile = NULL;
- char * szSymFile = NULL;
- int iOperation;
- BOOLEAN fAddCV = FALSE;
- // Minimun number of of arguments is 2 -- program and operation
- if (argc < 2 ||
- (strcmp(argv[1], "-?") == 0) ||
- (strcmp(argv[1], "?") == 0) )
- {
- PrintUsage();
- exit(1);
- }
- // All operations on 1 character wide
- if (argv[1][1] != 0) {
- FatalError(ERR_OP_UNKNOWN, argv[1]);
- }
- // Validate the operation
- switch( argv[1][0] ) {
- case 'C':
- case 'N':
- case 'X':
- case 'S':
- iOperation = argv[1][0];
- break;
- default:
- FatalError(ERR_OP_UNKNOWN, argv[1]);
- }
- // Parse out any other switches on the command line
- for (i=2; i<argc; i++) {
- if ((argv[i][0] == '-') || (argv[i][0] == '/')) {
- switch (toupper(argv[i][1])) {
- // Add the CV debug information section rather than
- // replace the COFF section with the CV info.
- case 'A':
- fAddCV = TRUE;
- break;
- // Specify the output name for the DBG file
- case 'D':
- if (argv[i][2] == 0) {
- i += 1;
- szDbgFile = argv[i];
- } else {
- szDbgFile = &argv[i][2];
- }
- break;
- // Specify a new name to shove into the name of the
- // debuggee field in the Misc. Debug info field
- case 'N':
- if (argv[i][2] == 0) {
- i += 1;
- szExeName = argv[i];
- } else {
- szExeName = &argv[i][2];
- }
- break;
- // Specify the name of the output file
- case 'O':
- if (argv[i][2] == 0) {
- i += 1;
- szOutputFile = argv[i];
- } else {
- szOutputFile = &argv[i][2];
- }
- break;
- // Be quite and don't put out the banner
- case 'Q':
- fQuiet = TRUE;
- fSilent = TRUE;
- break;
- // Replace COFF debug information with CODEVIEW debug information
- case 'R':
- break;
- // Convert a Symbol File to CV info
- case 'S':
- if (argv[i][2] == 0) {
- i += 1;
- szSymFile = argv[i];
- } else {
- szSymFile = &argv[i][2];
- }
- break;
- // Print the command line options
- case '?':
- PrintUsage();
- exit(1);
- break;
- // Unrecognized option
- default:
- FatalError( ERR_OP_UNKNOWN, argv[i] );
- break;
- }
- } else {
- // No leading switch character -- must be a file name
- szInputFile = &argv[i][0];
- // Process the file(s)
- if (!fQuiet) {
- PrintCopyright();
- fQuiet = TRUE;
- }
- if (!fSilent) {
- printf("processing file: %sn", szInputFile );
- }
- // Do switch validation cheching and setup any missing global variables
- switch ( iOperation ) {
- // For conversions -- there are three types
- //
- // 1. Coff to CV -- add
- // 2. Coff to CV -- replace
- // 3. SYM to CV --- add
- // 4. SYM to CV -- seperate file
- //
- // Optional input file (not needed for case 4)
- // Optional output file
- // Optional sym file (implys sym->CV)
- // Optional DBG file
- case 'C':
- if (szSymFile == NULL) {
- DoCoffToCv(szInputFile, szOutputFile, fAddCV);
- } else {
- DoSymToCv(szInputFile, szOutputFile, szDbgFile, szSymFile);
- }
- szInputFile = NULL;
- szOutputFile = NULL;
- szDbgFile = NULL;
- szSymFile = NULL;
- break;
- // For changing the name of the debuggee --
- // Must specify input file
- // Must specify new name
- // Optional output file
- case 'N':
- DoNameChange(szInputFile, szOutputFile, szExeName);
- szInputFile = NULL;
- szOutputFile = NULL;
- szExeName = NULL;
- break;
- // For extraction of debug information
- // Must specify input file
- // Optional output file name
- // Optional debug file name
- case 'X':
- DoExtract(szInputFile, szOutputFile, szDbgFile);
- break;
- // For full strip of debug information
- // Must specify input file
- // Optional output file
- case 'S':
- DoStrip(szInputFile, szOutputFile);
- break;
- }
- }
- }
- return;
- }
- void
- ReadDebugInfo(
- PPOINTERS p
- )
- /*++
- Routine Description:
- This function will go out and read in all of the debug information
- into memory -- this is required because the input and output
- files might be the same, if so then writing out informaiton may
- destory data we need at a later time.
- Arguments:
- p - Supplies a pointer to the structure describing the debug info file
- Return Value:
- None.
- --*/
- {
- int i;
- // int cb;
- // char * pb;
- // PIMAGE_COFF_SYMBOLS_HEADER pCoffDbgInfo;
- // Allocate space to save pointers to debug info
- p->iptrs.rgpbDebugSave = (PCHAR *) malloc(p->iptrs.cDebugDir * sizeof(PCHAR));
- memset(p->iptrs.rgpbDebugSave, 0, p->iptrs.cDebugDir * sizeof(PCHAR));
- // Check each possible debug type record
- for (i=0; i<p->iptrs.cDebugDir; i++) {
- // If there was debug information then copy over the
- // description block and cache in the actual debug data.
- if (p->iptrs.rgDebugDir[i] != NULL) {
- p->iptrs.rgpbDebugSave[i] =
- malloc( p->iptrs.rgDebugDir[i]->SizeOfData );
- if (p->iptrs.rgpbDebugSave[i] == NULL) {
- FatalError(ERR_NO_MEMORY);
- }
- __try {
- memcpy(p->iptrs.rgpbDebugSave[i],
- p->iptrs.fptr +
- p->iptrs.rgDebugDir[i]->PointerToRawData,
- p->iptrs.rgDebugDir[i]->SizeOfData );
- } __except(EXCEPTION_EXECUTE_HANDLER ) {
- free(p->iptrs.rgpbDebugSave[i]);
- p->iptrs.rgpbDebugSave[i] = NULL;
- }
- }
- }
- return;
- }
- void
- WriteDebugInfo(
- PPOINTERS p,
- BOOL fAddCV
- )
- /*++
- Routine Description:
- This function will go out and read in all of the debug information
- into memory -- this is required because the input and output
- files might be the same, if so then writing out informaiton may
- destory data we need at a later time.
- Arguments:
- p - Supplies a pointer to the structure describing the debug info file
- Return Value:
- None.
- --*/
- {
- ULONG PointerToDebugData = 0; // Offset from the start of the file
- // to the current location to write
- // debug information out.
- ULONG BaseOfDebugData = 0;
- int i, flen;
- PIMAGE_DEBUG_DIRECTORY pDir, pDbgDir = NULL;
- if (p->optrs.debugSection) {
- BaseOfDebugData = PointerToDebugData =
- p->optrs.debugSection->PointerToRawData;
- } else if (p->optrs.sepHdr) {
- BaseOfDebugData = PointerToDebugData =
- sizeof(IMAGE_SEPARATE_DEBUG_HEADER) +
- p->optrs.sepHdr->NumberOfSections * sizeof(IMAGE_SECTION_HEADER) +
- p->optrs.sepHdr->ExportedNamesSize;
- }
- // Step 2. If the debug information is mapped, we know this
- // from the section headers, then we may need to write
- // out a new debug director to point to the debug information
- if (fAddCV) {
- if (p->optrs.optHdr) {
- p->optrs.optHdr->DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].
- VirtualAddress = p->optrs.debugSection->VirtualAddress;
- p->optrs.optHdr->DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].Size +=
- sizeof(IMAGE_DEBUG_DIRECTORY);
- } else if (p->optrs.sepHdr) {
- p->optrs.sepHdr->DebugDirectorySize += sizeof(IMAGE_DEBUG_DIRECTORY);
- } else {
- exit(1);
- }
- if (p->optrs.sepHdr) {
- pDbgDir = (PIMAGE_DEBUG_DIRECTORY) malloc(p->optrs.cDebugDir * sizeof(IMAGE_DEBUG_DIRECTORY));
- for (i=0; i<p->optrs.cDebugDir; i++) {
- if (p->optrs.rgDebugDir[i] != NULL) {
- pDbgDir[i] = *(p->optrs.rgDebugDir[i]);
- p->optrs.rgDebugDir[i] = &pDbgDir[i];
- }
- }
- }
- for (i=0; i<p->optrs.cDebugDir; i++) {
- if (p->optrs.rgDebugDir[i]) {
- pDir = (PIMAGE_DEBUG_DIRECTORY) (PointerToDebugData +
- p->optrs.fptr);
- *pDir = *(p->optrs.rgDebugDir[i]);
- p->optrs.rgDebugDir[i] = pDir;
- PointerToDebugData += sizeof(IMAGE_DEBUG_DIRECTORY);
- }
- }
- }
- // Step 3. For every debug info type, write out the debug information
- // and update any header information required
- for (i=0; i<p->optrs.cDebugDir; i++) {
- if (p->optrs.rgDebugDir[i] != NULL) {
- if (p->optrs.rgpbDebugSave[i] != NULL) {
- p->optrs.rgDebugDir[i]->PointerToRawData =
- PointerToDebugData;
- if (p->optrs.debugSection) {
- p->optrs.rgDebugDir[i]->AddressOfRawData =
- p->optrs.debugSection->VirtualAddress +
- PointerToDebugData - BaseOfDebugData;
- }
- memcpy(p->optrs.fptr + PointerToDebugData,
- p->optrs.rgpbDebugSave[i],
- p->optrs.rgDebugDir[i]->SizeOfData);
- if ((i == IMAGE_DEBUG_TYPE_COFF) &&
- (p->optrs.fileHdr != NULL)) {
- PIMAGE_COFF_SYMBOLS_HEADER pCoffDbgInfo;
- pCoffDbgInfo = (PIMAGE_COFF_SYMBOLS_HEADER)p->optrs.rgpbDebugSave[i];
- p->optrs.fileHdr->PointerToSymbolTable =
- PointerToDebugData + pCoffDbgInfo->LvaToFirstSymbol;
- }
- }
- PointerToDebugData += p->optrs.rgDebugDir[i]->SizeOfData;
- }
- }
- // Step 4. Clean up any COFF structures if we are replacing
- // the coff information with CV info.
- if ((p->optrs.rgDebugDir[IMAGE_DEBUG_TYPE_COFF] == NULL) &&
- (p->optrs.fileHdr != NULL)) {
- // Since there is no coff debug information -- clean out
- // both fields pointing to the debug info
- p->optrs.fileHdr->PointerToSymbolTable = 0;
- p->optrs.fileHdr->NumberOfSymbols = 0;
- }
- // Step 5. Correct the alignments if needed. If there is a real .debug
- // section in the file (i.e. it is mapped) then update it.
- if (p->optrs.debugSection) {
- p->optrs.debugSection->SizeOfRawData =
- FileAlign(PointerToDebugData - BaseOfDebugData);
- // update the optional header with the new image size
- p->optrs.optHdr->SizeOfImage =
- SectionAlign(p->optrs.debugSection->VirtualAddress +
- p->optrs.debugSection->SizeOfRawData);
- p->optrs.optHdr->SizeOfInitializedData +=
- p->optrs.debugSection->SizeOfRawData;
- }
- // calculate the new file size
- if (p->optrs.optHdr != NULL) {
- flen = FileAlign(PointerToDebugData);
- } else {
- flen = PointerToDebugData;
- }
- // finally, update the eof pointer and close the file
- UnmapViewOfFile( p->optrs.fptr );
- if (!SetFilePointer( p->optrs.hFile, flen, 0, FILE_BEGIN )) {
- FatalError( ERR_FILE_PTRS );
- }
- if (!SetEndOfFile( p->optrs.hFile )) {
- FatalError( ERR_SET_EOF );
- }
- CloseHandle( p->optrs.hFile );
- // Exit -- we are done.
- return;
- }
- void
- MungeDebugHeadersCoffToCv(
- PPOINTERS p,
- BOOL fAddCV
- )
- /*++
- Routine Description:
- Arguments:
- p - pointer to a POINTERS structure (see symcvt.h)
- Return Value:
- void
- --*/
- {
- if (!fAddCV) {
- CV_DIR(&p->optrs) = COFF_DIR(&p->optrs);
- COFF_DIR(&p->optrs) = 0;
- } else {
- CV_DIR(&p->optrs) = &DbgDirSpare;
- *(COFF_DIR(&p->optrs)) = *(COFF_DIR(&p->iptrs));
- };
- *CV_DIR(&p->optrs) = *(COFF_DIR(&p->iptrs));
- CV_DIR(&p->optrs)->Type = IMAGE_DEBUG_TYPE_CODEVIEW;
- CV_DIR(&p->optrs)->SizeOfData = p->pCvStart.size;
- p->optrs.rgpbDebugSave[IMAGE_DEBUG_TYPE_CODEVIEW] = p->pCvStart.ptr;
- return;
- }
- BOOL
- MapOutputFile (
- PPOINTERS p,
- char *fname,
- int cb
- )
- /*++
- Routine Description:
- Maps the output file specified by the fname argument and saves the
- file handle & file pointer in the POINTERS structure.
- Arguments:
- p - pointer to a POINTERS structure (see symcvt.h)
- fname - ascii string for the file name
- Return Value:
- TRUE - file mapped ok
- FALSE - file could not be mapped
- --*/
- {
- BOOL rval;
- HANDLE hMap = NULL;
- DWORD oSize;
- rval = FALSE;
- p->optrs.hFile = CreateFile( fname,
- GENERIC_READ | GENERIC_WRITE,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- NULL,
- OPEN_ALWAYS,
- 0,
- NULL );
- if (p->optrs.hFile == INVALID_HANDLE_VALUE) {
- goto exit;
- }
- oSize = p->iptrs.fsize;
- if (p->pCvStart.ptr != NULL) {
- oSize += p->pCvStart.size;
- }
- oSize += cb;
- oSize += p->iptrs.cDebugDir * sizeof(IMAGE_DEBUG_DIRECTORY);
- hMap = CreateFileMapping( p->optrs.hFile, NULL, PAGE_READWRITE,
- 0, oSize, NULL );
- if (hMap == NULL) {
- goto exit;
- }
- p->optrs.fptr = MapViewOfFile( hMap, FILE_MAP_WRITE, 0, 0, 0 );
- CloseHandle(hMap);
- if (p->optrs.fptr == NULL) {
- goto exit;
- }
- rval = TRUE;
- exit:
- return rval;
- }
- BOOL
- CalculateOutputFilePointers(
- PIMAGEPOINTERS pi,
- PIMAGEPOINTERS po
- )
- /*++
- Routine Description:
- This function calculates the output file pointers based on the
- input file pointers. The same address is used but they are all
- re-based off the output file's file pointer.
- Arguments:
- p - pointer to a IMAGEPOINTERS structure (see symcvt.h)
- Return Value:
- TRUE - pointers were created
- FALSE - pointers could not be created
- --*/
- {
- int i;
- // fixup the pointers relative the fptr for the output file
- po->dosHdr = (PIMAGE_DOS_HEADER) AdjustPtr(pi->dosHdr);
- po->ntHdr = (PIMAGE_NT_HEADERS) AdjustPtr(pi->ntHdr);
- po->fileHdr = (PIMAGE_FILE_HEADER) AdjustPtr(pi->fileHdr);
- po->optHdr = (PIMAGE_OPTIONAL_HEADER) AdjustPtr(pi->optHdr);
- po->sectionHdrs = (PIMAGE_SECTION_HEADER) AdjustPtr(pi->sectionHdrs);
- po->sepHdr = (PIMAGE_SEPARATE_DEBUG_HEADER) AdjustPtr(pi->sepHdr);
- po->debugSection = (PIMAGE_SECTION_HEADER) AdjustPtr(pi->debugSection);
- po->AllSymbols = (PIMAGE_SYMBOL) AdjustPtr(pi->AllSymbols);
- po->stringTable = (PUCHAR) AdjustPtr(pi->stringTable);
- // move the data from the input file to the output file
- memcpy( po->fptr, pi->fptr, pi->fsize );
- po->cDebugDir = pi->cDebugDir;
- po->rgDebugDir = malloc(po->cDebugDir * sizeof(po->rgDebugDir[0]));
- memset(po->rgDebugDir, 0, po->cDebugDir * sizeof(po->rgDebugDir[0]));
- for (i=0; i<po->cDebugDir; i++) {
- po->rgDebugDir[i] = (PIMAGE_DEBUG_DIRECTORY) AdjustPtr(pi->rgDebugDir[i]);
- }
- po->rgpbDebugSave = pi->rgpbDebugSave;
- return TRUE;
- }
- void
- FatalError(
- int idMsg,
- ...
- )
- /*++
- Routine Description:
- Prints a message string to stderr and then exits.
- Arguments:
- s - message string to be printed
- Return Value:
- void
- --*/
- {
- va_list marker;
- char rgchFormat[256];
- char rgch[256];
- LoadString(GetModuleHandle(NULL), idMsg, rgchFormat, sizeof(rgchFormat));
- va_start(marker, idMsg);
- vsprintf(rgch, rgchFormat, marker);
- va_end(marker);
- fprintf(stderr, "%sn", rgch);
- exit(1);
- }
- void
- ComputeChecksum(
- char *szExeFile
- )
- /*++
- Routine Description:
- Computes a new checksum for the image by calling imagehlp.dll
- Arguments:
- szExeFile - exe file name
- Return Value:
- void
- --*/
- {
- DWORD dwHeaderSum = 0;
- DWORD dwCheckSum = 0;
- HANDLE hFile;
- DWORD cb;
- IMAGE_DOS_HEADER dosHdr;
- IMAGE_NT_HEADERS ntHdr;
- if (MapFileAndCheckSum(szExeFile, &dwHeaderSum, &dwCheckSum) != CHECKSUM_SUCCESS) {
- FatalError( ERR_CHECKSUM_CALC );
- }
- hFile = CreateFile( szExeFile,
- GENERIC_READ | GENERIC_WRITE,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- NULL,
- OPEN_EXISTING,
- 0,
- NULL
- );
- // seek to the beginning of the file
- SetFilePointer( hFile, 0, 0, FILE_BEGIN );
- // read in the dos header
- if ((ReadFile(hFile, &dosHdr, sizeof(dosHdr), &cb, 0) == FALSE) || (cb != sizeof(dosHdr))) {
- FatalError( ERR_CHECKSUM_CALC );
- }
- // read in the pe header
- if ((dosHdr.e_magic != IMAGE_DOS_SIGNATURE) ||
- (SetFilePointer(hFile, dosHdr.e_lfanew, 0, FILE_BEGIN) == -1L)) {
- FatalError( ERR_CHECKSUM_CALC );
- }
- // read in the nt header
- if ((!ReadFile(hFile, &ntHdr, sizeof(ntHdr), &cb, 0)) || (cb != sizeof(ntHdr))) {
- FatalError( ERR_CHECKSUM_CALC );
- }
- if (SetFilePointer(hFile, dosHdr.e_lfanew, 0, FILE_BEGIN) == -1L) {
- FatalError( ERR_CHECKSUM_CALC );
- }
- ntHdr.OptionalHeader.CheckSum = dwCheckSum;
- if (!WriteFile(hFile, &ntHdr, sizeof(ntHdr), &cb, NULL)) {
- FatalError( ERR_CHECKSUM_CALC );
- }
- CloseHandle(hFile);
- return;
- }
- void
- MungeExeName(
- PPOINTERS p,
- char * szExeName
- )
- /*++
- Routine Description:
- description-of-function.
- Arguments:
- argument-name - Supplies | Returns description of argument.
- .
- .
- Return Value:
- None.
- --*/
- {
- PIMAGE_DEBUG_MISC pMiscIn;
- PIMAGE_DEBUG_MISC pMiscOut;
- int cb;
- int i;
- for (i=0; i<p->iptrs.cDebugDir; i++) {
- if (p->optrs.rgDebugDir[i] != 0) {
- *(p->optrs.rgDebugDir[i]) = *(p->iptrs.rgDebugDir[i]);
- }
- }
- pMiscIn = (PIMAGE_DEBUG_MISC)
- p->iptrs.rgpbDebugSave[IMAGE_DEBUG_TYPE_MISC];
- if (p->optrs.rgDebugDir[IMAGE_DEBUG_TYPE_MISC] == NULL) {
- p->optrs.rgDebugDir[IMAGE_DEBUG_TYPE_MISC] = &DbgDirSpare;
- memset(&DbgDirSpare, 0, sizeof(DbgDirSpare));
- }
- pMiscOut = (PIMAGE_DEBUG_MISC)
- p->optrs.rgpbDebugSave[IMAGE_DEBUG_TYPE_MISC] =
- malloc(p->optrs.rgDebugDir[IMAGE_DEBUG_TYPE_MISC]->SizeOfData +
- strlen(szExeName));
- cb = p->optrs.rgDebugDir[IMAGE_DEBUG_TYPE_MISC]->SizeOfData;
- while ( cb > 0 ) {
- if (pMiscIn->DataType == IMAGE_DEBUG_MISC_EXENAME) {
- pMiscOut->DataType = IMAGE_DEBUG_MISC_EXENAME;
- pMiscOut->Length = (sizeof(IMAGE_DEBUG_MISC) +
- strlen(szExeName) + 3) & ~3;
- pMiscOut->Unicode = FALSE;
- strcpy(&pMiscOut->Data[0], szExeName);
- szExeName = NULL;
- } else {
- memcpy(pMiscOut, pMiscIn, pMiscIn->Length);
- }
- p->optrs.rgDebugDir[IMAGE_DEBUG_TYPE_MISC]->SizeOfData +=
- (pMiscOut->Length - pMiscIn->Length);
- cb -= pMiscIn->Length;
- pMiscIn = (PIMAGE_DEBUG_MISC) (((char *) pMiscIn) + pMiscIn->Length);
- pMiscOut = (PIMAGE_DEBUG_MISC) (((char *) pMiscOut) + pMiscOut->Length);
- }
- if (szExeName) {
- pMiscOut->DataType = IMAGE_DEBUG_MISC_EXENAME;
- pMiscOut->Length = (sizeof(IMAGE_DEBUG_MISC) +
- strlen(szExeName) + 3) & ~3;
- pMiscOut->Unicode = FALSE;
- strcpy(&pMiscOut->Data[0], szExeName);
- }
- return;
- }
- /*** DoCoffToCv
- *
- *
- */
- void DoCoffToCv(
- char * szInput,
- char * szOutput,
- BOOL fAddCV
- )
- {
- POINTERS p;
- // Do default checking
- if (szOutput == NULL) {
- szOutput = szInput;
- }
- // Open the input file name and setup the pointers into the file
- if (!MapInputFile( &p, NULL, szInput )) {
- FatalError( ERR_OPEN_INPUT_FILE, szInput );
- }
- // Now, if we thing we are playing with PE exes then we need
- // to setup the pointers into the map file
- if (!CalculateNtImagePointers( &p.iptrs )) {
- FatalError( ERR_INVALID_PE, szInput );
- }
- // We are about to try and do the coff to cv symbol conversion.
- //
- // Verify that the operation is legal.
- //
- // 1. We need to have coff debug information to start with
- // 2. If the debug info is not mapped then we must not
- // be trying to add CodeView info.
- if ((p.iptrs.AllSymbols == NULL) || (COFF_DIR(&p.iptrs) == NULL)) {
- FatalError( ERR_NO_COFF );
- }
- if (fAddCV && (p.iptrs.debugSection == 0) && (p.iptrs.sepHdr == NULL)) {
- FatalError( ERR_NOT_MAPPED );
- }
- // Now go out an preform the acutal conversion.
- if (!ConvertCoffToCv( &p )) {
- FatalError( ERR_COFF_TO_CV );
- }
- // Read in any additional debug information in the file
- ReadDebugInfo(&p);
- // Open the output file and adjust the pointers so that we are ok.
- if (!MapOutputFile( &p, szOutput, 0 )) {
- FatalError( ERR_MAP_FILE, szOutput );
- }
- CalculateOutputFilePointers( &p.iptrs, &p.optrs );
- // Munge the various debug information structures to preform the correct
- // operations
- MungeDebugHeadersCoffToCv( &p, fAddCV );
- // Free our handles on the input file
- UnMapInputFile(&p);
- // Write out the debug information to the end of the exe
- WriteDebugInfo( &p, fAddCV );
- // and finally compute the checksum
- if (p.iptrs.fileHdr != NULL) {
- ComputeChecksum( szOutput );
- }
- return;
- }
- /*** DoSymToCv
- *
- */
- void
- DoSymToCv(
- char * szInput,
- char * szOutput,
- char * szDbg,
- char * szSym
- )
- {
- POINTERS p;
- HANDLE hFile;
- DWORD cb;
- OFSTRUCT ofs;
- // Open the input file name and setup the pointers into the file
- if (!MapInputFile( &p, NULL, szSym )) {
- FatalError(ERR_OPEN_INPUT_FILE, szSym);
- }
- // Now preform the desired operation
- if ((szOutput == NULL) && (szDbg == NULL)) {
- szOutput = szInput;
- }
- ConvertSymToCv( &p );
- if (szOutput) {
- if (szOutput != szInput) {
- if (OpenFile(szInput, &ofs, OF_EXIST) == 0) {
- FatalError(ERR_OPEN_INPUT_FILE, szInput);
- }
- if (CopyFile(szInput, szOutput, FALSE) == 0) {
- FatalError(ERR_OPEN_WRITE_FILE, szOutput);
- }
- }
- hFile = CreateFile(szOutput, GENERIC_WRITE, 0, NULL,
- CREATE_ALWAYS,
- FILE_ATTRIBUTE_NORMAL, NULL);
- if (hFile == INVALID_HANDLE_VALUE) {
- FatalError(ERR_OPEN_WRITE_FILE, szOutput);
- }
- SetFilePointer(hFile, 0, 0, FILE_END);
- } else if (szDbg) {
- hFile = CreateFile(szDbg, GENERIC_WRITE, 0, NULL,
- OPEN_ALWAYS,
- FILE_ATTRIBUTE_NORMAL, NULL);
- if (hFile == INVALID_HANDLE_VALUE) {
- FatalError(ERR_OPEN_WRITE_FILE, szDbg);
- }
- }
- WriteFile(hFile, p.pCvStart.ptr, p.pCvStart.size, &cb, NULL);
- CloseHandle(hFile);
- return;
- }
- void
- DoNameChange(
- char * szInput,
- char * szOutput,
- char * szNewName
- )
- {
- POINTERS p;
- // Open the input file name and setup the pointers into the file
- if (!MapInputFile( &p, NULL, szInput )) {
- FatalError(ERR_OPEN_INPUT_FILE, szInput);
- }
- // Now, if we thing we are playing with PE exes then we need
- // to setup the pointers into the map file
- if (!CalculateNtImagePointers( &p.iptrs )) {
- FatalError(ERR_INVALID_PE, szInput);
- }
- // Now preform the desired operation
- if (szOutput == NULL) {
- szOutput = szInput;
- }
- if (szNewName == NULL) {
- szNewName = szOutput;
- }
- if (p.iptrs.sepHdr != NULL) {
- FatalError(ERR_EDIT_DBG_FILE);
- }
- // Read in all of the debug information
- ReadDebugInfo(&p);
- // Open the output file and adjust the pointers.
- if (!MapOutputFile(&p, szOutput,
- sizeof(szNewName) * 2 + sizeof(IMAGE_DEBUG_MISC))) {
- FatalError(ERR_MAP_FILE, szOutput);
- }
- CalculateOutputFilePointers(&p.iptrs, &p.optrs);
- // Munge the name of the file
- MungeExeName(&p, szNewName);
- // Close the input file
- UnMapInputFile(&p);
- // Write out the debug information to the end of the exe
- WriteDebugInfo(&p, FALSE);
- // and finally compute the checksum
- if (p.iptrs.fileHdr != NULL) {
- ComputeChecksum( szOutput );
- }
- return;
- }
- void
- DoStrip(
- char * szInput,
- char * szOutput
- )
- {
- char OutputFile[_MAX_PATH];
- // Make sure we only have the path to the output file (it will always be
- // named filename.DBG)
- if (szOutput != NULL) {
- CopyFileA(szInput, szOutput, FALSE);
- }
- SplitSymbols(szOutput, NULL, OutputFile, SPLITSYM_EXTRACT_ALL);
- // Always delete the output file.
- DeleteFileA(OutputFile);
- return;
- }
- void
- DoExtract(
- char * szInput,
- char * szOutput,
- char * szDbgFile
- )
- {
- char OutputFile[_MAX_PATH];
- char szExt[_MAX_EXT];
- char szFileName[_MAX_FNAME];
- if (szOutput != NULL) {
- CopyFileA(szInput, szOutput, FALSE);
- szInput = strdup(szOutput);
- _splitpath(szOutput, NULL, NULL, szFileName, szExt);
- *(szOutput + strlen(szOutput) - strlen(szFileName) - strlen(szExt)) = ' ';
- }
- SplitSymbols(szInput, szOutput, OutputFile, 0);
- CopyFileA(szDbgFile, OutputFile, TRUE);
- if (szOutput) {
- free(szInput);
- }
- return;
- }