Annotation of mstools/samples/sdktools/image/symedit/symedit.c, revision 1.1

1.1     ! root        1: /*++
        !             2: 
        !             3: 
        !             4: Copyright (c) 1992  Microsoft Corporation
        !             5: 
        !             6: Module Name:
        !             7: 
        !             8:     symedit.c
        !             9: 
        !            10: Abstract:
        !            11: 
        !            12: 
        !            13: Author:
        !            14: 
        !            15:     Wesley A. Witt (wesw) 19-April-1993
        !            16: 
        !            17: Environment:
        !            18: 
        !            19:     Win32, User Mode
        !            20: 
        !            21: --*/
        !            22: 
        !            23: #include <windows.h>
        !            24: #include <stdlib.h>
        !            25: #include <stdio.h>
        !            26: #include <string.h>
        !            27: 
        !            28: #include "symcvt.h"
        !            29: #include "cv.h"
        !            30: #include "cofftocv.h"
        !            31: #include "symtocv.h"
        !            32: #include "strings.h"
        !            33: 
        !            34: #include <imagehlp.h>
        !            35: 
        !            36: 
        !            37: /*
        !            38:  *      prototypes for this module
        !            39:  */
        !            40: 
        !            41: BOOL    CalculateOutputFilePointers( PIMAGEPOINTERS pi, PIMAGEPOINTERS po );
        !            42: void    ProcessCommandLineArgs( int argc, char *argv[] );
        !            43: void    PrintCopyright( void );
        !            44: void    PrintUsage( void );
        !            45: void    FatalError( int, ... );
        !            46: BOOL    MapOutputFile ( PPOINTERS p, char *fname, int );
        !            47: void    ComputeChecksum(  char *szExeFile );
        !            48: void    ReadDebugInfo( PPOINTERS p );
        !            49: void    WriteDebugInfo( PPOINTERS p, BOOL, BOOL );
        !            50: void    MungeDebugHeadersCoffToCv( PPOINTERS  p, BOOL fAddCV );
        !            51: void    MungeExeName( PPOINTERS p, char * szExeName );
        !            52: void    DoCoffToCv(char *, char *, BOOL);
        !            53: void    DoSymToCv(char *, char *, char *, char *);
        !            54: void    DoNameChange(char *, char *, char *);
        !            55: void    DoExtract(char *, char *, char *);
        !            56: void    DoStrip(char *, char *);
        !            57: 
        !            58: IMAGE_DEBUG_DIRECTORY   DbgDirSpare;
        !            59: IMAGE_DEBUG_DIRECTORY   DbgDirCoff;
        !            60: 
        !            61: #define AdjustPtr(ptr) (((ptr) != NULL) ? ((DWORD)ptr - (DWORD)pi->fptr + (DWORD)po->fptr) : ((DWORD)(ptr)))
        !            62: 
        !            63: 
        !            64: 
        !            65: int _CRTAPI1
        !            66: main(
        !            67:      int        argc,
        !            68:      char *     argv[]
        !            69:      )
        !            70: /*++
        !            71: 
        !            72: Routine Description:
        !            73: 
        !            74:     Shell for this utility.
        !            75: 
        !            76: Arguments:
        !            77: 
        !            78:     argc     - argument count
        !            79:     argv     - argument pointers
        !            80: 
        !            81: 
        !            82: Return Value:
        !            83: 
        !            84:     0        - image was converted
        !            85:     >0       - image could not be converted
        !            86: 
        !            87: --*/
        !            88: 
        !            89: {
        !            90:     /*
        !            91:      *  Scan the command line and check what operations we are doing
        !            92:      */
        !            93:      
        !            94:     ProcessCommandLineArgs( argc, argv );
        !            95:     return 0;
        !            96: }
        !            97: 
        !            98: void
        !            99: PrintCopyright( void )
        !           100: 
        !           101: /*++
        !           102: 
        !           103: Routine Description:
        !           104: 
        !           105:     Prints the MS copyright message to stdout.
        !           106: 
        !           107: Arguments:
        !           108: 
        !           109:     void
        !           110: 
        !           111: 
        !           112: Return Value:
        !           113: 
        !           114:     void
        !           115: 
        !           116: --*/
        !           117: 
        !           118: {
        !           119:     printf( "\nMicrosoft(R) Windows NT SymEdit Version 1.0\n" );
        !           120:     printf( "(C) 1989-1993 Microsoft Corp. All rights reserved.\n\n");
        !           121: }
        !           122: 
        !           123: void
        !           124: PrintUsage( void )
        !           125: 
        !           126: /*++
        !           127: 
        !           128: Routine Description:
        !           129: 
        !           130:     Prints the command line help to stdout
        !           131: 
        !           132: Arguments:
        !           133: 
        !           134:     void
        !           135: 
        !           136: 
        !           137: Return Value:
        !           138: 
        !           139:     void
        !           140: 
        !           141: --*/
        !           142: 
        !           143: {
        !           144:     PrintCopyright();
        !           145:     printf("\nUsage: SYMEDIT <OPERATION> -q -o<file out> <file in>\n\n" );
        !           146:     printf("\t<OPERATION> is:\n");
        !           147:     printf("\tA\tAdd debug information\n");
        !           148:     printf("\tC\tConvert symbol information\n" );
        !           149:     printf("\tN\tEdit name field\n");
        !           150:     printf("\tX\tExtract debug information\n");
        !           151:     printf("\tS\tStrip all debug information\n\n");
        !           152:     printf("Options:\n");
        !           153:     printf("\t-a\t\tAdd CodeView debug info to file\n");
        !           154:     printf("\t-n<name>\tName to change to\n");
        !           155:     printf("\t-o<file>\tspecify output file\n" );
        !           156:     printf("\t-q\t\tquiet mode\n" );
        !           157:     printf("\t-s<file>\tSym file source\n");
        !           158: }
        !           159: 
        !           160: void
        !           161: ProcessCommandLineArgs( int argc, char *argv[] )
        !           162: 
        !           163: /*++
        !           164: 
        !           165: Routine Description:
        !           166: 
        !           167:     Processes the command line arguments and sets global flags to
        !           168:     indicate the user's desired behavior.
        !           169: 
        !           170: Arguments:
        !           171: 
        !           172:     argc     - argument count
        !           173:     argv     - argument pointers
        !           174: 
        !           175: 
        !           176: Return Value:
        !           177: 
        !           178:     void
        !           179: 
        !           180: --*/
        !           181: 
        !           182: {
        !           183:     int     i;
        !           184:     BOOL        fQuiet = FALSE;
        !           185:     BOOL        fSilent = FALSE;
        !           186:     char *      szOutputFile = NULL;
        !           187:     char *      szInputFile = NULL;
        !           188:     char *      szExeName = NULL;
        !           189:     char *      szDbgFile = NULL;
        !           190:     char *      szSymFile = NULL;
        !           191:     int         iOperation;
        !           192:     BOOLEAN     fAddCV = FALSE;
        !           193: 
        !           194:     /*
        !           195:      * Minimun number of of arguments is 2 -- program and operation
        !           196:      */
        !           197: 
        !           198:     if (argc < 2) {
        !           199:         PrintUsage();
        !           200:         exit(1);
        !           201:     }
        !           202: 
        !           203:     if ((strcmp(argv[1], "-?") == 0) || (strcmp(argv[1], "?") == 0)) {
        !           204:         PrintUsage();
        !           205:         exit(1);
        !           206:     }
        !           207: 
        !           208:     /*
        !           209:      *  All operations on 1 character wide
        !           210:      */
        !           211:     
        !           212:     if (argv[1][1] != 0) {
        !           213:         FatalError(ERR_OP_UNKNOWN, argv[1]);
        !           214:     }
        !           215: 
        !           216:     /*
        !           217:      *  Validate the operation
        !           218:      */
        !           219:     
        !           220:     switch( argv[1][0] ) {
        !           221:     case 'C':
        !           222:     case 'N':
        !           223:     case 'X':
        !           224:     case 'S':
        !           225:         iOperation = argv[1][0];
        !           226:         break;
        !           227:     default:
        !           228:         FatalError(ERR_OP_UNKNOWN, argv[1]);
        !           229:     }
        !           230: 
        !           231:     /*
        !           232:      *  Parse out any other switches on the command line
        !           233:      */
        !           234:     
        !           235:     for (i=2; i<argc; i++) {
        !           236:         if ((argv[i][0] == '-') || (argv[i][0] == '/')) {
        !           237:             switch (argv[i][1]) {
        !           238:                 /*
        !           239:                  *   Add the CV debug information section rather than
        !           240:                  *  replace the COFF section with the CV info.
        !           241:                  */
        !           242:             case 'a':
        !           243:             case 'A':
        !           244:                 fAddCV = TRUE;
        !           245:                 break;
        !           246:                 
        !           247:                 /*
        !           248:                  *  Specify the output name for the DBG file
        !           249:                  */
        !           250:                 
        !           251:             case 'd':
        !           252:             case 'D':
        !           253:                 if (argv[i][2] == 0) {
        !           254:                     i += 1;
        !           255:                     szDbgFile = argv[i];
        !           256:                 } else {
        !           257:                     szDbgFile = &argv[i][2];
        !           258:                 }
        !           259:                 break;
        !           260:                 
        !           261:                 /*
        !           262:                  *  Specify a new name to shove into the name of the
        !           263:                  *  debuggee field in the Misc. Debug info field
        !           264:                  */
        !           265:                 
        !           266:             case 'N':
        !           267:             case 'n':
        !           268:                 if (argv[i][2] == 0) {
        !           269:                     i += 1;
        !           270:                     szExeName = argv[i];
        !           271:                 } else {
        !           272:                     szExeName = &argv[i][2];
        !           273:                 }
        !           274:                 break;
        !           275:                 
        !           276:                 /*
        !           277:                  * Specify the name of the output file
        !           278:                  */
        !           279:                 
        !           280:             case 'O':
        !           281:             case 'o':
        !           282:                 if (argv[i][2] == 0) {
        !           283:                     i += 1;
        !           284:                     szOutputFile = argv[i];
        !           285:                 } else {
        !           286:                     szOutputFile = &argv[i][2];
        !           287:                 }
        !           288:                 break;
        !           289:                 
        !           290:                 /*
        !           291:                  *  Be quite and don't put out the banner
        !           292:                  */
        !           293:                 
        !           294:             case 'Q':
        !           295:             case 'q':
        !           296:                 fQuiet = TRUE;
        !           297:                 fSilent = TRUE;
        !           298:                 break;
        !           299:                 
        !           300:                 /*
        !           301:                  *  Replace COFF debug information with CODEVIEW debug information
        !           302:                  */
        !           303:                 
        !           304:             case 'R':
        !           305:             case 'r':
        !           306:                 break;
        !           307:                 
        !           308:                 /*
        !           309:                  *  Convert a Symbol File to CV info
        !           310:                  */
        !           311:                 
        !           312:             case 'S':
        !           313:             case 's':
        !           314:                 if (argv[i][2] == 0) {
        !           315:                     i += 1;
        !           316:                     szSymFile = argv[i];
        !           317:                 } else {
        !           318:                     szSymFile = &argv[i][2];
        !           319:                 }
        !           320:                 break;
        !           321:                 
        !           322:                 /*
        !           323:                  * Print the command line options
        !           324:                  */
        !           325:                 
        !           326:             case '?':
        !           327:                 PrintUsage();
        !           328:                 exit(1);
        !           329:                 break;
        !           330:                 
        !           331:                 /*
        !           332:                  * Unrecognized option
        !           333:                  */
        !           334:                 
        !           335:             default:
        !           336:                 FatalError( ERR_OP_UNKNOWN, argv[i] );
        !           337:                 break;
        !           338:             }
        !           339:         } else {
        !           340:             /*
        !           341:              *  No leading switch character -- must be a file name
        !           342:              */
        !           343:             
        !           344:             szInputFile = &argv[i][0];
        !           345:             
        !           346:             /*
        !           347:              *  Process the file(s)
        !           348:              */
        !           349:             
        !           350:             if (!fQuiet) {
        !           351:                 PrintCopyright();
        !           352:                 fQuiet = TRUE;
        !           353:             }
        !           354: 
        !           355:             if (!fSilent) {
        !           356:                 printf("processing file: %s\n", szInputFile );
        !           357:             }
        !           358:             
        !           359:             /*
        !           360:              *  Do switch validation cheching and setup any missing global variables
        !           361:              */
        !           362:             
        !           363:             switch ( iOperation ) {
        !           364:                 /*
        !           365:                  *  Add debug information to an exe file
        !           366:                  *
        !           367:                  *      Must specify in input file
        !           368:                  *      Optional outputfile
        !           369:                  *      Must specify a debug info file
        !           370:                  */
        !           371:                 
        !           372:             case 'A':
        !           373:                 break;
        !           374:                 
        !           375:                 /*
        !           376:                  * For conversions -- there are three types
        !           377:                  *
        !           378:                  *      1.  Coff to CV -- add
        !           379:                  *      2.  Coff to CV -- replace
        !           380:                  *      3.  SYM to CV --- add
        !           381:                  *      4.  SYM to CV -- seperate file
        !           382:                  *
        !           383:                  *      Optional input file (not needed for case 4)
        !           384:                  *      Optional output file
        !           385:                  *      Optional sym file (implys sym->CV)
        !           386:                  *      Optional DBG file
        !           387:                  */
        !           388:                 
        !           389:             case 'C':
        !           390:                 if (szSymFile == NULL) {
        !           391:                     DoCoffToCv(szInputFile, szOutputFile, fAddCV);
        !           392:                 } else {
        !           393:                     DoSymToCv(szInputFile, szOutputFile, szDbgFile, szSymFile);
        !           394:                 }
        !           395:                 szInputFile = NULL;
        !           396:                 szOutputFile = NULL;
        !           397:                 szDbgFile = NULL;
        !           398:                 szSymFile = NULL;
        !           399:                 break;
        !           400:                 
        !           401:                 /*
        !           402:                  *  For changing the name of the debuggee --
        !           403:                  *      Must specify input file
        !           404:                  *      Must specify new name
        !           405:                  *      Optional output file
        !           406:                  */
        !           407:                 
        !           408:             case 'N':
        !           409:                 DoNameChange(szInputFile, szOutputFile, szExeName);
        !           410:                 szInputFile = NULL;
        !           411:                 szOutputFile = NULL;
        !           412:                 szExeName = NULL;
        !           413:                 break;
        !           414:                 
        !           415:                 /*
        !           416:                  *  For extraction of debug information
        !           417:                  *      Must specify input file
        !           418:                  *      Optional output file name
        !           419:                  *      Optional debug file name
        !           420:                  */
        !           421:                 
        !           422:             case 'X':
        !           423:                 DoExtract(szInputFile, szOutputFile, szDbgFile);
        !           424:                 break;
        !           425:                 
        !           426:                 /*
        !           427:                  *  For full strip of debug information
        !           428:                  *      Must specify input file
        !           429:                  *      Optional output file
        !           430:                  *      Optional debug file name
        !           431:                  */
        !           432:                 
        !           433:             case 'S':
        !           434:                 DoStrip(szInputFile, szOutputFile);
        !           435:                 break;
        !           436:             }
        !           437:         }
        !           438:     }
        !           439:     return;
        !           440: }                               /* ProcessCommandLineArgs() */
        !           441: 
        !           442: 
        !           443: void
        !           444: ReadDebugInfo(
        !           445:               PPOINTERS         p
        !           446:               )
        !           447: /*++
        !           448: 
        !           449: Routine Description:
        !           450: 
        !           451:     This function will go out and read in all of the debug information
        !           452:     into memory -- this is required because the input and output
        !           453:     files might be the same, if so then writing out informaiton may
        !           454:     destory data we need at a later time.
        !           455: 
        !           456: Arguments:
        !           457: 
        !           458:     p   - Supplies a pointer to the structure describing the debug info file
        !           459: 
        !           460: Return Value:
        !           461: 
        !           462:     None.
        !           463: 
        !           464: --*/
        !           465: 
        !           466: {
        !           467:     int                         i;
        !           468:     int                         cb;
        !           469:     char *                      pb;
        !           470:     PIMAGE_COFF_SYMBOLS_HEADER  pCoffDbgInfo;
        !           471:     
        !           472:     
        !           473:     /*
        !           474:      *   Allocate space to save pointers to debug info
        !           475:      */
        !           476:     
        !           477:     p->iptrs.rgpbDebugSave = (PCHAR *) malloc(p->iptrs.cDebugDir * sizeof(PCHAR));
        !           478:     memset(p->iptrs.rgpbDebugSave, 0, p->iptrs.cDebugDir * sizeof(PCHAR));
        !           479: 
        !           480:     /*
        !           481:      * Check each possible debug type record
        !           482:      */
        !           483: 
        !           484:     for (i=0; i<p->iptrs.cDebugDir; i++) {
        !           485:         /*
        !           486:          *   If there was debug information then copy over the
        !           487:          *      description block and cache in the actual debug
        !           488:          *      data.
        !           489:          */
        !           490:         
        !           491:         if ((i != IMAGE_DEBUG_TYPE_COFF) && (p->iptrs.rgDebugDir[i] != NULL)) {
        !           492:             p->iptrs.rgpbDebugSave[i] =
        !           493:               malloc( p->iptrs.rgDebugDir[i]->SizeOfData );
        !           494:             if (p->iptrs.rgpbDebugSave[i] == NULL) {
        !           495:                 FatalError(ERR_NO_MEMORY);
        !           496:             }
        !           497:             _try {
        !           498:                 memcpy(p->iptrs.rgpbDebugSave[i],
        !           499:                        p->iptrs.fptr +
        !           500:                        p->iptrs.rgDebugDir[i]->PointerToRawData,
        !           501:                        p->iptrs.rgDebugDir[i]->SizeOfData );
        !           502:             } _except(EXCEPTION_EXECUTE_HANDLER ) {
        !           503:                 free(p->iptrs.rgpbDebugSave[i]);
        !           504:                 p->iptrs.rgpbDebugSave[i] = NULL;
        !           505:             }
        !           506:         }
        !           507:     }
        !           508: 
        !           509:     /*
        !           510:      *  Treat COFF debug information seperately -- since the linker loves
        !           511:      *  to mix it in with other things
        !           512:      */
        !           513: 
        !           514:     if (p->iptrs.rgDebugDir[IMAGE_DEBUG_TYPE_COFF] != NULL) {
        !           515:         DbgDirCoff = *COFF_DIR(&p->iptrs);
        !           516:         
        !           517:         /*
        !           518:          *  Allocate space to save the coff debug info
        !           519:          */
        !           520:         
        !           521:         pb = p->iptrs.rgpbDebugSave[i] = malloc(DbgDirCoff.SizeOfData);
        !           522: 
        !           523:         /*
        !           524:          *  Copy over and point to the description for the
        !           525:          *      debug info.
        !           526:          */
        !           527:         
        !           528:         memcpy(pb, DbgDirCoff.PointerToRawData + p->iptrs.fptr,
        !           529:                sizeof(IMAGE_COFF_SYMBOLS_HEADER));
        !           530:         pCoffDbgInfo = (PIMAGE_COFF_SYMBOLS_HEADER) pb;
        !           531: 
        !           532:         /*
        !           533:          *  Now figure out how much space we really have -- only things
        !           534:          *      after the first symbol are "good" -- everything else is
        !           535:          *      suspect as part of something else.
        !           536:          */
        !           537:         
        !           538:         cb = DbgDirCoff.SizeOfData - pCoffDbgInfo->LvaToFirstSymbol;
        !           539: 
        !           540:         /*
        !           541:          *  Now copy over the real symbol information and set up the
        !           542:          *      new pointers in the header record
        !           543:          */
        !           544:         
        !           545:         memcpy(pb+sizeof(IMAGE_COFF_SYMBOLS_HEADER),
        !           546:                p->iptrs.fptr + DbgDirCoff.PointerToRawData +
        !           547:                pCoffDbgInfo->LvaToFirstSymbol, cb);
        !           548:         pCoffDbgInfo->LvaToFirstSymbol = sizeof(IMAGE_COFF_SYMBOLS_HEADER);
        !           549:         DbgDirCoff.SizeOfData = cb + sizeof(IMAGE_COFF_SYMBOLS_HEADER);
        !           550:         pCoffDbgInfo->NumberOfLinenumbers = 0;
        !           551:         pCoffDbgInfo->LvaToFirstLinenumber = 0;
        !           552:     }
        !           553:     return;
        !           554: }                               /* ReadDebugInfo() */
        !           555: 
        !           556: 
        !           557: 
        !           558: void
        !           559: WriteDebugInfo(
        !           560:               PPOINTERS         p,
        !           561:               BOOL              fAddCV,
        !           562:               BOOL              fStrip
        !           563:               )
        !           564: /*++
        !           565: 
        !           566: Routine Description:
        !           567: 
        !           568:     This function will go out and read in all of the debug information
        !           569:     into memory -- this is required because the input and output
        !           570:     files might be the same, if so then writing out informaiton may
        !           571:     destory data we need at a later time.
        !           572: 
        !           573: Arguments:
        !           574: 
        !           575:     p   - Supplies a pointer to the structure describing the debug info file
        !           576: 
        !           577: Return Value:
        !           578: 
        !           579:     None.
        !           580: 
        !           581: --*/
        !           582: 
        !           583: {
        !           584:     ULONG       PointerToDebugData = 0; /*  Offset from the start of the file
        !           585:                                          *  to the current location to write
        !           586:                                          *  debug information out.
        !           587:                                          */
        !           588:     ULONG       BaseOfDebugData = 0;
        !           589:     int                         i;
        !           590:     PIMAGE_DEBUG_DIRECTORY      pDir;
        !           591:     int                         flen;
        !           592:     PIMAGE_DEBUG_DIRECTORY      pDbgDir = NULL;
        !           593: 
        !           594: 
        !           595:     if (p->optrs.debugSection) {
        !           596:         BaseOfDebugData = PointerToDebugData =
        !           597:           p->optrs.debugSection->PointerToRawData;
        !           598:     } else if (p->optrs.sepHdr) {
        !           599:         BaseOfDebugData =  PointerToDebugData =
        !           600:           sizeof(IMAGE_SEPARATE_DEBUG_HEADER) +
        !           601:           p->optrs.sepHdr->NumberOfSections * sizeof(IMAGE_SECTION_HEADER) +
        !           602:           p->optrs.sepHdr->ExportedNamesSize;
        !           603:     }
        !           604: 
        !           605: 
        !           606:     /*
        !           607:      *  Step 2. If the debug information is mapped, we know this
        !           608:      *          from the section headers, then we may need to write
        !           609:      *          out a new debug director to point to the debug information
        !           610:      */
        !           611: 
        !           612:     if (fAddCV) {
        !           613:         if (p->optrs.optHdr) {
        !           614:             p->optrs.optHdr->DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].
        !           615:               VirtualAddress = p->optrs.debugSection->VirtualAddress;
        !           616:             p->optrs.optHdr->DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].Size +=
        !           617:               sizeof(IMAGE_DEBUG_DIRECTORY);
        !           618:         } else if (p->optrs.sepHdr) {
        !           619:             p->optrs.sepHdr->DebugDirectorySize +=
        !           620:               sizeof(IMAGE_DEBUG_DIRECTORY);
        !           621:         } else {
        !           622:             exit(1);
        !           623:         }
        !           624: 
        !           625:         if (p->optrs.sepHdr) {
        !           626:             pDbgDir = (PIMAGE_DEBUG_DIRECTORY) malloc(p->optrs.cDebugDir * sizeof(IMAGE_DEBUG_DIRECTORY));
        !           627:             for (i=0; i<p->optrs.cDebugDir; i++) {
        !           628:                 if (p->optrs.rgDebugDir[i] != NULL) {
        !           629:                     pDbgDir[i] = *(p->optrs.rgDebugDir[i]);
        !           630:                     p->optrs.rgDebugDir[i] = &pDbgDir[i];
        !           631:                 }
        !           632:             }
        !           633:         }
        !           634:         for (i=0; i<p->optrs.cDebugDir; i++) {
        !           635:             if (p->optrs.rgDebugDir[i]) {
        !           636:                 pDir = (PIMAGE_DEBUG_DIRECTORY) (PointerToDebugData +
        !           637:                                                  p->optrs.fptr);
        !           638:                 *pDir = *(p->optrs.rgDebugDir[i]);
        !           639:                 p->optrs.rgDebugDir[i] = pDir;
        !           640:                PointerToDebugData += sizeof(IMAGE_DEBUG_DIRECTORY);
        !           641:             }
        !           642:         }
        !           643:     }
        !           644: 
        !           645:     /*
        !           646:      *  For every debug info type, write out the debug information
        !           647:      *  and update any header information required
        !           648:      */
        !           649:     
        !           650:     for (i=0; i<p->optrs.cDebugDir; i++) {
        !           651:         if (p->optrs.rgDebugDir[i] != NULL) {
        !           652:             if (!fStrip ||
        !           653:                 (i == IMAGE_DEBUG_TYPE_FPO) ||
        !           654:                 (i == IMAGE_DEBUG_TYPE_MISC)) {
        !           655:                 if (p->optrs.rgpbDebugSave[i] != NULL) {
        !           656:                     p->optrs.rgDebugDir[i]->PointerToRawData =
        !           657:                       PointerToDebugData;
        !           658:                     if (p->optrs.debugSection) {
        !           659:                         p->optrs.rgDebugDir[i]->AddressOfRawData =
        !           660:                           p->optrs.debugSection->VirtualAddress +
        !           661:                             PointerToDebugData - BaseOfDebugData;
        !           662:                     }
        !           663:                     memcpy(p->optrs.fptr + PointerToDebugData,
        !           664:                            p->optrs.rgpbDebugSave[i],
        !           665:                            p->optrs.rgDebugDir[i]->SizeOfData);
        !           666: 
        !           667:                     if ((i == IMAGE_DEBUG_TYPE_COFF) &&
        !           668:                         (p->optrs.fileHdr != NULL)) {
        !           669:                         p->optrs.fileHdr->PointerToSymbolTable =
        !           670:                           PointerToDebugData + sizeof(IMAGE_COFF_SYMBOLS_HEADER);
        !           671:                     }
        !           672:                 }
        !           673:                 PointerToDebugData += p->optrs.rgDebugDir[i]->SizeOfData;
        !           674:             }
        !           675:         }
        !           676:     }
        !           677: 
        !           678:     if ((PointerToDebugData == BaseOfDebugData) && fStrip) {
        !           679:         p->optrs.fileHdr->NumberOfSections -= 1;
        !           680:     }
        !           681:      
        !           682:     /*
        !           683:      *   Step 4.  Clean up any COFF structures if we are replacing
        !           684:      *          the coff information with CV info.
        !           685:      */
        !           686: 
        !           687:     if ((p->optrs.rgDebugDir[IMAGE_DEBUG_TYPE_COFF] == NULL) &&
        !           688:         (p->optrs.fileHdr != NULL)) {
        !           689:         /*
        !           690:          *  Since there is no coff debug information -- clean out
        !           691:          *      both fields pointing to the debug info
        !           692:          */
        !           693:         
        !           694:         p->optrs.fileHdr->PointerToSymbolTable = 0;
        !           695:         p->optrs.fileHdr->NumberOfSymbols = 0;
        !           696:     }
        !           697: 
        !           698:     /*
        !           699:      *  Step 5.  Correct the alignments if needed.  If there is
        !           700:      *          a real .debug section in the file (i.e. it is mapped)
        !           701:      *          then update the description of the section.
        !           702:      */
        !           703: 
        !           704:     if (p->optrs.debugSection) {
        !           705:         p->optrs.debugSection->SizeOfRawData =
        !           706:           FileAlign(PointerToDebugData - BaseOfDebugData);
        !           707:         /*
        !           708:          * update the optional header with the new image size
        !           709:          */
        !           710:         
        !           711:         p->optrs.optHdr->SizeOfImage =
        !           712:           SectionAlign(p->optrs.debugSection->VirtualAddress +
        !           713:                        p->optrs.debugSection->SizeOfRawData);
        !           714:         p->optrs.optHdr->SizeOfInitializedData +=
        !           715:           p->optrs.debugSection->SizeOfRawData;
        !           716:     }
        !           717: 
        !           718:     /*
        !           719:      *  calculate the new file size
        !           720:      */
        !           721: 
        !           722:     if (p->optrs.optHdr != NULL) {
        !           723:         flen = FileAlign(PointerToDebugData);
        !           724:     } else {
        !           725:         flen = PointerToDebugData;
        !           726:     }
        !           727: 
        !           728:     /*
        !           729:      *  finally, update the eof pointer and close the file
        !           730:      */
        !           731:     
        !           732:     UnmapViewOfFile( p->optrs.fptr );
        !           733:     
        !           734:     if (!SetFilePointer( p->optrs.hFile, flen, 0, FILE_BEGIN )) {
        !           735:         FatalError( ERR_FILE_PTRS );
        !           736:     }
        !           737:     
        !           738:     if (!SetEndOfFile( p->optrs.hFile )) {
        !           739:         FatalError( ERR_SET_EOF );
        !           740:     }
        !           741:     
        !           742:     CloseHandle( p->optrs.hFile );
        !           743: 
        !           744:     /*
        !           745:      *  Exit -- we are done.
        !           746:      */
        !           747:     
        !           748:     return;
        !           749: }                               /* WriteDebugInfo() */
        !           750: 
        !           751: 
        !           752: 
        !           753: void
        !           754: MungeDebugHeadersCoffToCv(
        !           755:                           PPOINTERS  p,
        !           756:                           BOOL          fAddCV
        !           757:                           )
        !           758: 
        !           759: /*++
        !           760: 
        !           761: Routine Description:
        !           762: 
        !           763: 
        !           764: Arguments:
        !           765: 
        !           766:     p        - pointer to a POINTERS structure (see cofftocv.h)
        !           767: 
        !           768: Return Value:
        !           769: 
        !           770:     void
        !           771: 
        !           772: --*/
        !           773: 
        !           774: {
        !           775:     if (!fAddCV) {
        !           776:         CV_DIR(&p->optrs) = COFF_DIR(&p->optrs);
        !           777:         COFF_DIR(&p->optrs) = 0;
        !           778:     } else {
        !           779:         CV_DIR(&p->optrs) = &DbgDirSpare;
        !           780:         *(COFF_DIR(&p->optrs)) = *(COFF_DIR(&p->iptrs));
        !           781:     };
        !           782: 
        !           783:     *CV_DIR(&p->optrs) = *(COFF_DIR(&p->iptrs));
        !           784:     CV_DIR(&p->optrs)->Type = IMAGE_DEBUG_TYPE_CODEVIEW;
        !           785:     CV_DIR(&p->optrs)->SizeOfData =  p->pCvStart.size;
        !           786:     p->optrs.rgpbDebugSave[IMAGE_DEBUG_TYPE_CODEVIEW] = p->pCvStart.ptr;
        !           787:     
        !           788:     return;
        !           789: }                               /* MungeDebugHeadersCoffToCv() */
        !           790: 
        !           791: 
        !           792: 
        !           793: BOOL
        !           794: MapOutputFile ( PPOINTERS p, char *fname, int cb )
        !           795: 
        !           796: /*++
        !           797: 
        !           798: Routine Description:
        !           799: 
        !           800:     Maps the output file specified by the fname argument and saves the
        !           801:     file handle & file pointer in the POINTERS structure.
        !           802: 
        !           803: 
        !           804: Arguments:
        !           805: 
        !           806:     p        - pointer to a POINTERS structure (see cofftocv.h)
        !           807:     fname    - ascii string for the file name
        !           808: 
        !           809: 
        !           810: Return Value:
        !           811: 
        !           812:     TRUE     - file mapped ok
        !           813:     FALSE    - file could not be mapped
        !           814: 
        !           815: --*/
        !           816: 
        !           817: {
        !           818:     BOOL        rval;
        !           819:     HANDLE      hMap   = NULL;
        !           820:     DWORD       oSize;
        !           821: 
        !           822:     rval = FALSE;
        !           823: 
        !           824:     p->optrs.hFile = CreateFile( fname,
        !           825:                         GENERIC_READ | GENERIC_WRITE,
        !           826:                         FILE_SHARE_READ | FILE_SHARE_WRITE,
        !           827:                         NULL,
        !           828:                         OPEN_ALWAYS,
        !           829:                         0,
        !           830:                         NULL );
        !           831: 
        !           832:     if (p->optrs.hFile == INVALID_HANDLE_VALUE) {
        !           833:        goto exit;
        !           834:     }
        !           835: 
        !           836:     oSize = p->iptrs.fsize;
        !           837:     if (p->pCvStart.ptr != NULL) {
        !           838:         oSize += p->pCvStart.size;
        !           839:     }
        !           840:     oSize += cb;
        !           841:     oSize += p->iptrs.cDebugDir * sizeof(IMAGE_DEBUG_DIRECTORY);
        !           842: 
        !           843:     hMap = CreateFileMapping( p->optrs.hFile, NULL, PAGE_READWRITE,
        !           844:                               0, oSize, NULL );
        !           845: 
        !           846:     if (hMap == NULL) {
        !           847:        goto exit;
        !           848:     }
        !           849: 
        !           850:     p->optrs.fptr = MapViewOfFile( hMap, FILE_MAP_WRITE, 0, 0, 0 );
        !           851: 
        !           852:     if (p->optrs.fptr == NULL) {
        !           853:        goto exit;
        !           854:     }
        !           855:     rval = TRUE;
        !           856: exit:
        !           857:     return rval;
        !           858: }                               /* MapOutputFile() */
        !           859: 
        !           860: BOOL
        !           861: CalculateOutputFilePointers( PIMAGEPOINTERS pi, PIMAGEPOINTERS po )
        !           862: 
        !           863: /*++
        !           864: 
        !           865: Routine Description:
        !           866: 
        !           867:     This function calculates the output file pointers based on the
        !           868:     input file pointers.  The same address is used but they are all
        !           869:     re-based off the output file's file pointer.
        !           870: 
        !           871: Arguments:
        !           872: 
        !           873:     p        - pointer to a IMAGEPOINTERS structure (see cofftocv.h)
        !           874: 
        !           875: 
        !           876: Return Value:
        !           877: 
        !           878:     TRUE     - pointers were created
        !           879:     FALSE    - pointers could not be created
        !           880: 
        !           881: --*/
        !           882: {
        !           883:     int i;
        !           884:     
        !           885:     // fixup the pointers relative the fptr for the output file
        !           886:     po->dosHdr       = (PIMAGE_DOS_HEADER)      AdjustPtr(pi->dosHdr);
        !           887:     po->ntHdr        = (PIMAGE_NT_HEADERS)      AdjustPtr(pi->ntHdr);
        !           888:     po->fileHdr      = (PIMAGE_FILE_HEADER)     AdjustPtr(pi->fileHdr);
        !           889:     po->optHdr       = (PIMAGE_OPTIONAL_HEADER) AdjustPtr(pi->optHdr);
        !           890:     po->sectionHdrs  = (PIMAGE_SECTION_HEADER)  AdjustPtr(pi->sectionHdrs);
        !           891:     po->sepHdr       = (PIMAGE_SEPARATE_DEBUG_HEADER) AdjustPtr(pi->sepHdr);
        !           892:     po->debugSection = (PIMAGE_SECTION_HEADER)  AdjustPtr(pi->debugSection);
        !           893:     po->AllSymbols   = (PIMAGE_SYMBOL)          AdjustPtr(pi->AllSymbols);
        !           894:     po->stringTable  = (PUCHAR)                 AdjustPtr(pi->stringTable);
        !           895: 
        !           896:     // move the data from the input file to the output file
        !           897:     memcpy( po->fptr, pi->fptr, pi->fsize );
        !           898: 
        !           899:     po->cDebugDir = pi->cDebugDir;
        !           900:     po->rgDebugDir = malloc(po->cDebugDir * sizeof(po->rgDebugDir[0]));
        !           901:     memset(po->rgDebugDir, 0, po->cDebugDir * sizeof(po->rgDebugDir[0]));
        !           902:     
        !           903:     for (i=0; i<po->cDebugDir; i++) {
        !           904:         po->rgDebugDir[i] = (PIMAGE_DEBUG_DIRECTORY) AdjustPtr(pi->rgDebugDir[i]);
        !           905:     }
        !           906:     po->rgpbDebugSave = pi->rgpbDebugSave;
        !           907: 
        !           908:     /*
        !           909:      *  Point the input stream to the modified coff descriptor
        !           910:      */
        !           911: 
        !           912:     if (pi->rgDebugDir[IMAGE_DEBUG_TYPE_COFF] != NULL) {
        !           913:         pi->rgDebugDir[IMAGE_DEBUG_TYPE_COFF] = &DbgDirCoff;
        !           914:     }
        !           915: 
        !           916:     return TRUE;
        !           917: }
        !           918: 
        !           919: 
        !           920: void
        !           921: FatalError(
        !           922:            int  idMsg,
        !           923:            ...
        !           924:            )
        !           925: /*++
        !           926: 
        !           927: Routine Description:
        !           928: 
        !           929:     Prints a message string to stderr and then exits.
        !           930: 
        !           931: Arguments:
        !           932: 
        !           933:     s        - message string to be printed
        !           934: 
        !           935: Return Value:
        !           936: 
        !           937:     void
        !           938: 
        !           939: --*/
        !           940: 
        !           941: {
        !           942:     va_list     marker;
        !           943:     char        rgchFormat[256];
        !           944:     char        rgch[256];
        !           945: 
        !           946:     LoadString(GetModuleHandle(NULL), idMsg, rgchFormat, sizeof(rgchFormat));
        !           947:     
        !           948:     va_start(marker, idMsg);
        !           949:     vsprintf(rgch, rgchFormat, marker);
        !           950:     va_end(marker);
        !           951:     
        !           952:     fprintf(stderr, "%s\n", rgch);
        !           953:     
        !           954:     exit(1);
        !           955: }                               /* FatalError() */
        !           956: 
        !           957: 
        !           958: void
        !           959: ComputeChecksum(  char *szExeFile )
        !           960: 
        !           961: /*++
        !           962: 
        !           963: Routine Description:
        !           964: 
        !           965:     Computes a new checksum for the image by calling imagehlp.dll
        !           966: 
        !           967: Arguments:
        !           968: 
        !           969:     szExeFile - exe file name
        !           970: 
        !           971: 
        !           972: Return Value:
        !           973: 
        !           974:     void
        !           975: 
        !           976: --*/
        !           977: 
        !           978: {
        !           979:     DWORD              dwHeaderSum = 0;
        !           980:     DWORD              dwCheckSum = 0;
        !           981:     HANDLE             hFile;
        !           982:     DWORD              cb;
        !           983:     IMAGE_DOS_HEADER   dosHdr;
        !           984:     IMAGE_NT_HEADERS   ntHdr;
        !           985: 
        !           986:     if (MapFileAndCheckSum(szExeFile, &dwHeaderSum, &dwCheckSum) != CHECKSUM_SUCCESS) {
        !           987:         FatalError( ERR_CHECKSUM_CALC );
        !           988:     }
        !           989: 
        !           990:     hFile = CreateFile( szExeFile,
        !           991:                         GENERIC_READ | GENERIC_WRITE,
        !           992:                         FILE_SHARE_READ | FILE_SHARE_WRITE,
        !           993:                         NULL,
        !           994:                         OPEN_EXISTING,
        !           995:                         0,
        !           996:                         NULL
        !           997:                       );
        !           998: 
        !           999:     // seek to the beginning of the file
        !          1000:     SetFilePointer( hFile, 0, 0, FILE_BEGIN );
        !          1001: 
        !          1002:     // read in the dos header
        !          1003:     if ((ReadFile(hFile, &dosHdr, sizeof(dosHdr), &cb, 0) == FALSE) || (cb != sizeof(dosHdr))) {
        !          1004:         FatalError( ERR_CHECKSUM_CALC );
        !          1005:     }
        !          1006: 
        !          1007:     // read in the pe header
        !          1008:     if ((dosHdr.e_magic != IMAGE_DOS_SIGNATURE) ||
        !          1009:         (SetFilePointer(hFile, dosHdr.e_lfanew, 0, FILE_BEGIN) == -1L)) {
        !          1010:         FatalError( ERR_CHECKSUM_CALC );
        !          1011:     }
        !          1012: 
        !          1013:     // read in the nt header
        !          1014:     if ((!ReadFile(hFile, &ntHdr, sizeof(ntHdr), &cb, 0)) || (cb != sizeof(ntHdr))) {
        !          1015:         FatalError( ERR_CHECKSUM_CALC );
        !          1016:     }
        !          1017: 
        !          1018:     if (SetFilePointer(hFile, dosHdr.e_lfanew, 0, FILE_BEGIN) == -1L) {
        !          1019:         FatalError( ERR_CHECKSUM_CALC );
        !          1020:     }
        !          1021: 
        !          1022:     ntHdr.OptionalHeader.CheckSum = dwCheckSum;
        !          1023: 
        !          1024:     if (!WriteFile(hFile, &ntHdr, sizeof(ntHdr), &cb, NULL)) {
        !          1025:         FatalError( ERR_CHECKSUM_CALC );
        !          1026:     }
        !          1027: 
        !          1028:     CloseHandle(hFile);
        !          1029:     return;
        !          1030: }
        !          1031: 
        !          1032: 
        !          1033: void
        !          1034: MungeExeName(
        !          1035:              PPOINTERS          p,
        !          1036:              char *             szExeName
        !          1037:              )
        !          1038: /*++
        !          1039: 
        !          1040: Routine Description:
        !          1041: 
        !          1042:     description-of-function.
        !          1043: 
        !          1044: Arguments:
        !          1045: 
        !          1046:     argument-name - Supplies | Returns description of argument.
        !          1047:     .
        !          1048:     .
        !          1049: 
        !          1050: Return Value:
        !          1051: 
        !          1052:     None.
        !          1053: 
        !          1054: --*/
        !          1055: 
        !          1056: {
        !          1057:     PIMAGE_DEBUG_MISC   pMiscIn;
        !          1058:     PIMAGE_DEBUG_MISC   pMiscOut;
        !          1059:     int                 cb;
        !          1060:     int                 i;
        !          1061: 
        !          1062:     for (i=0; i<p->iptrs.cDebugDir; i++) {
        !          1063:         if (p->optrs.rgDebugDir[i] != 0) {
        !          1064:             *(p->optrs.rgDebugDir[i]) = *(p->iptrs.rgDebugDir[i]);
        !          1065:         }
        !          1066:     }
        !          1067: 
        !          1068:     pMiscIn = (PIMAGE_DEBUG_MISC)
        !          1069:       p->iptrs.rgpbDebugSave[IMAGE_DEBUG_TYPE_MISC];
        !          1070: 
        !          1071:     if (p->optrs.rgDebugDir[IMAGE_DEBUG_TYPE_MISC] == NULL) {
        !          1072:         p->optrs.rgDebugDir[IMAGE_DEBUG_TYPE_MISC] = &DbgDirSpare;
        !          1073:         memset(&DbgDirSpare, 0, sizeof(DbgDirSpare));
        !          1074:     }
        !          1075:         
        !          1076:     pMiscOut = (PIMAGE_DEBUG_MISC)
        !          1077:       p->optrs.rgpbDebugSave[IMAGE_DEBUG_TYPE_MISC] = 
        !          1078:       malloc(p->optrs.rgDebugDir[IMAGE_DEBUG_TYPE_MISC]->SizeOfData +
        !          1079:              strlen(szExeName));
        !          1080:     cb = p->optrs.rgDebugDir[IMAGE_DEBUG_TYPE_MISC]->SizeOfData;
        !          1081: 
        !          1082:     while ( cb > 0 ) {
        !          1083:         if (pMiscIn->DataType == IMAGE_DEBUG_MISC_EXENAME) {
        !          1084:             pMiscOut->DataType = IMAGE_DEBUG_MISC_EXENAME;
        !          1085:             pMiscOut->Length = (sizeof(IMAGE_DEBUG_MISC) +
        !          1086:                                 strlen(szExeName) + 3) & ~3;
        !          1087:             pMiscOut->Unicode = FALSE;
        !          1088:             strcpy(&pMiscOut->Data[0], szExeName);
        !          1089:             szExeName = NULL;
        !          1090:         } else {
        !          1091:             memcpy(pMiscOut, pMiscIn, pMiscIn->Length);
        !          1092:         }
        !          1093: 
        !          1094:         p->optrs.rgDebugDir[IMAGE_DEBUG_TYPE_MISC]->SizeOfData +=
        !          1095:           (pMiscOut->Length - pMiscIn->Length);
        !          1096:         
        !          1097:         cb -= pMiscIn->Length;
        !          1098:         pMiscIn = (PIMAGE_DEBUG_MISC) (((char *) pMiscIn) + pMiscIn->Length);
        !          1099:         pMiscOut = (PIMAGE_DEBUG_MISC) (((char *) pMiscOut) + pMiscOut->Length);
        !          1100:     }
        !          1101: 
        !          1102:     if (szExeName) {
        !          1103:         pMiscOut->DataType = IMAGE_DEBUG_MISC_EXENAME;
        !          1104:         pMiscOut->Length = (sizeof(IMAGE_DEBUG_MISC) +
        !          1105:                             strlen(szExeName) + 3) & ~3;
        !          1106:         pMiscOut->Unicode = FALSE;
        !          1107:         strcpy(&pMiscOut->Data[0], szExeName);
        !          1108:     }
        !          1109:     
        !          1110:     return;
        !          1111: }                               /* MungeExeName() */
        !          1112: 
        !          1113: 
        !          1114: /***    DoCoffToCv
        !          1115:  *
        !          1116:  *
        !          1117:  */
        !          1118: 
        !          1119: void DoCoffToCv(char * szInput, char * szOutput, BOOL fAddCV)
        !          1120: {
        !          1121:     POINTERS    p;
        !          1122:     
        !          1123:     /*
        !          1124:      *  Do default checking
        !          1125:      */
        !          1126:      
        !          1127:     if (szOutput == NULL) {
        !          1128:         szOutput = szInput;
        !          1129:     }
        !          1130: 
        !          1131:     /*
        !          1132:      *  Open the input file name and setup the pointers into the file
        !          1133:      */
        !          1134:     
        !          1135:     if (!MapInputFile( &p, NULL, szInput )) {
        !          1136:         FatalError( ERR_OPEN_INPUT_FILE, szInput );
        !          1137:     }
        !          1138: 
        !          1139:     /*
        !          1140:      *  Now, if we thing we are playing with PE exes then we need
        !          1141:      *  to setup the pointers into the map file
        !          1142:      */
        !          1143: 
        !          1144:     if (!CalculateNtImagePointers( &p.iptrs )) {
        !          1145:         FatalError( ERR_INVALID_PE, szInput );
        !          1146:     }
        !          1147: 
        !          1148:     /*
        !          1149:      *  We are about to try and do the coff to cv symbol conversion.
        !          1150:      *
        !          1151:      *  Verify that the operation is legal.
        !          1152:      *
        !          1153:      *      1.  We need to have coff debug information to start with
        !          1154:      *      2.  If the debug info is not mapped then we must not
        !          1155:      *              be trying to add CodeView info.
        !          1156:      */
        !          1157:     
        !          1158:     if ((p.iptrs.AllSymbols == NULL) || (COFF_DIR(&p.iptrs) == NULL)) {
        !          1159:         FatalError( ERR_NO_COFF );
        !          1160:     }
        !          1161:     
        !          1162:     if (fAddCV && (p.iptrs.debugSection == 0) && (p.iptrs.sepHdr == NULL)) {
        !          1163:         FatalError( ERR_NOT_MAPPED );
        !          1164:     }
        !          1165:     
        !          1166:     /*
        !          1167:      *  Now go out an preform the acutal conversion.
        !          1168:      */
        !          1169:     
        !          1170:     if (!ConvertCoffToCv( &p )) {
        !          1171:         FatalError( ERR_COFF_TO_CV );
        !          1172:     }
        !          1173:     
        !          1174:     /*
        !          1175:      *  Read in any additional debug information in the file
        !          1176:      */
        !          1177:     
        !          1178:     ReadDebugInfo(&p);
        !          1179:     
        !          1180:     /*
        !          1181:      *  Open the output file and adjust the pointers so that
        !          1182:      *      we are ok.
        !          1183:      */
        !          1184:     
        !          1185:     if (!MapOutputFile( &p, szOutput, 0 )) {
        !          1186:         FatalError( ERR_MAP_FILE, szOutput );
        !          1187:     }
        !          1188:     
        !          1189:     CalculateOutputFilePointers( &p.iptrs, &p.optrs );
        !          1190:     
        !          1191:     /*
        !          1192:      *      Munge the various debug information structures
        !          1193:      *      to preform the correct operations
        !          1194:      */
        !          1195:     
        !          1196:     MungeDebugHeadersCoffToCv( &p, fAddCV );
        !          1197:     
        !          1198:     /*
        !          1199:      *  Write out the debug information to the end of the exe
        !          1200:      */
        !          1201:     
        !          1202:     WriteDebugInfo( &p, fAddCV, FALSE );
        !          1203: 
        !          1204:     /*
        !          1205:      *  and finally compute the checksum
        !          1206:      */
        !          1207: 
        !          1208:     if (p.iptrs.fileHdr != NULL) {
        !          1209:         ComputeChecksum( szOutput );
        !          1210:     }
        !          1211: 
        !          1212:     return;
        !          1213: }                               /* DoCoffToCv() */
        !          1214:  
        !          1215: /***    DoSymToCv
        !          1216:  *
        !          1217:  */
        !          1218: 
        !          1219: void DoSymToCv(char * szInput, char * szOutput, char * szDbg, char * szSym)
        !          1220: {
        !          1221:     POINTERS    p;
        !          1222:     HANDLE      hFile;
        !          1223:     DWORD       cb;
        !          1224:     OFSTRUCT    ofs;
        !          1225:     
        !          1226:     /*
        !          1227:      *  Open the input file name and setup the pointers into the file
        !          1228:      */
        !          1229:     
        !          1230:     if (!MapInputFile( &p, NULL, szSym )) {
        !          1231:         FatalError(ERR_OPEN_INPUT_FILE, szSym);
        !          1232:     }
        !          1233: 
        !          1234:     /*
        !          1235:      *   Now preform the desired operation
        !          1236:      */
        !          1237: 
        !          1238:     if ((szOutput == NULL) && (szDbg == NULL)) {
        !          1239:         szOutput = szInput;
        !          1240:     }
        !          1241:         
        !          1242:     ConvertSymToCv( &p );
        !          1243: 
        !          1244:     if (szOutput) {
        !          1245:         if (szOutput != szInput) {
        !          1246:             if (OpenFile(szInput, &ofs, OF_EXIST) == 0) {
        !          1247:                 FatalError(ERR_OPEN_INPUT_FILE, szInput);
        !          1248:             }
        !          1249:             if (CopyFile(szInput, szOutput, FALSE) == 0) {
        !          1250:                 FatalError(ERR_OPEN_WRITE_FILE, szOutput);
        !          1251:             }
        !          1252:         }
        !          1253:         hFile = CreateFile(szOutput, GENERIC_WRITE, 0, NULL,
        !          1254:                            CREATE_ALWAYS,
        !          1255:                            FILE_ATTRIBUTE_NORMAL,  NULL);
        !          1256:         if (hFile == INVALID_HANDLE_VALUE) {
        !          1257:             FatalError(ERR_OPEN_WRITE_FILE, szOutput);
        !          1258:         }
        !          1259:         SetFilePointer(hFile, 0, 0, FILE_END);
        !          1260:     } else if (szDbg) {
        !          1261:         hFile = CreateFile(szDbg, GENERIC_WRITE, 0, NULL,
        !          1262:                                OPEN_ALWAYS,
        !          1263:                                FILE_ATTRIBUTE_NORMAL,  NULL);
        !          1264:         if (hFile == INVALID_HANDLE_VALUE) {
        !          1265:             FatalError(ERR_OPEN_WRITE_FILE, szDbg);
        !          1266:         }
        !          1267:     }
        !          1268:     
        !          1269:     WriteFile(hFile, p.pCvStart.ptr, p.pCvStart.size, &cb, NULL);
        !          1270:     CloseHandle(hFile);
        !          1271: 
        !          1272:     return;
        !          1273: }                               /* DoSymToCv() */
        !          1274: 
        !          1275: 
        !          1276: void DoNameChange(char * szInput, char * szOutput, char * szNewName)
        !          1277: {
        !          1278:     POINTERS    p;
        !          1279:     
        !          1280:     /*
        !          1281:      *  Open the input file name and setup the pointers into the file
        !          1282:      */
        !          1283:     
        !          1284:     if (!MapInputFile( &p, NULL, szInput )) {
        !          1285:         FatalError(ERR_OPEN_INPUT_FILE, szInput);
        !          1286:     }
        !          1287: 
        !          1288:     /*
        !          1289:      *  Now, if we thing we are playing with PE exes then we need
        !          1290:      *  to setup the pointers into the map file
        !          1291:      */
        !          1292: 
        !          1293:     if (!CalculateNtImagePointers( &p.iptrs )) {
        !          1294:         FatalError(ERR_INVALID_PE, szInput);
        !          1295:     }
        !          1296: 
        !          1297:     /*
        !          1298:      *   Now preform the desired operation
        !          1299:      */
        !          1300: 
        !          1301:     if (szOutput == NULL) {
        !          1302:         szOutput = szInput;
        !          1303:     }
        !          1304:     
        !          1305:     if (szNewName == NULL) {
        !          1306:         szNewName = szOutput;
        !          1307:     }
        !          1308: 
        !          1309:     if (p.iptrs.sepHdr != NULL) {
        !          1310:         FatalError(ERR_EDIT_DBG_FILE);
        !          1311:     }
        !          1312:     
        !          1313:     /*
        !          1314:      *  Read in all of the debug information
        !          1315:      */
        !          1316:     
        !          1317:     ReadDebugInfo(&p);
        !          1318:     
        !          1319:     /*
        !          1320:      *   Open the output file and adjust the pointers.
        !          1321:      */
        !          1322:     
        !          1323:     if (!MapOutputFile(&p, szOutput,
        !          1324:                        sizeof(szNewName) * 2 + sizeof(IMAGE_DEBUG_MISC))) {
        !          1325:         FatalError(ERR_MAP_FILE, szOutput);
        !          1326:     }
        !          1327:     
        !          1328:     CalculateOutputFilePointers(&p.iptrs, &p.optrs);
        !          1329:     
        !          1330:     /*
        !          1331:      *      Munge the name of the file
        !          1332:      */
        !          1333:     
        !          1334:     MungeExeName(&p, szNewName);
        !          1335:     
        !          1336:     /*
        !          1337:      *  Write out the debug information to the end of the exe
        !          1338:      */
        !          1339:     
        !          1340:     WriteDebugInfo(&p, FALSE, FALSE);
        !          1341:     
        !          1342:     /*
        !          1343:      *  and finally compute the checksum
        !          1344:      */
        !          1345: 
        !          1346:     if (p.iptrs.fileHdr != NULL) {
        !          1347:         ComputeChecksum( szOutput );
        !          1348:     }
        !          1349: 
        !          1350:     return;
        !          1351: }                               /* DoNameChange() */
        !          1352: 
        !          1353: 
        !          1354: void MungeStrip(PPOINTERS p, BOOL fPartial)
        !          1355: {
        !          1356:     PIMAGE_SECTION_HEADER       pSection;
        !          1357:     ULONG                       flen;
        !          1358:     
        !          1359:     if (p->iptrs.debugSection == NULL) {
        !          1360:                                 /* unmapped */
        !          1361:         return;
        !          1362:     }
        !          1363:     
        !          1364:     /*
        !          1365:      *  If the last section is not the debug section then
        !          1366:      *  we can't do this.
        !          1367:      */
        !          1368: 
        !          1369:     pSection = &p->optrs.sectionHdrs[p->iptrs.numberOfSections-1];
        !          1370:     if (p->optrs.debugSection != pSection) {
        !          1371:         exit(1);
        !          1372:     }
        !          1373:     pSection -= 1;
        !          1374: 
        !          1375:     /*
        !          1376:      *  If full strip ----
        !          1377:      *  Reduced the number of sections by one, but don't bother
        !          1378:      *  actucally removing the section descriptor, its not worth
        !          1379:      *  the time.
        !          1380:      */
        !          1381: 
        !          1382:     if (!fPartial) {
        !          1383:         p->optrs.numberOfSections -= 1;
        !          1384:         p->optrs.fileHdr->NumberOfSections -= 1;
        !          1385: 
        !          1386:         /*
        !          1387:          *  If we are doing a full strip then clear out all pointers
        !          1388:          *      to debug info
        !          1389:          */
        !          1390: 
        !          1391:         p->optrs.optHdr->DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress = 0;
        !          1392:         p->optrs.optHdr->DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].Size = 0;
        !          1393:         p->optrs.fileHdr->PointerToSymbolTable = 0;
        !          1394:         p->optrs.fileHdr->NumberOfSymbols = 0;
        !          1395: 
        !          1396:         p->optrs.optHdr->SizeOfImage = SectionAlign(pSection->VirtualAddress +
        !          1397:                                                     pSection->SizeOfRawData);
        !          1398:         p->optrs.optHdr->SizeOfInitializedData -=
        !          1399:           p->optrs.debugSection->SizeOfRawData;
        !          1400: 
        !          1401:         flen = FileAlign(pSection->VirtualAddress + pSection->SizeOfRawData );
        !          1402:         UnmapViewOfFile( p->optrs.fptr );
        !          1403: 
        !          1404:         if (!SetFilePointer( p->optrs.hFile, flen, 0, FILE_BEGIN )) {
        !          1405:             FatalError(ERR_FILE_PTRS);
        !          1406:         }
        !          1407: 
        !          1408:         if (!SetEndOfFile( p->optrs.hFile )) {
        !          1409:             FatalError( ERR_SET_EOF );
        !          1410:         }
        !          1411: 
        !          1412:         CloseHandle( p->optrs.hFile );
        !          1413: 
        !          1414:         return;
        !          1415:     }
        !          1416: 
        !          1417:     /*
        !          1418:      *  Partial strip
        !          1419:      */
        !          1420: 
        !          1421:     p->optrs.fileHdr->PointerToSymbolTable = 0;
        !          1422:     p->optrs.fileHdr->NumberOfSymbols = 0;
        !          1423: 
        !          1424:     WriteDebugInfo( p, FALSE, TRUE );
        !          1425: 
        !          1426:     return;
        !          1427: }                               /* MungeStrip() */
        !          1428: 
        !          1429: void    DoStrip(char * szInput, char * szOutput)
        !          1430: {
        !          1431:     POINTERS    p;
        !          1432:     
        !          1433:     if (szOutput == NULL) {
        !          1434:         szOutput = szInput;
        !          1435:     }
        !          1436: 
        !          1437:     /*
        !          1438:      *  Open the input file and setup the pointers into it.
        !          1439:      */
        !          1440: 
        !          1441:     if (!MapInputFile(&p, NULL, szInput)) {
        !          1442:         FatalError(ERR_OPEN_INPUT_FILE, szInput);
        !          1443:     }
        !          1444: 
        !          1445:     /*
        !          1446:      *  Now, setup the rest of the input points
        !          1447:      */
        !          1448: 
        !          1449:     if (!CalculateNtImagePointers(&p.iptrs)) {
        !          1450:         FatalError(ERR_INVALID_PE, szInput);
        !          1451:     }
        !          1452: 
        !          1453:     /*
        !          1454:      *  Open the output file and adjust the pointers
        !          1455:      */
        !          1456: 
        !          1457:     if (!MapOutputFile(&p, szOutput, 0)) {
        !          1458:         FatalError(ERR_MAP_FILE, szOutput);
        !          1459:     }
        !          1460: 
        !          1461:     CalculateOutputFilePointers(&p.iptrs, &p.optrs);
        !          1462: 
        !          1463:     /*
        !          1464:      *  Munge the file headers
        !          1465:      */
        !          1466: 
        !          1467:     MungeStrip(&p, FALSE);
        !          1468:     
        !          1469:     ComputeChecksum(szOutput);
        !          1470: 
        !          1471:     return;
        !          1472: }                               /* DoStrip() */
        !          1473: 
        !          1474: void DoExtract(char * szInput, char * szOutput, char * szDbgFile)
        !          1475: {
        !          1476:     IMAGE_SEPARATE_DEBUG_HEADER         sepHdr;
        !          1477:     DWORD *                             rgobDbgDir;
        !          1478:     PIMAGE_DEBUG_DIRECTORY              rgDbgDir;
        !          1479:     POINTERS                            p;
        !          1480:     HANDLE                              hFile;
        !          1481:     int                                 cb;
        !          1482:     int                                 i;
        !          1483:     DWORD                               BaseOfDebugData;
        !          1484:     DWORD                               PointerToDebugData;
        !          1485:     
        !          1486:     if (!MapInputFile(&p, NULL, szInput)) {
        !          1487:         FatalError(ERR_OPEN_INPUT_FILE, szInput);
        !          1488:     }
        !          1489: 
        !          1490:     if (!CalculateNtImagePointers(&p.iptrs)) {
        !          1491:         FatalError(ERR_INVALID_PE, szInput);
        !          1492:     }
        !          1493: 
        !          1494:     if (szOutput == NULL) {
        !          1495:         szOutput = szInput;
        !          1496:     }
        !          1497:     
        !          1498:     if (!MapOutputFile(&p, szOutput, 0)) {
        !          1499:         FatalError(ERR_MAP_FILE, szOutput);
        !          1500:     }
        !          1501: 
        !          1502:     ReadDebugInfo(&p);
        !          1503: 
        !          1504: 
        !          1505:     CalculateOutputFilePointers(&p.iptrs, &p.optrs);
        !          1506: 
        !          1507:     /*
        !          1508:      * Open the DBG file to be dumped
        !          1509:      */
        !          1510: 
        !          1511:     if (szDbgFile == NULL) {
        !          1512:         char    rgchDrive[_MAX_DRIVE];
        !          1513:         char    rgchPath[_MAX_PATH];
        !          1514:         char    rgchBase[_MAX_FNAME];
        !          1515: 
        !          1516:         _splitpath(szInput, rgchDrive, rgchPath, rgchBase, NULL);
        !          1517:         szDbgFile = malloc(strlen(rgchDrive) + strlen(rgchPath) +
        !          1518:                              strlen(rgchBase) + 5);
        !          1519:         strcpy(szDbgFile, rgchDrive);
        !          1520:         strcat(szDbgFile, rgchPath);
        !          1521:         strcat(szDbgFile, rgchBase);
        !          1522:         strcat(szDbgFile, ".DBG");
        !          1523:     }
        !          1524: 
        !          1525:     hFile = CreateFile(szDbgFile, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS,
        !          1526:                        FILE_ATTRIBUTE_NORMAL, NULL);
        !          1527:     if (hFile == INVALID_HANDLE_VALUE) {
        !          1528:         FatalError(ERR_OPEN_WRITE_FILE, szDbgFile);
        !          1529:     }
        !          1530: 
        !          1531:     /*
        !          1532:      *  Create a header for the Dbg File
        !          1533:      */
        !          1534: 
        !          1535:     sepHdr.Signature = IMAGE_SEPARATE_DEBUG_SIGNATURE;
        !          1536:     sepHdr.Flags = 0;
        !          1537:     sepHdr.Machine = p.optrs.fileHdr->Machine;
        !          1538:     sepHdr.Characteristics = 0;
        !          1539:     sepHdr.TimeDateStamp = 0;
        !          1540:     sepHdr.CheckSum = 0;
        !          1541:     sepHdr.ImageBase = 0;
        !          1542:     sepHdr.SizeOfImage = 0;
        !          1543:     sepHdr.NumberOfSections = p.iptrs.numberOfSections;
        !          1544:     sepHdr.ExportedNamesSize = 0;
        !          1545:     sepHdr.DebugDirectorySize = 0;
        !          1546: 
        !          1547:     WriteFile(hFile, &sepHdr, sizeof(sepHdr), &cb, NULL);
        !          1548: 
        !          1549:     /*
        !          1550:      *  Put out the new section headers
        !          1551:      */
        !          1552: 
        !          1553:     for (i=0; i<p.iptrs.numberOfSections; i++) {
        !          1554:         WriteFile(hFile, &p.iptrs.sectionHdrs[i], sizeof(IMAGE_SECTION_HEADER),
        !          1555:                   &cb, NULL);
        !          1556:     }
        !          1557:     
        !          1558:     /*
        !          1559:      *  Put out the export table
        !          1560:      */
        !          1561: 
        !          1562:     for (i=0; i<p.iptrs.numberOfSections; i++) {
        !          1563:         if (strcmp(p.iptrs.sectionHdrs[i].Name, ".edata") == 0) {
        !          1564:             WriteFile(hFile,
        !          1565:                       p.iptrs.fptr + p.iptrs.sectionHdrs[i].PointerToRawData,
        !          1566:                       p.iptrs.sectionHdrs[i].SizeOfRawData, &cb, NULL);
        !          1567:             sepHdr.ExportedNamesSize = p.iptrs.sectionHdrs[i].SizeOfRawData;
        !          1568:             break;
        !          1569:         }
        !          1570:     }
        !          1571:     
        !          1572:     /*
        !          1573:      *  Put out the new dbg directory headers
        !          1574:      */
        !          1575: 
        !          1576:     BaseOfDebugData = PointerToDebugData =
        !          1577:       SetFilePointer(hFile, 0, 0, FILE_CURRENT);
        !          1578:     
        !          1579:     rgobDbgDir = (DWORD *) malloc(p.optrs.cDebugDir * sizeof(DWORD));
        !          1580:     rgDbgDir = (PIMAGE_DEBUG_DIRECTORY)
        !          1581:       malloc(p.optrs.cDebugDir * sizeof(IMAGE_DEBUG_DIRECTORY));
        !          1582:     memset(rgobDbgDir, 0, p.optrs.cDebugDir * sizeof(DWORD));
        !          1583:     memset(rgDbgDir, 0, p.optrs.cDebugDir * sizeof(IMAGE_DEBUG_DIRECTORY));
        !          1584:     
        !          1585:     for (i=0; i<p.iptrs.cDebugDir; i++) {
        !          1586:         if (p.iptrs.rgDebugDir[i] != NULL) {
        !          1587:             WriteFile(hFile, p.iptrs.rgDebugDir[i],
        !          1588:                       sizeof(IMAGE_DEBUG_DIRECTORY), &cb, NULL);
        !          1589:             rgobDbgDir[i] = PointerToDebugData;
        !          1590:             rgDbgDir[i] = *(p.iptrs.rgDebugDir[i]);
        !          1591:             PointerToDebugData += sizeof(IMAGE_DEBUG_DIRECTORY);
        !          1592:             sepHdr.DebugDirectorySize += sizeof(IMAGE_DEBUG_DIRECTORY);
        !          1593:         }
        !          1594:     }
        !          1595: 
        !          1596:     /*
        !          1597:      *  Write out debug info
        !          1598:      */
        !          1599: 
        !          1600:     for (i=0; i<p.iptrs.cDebugDir; i++) {
        !          1601:         if (p.iptrs.rgDebugDir[i] != NULL) {
        !          1602:             p.optrs.rgDebugDir[i]->AddressOfRawData = 0;
        !          1603:             rgDbgDir[i].AddressOfRawData = 0;
        !          1604:             p.optrs.rgDebugDir[i]->PointerToRawData =
        !          1605:               rgDbgDir[i].PointerToRawData =
        !          1606:                 SetFilePointer(hFile, 0, 0, FILE_CURRENT);
        !          1607:             WriteFile(hFile, p.iptrs.rgpbDebugSave[i], rgDbgDir[i].SizeOfData,
        !          1608:                       &cb, NULL);
        !          1609:         }
        !          1610:     }
        !          1611:                       
        !          1612: 
        !          1613:     /*
        !          1614:      *
        !          1615:      */
        !          1616: 
        !          1617:     p.optrs.fileHdr->Characteristics |= IMAGE_FILE_DEBUG_STRIPPED;
        !          1618:     MungeStrip(&p, TRUE);
        !          1619: 
        !          1620:     ComputeChecksum(szOutput);
        !          1621: 
        !          1622:     UnmapViewOfFile( p.iptrs.fptr );
        !          1623:     CloseHandle( p.iptrs.hFile);
        !          1624: 
        !          1625:     if (!MapInputFile(&p, NULL, szOutput)) {
        !          1626:         FatalError(ERR_OPEN_INPUT_FILE, szOutput);
        !          1627:     }
        !          1628: 
        !          1629:     if (!CalculateNtImagePointers(&p.iptrs)) {
        !          1630:         FatalError(ERR_INVALID_PE, szOutput);
        !          1631:     }
        !          1632: 
        !          1633:     /*
        !          1634:      *   Correct the header and the debug directory records
        !          1635:      */
        !          1636: 
        !          1637:     sepHdr.Characteristics = p.iptrs.fileHdr->Characteristics;
        !          1638:     sepHdr.TimeDateStamp = p.iptrs.fileHdr->TimeDateStamp;
        !          1639:     sepHdr.CheckSum = p.iptrs.optHdr->CheckSum;
        !          1640:     sepHdr.ImageBase = p.iptrs.optHdr->ImageBase;
        !          1641:     sepHdr.SizeOfImage = p.iptrs.optHdr->SizeOfImage;
        !          1642:     
        !          1643:     SetFilePointer(hFile, 0, 0, FILE_BEGIN);
        !          1644:     WriteFile(hFile, &sepHdr, sizeof(sepHdr), &cb, NULL);
        !          1645:     SetFilePointer(hFile, BaseOfDebugData, 0, FILE_BEGIN);
        !          1646:     for (i=0; i<p.iptrs.cDebugDir; i++) {
        !          1647:         if (p.iptrs.rgDebugDir[i] != NULL) {
        !          1648:             WriteFile(hFile, &rgDbgDir[i],
        !          1649:                       sizeof(IMAGE_DEBUG_DIRECTORY), &cb, NULL);
        !          1650:         }
        !          1651:     }
        !          1652: 
        !          1653:     UnmapViewOfFile( p.iptrs.fptr );
        !          1654:     CloseHandle( p.iptrs.hFile);
        !          1655:     CloseHandle(hFile);
        !          1656: 
        !          1657:     return;
        !          1658: }                               /* DoExtract() */
        !          1659: 
        !          1660: void DoJoin(char * szInput, char * szOutput, char * szDbgFile)
        !          1661: {
        !          1662: }                               /* DoJoin() */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.