|
|
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() */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.