Annotation of mstools/samples/sdktools/image/symedit/symedit.c, revision 1.1.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.