Last active
July 18, 2020 23:52
-
-
Save droogie/c66ba8a0b9daa54212fded336bf196fa to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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*)∈ | |
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