mirror of
				https://git.proxmox.com/git/mirror_edk2
				synced 2025-10-27 10:50:43 +00:00 
			
		
		
		
	 26355eed43
			
		
	
	
		26355eed43
		
	
	
	
	
		
			
			git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@2263 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			434 lines
		
	
	
		
			9.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			434 lines
		
	
	
		
			9.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*++
 | |
| 
 | |
| Copyright (c)  2004-2006 Intel Corporation. All rights reserved
 | |
| This program and the accompanying materials are licensed and made available
 | |
| under the terms and conditions of the BSD License which accompanies this
 | |
| distribution.  The full text of the license may be found at
 | |
| http://opensource.org/licenses/bsd-license.php
 | |
| 
 | |
| THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
 | |
| WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 | |
| 
 | |
| 
 | |
| Module Name:
 | |
| 
 | |
|   ZeroDebugData.c
 | |
| 
 | |
| Abstract:
 | |
| 
 | |
|   Zero the Debug Data Fields of Portable Executable (PE) format file.
 | |
| 
 | |
| --*/
 | |
| 
 | |
| #include <stdio.h>
 | |
| #include <string.h>
 | |
| #include <stdlib.h>
 | |
| 
 | |
| #define UTILITY_NAME    "GenTEImage"
 | |
| #define UTILITY_MAJOR_VERSION   0
 | |
| #define UTILITY_MINOR_VERSION   1
 | |
| 
 | |
| void
 | |
| Version (
 | |
|   void
 | |
|   )
 | |
| /*++
 | |
| Routine Description:
 | |
|   print version information for this utility
 | |
| 
 | |
| Arguments:
 | |
|   None
 | |
| 
 | |
| Returns:
 | |
|   None
 | |
| --*/
 | |
| // GC_TODO:    void - add argument and description to function comment
 | |
| {
 | |
|   //
 | |
|   // print usage of command
 | |
|   //
 | |
|   printf ("%s v%d.%d -Utility to zero the Debug Data Fields of Portable Executable (PE) format file.\n", UTILITY_NAME, UTILITY_MAJOR_VERSION, UTILITY_MINOR_VERSION);
 | |
|   printf ("Copyright (c) 1999-2007 Intel Corporation. All rights reserved.\n");
 | |
| }
 | |
| 
 | |
| void
 | |
| Usage (
 | |
|   void
 | |
|   )
 | |
| /*++
 | |
| Routine Description:
 | |
|   print usage of ZeroDebugData command
 | |
| 
 | |
| Arguments:
 | |
|   None
 | |
| 
 | |
| Returns:
 | |
|   None
 | |
| --*/
 | |
| // GC_TODO:    void - add argument and description to function comment
 | |
| {
 | |
|   Version();
 | |
|   //
 | |
|   // print usage of command
 | |
|   //
 | |
|   printf ("\nUsage: ZeroDebugData <PE-File> [DebugData-File]\n");
 | |
| }
 | |
| 
 | |
| int
 | |
| ReadFromFile (
 | |
|   FILE      *fp,
 | |
|   long      offset,
 | |
|   void      *buffer,
 | |
|   int       size
 | |
|   )
 | |
| /*++
 | |
| Routine Description:
 | |
|   read data from a specified location of file
 | |
| 
 | |
| Arguments:
 | |
|   fp              - file pointer
 | |
|   offset          - number of bytes from beginning of file
 | |
|   buffer          - buffer used to store data
 | |
|   size            - size of buffer
 | |
| 
 | |
| Returns:
 | |
|   =  0            - Success
 | |
|   = -1            - Failed
 | |
| --*/
 | |
| {
 | |
|   //
 | |
|   // set file pointer to the specified location of file
 | |
|   //
 | |
|   if (fseek (fp, offset, SEEK_SET) != 0) {
 | |
|     printf ("Error: Cannot move the current location of the file.\n");
 | |
|     return -1;
 | |
|   }
 | |
|   //
 | |
|   // read data from the file
 | |
|   //
 | |
|   if (fread (buffer, size, 1, fp) != 1) {
 | |
|     printf ("Error: Cannot read data from the file.\n");
 | |
|     return -1;
 | |
|   }
 | |
| 
 | |
|   return 0;
 | |
| }
 | |
| 
 | |
| int
 | |
| ZeroDebugData (
 | |
|   FILE      *fp,
 | |
|   FILE      *fpData
 | |
|   )
 | |
| /*++
 | |
| 
 | |
| Routine Description:
 | |
| 
 | |
|   Zero the debug data fields of the file
 | |
| 
 | |
| Arguments:
 | |
| 
 | |
|   fp              - file pointer
 | |
|   fpData          - pointer to output file that ZeroDebugData progress is written to
 | |
| 
 | |
| Returns:
 | |
| 
 | |
|   =  0            - Success
 | |
|   = -1            - Failed
 | |
| 
 | |
| --*/
 | |
| {
 | |
|   unsigned char header[4];
 | |
|   unsigned long offset;
 | |
|   unsigned long NumberOfRvaAndSizes;
 | |
|   unsigned int  nvalue;
 | |
|   unsigned long lvalue;
 | |
|   unsigned long Size;
 | |
|   unsigned long Pointer;
 | |
|   unsigned char *Buffer;
 | |
|   unsigned long Index;
 | |
| 
 | |
|   //
 | |
|   // read the header of file
 | |
|   //
 | |
|   if (ReadFromFile (fp, 0, header, 2) != 0) {
 | |
|     printf ("Error: open image file\n");
 | |
|     return -1;
 | |
|   }
 | |
|   //
 | |
|   // "MZ" -- the header of image file (PE)
 | |
|   //
 | |
|   if (strncmp ((char *) header, "MZ", 2) != 0) {
 | |
|     printf ("Error: Invalid Image file.\n");
 | |
|     return -1;
 | |
|   }
 | |
|   //
 | |
|   // At location 0x3C, the stub has the file offset to the
 | |
|   // PE signature.
 | |
|   //
 | |
|   if (ReadFromFile (fp, 0x3C, &offset, 4) != 0) {
 | |
|     return -1;
 | |
|   }
 | |
|   //
 | |
|   // read the header of optional
 | |
|   //
 | |
|   if (ReadFromFile (fp, offset, header, 4) != 0) {
 | |
|     return -1;
 | |
|   }
 | |
|   //
 | |
|   // "PE\0\0" -- the signature of optional header
 | |
|   //
 | |
|   if (strncmp ((char *) header, "PE\0\0", 4) != 0) {
 | |
|     printf ("Error: Invalid PE format file.\n");
 | |
|     return -1;
 | |
|   }
 | |
|   //
 | |
|   // Add 16 to skip COFF file header, and get to optional header.
 | |
|   //
 | |
|   offset += 24;
 | |
| 
 | |
|   //
 | |
|   // Check the magic field, 0x10B for PE32 and 0x20B for PE32+
 | |
|   //
 | |
|   if (ReadFromFile (fp, offset, &nvalue, 2) != 0) {
 | |
|     return -1;
 | |
|   }
 | |
|   //
 | |
|   // If this is PE32 image file, offset of NumberOfRvaAndSizes is 92.
 | |
|   // Else it is 108.
 | |
|   //
 | |
|   switch (nvalue & 0xFFFF) {
 | |
|   case 0x10B:
 | |
|     offset += 92;
 | |
|     printf ("Info: Image is PE32. ");
 | |
|     break;
 | |
| 
 | |
|   case 0x20B:
 | |
|     offset += 108;
 | |
|     printf ("Info: Image is PE32+. ");
 | |
|     break;
 | |
| 
 | |
|   default:
 | |
|     printf ("Error: Magic value is unknown.\n");
 | |
|     return -1;
 | |
|   }
 | |
|   //
 | |
|   // get the value of NumberOfRvaAndSizes
 | |
|   //
 | |
|   if (ReadFromFile (fp, offset, &NumberOfRvaAndSizes, 4) != 0) {
 | |
|     printf ("Error: read NumberOfRvaAndSizes error.\n");
 | |
|     return -1;
 | |
|   }
 | |
|   //
 | |
|   // printf ("Info: NumberOfRvaAndSizes = %d\n", NumberOfRvaAndSizes);
 | |
|   //
 | |
|   //
 | |
|   // Finding Debug Table, offset of Debug Table
 | |
|   // is 4 + 6 * 8 = 52.
 | |
|   //
 | |
|   if (NumberOfRvaAndSizes >= 7) {
 | |
|     if (ReadFromFile (fp, offset + 52, &lvalue, 4) != 0) {
 | |
|       return -1;
 | |
|     }
 | |
|     //
 | |
|     // Read the SizeOfData(16) and PointerToRawData(24)
 | |
|     //
 | |
|     if (ReadFromFile (fp, lvalue + 16, &Size, 4) != 0) {
 | |
|       printf ("error: Size = %d\n", Size);
 | |
|       return -1;
 | |
|     }
 | |
| 
 | |
|     printf ("Debug data: size = %xh, ", Size);
 | |
|     fprintf (fpData, "Debug data: size = %xh, ", Size);
 | |
| 
 | |
|     if (ReadFromFile (fp, lvalue + 20, &Pointer, 4) != 0) {
 | |
|       printf ("error: LoadOffset = %xh\n", Pointer);
 | |
|       return -1;
 | |
|     }
 | |
|     //
 | |
|     // printf ("LoadOffset = %xh, ", Pointer);
 | |
|     //
 | |
|     fprintf (fpData, "LoadOffset = %xh, ", Pointer);
 | |
| 
 | |
|     if (ReadFromFile (fp, lvalue + 24, &Pointer, 4) != 0) {
 | |
|       printf ("error: FileOffset = %xh\n", Pointer);
 | |
|       return -1;
 | |
|     }
 | |
| 
 | |
|     printf ("FileOffset = %xh, ", Pointer);
 | |
|     fprintf (fpData, "FileOffset = %xh, \n", Pointer);
 | |
| 
 | |
|     if ((lvalue != 0) && (Pointer != 0)) {
 | |
|       //
 | |
|       // prepare buffer
 | |
|       //
 | |
|       Buffer = malloc (Size + 1);
 | |
|       if (Buffer == NULL) {
 | |
|         printf ("Error: Cannot allocate memory.\n");
 | |
|         return -1;
 | |
|       }
 | |
|       //
 | |
|       // set file pointer to the specified location of file
 | |
|       //
 | |
|       if (fseek (fp, Pointer, SEEK_SET) != 0) {
 | |
|         printf ("Error: Cannot move the current location of the file.\n");
 | |
|         free (Buffer);
 | |
|         return -1;
 | |
|       }
 | |
|       //
 | |
|       // read data from PE file
 | |
|       //
 | |
|       if (fread (Buffer, Size, 1, fp) != 1) {
 | |
|         printf ("Error: Cannot read data from the file.\n");
 | |
|         free (Buffer);
 | |
|         return -1;
 | |
|       }
 | |
|       //
 | |
|       // write to data file
 | |
|       //
 | |
|       for (Index = 0; Index < Size;) {
 | |
|         fprintf (fpData, "%02x ", Buffer[Index]);
 | |
| 
 | |
|         Index++;
 | |
|         if (Index % 8 == 0) {
 | |
|           fprintf (fpData, "\n");
 | |
|         }
 | |
|       }
 | |
| 
 | |
|       fprintf (fpData, "\n");
 | |
| 
 | |
|       //
 | |
|       // zero buffer and write back to PE file
 | |
|       //
 | |
|       if (fseek (fp, Pointer, SEEK_SET) != 0) {
 | |
|         printf ("Error: Cannot move the current location of the file.\n");
 | |
|         free (Buffer);
 | |
|         return -1;
 | |
|       }
 | |
| 
 | |
|       memset (Buffer, 0, Size);
 | |
|       if (fwrite (Buffer, Size, 1, fp) != 1) {
 | |
|         perror ("Error: Cannot write zero to the file.\n");
 | |
|         free (Buffer);
 | |
|         return -1;
 | |
|       }
 | |
|       //
 | |
|       // set file pointer to the specified location of file
 | |
|       //
 | |
|       if (fseek (fp, lvalue + 4, SEEK_SET) != 0) {
 | |
|         printf ("Error: Cannot move the current location of the file.\n");
 | |
|         free (Buffer);
 | |
|         return -1;
 | |
|       }
 | |
| 
 | |
|       if (fwrite (Buffer, 4, 1, fp) != 1) {
 | |
|         perror ("Error: Cannot write zero to the file.\n");
 | |
|         free (Buffer);
 | |
|         return -1;
 | |
|       }
 | |
| 
 | |
|       free (Buffer);
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   return 0;
 | |
| }
 | |
| 
 | |
| int
 | |
| main (
 | |
|   int       argc,
 | |
|   char      *argv[]
 | |
|   )
 | |
| /*++
 | |
| 
 | |
| Routine Description:
 | |
| 
 | |
|   Prints the zero debug data of the PE file to the DebugData file.
 | |
|   Executes the ZeroDebugData function.
 | |
| 
 | |
| Arguments:
 | |
| 
 | |
|   argc   - Standard C argument, number of command line arguments.
 | |
|   argv[] - Standard C argument, array of pointers to the input files,
 | |
|            such as the PE and DebugData files.
 | |
| 
 | |
| Returns:
 | |
| 
 | |
|   zero    - success
 | |
|   nonzero - failure
 | |
| 
 | |
| --*/
 | |
| {
 | |
|   FILE  *fp;
 | |
|   FILE  *fpData;
 | |
|   char  DataFile[1024] = "";
 | |
| 
 | |
|   if (argc == 1) {
 | |
|     Usage();
 | |
|     return -1;
 | |
|   }
 | |
|     
 | |
|   if ((strcmp(argv[1], "-h") == 0) || (strcmp(argv[1], "--help") == 0) ||
 | |
|       (strcmp(argv[1], "-?") == 0) || (strcmp(argv[1], "/?") == 0)) {
 | |
|     Usage();
 | |
|     return -1;
 | |
|   }
 | |
|   
 | |
|   if ((strcmp(argv[1], "-V") == 0) || (strcmp(argv[1], "--version") == 0)) {
 | |
|     Version();
 | |
|     return -1;
 | |
|   }
 | |
| 
 | |
|   if (argc == 2) {
 | |
|     Usage();
 | |
|     return -1;
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // open the DebugData file, if not exists, return
 | |
|   //
 | |
|   if (argc >= 3) {
 | |
|     strcpy (DataFile, argv[2]);
 | |
|   } else {
 | |
|     strcpy (DataFile, "DebugData.dat");
 | |
|   }
 | |
| 
 | |
|   fpData = fopen (DataFile, "a+");
 | |
|   if (fpData == NULL) {
 | |
|     fpData = fopen (DataFile, "w");
 | |
|     if (fpData == NULL) {
 | |
|       printf ("Error: Cannot open the data file!\n");
 | |
|       return -1;
 | |
|     }
 | |
|   }
 | |
|   //
 | |
|   // open the PE file
 | |
|   //
 | |
|   fp = fopen (argv[1], "r+b");
 | |
|   if (fp == NULL) {
 | |
|     printf ("Error: Cannot open the PE file!\n");
 | |
|     return -1;
 | |
|   }
 | |
|   //
 | |
|   // Zero the Debug Data to the PE file
 | |
|   //
 | |
|   printf ("Zero Debug Data to file %s:\n", argv[1]);
 | |
|   fprintf (fpData, "\nZero Debug Data to file %s:\n", argv[1]);
 | |
|   if ((int *) ZeroDebugData (fp, fpData) != 0) {
 | |
|     printf ("Error: Zero Debug Data PE file\n");
 | |
|     fclose (fp);
 | |
|     return -1;
 | |
|   }
 | |
| 
 | |
|   printf (" success\n");
 | |
| 
 | |
|   //
 | |
|   // close the PE file
 | |
|   //
 | |
|   fflush (fpData);
 | |
|   fflush (fp);
 | |
|   fclose (fpData);
 | |
|   fclose (fp);
 | |
| 
 | |
|   return 0;
 | |
| }
 |