mirror of
https://github.com/bats3c/DarkLoadLibrary
synced 2026-06-06 15:14:33 +00:00
add a few more changes and improvements
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
|
||||
@@ -13,11 +13,11 @@ typedef struct _DARKMODULE {
|
||||
PBYTE pbDllData;
|
||||
DWORD dwDllDataLen;
|
||||
LPWSTR LocalDLLName;
|
||||
PWCHAR CrackedDLLName;
|
||||
PWCHAR CrackedDLLName;
|
||||
ULONG_PTR ModuleBase;
|
||||
} DARKMODULE, *PDARKMODULE;
|
||||
|
||||
DARKMODULE DarkLoadLibrary(
|
||||
PDARKMODULE DarkLoadLibrary(
|
||||
DWORD dwFlags,
|
||||
LPCWSTR lpwBuffer,
|
||||
LPVOID lpFileBuffer,
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#define RVA(type, base_addr, rva) (type)((ULONG_PTR) base_addr + rva)
|
||||
|
||||
typedef BOOL(WINAPI * DLLMAIN)(HINSTANCE, DWORD, LPVOID);
|
||||
typedef NTSTATUS(WINAPI *LDRGETPROCADDRESS)(HMODULE, PANSI_STRING, WORD, PVOID*);
|
||||
typedef HMODULE(WINAPI* LOADLIBRARYA)(LPCSTR);
|
||||
|
||||
BOOL IsValidPE(PBYTE pbData);
|
||||
BOOL MapSections(PDARKMODULE pdModule);
|
||||
|
||||
@@ -8,12 +8,15 @@
|
||||
string.MaximumLength = string.Length; \
|
||||
string.Buffer = buffer
|
||||
|
||||
typedef NTSTATUS(WINAPI* LDRGETPROCADDRESS)(HMODULE, PANSI_STRING, WORD, PVOID*);
|
||||
typedef VOID(WINAPI* RTLRBINSERTNODEEX)(_In_ PRTL_RB_TREE Tree, _In_opt_ PRTL_BALANCED_NODE Parent, _In_ BOOLEAN Right, _Out_ PRTL_BALANCED_NODE Node);
|
||||
|
||||
#ifdef _WIN64
|
||||
#define PEB_OFFSET 0x60
|
||||
#define READ_MEMLOC __readgsqword
|
||||
#else
|
||||
#define PEB_OFFSET 0x30
|
||||
#define READ_MEMLOC __readfsdword
|
||||
#define READ_MEMLOC __readfsdword
|
||||
#endif
|
||||
|
||||
#pragma once
|
||||
@@ -27,8 +30,12 @@
|
||||
|
||||
#define LDR_HASH_TABLE_ENTRIES 32
|
||||
|
||||
NTSYSAPI NTSTATUS NTAPI RtlHashUnicodeString(__in PCUNICODE_STRING String, __in BOOLEAN CaseInSensitive, __in ULONG HashAlgorithm, __out PULONG HashValue);
|
||||
NTSYSAPI VOID NTAPI RtlRbInsertNodeEx(_In_ PRTL_RB_TREE Tree, _In_opt_ PRTL_BALANCED_NODE Parent, _In_ BOOLEAN Right, _Out_ PRTL_BALANCED_NODE Node);
|
||||
|
||||
HMODULE IsModulePresent(LPCWSTR lpwName);
|
||||
HMODULE IsModulePresentA(char* Name);
|
||||
BOOL LinkModuleToPEB(PDARKMODULE pdModule);
|
||||
FARPROC GetFunctionAddress(HMODULE hModule, char* ProcName);
|
||||
BOOL LocalLdrGetProcedureAddress(HMODULE hLibrary, PANSI_STRING ProcName, WORD Ordinal, PVOID* FunctionAddress);
|
||||
BOOL LocalLdrGetProcedureAddress(HMODULE hLibrary, PANSI_STRING ProcName, WORD Ordinal, PVOID* FunctionAddress);
|
||||
BOOL _LocalLdrGetProcedureAddress(HMODULE hLibrary, PANSI_STRING ProcName, WORD Ordinal, PVOID* FunctionAddress);
|
||||
@@ -1,258 +1,269 @@
|
||||
#include "darkloadlibrary.h"
|
||||
|
||||
BOOL ParseFileName(
|
||||
PDARKMODULE pdModule,
|
||||
LPWSTR lpwFileName
|
||||
)
|
||||
{
|
||||
if (lpwFileName == NULL)
|
||||
{
|
||||
pdModule->ErrorMsg = L"Invalid filename";
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pdModule->LocalDLLName = lpwFileName;
|
||||
|
||||
HANDLE hHeap = GetProcessHeap();
|
||||
if (!hHeap)
|
||||
{
|
||||
pdModule->ErrorMsg = L"Failed to find valid heap";
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pdModule->CrackedDLLName = (PWCHAR)HeapAlloc(
|
||||
hHeap,
|
||||
HEAP_ZERO_MEMORY,
|
||||
MAX_PATH * 2
|
||||
);
|
||||
|
||||
PWCHAR lpwExt = (PWCHAR)HeapAlloc(
|
||||
hHeap,
|
||||
HEAP_ZERO_MEMORY,
|
||||
MAX_PATH
|
||||
);
|
||||
|
||||
PWCHAR lpwFilename = (PWCHAR)HeapAlloc(
|
||||
hHeap,
|
||||
HEAP_ZERO_MEMORY,
|
||||
MAX_PATH
|
||||
);
|
||||
|
||||
if (!pdModule->CrackedDLLName || !lpwExt || !lpwFilename)
|
||||
{
|
||||
pdModule->ErrorMsg = L"Failed to allocate memory";
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
_wsplitpath(
|
||||
lpwFileName,
|
||||
NULL,
|
||||
NULL,
|
||||
lpwFilename,
|
||||
lpwExt
|
||||
);
|
||||
|
||||
if (lpwFilename == NULL || lpwExt == NULL)
|
||||
{
|
||||
pdModule->ErrorMsg = L"Failed to crack filename";
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
PCHAR lpCpy = wcscpy(
|
||||
pdModule->CrackedDLLName,
|
||||
lpwFilename
|
||||
);
|
||||
|
||||
PCHAR lpCat = wcscat(
|
||||
pdModule->CrackedDLLName,
|
||||
lpwExt
|
||||
);
|
||||
|
||||
if (!lpCpy || !lpCat)
|
||||
{
|
||||
pdModule->ErrorMsg = L"Failed to format cracked path";
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL ReadFileToBuffer(
|
||||
PDARKMODULE pdModule
|
||||
)
|
||||
{
|
||||
HANDLE hFile = CreateFileW(
|
||||
pdModule->LocalDLLName,
|
||||
GENERIC_READ,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
0,
|
||||
NULL
|
||||
);
|
||||
|
||||
if (hFile == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
pdModule->ErrorMsg = L"Failed to open local DLL file";
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
DWORD dwSize = GetFileSize(
|
||||
hFile,
|
||||
NULL
|
||||
);
|
||||
|
||||
if (dwSize == INVALID_FILE_SIZE)
|
||||
{
|
||||
pdModule->ErrorMsg = L"Failed to get DLL file size";
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pdModule->pbDllData = VirtualAlloc(
|
||||
NULL,
|
||||
dwSize,
|
||||
MEM_COMMIT | MEM_RESERVE,
|
||||
PAGE_READWRITE
|
||||
);
|
||||
|
||||
if (pdModule->pbDllData == NULL)
|
||||
{
|
||||
pdModule->ErrorMsg = L"Failed to allocate memory for DLL data";
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!ReadFile(
|
||||
hFile,
|
||||
pdModule->pbDllData,
|
||||
dwSize,
|
||||
&pdModule->dwDllDataLen,
|
||||
NULL))
|
||||
{
|
||||
pdModule->ErrorMsg = L"Failed to read data from DLL file";
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!CloseHandle(hFile))
|
||||
{
|
||||
pdModule->ErrorMsg = L"Failed to close handle on DLL file";
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
DARKMODULE DarkLoadLibrary(
|
||||
DWORD dwFlags,
|
||||
LPCWSTR lpwBuffer,
|
||||
LPVOID lpFileBuffer,
|
||||
DWORD dwLen,
|
||||
LPCWSTR lpwName
|
||||
)
|
||||
{
|
||||
DARKMODULE dModule;
|
||||
|
||||
dModule.bSuccess = FALSE;
|
||||
|
||||
// get the DLL data into memory, whatever the format it's in
|
||||
switch (dwFlags)
|
||||
{
|
||||
case LOAD_LOCAL_FILE:
|
||||
if (!ParseFileName(&dModule, lpwBuffer) || !ReadFileToBuffer(&dModule))
|
||||
{
|
||||
goto Cleanup;
|
||||
}
|
||||
break;
|
||||
|
||||
case LOAD_MEMORY:
|
||||
dModule.dwDllDataLen = dwLen;
|
||||
dModule.pbDllData = lpFileBuffer;
|
||||
|
||||
/*
|
||||
This is probably a hack for the greater scheme but lol
|
||||
*/
|
||||
dModule.CrackedDLLName = lpwName;
|
||||
dModule.LocalDLLName = lpwName;
|
||||
|
||||
break;
|
||||
|
||||
case NO_LINK:
|
||||
dModule.ErrorMsg = L"Not implemented yet, sorry";
|
||||
goto Cleanup;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// is there a module with the same name already loaded
|
||||
if (lpwName == NULL)
|
||||
{
|
||||
lpwName = dModule.CrackedDLLName;
|
||||
}
|
||||
|
||||
HMODULE hModule = IsModulePresent(
|
||||
lpwName
|
||||
);
|
||||
|
||||
if (hModule != NULL)
|
||||
{
|
||||
dModule.ModuleBase = hModule;
|
||||
dModule.bSuccess = TRUE;
|
||||
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
// make sure the PE we are about to load is valid
|
||||
if (!IsValidPE(dModule.pbDllData))
|
||||
{
|
||||
dModule.ErrorMsg = L"Data is an invalid PE";
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
// map the sections into memory
|
||||
if (!MapSections(&dModule))
|
||||
{
|
||||
dModule.ErrorMsg = L"Failed to map sections";
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
// handle the import tables
|
||||
if (!ResolveImports(&dModule))
|
||||
{
|
||||
dModule.ErrorMsg = L"Failed to resolve imports";
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
// link the module to the PEB
|
||||
if (!LinkModuleToPEB(&dModule))
|
||||
{
|
||||
dModule.ErrorMsg = L"Failed to link module to PEB";
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
// trigger tls callbacks, set permissions and call the entry point
|
||||
if (!BeginExecution(&dModule))
|
||||
{
|
||||
dModule.ErrorMsg = L"Failed to execute";
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
dModule.bSuccess = TRUE;
|
||||
|
||||
goto Cleanup;
|
||||
|
||||
Cleanup:
|
||||
return dModule;
|
||||
}
|
||||
|
||||
BOOL ConcealLibrary(
|
||||
PDARKMODULE pdModule,
|
||||
BOOL bConceal
|
||||
)
|
||||
{
|
||||
// TODO: reimplement this function, so it is better
|
||||
|
||||
pdModule->ErrorMsg = L"Not implemented yet, sorry";
|
||||
|
||||
return FALSE;
|
||||
#include "darkloadlibrary.h"
|
||||
#include "ldrutils.h"
|
||||
|
||||
BOOL ParseFileName(
|
||||
PDARKMODULE pdModule,
|
||||
LPWSTR lpwFileName
|
||||
)
|
||||
{
|
||||
if (lpwFileName == NULL)
|
||||
{
|
||||
pdModule->ErrorMsg = L"Invalid filename";
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pdModule->LocalDLLName = lpwFileName;
|
||||
|
||||
HANDLE hHeap = GetProcessHeap();
|
||||
if (!hHeap)
|
||||
{
|
||||
pdModule->ErrorMsg = L"Failed to find valid heap";
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pdModule->CrackedDLLName = (PWCHAR)HeapAlloc(
|
||||
hHeap,
|
||||
HEAP_ZERO_MEMORY,
|
||||
MAX_PATH * 2
|
||||
);
|
||||
|
||||
PWCHAR lpwExt = (PWCHAR)HeapAlloc(
|
||||
hHeap,
|
||||
HEAP_ZERO_MEMORY,
|
||||
MAX_PATH
|
||||
);
|
||||
|
||||
PWCHAR lpwFilename = (PWCHAR)HeapAlloc(
|
||||
hHeap,
|
||||
HEAP_ZERO_MEMORY,
|
||||
MAX_PATH
|
||||
);
|
||||
|
||||
if (!pdModule->CrackedDLLName || !lpwExt || !lpwFilename)
|
||||
{
|
||||
pdModule->ErrorMsg = L"Failed to allocate memory";
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
_wsplitpath(
|
||||
lpwFileName,
|
||||
NULL,
|
||||
NULL,
|
||||
lpwFilename,
|
||||
lpwExt
|
||||
);
|
||||
|
||||
if (lpwFilename == NULL || lpwExt == NULL)
|
||||
{
|
||||
pdModule->ErrorMsg = L"Failed to crack filename";
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
PCHAR lpCpy = (PCHAR)wcscpy(
|
||||
pdModule->CrackedDLLName,
|
||||
lpwFilename
|
||||
);
|
||||
|
||||
PCHAR lpCat = (PCHAR)wcscat(
|
||||
pdModule->CrackedDLLName,
|
||||
lpwExt
|
||||
);
|
||||
|
||||
if (!lpCpy || !lpCat)
|
||||
{
|
||||
pdModule->ErrorMsg = L"Failed to format cracked path";
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL ReadFileToBuffer(
|
||||
PDARKMODULE pdModule
|
||||
)
|
||||
{
|
||||
HANDLE hFile = CreateFileW(
|
||||
pdModule->LocalDLLName,
|
||||
GENERIC_READ,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
0,
|
||||
NULL
|
||||
);
|
||||
|
||||
if (hFile == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
pdModule->ErrorMsg = L"Failed to open local DLL file";
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
DWORD dwSize = GetFileSize(
|
||||
hFile,
|
||||
NULL
|
||||
);
|
||||
|
||||
if (dwSize == INVALID_FILE_SIZE)
|
||||
{
|
||||
pdModule->ErrorMsg = L"Failed to get DLL file size";
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pdModule->pbDllData = VirtualAlloc(
|
||||
NULL,
|
||||
dwSize,
|
||||
MEM_COMMIT | MEM_RESERVE,
|
||||
PAGE_READWRITE
|
||||
);
|
||||
|
||||
if (pdModule->pbDllData == NULL)
|
||||
{
|
||||
pdModule->ErrorMsg = L"Failed to allocate memory for DLL data";
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!ReadFile(
|
||||
hFile,
|
||||
pdModule->pbDllData,
|
||||
dwSize,
|
||||
&pdModule->dwDllDataLen,
|
||||
NULL))
|
||||
{
|
||||
pdModule->ErrorMsg = L"Failed to read data from DLL file";
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!CloseHandle(hFile))
|
||||
{
|
||||
pdModule->ErrorMsg = L"Failed to close handle on DLL file";
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
PDARKMODULE DarkLoadLibrary(
|
||||
DWORD dwFlags,
|
||||
LPCWSTR lpwBuffer,
|
||||
LPVOID lpFileBuffer,
|
||||
DWORD dwLen,
|
||||
LPCWSTR lpwName
|
||||
)
|
||||
{
|
||||
PDARKMODULE dModule = (DARKMODULE*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DARKMODULE));
|
||||
|
||||
dModule->bSuccess = FALSE;
|
||||
|
||||
// get the DLL data into memory, whatever the format it's in
|
||||
switch (dwFlags)
|
||||
{
|
||||
case LOAD_LOCAL_FILE:
|
||||
if (!ParseFileName(dModule, lpwBuffer) || !ReadFileToBuffer(dModule))
|
||||
{
|
||||
goto Cleanup;
|
||||
}
|
||||
break;
|
||||
|
||||
case LOAD_MEMORY:
|
||||
dModule->dwDllDataLen = dwLen;
|
||||
dModule->pbDllData = lpFileBuffer;
|
||||
|
||||
/*
|
||||
This is probably a hack for the greater scheme but lol
|
||||
*/
|
||||
dModule->CrackedDLLName = lpwName;
|
||||
dModule->LocalDLLName = lpwName;
|
||||
|
||||
break;
|
||||
|
||||
case NO_LINK:
|
||||
dModule->ErrorMsg = L"Not implemented yet, sorry";
|
||||
goto Cleanup;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// is there a module with the same name already loaded
|
||||
if (lpwName == NULL)
|
||||
{
|
||||
lpwName = dModule->CrackedDLLName;
|
||||
}
|
||||
|
||||
HMODULE hModule = IsModulePresent(
|
||||
lpwName
|
||||
);
|
||||
|
||||
if (hModule != NULL)
|
||||
{
|
||||
dModule->ModuleBase = (ULONG_PTR)hModule;
|
||||
dModule->bSuccess = TRUE;
|
||||
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
// make sure the PE we are about to load is valid
|
||||
if (!IsValidPE(dModule->pbDllData))
|
||||
{
|
||||
dModule->ErrorMsg = (wchar_t*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 500);
|
||||
wcscat(dModule->ErrorMsg, L"Data is an invalid PE: ");
|
||||
wcscat(dModule->ErrorMsg, lpwName);
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
// map the sections into memory
|
||||
if (!MapSections(dModule))
|
||||
{
|
||||
dModule->ErrorMsg = (wchar_t*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 500);
|
||||
wcscat(dModule->ErrorMsg, L"Failed to map sections: ");
|
||||
wcscat(dModule->ErrorMsg, lpwName);
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
// handle the import tables
|
||||
if (!ResolveImports(dModule))
|
||||
{
|
||||
dModule->ErrorMsg = (wchar_t*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 500);
|
||||
wcscat(dModule->ErrorMsg, L"Failed to resolve imports: ");
|
||||
wcscat(dModule->ErrorMsg, lpwName);
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
// link the module to the PEB
|
||||
if (!LinkModuleToPEB(dModule))
|
||||
{
|
||||
dModule->ErrorMsg = (wchar_t*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 500);
|
||||
wcscat(dModule->ErrorMsg, L"Failed to link module to PEB: ");
|
||||
wcscat(dModule->ErrorMsg, lpwName);
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
// trigger tls callbacks, set permissions and call the entry point
|
||||
if (!BeginExecution(dModule))
|
||||
{
|
||||
dModule->ErrorMsg = (wchar_t*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 500);
|
||||
wcscat(dModule->ErrorMsg, L"Failed to execute: ");
|
||||
wcscat(dModule->ErrorMsg, lpwName);
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
dModule->bSuccess = TRUE;
|
||||
|
||||
goto Cleanup;
|
||||
|
||||
Cleanup:
|
||||
return dModule;
|
||||
}
|
||||
|
||||
BOOL ConcealLibrary(
|
||||
PDARKMODULE pdModule,
|
||||
BOOL bConceal
|
||||
)
|
||||
{
|
||||
// TODO: reimplement this function, so it is better
|
||||
|
||||
pdModule->ErrorMsg = L"Not implemented yet, sorry";
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
@@ -44,7 +44,7 @@ BOOL MapSections(
|
||||
SIZE_T RegionSize = pNtHeaders->OptionalHeader.SizeOfImage;
|
||||
NTSTATUS status = NtAllocateVirtualMemory(
|
||||
(HANDLE)-1,
|
||||
&pdModule->ModuleBase,
|
||||
(PVOID)&pdModule->ModuleBase,
|
||||
0,
|
||||
&RegionSize,
|
||||
MEM_RESERVE | MEM_COMMIT,
|
||||
@@ -52,11 +52,11 @@ BOOL MapSections(
|
||||
);
|
||||
if (!NT_SUCCESS(status) || pdModule->ModuleBase != pNtHeaders->OptionalHeader.ImageBase)
|
||||
{
|
||||
pdModule->ModuleBase = NULL;
|
||||
pdModule->ModuleBase = 0;
|
||||
RegionSize = pNtHeaders->OptionalHeader.SizeOfImage;
|
||||
status = NtAllocateVirtualMemory(
|
||||
(HANDLE)-1,
|
||||
&pdModule->ModuleBase,
|
||||
(PVOID)&pdModule->ModuleBase,
|
||||
0,
|
||||
&RegionSize,
|
||||
MEM_RESERVE | MEM_COMMIT,
|
||||
@@ -91,7 +91,7 @@ BOOL MapSections(
|
||||
}
|
||||
#endif
|
||||
// copy across the headers
|
||||
for (INT i = 0; i < pNtHeaders->OptionalHeader.SizeOfHeaders; i++)
|
||||
for (DWORD i = 0; i < pNtHeaders->OptionalHeader.SizeOfHeaders; i++)
|
||||
{
|
||||
((PBYTE)pdModule->ModuleBase)[i] = ((PBYTE)pdModule->pbDllData)[i];
|
||||
}
|
||||
@@ -99,9 +99,9 @@ BOOL MapSections(
|
||||
// copy across the sections
|
||||
pSectionHeader = IMAGE_FIRST_SECTION(pNtHeaders);
|
||||
|
||||
for (INT i = 0; i < pNtHeaders->FileHeader.NumberOfSections; i++, pSectionHeader++)
|
||||
for (DWORD i = 0; i < pNtHeaders->FileHeader.NumberOfSections; i++, pSectionHeader++)
|
||||
{
|
||||
for (INT j = 0; j < pSectionHeader->SizeOfRawData; j++)
|
||||
for (DWORD j = 0; j < pSectionHeader->SizeOfRawData; j++)
|
||||
{
|
||||
((PBYTE)(pdModule->ModuleBase + pSectionHeader->VirtualAddress))[j] = ((PBYTE)(pdModule->pbDllData + pSectionHeader->PointerToRawData))[j];
|
||||
}
|
||||
@@ -150,6 +150,7 @@ BOOL MapSections(
|
||||
|
||||
} while (pRelocation->VirtualAddress);
|
||||
}
|
||||
pNtHeaders->OptionalHeader.ImageBase = pdModule->ModuleBase; // set the prefered base to the real base
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -166,6 +167,11 @@ BOOL ResolveImports(
|
||||
PIMAGE_THUNK_DATA pFirstThunk, pOrigFirstThunk;
|
||||
BOOL ok;
|
||||
|
||||
LOADLIBRARYA pLoadLibraryA = (LOADLIBRARYA)GetFunctionAddress(
|
||||
IsModulePresentA("Kernel32.dll"),
|
||||
"LoadLibraryA"
|
||||
);
|
||||
|
||||
STRING aString = { 0 };
|
||||
|
||||
pNtHeaders = RVA(
|
||||
@@ -202,9 +208,15 @@ BOOL ResolveImports(
|
||||
{
|
||||
// use LoadLibraryA for the time being.
|
||||
// make this recursive in the future.
|
||||
HMODULE hLibrary = LoadLibraryA(
|
||||
(LPSTR)(pdModule->ModuleBase + pImportDesc->Name)
|
||||
HMODULE hLibrary = IsModulePresentA(
|
||||
(char*)(pdModule->ModuleBase + pImportDesc->Name)
|
||||
);
|
||||
if (hLibrary == NULL)
|
||||
{
|
||||
hLibrary = pLoadLibraryA(
|
||||
(LPSTR)(pdModule->ModuleBase + pImportDesc->Name)
|
||||
);
|
||||
}
|
||||
|
||||
pFirstThunk = RVA(
|
||||
PIMAGE_THUNK_DATA,
|
||||
@@ -271,7 +283,15 @@ BOOL ResolveImports(
|
||||
{
|
||||
// use LoadLibraryA for the time being.
|
||||
// make this recursive in the future.
|
||||
HMODULE hLibrary = LoadLibraryA((LPSTR)(pdModule->ModuleBase + pDelayDesc->DllNameRVA));
|
||||
HMODULE hLibrary = IsModulePresentA(
|
||||
(char*)(pdModule->ModuleBase + pDelayDesc->DllNameRVA)
|
||||
);
|
||||
if (hLibrary == NULL)
|
||||
{
|
||||
hLibrary = pLoadLibraryA(
|
||||
(LPSTR)(pdModule->ModuleBase + pDelayDesc->DllNameRVA)
|
||||
);
|
||||
}
|
||||
|
||||
pFirstThunk = RVA(
|
||||
PIMAGE_THUNK_DATA,
|
||||
@@ -337,7 +357,7 @@ BOOL BeginExecution(
|
||||
PIMAGE_DATA_DIRECTORY pDataDir;
|
||||
PIMAGE_TLS_CALLBACK* ppCallback;
|
||||
PIMAGE_SECTION_HEADER pSectionHeader;
|
||||
PIMAGE_RUNTIME_FUNCTION_ENTRY pFuncEntry;
|
||||
//PIMAGE_RUNTIME_FUNCTION_ENTRY pFuncEntry;
|
||||
|
||||
DLLMAIN DllMain = NULL;
|
||||
|
||||
@@ -372,7 +392,7 @@ BOOL BeginExecution(
|
||||
dwProtect |= PAGE_NOCACHE;
|
||||
}
|
||||
#if _M_X64
|
||||
PVOID BaseAddress = pdModule->ModuleBase + pSectionHeader->VirtualAddress;
|
||||
PVOID BaseAddress = (PVOID)(pdModule->ModuleBase + pSectionHeader->VirtualAddress);
|
||||
SIZE_T RegionSize = pSectionHeader->SizeOfRawData;
|
||||
NTSTATUS status = NtProtectVirtualMemory(
|
||||
(HANDLE)-1,
|
||||
@@ -438,6 +458,10 @@ BOOL BeginExecution(
|
||||
// }
|
||||
// #endif
|
||||
|
||||
// some DLLs don't have an entry point
|
||||
if (pNtHeaders->OptionalHeader.AddressOfEntryPoint == 0)
|
||||
return TRUE;
|
||||
|
||||
// call the image entry point
|
||||
DllMain = RVA(
|
||||
DLLMAIN,
|
||||
@@ -445,11 +469,11 @@ BOOL BeginExecution(
|
||||
pNtHeaders->OptionalHeader.AddressOfEntryPoint
|
||||
);
|
||||
|
||||
DllMain(
|
||||
BOOL ok = DllMain(
|
||||
(HINSTANCE)pdModule->ModuleBase,
|
||||
DLL_PROCESS_ATTACH,
|
||||
(LPVOID)NULL
|
||||
);
|
||||
|
||||
return TRUE;
|
||||
return ok;
|
||||
}
|
||||
@@ -8,7 +8,7 @@ typedef DWORD (WINAPI * _ThisIsAFunction) (LPCWSTR);
|
||||
|
||||
VOID main()
|
||||
{
|
||||
DARKMODULE DarkModule = DarkLoadLibrary(
|
||||
PDARKMODULE DarkModule = DarkLoadLibrary(
|
||||
LOAD_LOCAL_FILE,
|
||||
L"TestDLL.dll",
|
||||
NULL,
|
||||
@@ -16,16 +16,19 @@ VOID main()
|
||||
NULL
|
||||
);
|
||||
|
||||
if (!DarkModule.bSuccess)
|
||||
if (!DarkModule->bSuccess)
|
||||
{
|
||||
printf("load failed: %S\n", DarkModule.ErrorMsg);
|
||||
printf("load failed: %S\n", DarkModule->ErrorMsg);
|
||||
HeapFree(GetProcessHeap(), 0, DarkModule->ErrorMsg);
|
||||
HeapFree(GetProcessHeap(), 0, DarkModule);
|
||||
return;
|
||||
}
|
||||
|
||||
_ThisIsAFunction ThisIsAFunction = GetFunctionAddress(
|
||||
DarkModule.ModuleBase,
|
||||
_ThisIsAFunction ThisIsAFunction = (_ThisIsAFunction)GetFunctionAddress(
|
||||
(HMODULE)DarkModule->ModuleBase,
|
||||
"CallThisFunction"
|
||||
);
|
||||
HeapFree(GetProcessHeap(), 0, DarkModule);
|
||||
|
||||
if (!ThisIsAFunction)
|
||||
{
|
||||
|
||||
@@ -173,10 +173,13 @@ BOOL AddBaseAddressEntry(
|
||||
{
|
||||
pLdrNode->DdagNode->LoadCount++;
|
||||
}
|
||||
|
||||
} while (TRUE);
|
||||
|
||||
RtlRbInsertNodeEx(pModBaseAddrIndex, &pLdrNode->BaseAddressIndexNode, bRight, &pLdrEntry->BaseAddressIndexNode);
|
||||
RTLRBINSERTNODEEX pRtlRbInsertNodeEx = (RTLRBINSERTNODEEX)GetFunctionAddress(
|
||||
IsModulePresent(L"ntdll.dll"),
|
||||
"RtlRbInsertNodeEx"
|
||||
);
|
||||
pRtlRbInsertNodeEx(pModBaseAddrIndex, &pLdrNode->BaseAddressIndexNode, bRight, &pLdrEntry->BaseAddressIndexNode);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -427,11 +430,28 @@ BOOL LocalLdrGetProcedureAddress(
|
||||
if (ok)
|
||||
return TRUE;
|
||||
|
||||
if (ProcName != NULL)
|
||||
printf("LocalLdrGetProcedureAddress: unable to resolve address of function: %s\n", ProcName->Buffer);
|
||||
else
|
||||
printf("LocalLdrGetProcedureAddress: unable to resolve address of function ordinal: %d\n", Ordinal);
|
||||
return FALSE;
|
||||
//printf("Using fallback LdrGetProcedureAddress for resolving an unknown function address\n");
|
||||
|
||||
*FunctionAddress = NULL;
|
||||
LDRGETPROCADDRESS pLdrGetProcedureAddress = NULL;
|
||||
STRING funcname_s = { 0 };
|
||||
FILL_STRING(
|
||||
funcname_s,
|
||||
"LdrGetProcedureAddress"
|
||||
);
|
||||
_LocalLdrGetProcedureAddress(
|
||||
IsModulePresent(L"ntdll.dll"),
|
||||
&funcname_s,
|
||||
0,
|
||||
(PVOID*)&pLdrGetProcedureAddress
|
||||
);
|
||||
pLdrGetProcedureAddress(
|
||||
hLibrary,
|
||||
ProcName,
|
||||
Ordinal,
|
||||
FunctionAddress
|
||||
);
|
||||
return *FunctionAddress != NULL;
|
||||
}
|
||||
|
||||
BOOL _LocalLdrGetProcedureAddress(
|
||||
@@ -681,7 +701,7 @@ BOOL LinkModuleToPEB(
|
||||
(PVOID)pdModule->ModuleBase
|
||||
);
|
||||
|
||||
// an the rest
|
||||
// and the rest
|
||||
pLdrEntry->ImageDll = TRUE;
|
||||
pLdrEntry->LoadNotificationsSent = TRUE; // lol
|
||||
pLdrEntry->EntryProcessed = TRUE;
|
||||
|
||||
Reference in New Issue
Block a user