How to write a C Program to Identifies the architecture for which a Windows PE (exe or dll) file was compiled in C Programming Language ?
Solution:
/*C Program to Identifies the architecture for which a Windows PE (exe or dll) file was compiled. */
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <stdbool.h>
void displayProgramInfo();
char* extractFileName(char* filename); // Returns pointer to filename in the passed string.
char* getArch(unsigned short int arch); // Returns a new string which must be deallocated by the caller.
int main(int argc, char** argv) {
const char FILE_SIGNATURE[2] = { 0x4d, 0x5a };
const char PE_SIGNATURE[4] = { 0x50, 0x45, 0x00, 0x00 };
const unsigned int PE_POINTER = 0x3C;
displayProgramInfo();
if (argc < 2) {
printf(
"Identifies the architecture for which a Windows PE (exe or dll) file was compiled.\n"
"Please supply a filename via the command line.\n");
return 1;
}
char filename[strlen(argv[1])];
strcpy(filename, argv[1]);
FILE *ptr_pefile = fopen(filename, "rb");
if (!ptr_pefile) {
printf("Could not open file: \"%s\"\n", filename);
return 2;
}
unsigned char buffer[4];
unsigned int offset_value;
// Get file signature
fseek(ptr_pefile, SEEK_SET, 0);
memset(buffer, 0, 4);
fread(buffer, 1, 2, ptr_pefile);
if (memcmp(buffer, FILE_SIGNATURE, 2) != 0) {
printf("Error: \"%s\" is not a valid PE file (file signature is invalid).\n", filename);
fclose(ptr_pefile);
return 3;
}
// Get PE signature pointer offset value
fseek(ptr_pefile, PE_POINTER, SEEK_SET);
offset_value = 0;
fread(&offset_value, 4, 1, ptr_pefile);
// Get PE signature
fseek(ptr_pefile, offset_value, SEEK_SET);
memset(buffer, 0, 4);
fread(&buffer, 1, 4, ptr_pefile);
if (memcmp(buffer, PE_SIGNATURE, 4) != 0) {
printf("Error: \"%s\" is not a valid PE file (PE signature is invalid).\n", filename);
fclose(ptr_pefile);
return 4;
}
// Get arch identifier (int) from current offset
offset_value = 0;
fread(&offset_value, 1, 2, ptr_pefile);
char* pArchStr = getArch(offset_value);
if (pArchStr[0] == 0) {
printf(
"Unrecognised machine type.\n"
"This executable is either corrupt or the file specification was revised "
"after this program was created.\n");
} else {
printf("%s was compiled for %s\n", extractFileName(filename), pArchStr);
}
free(pArchStr);
fclose(ptr_pefile);
return EXIT_SUCCESS;
}
void displayProgramInfo() {
static const char PROG_NAME[] = "ArchPE";
static const char PROG_VERS[] = "0.3";
static const char PROG_AUTH[] = "(c)2015 Walker Moore.";
printf("%s %s - %s\n\n", PROG_NAME, PROG_VERS, PROG_AUTH);
}
char* extractFileName(char* filename) {
size_t sz_filename = strlen(filename) + 1; // +1 to include null terminator in length
char *pEnd = &filename[sz_filename];
int i = 0;
while (*pEnd != 0x5c && i++ != sz_filename) { // 0x5c is ASCII code for '\'
pEnd--;
}
return sz_filename == --i ? pEnd : pEnd + 1;
}
char* getArch(unsigned short int arch) {
char archStr[50];
switch (arch) {
case 0x14c:
strcpy(archStr, "Intel 386 or later, and compatibles (32bit)");
break;
case 0x14d:
strcpy(archStr, "Intel i860");
break;
case 0x162:
strcpy(archStr, "MIPS R3000");
break;
case 0x166:
strcpy(archStr, "MIPS little endian (R4000)");
break;
case 0x168:
strcpy(archStr, "MIPS R10000");
break;
case 0x169:
strcpy(archStr, "MIPS little endian WCI v2");
break;
case 0x183:
strcpy(archStr, "Alpha AXP (old)");
break;
case 0x184:
strcpy(archStr, "Alpha AXP");
break;
case 0x1a2:
strcpy(archStr, "Hitachi SH3");
break;
case 0x1a3:
strcpy(archStr, "Hitachi SH3 DSP");
break;
case 0x1a6:
strcpy(archStr, "Hitachi SH4");
break;
case 0x1a8:
strcpy(archStr, "Hitachi SH5");
break;
case 0x1c0:
strcpy(archStr, "ARM little endian");
break;
case 0x1c2:
strcpy(archStr, "Thumb");
break;
case 0x1d3:
strcpy(archStr, "Matsushita AM33");
break;
case 0x1f0:
strcpy(archStr, "PowerPC little endian");
break;
case 0x1f1:
strcpy(archStr, "PowerPC with floating point support");
break;
case 0x200:
strcpy(archStr, "Intel IA64");
break;
case 0x266:
strcpy(archStr, "MIPS16");
break;
case 0x268:
strcpy(archStr, "Motorola 68000 series");
break;
case 0x284:
strcpy(archStr, "Alpha AXP 64-bit");
break;
case 0x366:
strcpy(archStr, "MIPS with FPU");
break;
case 0x466:
strcpy(archStr, "MIPS16 with FPU");
break;
case 0xebc:
strcpy(archStr, "EFI Byte Code");
break;
case 0x8664:
strcpy(archStr, "AMD AMD64 (64bit)");
break;
case 0x9041:
strcpy(archStr, "Mitsubishi M32R little endian");
break;
case 0xc0ee:
strcpy(archStr, "clr pure MSIL");
break;
default:
strcpy(archStr, "");
break;
}
char *result = malloc(strlen(archStr) + 1);
strcpy(result, archStr);
return result;
}
Learn More :
File
- COPY DATA FROM ONE FILE TO ANOTHER FILE USING C PROGRAM
- C Program File Input & Output Example
- C Program To Destruc Self Execution File ?
- C Program To Store Students Record In A Text File
- C Program To Write Data In A File And Search Data From File
- Make a copy of file given in argv[1] to file given in argv[2]
- C Program to copy a file to another file
- C Function to read instructions from the file and obey them
- Client/Server C program to make client send the name of a file
- A small I/O bound program to copy N bytes from an input file to an output file.
- C Program to Read and Write FIFO
- File Number Control C Program Example
- C Program to opens and reads dictionary file specified in spellrc
- C Program to Recursively converts all file-names to lower-case
- C Program to Find the Size of File using File Handling Function
- C Program Recursive function that searches for a given file in a given folder
- C Program Read a char & print next char ( file to file )
- C Program to Input Student Details into a File For Two Subjects
- File Handling (console to file) in C Program
Architecture
dll
Windows PE
Identifies
Compiled
exe