Skip to content

Instantly share code, notes, and snippets.

@bencz
Last active July 2, 2024 05:32
Show Gist options
  • Save bencz/3576dfc8a217a34c05a9 to your computer and use it in GitHub Desktop.
Save bencz/3576dfc8a217a34c05a9 to your computer and use it in GitHub Desktop.
ExeMaker_DLanguae
// A big special thanks to 'bearophile' ( from dlang forum! )
import std.c.windows.windows: WORD, LONG, DWORD, BYTE, UCHAR, ULONG;
struct IMAGE_DOS_HEADER
{
WORD e_magic,
e_cblp,
e_cp,
e_crlc,
e_cparhdr,
e_minalloc,
e_maxalloc,
e_ss,
e_sp,
e_csum,
e_ip,
e_cs,
e_lfarlc,
e_ovno;
WORD[4] e_res;
WORD e_oemid,
e_oeminfo;
WORD[10] e_res2;
LONG e_lfanew;
}
alias PIMAGE_DOS_HEADER = IMAGE_DOS_HEADER*;
struct IMAGE_FILE_HEADER
{
WORD Machine,
NumberOfSections;
DWORD TimeDateStamp,
PointerToSymbolTable,
NumberOfSymbols;
WORD SizeOfOptionalHeader,
Characteristics;
}
alias PIMAGE_FILE_HEADER = IMAGE_FILE_HEADER*;
struct IMAGE_DATA_DIRECTORY
{
DWORD VirtualAddress, Size;
}
alias PIMAGE_DATA_DIRECTORY = IMAGE_DATA_DIRECTORY*;
struct IMAGE_OPTIONAL_HEADER32
{
//
// Standard fields.
//
WORD Magic;
BYTE MajorLinkerVersion, MinorLinkerVersion;
DWORD SizeOfCode,
SizeOfInitializedData,
SizeOfUninitializedData,
AddressOfEntryPoint,
BaseOfCode,
BaseOfData;
// // NT additional fields.
//
DWORD ImageBase,
SectionAlignment,
FileAlignment;
WORD MajorOperatingSystemVersion,
MinorOperatingSystemVersion;
WORD MajorImageVersion,
MinorImageVersion,
MajorSubsystemVersion,
MinorSubsystemVersion;
DWORD Win32VersionValue,
SizeOfImage,
SizeOfHeaders,
CheckSum;
WORD Subsystem,
DllCharacteristics;
DWORD SizeOfStackReserve,
SizeOfStackCommit,
SizeOfHeapReserve,
SizeOfHeapCommit,
LoaderFlags,
NumberOfRvaAndSizes;
IMAGE_DATA_DIRECTORY[16] DataDirectory;
}
alias PIMAGE_OPTIONAL_HEADER32 = IMAGE_OPTIONAL_HEADER32*;
struct IMAGE_NT_HEADERS32
{
DWORD Signature;
IMAGE_FILE_HEADER FileHeader;
IMAGE_OPTIONAL_HEADER32 OptionalHeader;
}
alias PIMAGE_NT_HEADERS32 = IMAGE_NT_HEADERS32*;
struct IMAGE_SECTION_HEADER
{
@disable this();
BYTE[8] Name;
union
{
DWORD PhysicalAddress,
VirtualSize;
}
DWORD VirtualAddress,
SizeOfRawData,
PointerToRawData,
PointerToRelocations,
PointerToLinenumbers;
WORD NumberOfRelocations,
NumberOfLinenumbers;
DWORD Characteristics;
}
alias PIMAGE_SECTION_HEADER = IMAGE_SECTION_HEADER*;
struct IMAGE_IMPORT_DESCRIPTOR
{
union
{
DWORD Characteristics; // 0 for terminating null import descriptor
DWORD OriginalFirstThunk; // RVA to original unbound IAT (PIMAGE_THUNK_DATA)
}
DWORD TimeDateStamp, // 0 if not bound,
// -1 if bound, and real date\time stamp
// in IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (new BIND)
// O.W. date/time stamp of DLL bound to (Old BIND)
ForwarderChain, // -1 if no forwarders
Name,
FirstThunk; // RVA to IAT (if bound this IAT has actual addresses)
}
alias PIMAGE_IMPORT_DESCRIPTOR = IMAGE_IMPORT_DESCRIPTOR*;
__gshared ubyte[0x800] image;
@nogc
void injectData(T)(ref T BaseSrc, string data)
{
memcpy(&BaseSrc, data.ptr, data.length);
}
void main()
{
import std.stdio;
import std.file;
import std.conv : to;
auto dosh = cast(PIMAGE_DOS_HEADER)image.ptr;
injectData(dosh.e_magic, "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;
/*
push cs
pop ds
mov dx, 0x000e
mov ah, 9
int 0x21
mov ax, 0x4c01
int 0x21
stub << "This program cannot be run in DOS mode.\r\r\n$";
*/
auto stub = x"0e 1f ba 0e 00";
stub ~= x"b4 09 cd 21";
stub ~= x"b8 01 4c";
stub ~= x"cd 21";
stub ~= "This program cannot be run in DOS mode.\r\r\n$";
injectData(image[IMAGE_DOS_HEADER.sizeof], stub);
auto peh = cast(PIMAGE_NT_HEADERS32)&image[0x80];
injectData(peh.Signature, "PE\0\0");
auto fh = &peh.FileHeader;
fh.Machine = 0x14c;
fh.NumberOfSections = 0x03;
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 = cast(PIMAGE_SECTION_HEADER)&image[0x178];
injectData(scth[0].Name, ".text");
scth[0].VirtualSize = 15;
scth[0].VirtualAddress = 0x1000;
scth[0].SizeOfRawData = 0x200;
scth[0].PointerToRawData = 0x200;
scth[0].Characteristics = 0x60000020;
injectData(scth[1].Name, ".idata");
scth[1].VirtualSize = 0x54;
scth[1].VirtualAddress = 0x2000;
scth[1].SizeOfRawData = 0x200;
scth[1].PointerToRawData = 0x400;
scth[1].Characteristics = 0xc0300040;
injectData(scth[2].Name, ".data");
scth[2].VirtualSize = 7;
scth[2].VirtualAddress = 0x3000;
scth[2].SizeOfRawData = 0x200;
scth[2].PointerToRawData = 0x600;
scth[2].Characteristics = 0xc0000040;
//.idata inf
auto ilt = cast(PIMAGE_IMPORT_DESCRIPTOR)&image[0x400];
ilt[0].OriginalFirstThunk = 0x2028;
ilt[0].Name = 0x2048;
ilt[0].FirstThunk = 0x2030;
injectData(image[0x428], x"3820");
injectData(image[0x430], x"3820");
injectData(image[0x43a], "printf");
injectData(image[0x448], "msvcrt.dll");
// .text infs
// push 0x00403000
image[0x200] = 0x68;
injectData(image[0x201], x"00304000");
// call [0x00402030]
image[0x205] = 0xff;
image[0x206] = 0x15;
injectData(image[0x207], x"30204000");
// add esp, 4
image[0x20b] = 0x83;
image[0x20c] = 0xc4;
image[0x20d] = 4;
// ret
image[0x20e] = 0xc3;
// .data
injectData(image[0x600], "hello\n");
std.file.write("a.exe", image);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment