Skip to content

Instantly share code, notes, and snippets.

@droogie
Last active July 18, 2020 23:52
Show Gist options
  • Save droogie/c66ba8a0b9daa54212fded336bf196fa to your computer and use it in GitHub Desktop.
Save droogie/c66ba8a0b9daa54212fded336bf196fa to your computer and use it in GitHub Desktop.
// basic program to grab if a PE binary was compiled with ASLR or DEP
#include <stdio.h>
#include <stdlib.h>
#define BYTE unsigned char
#define WORD unsigned short
#define DWORD unsigned int
#define LONG long
#define ULONGLONG unsigned long long
#define IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x10b
#define IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b
#define DOS_MAGIC 0x5A4D
#define PE_MAGIC 0x50450000
#define IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE 0x0040 // ASLR
#define IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY 0x0080 // Code integrity checks are forced.
#define IMAGE_DLLCHARACTERISTICS_NX_COMPAT 0x0100 // The image is compatible with data execution prevention(DEP).
#define IMAGE_DLLCHARACTERISTICS_NO_ISOLATION 0x0200 // The image is isolation aware, but should not be isolated.
#define IMAGE_DLLCHARACTERISTICS_NO_SEH 0x0400 // The image does not use structured exception handling(SEH).
#define IMAGE_DLLCHARACTERISTICS_NO_BIND 0x0800 // Do not bind the image.
#define IMAGE_DLLCHARACTERISTICS_WDM_DRIVER 0x2000 // A WDM driver.
#define IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE 0x8000 // The image is terminal server aware.
#define IMAGE_FILE_MACHINE_UNKNOWN 0x0 // The contents of this field are assumed to be applicable to any machine type
#define IMAGE_FILE_MACHINE_AM33 0x1d3 // Matsushita AM33
#define IMAGE_FILE_MACHINE_AMD64 0x8664 // x64
#define IMAGE_FILE_MACHINE_ARM 0x1c0 // ARM little endian
#define IMAGE_FILE_MACHINE_ARM64 0xaa64 // ARM64 little endian
#define IMAGE_FILE_MACHINE_ARMNT 0x1c4 // ARM Thumb - 2 little endian
#define IMAGE_FILE_MACHINE_EBC 0xebc // EFI byte code
#define IMAGE_FILE_MACHINE_I386 0x14c // Intel 386 or later processors and compatible processors
#define IMAGE_FILE_MACHINE_IA64 0x200 // Intel Itanium processor family
#define IMAGE_FILE_MACHINE_M32R 0x9041 // Mitsubishi M32R little endian
#define IMAGE_FILE_MACHINE_MIPS16 0x266 // MIPS16
#define IMAGE_FILE_MACHINE_MIPSFPU 0x366 // MIPS with FPU
#define IMAGE_FILE_MACHINE_MIPSFPU16 0x466 // MIPS16 with FPU
#define IMAGE_FILE_MACHINE_POWERPC 0x1f0 // Power PC little endian
#define IMAGE_FILE_MACHINE_POWERPCFP 0x1f1 // Power PC with floating point support
#define IMAGE_FILE_MACHINE_R4000 0x166 // MIPS little endian
#define IMAGE_FILE_MACHINE_RISCV32 0x5032 // RISC - V 32 - bit address space
#define IMAGE_FILE_MACHINE_RISCV64 0x5064 // RISC - V 64 - bit address space
#define IMAGE_FILE_MACHINE_RISCV128 0x5128 // RISC - V 128 - bit address space
#define IMAGE_FILE_MACHINE_SH3 0x1a2 // Hitachi SH3
#define IMAGE_FILE_MACHINE_SH3DSP 0x1a3 // Hitachi SH3 DSP
#define IMAGE_FILE_MACHINE_SH4 0x1a6 // Hitachi SH4
#define IMAGE_FILE_MACHINE_SH5 0x1a8 // Hitachi SH5
#define IMAGE_FILE_MACHINE_THUMB 0x1c2 // Thumb
#define IMAGE_FILE_MACHINE_WCEMIPSV2 0x169 // MIPS little - endian WCE v2
typedef struct machine_t { int value; const char* name;} machine_t;
machine_t table[] = {
{ IMAGE_FILE_MACHINE_UNKNOWN, "Unknown" },
{ IMAGE_FILE_MACHINE_AM33, "Matsushita AM33" },
{ IMAGE_FILE_MACHINE_AMD64, "x64" },
{ IMAGE_FILE_MACHINE_ARM, "ARM little endian" },
{ IMAGE_FILE_MACHINE_ARM64, "ARM64 little endian" },
{ IMAGE_FILE_MACHINE_ARMNT, "ARM Thumb - 2 little endian" },
{ IMAGE_FILE_MACHINE_EBC, "EFI byte code" },
{ IMAGE_FILE_MACHINE_I386, "Intel 386 or later processors and compatible processors" },
{ IMAGE_FILE_MACHINE_IA64, "Intel Itanium processor family" },
{ IMAGE_FILE_MACHINE_M32R, "Mitsubishi M32R little endian" },
{ IMAGE_FILE_MACHINE_MIPS16, "MIPS16" },
{ IMAGE_FILE_MACHINE_MIPSFPU, "MIPS with FPU" },
{ IMAGE_FILE_MACHINE_MIPSFPU16, "MIPS16 with FPU" },
{ IMAGE_FILE_MACHINE_POWERPC, "Power PC little endian" },
{ IMAGE_FILE_MACHINE_POWERPCFP, "Power PC with floating point support" },
{ IMAGE_FILE_MACHINE_R4000, "MIPS little endian" },
{ IMAGE_FILE_MACHINE_RISCV32, "RISC - V 32 - bit address space" },
{ IMAGE_FILE_MACHINE_RISCV64, "RISC - V 64 - bit address space" },
{ IMAGE_FILE_MACHINE_RISCV128, "RISC - V 128 - bit address space" },
{ IMAGE_FILE_MACHINE_SH3, "Hitachi SH3" },
{ IMAGE_FILE_MACHINE_SH3DSP, "Hitachi SH3 DSP" },
{ IMAGE_FILE_MACHINE_SH4, "Hitachi SH4" },
{ IMAGE_FILE_MACHINE_SH5, "Hitachi SH5" },
{ IMAGE_FILE_MACHINE_THUMB, "Thumb" },
{ IMAGE_FILE_MACHINE_WCEMIPSV2, "MIPS little - endian WCE v2" },
};
typedef struct _IMAGE_DOS_HEADER { // DOS .EXE header
WORD e_magic; // Magic number
WORD e_cblp; // Bytes on last page of file
WORD e_cp; // Pages in file
WORD e_crlc; // Relocations
WORD e_cparhdr; // Size of header in paragraphs
WORD e_minalloc; // Minimum extra paragraphs needed
WORD e_maxalloc; // Maximum extra paragraphs needed
WORD e_ss; // Initial (relative) SS value
WORD e_sp; // Initial SP value
WORD e_csum; // Checksum
WORD e_ip; // Initial IP value
WORD e_cs; // Initial (relative) CS value
WORD e_lfarlc; // File address of relocation table
WORD e_ovno; // Overlay number
WORD e_res[4]; // Reserved words
WORD e_oemid; // OEM identifier (for e_oeminfo)
WORD e_oeminfo; // OEM information; e_oemid specific
WORD e_res2[10]; // Reserved words
LONG e_lfanew; // File address of new exe header
} IMAGE_DOS_HEADER, * PIMAGE_DOS_HEADER;
typedef struct _IMAGE_FILE_HEADER {
WORD Machine;
WORD NumberOfSections;
DWORD TimeDateStamp;
DWORD PointerToSymbolTable;
DWORD NumberOfSymbols;
WORD SizeOfOptionalHeader;
WORD Characteristics;
} IMAGE_FILE_HEADER, * PIMAGE_FILE_HEADER;
typedef struct _IMAGE_DATA_DIRECTORY {
DWORD VirtualAddress;
DWORD Size;
} IMAGE_DATA_DIRECTORY, * PIMAGE_DATA_DIRECTORY;
#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16
typedef struct _IMAGE_OPTIONAL_HEADER {
WORD Magic;
BYTE MajorLinkerVersion;
BYTE MinorLinkerVersion;
DWORD SizeOfCode;
DWORD SizeOfInitializedData;
DWORD SizeOfUninitializedData;
DWORD AddressOfEntryPoint;
DWORD BaseOfCode;
DWORD BaseOfData;
DWORD ImageBase;
DWORD SectionAlignment;
DWORD FileAlignment;
WORD MajorOperatingSystemVersion;
WORD MinorOperatingSystemVersion;
WORD MajorImageVersion;
WORD MinorImageVersion;
WORD MajorSubsystemVersion;
WORD MinorSubsystemVersion;
DWORD Win32VersionValue;
DWORD SizeOfImage;
DWORD SizeOfHeaders;
DWORD CheckSum;
WORD Subsystem;
WORD DllCharacteristics; // Stores security details we are interested in
DWORD SizeOfStackReserve;
DWORD SizeOfStackCommit;
DWORD SizeOfHeapReserve;
DWORD SizeOfHeapCommit;
DWORD LoaderFlags;
DWORD NumberOfRvaAndSizes;
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
} IMAGE_OPTIONAL_HEADER32, * PIMAGE_OPTIONAL_HEADER32;
typedef struct _IMAGE_OPTIONAL_HEADER64 {
WORD Magic;
BYTE MajorLinkerVersion;
BYTE MinorLinkerVersion;
DWORD SizeOfCode;
DWORD SizeOfInitializedData;
DWORD SizeOfUninitializedData;
DWORD AddressOfEntryPoint;
DWORD BaseOfCode;
ULONGLONG ImageBase;
DWORD SectionAlignment;
DWORD FileAlignment;
WORD MajorOperatingSystemVersion;
WORD MinorOperatingSystemVersion;
WORD MajorImageVersion;
WORD MinorImageVersion;
WORD MajorSubsystemVersion;
WORD MinorSubsystemVersion;
DWORD Win32VersionValue;
DWORD SizeOfImage;
DWORD SizeOfHeaders;
DWORD CheckSum;
WORD Subsystem;
WORD DllCharacteristics; // Stores security details we are interested in
ULONGLONG SizeOfStackReserve;
ULONGLONG SizeOfStackCommit;
ULONGLONG SizeOfHeapReserve;
ULONGLONG SizeOfHeapCommit;
DWORD LoaderFlags;
DWORD NumberOfRvaAndSizes;
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
} IMAGE_OPTIONAL_HEADER64, * PIMAGE_OPTIONAL_HEADER64;
#define Fread(p, s, h, e) do { size_t r = fread(p,1,s,h); if (r != s) {printf(e); exit(0);} } while (0);
#define Fopen(h,n, e) do { errno_t ee = fopen_s(&h,n,"rb"); if (h == NULL) {printf(e, ee); exit(0); } } while(0);
#define Fsize(h, s) do {fseek(h, 0, SEEK_END); s = ftell(f); fseek(f, 0, SEEK_SET); } while(0);
DWORD reverse_dword(DWORD in) {
DWORD out;
BYTE* bin = (BYTE*)&in;
BYTE* bout = (BYTE*)&out;
bout[0] = bin[3];
bout[1] = bin[2];
bout[2] = bin[1];
bout[3] = bin[0];
return out;
}
char* bitCheck(int val) {
if (val) {
return "True";
}
else {
return "False";
}
}
void printSecurityInfo(WORD characteristics) {
printf("ASLR: %s\n", bitCheck(characteristics & IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE));
//IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY
printf("DEP: %s\n", bitCheck(characteristics & IMAGE_DLLCHARACTERISTICS_NX_COMPAT));
// IMAGE_DLLCHARACTERISTICS_NO_ISOLATION
// need to get SEH handler count to get accurate info
//printf("SafeSEH: %s\n", bitCheck(~(characteristics & IMAGE_DLLCHARACTERISTICS_NO_SEH)));
// IMAGE_DLLCHARACTERISTICS_NO_BIND
// IMAGE_DLLCHARACTERISTICS_WDM_DRIVER
// IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE
}
int main(int argc, char** argv) {
char data[100];
PIMAGE_DOS_HEADER dh = (PIMAGE_DOS_HEADER)data;
PIMAGE_FILE_HEADER fh = (PIMAGE_FILE_HEADER)data;
PIMAGE_OPTIONAL_HEADER64 oh64 = (PIMAGE_OPTIONAL_HEADER64)data;
PIMAGE_OPTIONAL_HEADER32 oh32 = (PIMAGE_OPTIONAL_HEADER32)data;
WORD magic;
WORD characteristics;
DWORD peSig;
FILE* f = NULL;
size_t s;
if (argc < 2) {
printf("pass a filename as argument\n");
exit(0);
}
Fopen(f, argv[1], "error opening file (0x%x)\n");
Fsize(f, s);
Fread(dh, sizeof(*dh), f, "error reading dos header\n");
if (dh->e_magic != DOS_MAGIC) {
printf("dos hdr magic doesn't match\n");
exit(0);
}
if (dh->e_lfanew > s || dh->e_lfanew < 0 || dh->e_lfanew < sizeof(*dh)) {
printf("malformed e_lfanew\n");
exit(0);
}
fseek(f, dh->e_lfanew - sizeof(*dh), SEEK_CUR);
Fread(&peSig, sizeof(peSig), f, "error reading PE signature");
if (reverse_dword(peSig) != PE_MAGIC) {
printf("PE signature(0x%x) not recognized\n", peSig);
exit(0);
}
Fread(fh, sizeof(*fh), f, "error reading file header\n");
int validMachine = 0;
for (machine_t* p = table; p->name != NULL; ++p) {
if (fh->Machine == p->value) {
validMachine = 1;
printf("machine(0x%x): %s\n\n", fh->Machine, p->name);
}
}
if (!validMachine){
printf("machine(0x%x) not recognized in file header\n", fh->Machine);
exit(0);
}
Fread(oh64, sizeof(*oh64), f, "couldn't read optional header\n");
if (oh64->Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC && oh64->Magic != IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
printf("magic(0x%x) in optional header not recognized\n", oh64->Magic);
exit(0);
}
if (oh64->Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
characteristics = oh32->DllCharacteristics;
}
else {
characteristics = oh64->DllCharacteristics;
}
printSecurityInfo(characteristics);
exit(0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment