mirror of https://github.com/acidanthera/audk.git
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;
|
|
}
|