Last active
July 2, 2024 05:32
-
-
Save bencz/3576dfc8a217a34c05a9 to your computer and use it in GitHub Desktop.
ExeMaker_DLanguae
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
// 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