Skip to content

Instantly share code, notes, and snippets.

@7shi
Created November 10, 2012 01:01
Show Gist options
  • Save 7shi/4049338 to your computer and use it in GitHub Desktop.
Save 7shi/4049338 to your computer and use it in GitHub Desktop.
generate an exe, a simple hello world.
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <windows.h>
using namespace std;
char image[0x800];
int main()
{
auto dosh = reinterpret_cast<IMAGE_DOS_HEADER*>(&image[0]);
dosh->e_magic = *(WORD*)"MZ";
dosh->e_cblp = 0x90;
dosh->e_cp = 3;
dosh->e_cparhdr = 4;
dosh->e_maxalloc = 0xffff;
dosh->e_sp = 0xb8;
dosh->e_lfarlc = 0x40;
dosh->e_lfanew = 0x80;
BYTE stub[] = { 0xb8, 0x01, 0x4c, 0xcd, 0x21 };
memcpy(&image[0x40], stub, sizeof(stub));
auto peh = reinterpret_cast<IMAGE_NT_HEADERS32*>(&image[0x80]);
peh->Signature = *(DWORD*)"PE\0\0";
auto fh = &peh->FileHeader;
fh->Machine = 0x14c;
fh->NumberOfSections = 3;
fh->SizeOfOptionalHeader = 0xe0;
fh->Characteristics = 0x102;
auto oph = &peh->OptionalHeader;
oph->Magic = 0x10b;
oph->MajorLinkerVersion = 10;
oph->SizeOfCode = 0x200;
oph->AddressOfEntryPoint = 0x1000;
oph->BaseOfCode = 0x1000;
oph->BaseOfData = 0x2000;
oph->ImageBase = 0x400000;
oph->SectionAlignment = 0x1000;
oph->FileAlignment = 0x200;
oph->MajorOperatingSystemVersion = 5;
oph->MinorOperatingSystemVersion = 1;
oph->MajorSubsystemVersion = 5;
oph->MinorSubsystemVersion = 1;
oph->SizeOfImage = 0x4000;
oph->SizeOfHeaders = 0x200;
oph->Subsystem = 3;
oph->SizeOfStackReserve = 0x100000;
oph->SizeOfStackCommit = 0x1000;
oph->SizeOfHeapReserve = 0x100000;
oph->SizeOfHeapCommit = 0x1000;
oph->NumberOfRvaAndSizes = 16;
oph->DataDirectory[1].VirtualAddress = 0x00002000;
oph->DataDirectory[1].Size = 0x00001000;
auto scth = reinterpret_cast<IMAGE_SECTION_HEADER*>(&image[0x178]);
memcpy(scth[0].Name, ".text", 5);
scth[0].Misc.VirtualSize = 15;
scth[0].VirtualAddress = 0x1000;
scth[0].SizeOfRawData = 0x200;
scth[0].PointerToRawData = 0x200;
scth[0].Characteristics = 0x60000020;
memcpy(scth[1].Name, ".idata", 6);
scth[1].Misc.VirtualSize = 0x54;
scth[1].VirtualAddress = 0x2000;
scth[1].SizeOfRawData = 0x200;
scth[1].PointerToRawData = 0x400;
scth[1].Characteristics = 0xc0300040;
memcpy(scth[2].Name, ".data", 5);
scth[2].Misc.VirtualSize = 7;
scth[2].VirtualAddress = 0x3000;
scth[2].SizeOfRawData = 0x200;
scth[2].PointerToRawData = 0x600;
scth[2].Characteristics = 0xc0000040;
// .idata
auto ilt = reinterpret_cast<IMAGE_IMPORT_DESCRIPTOR*>(&image[0x400]);
ilt[0].OriginalFirstThunk = 0x2028;
ilt[0].Name = 0x2048;
ilt[0].FirstThunk = 0x2030;
*(DWORD*)&image[0x428] = 0x2038;
*(DWORD*)&image[0x430] = 0x2038;
strcpy(&image[0x43a], "printf");
strcpy(&image[0x448], "msvcrt.dll");
// .text
// push 0x00403000
image[0x200] = 0x68;
*(DWORD*)&image[0x201] = 0x00403000;
// call [0x00402030]
image[0x205] = 0xff;
image[0x206] = 0x15;
*(DWORD*)&image[0x207] = 0x00402030;
// add esp, 4
image[0x20b] = 0x83;
image[0x20c] = 0xc4;
image[0x20d] = 4;
// ret
image[0x20e] = 0xc3;
// .data
strcpy(&image[0x600], "hello\n");
auto f = fopen("output.exe", "wb");
if (!f) return 1;
fwrite(image, 1, sizeof(image), f);
fclose(f);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment