Skip to content

Instantly share code, notes, and snippets.

@Alligator-1
Forked from bats3c/ldrloaddll_hook.c
Created August 11, 2023 04:06
Show Gist options
  • Save Alligator-1/b6f274b53c954f056e50a39c14b22748 to your computer and use it in GitHub Desktop.
Save Alligator-1/b6f274b53c954f056e50a39c14b22748 to your computer and use it in GitHub Desktop.
Hook LdrLoadDll to whitelist DLLs being loaded into a process
#include <stdio.h>
#include <windows.h>
#include <winternl.h>
#define dwAllowDllCount 1
CHAR cAllowDlls[dwAllowDllCount][MAX_PATH] = {
"W:\\allowed.dll"
};
VOID HookLoadDll(LPVOID lpAddr);
NTSTATUS __stdcall _LdrLoadDll(PWSTR SearchPath OPTIONAL, PULONG DllCharacteristics OPTIONAL, PUNICODE_STRING DllName, PVOID *BaseAddress);
typedef void (WINAPI * LdrLoadDll_) (PWSTR SearchPath OPTIONAL,
PULONG DllCharacteristics OPTIONAL,
PUNICODE_STRING DllName,
PVOID *BaseAddress);
LPVOID lpAddr;
CHAR OriginalBytes[50] = {};
NTSTATUS __stdcall _LdrLoadDll(PWSTR SearchPath OPTIONAL, PULONG DllCharacteristics OPTIONAL, PUNICODE_STRING DllName, PVOID *BaseAddress)
{
INT i;
DWORD dwOldProtect;
BOOL bAllow = FALSE;
DWORD dwbytesWritten;
CHAR cDllName[MAX_PATH];
sprintf(cDllName, "%S", DllName->Buffer);
for (i = 0; i < dwAllowDllCount; i++)
{
if (strcmp(cDllName, cAllowDlls[i]) == 0)
{
bAllow = TRUE;
printf("Allowing DLL: %s\n", cDllName);
VirtualProtect(lpAddr, sizeof(OriginalBytes), PAGE_EXECUTE_READWRITE, &dwOldProtect);
memcpy(lpAddr, OriginalBytes, sizeof(OriginalBytes));
VirtualProtect(lpAddr, sizeof(OriginalBytes), dwOldProtect, &dwOldProtect);
LdrLoadDll_ LdrLoadDll = (LdrLoadDll_)GetProcAddress(LoadLibrary("ntdll.dll"), "LdrLoadDll");
LdrLoadDll(SearchPath, DllCharacteristics, DllName, BaseAddress);
HookLoadDll(lpAddr);
}
}
if (!bAllow)
{
printf("Blocked DLL: %s\n", cDllName);
}
return TRUE;
}
VOID HookLoadDll(LPVOID lpAddr)
{
DWORD oldProtect, oldOldProtect;
void *hLdrLoadDll = &_LdrLoadDll;
// our trampoline
unsigned char boing[] = { 0x49, 0xbb, 0xde, 0xad, 0xc0, 0xde, 0xde, 0xad, 0xc0, 0xde, 0x41, 0xff, 0xe3 };
// add in the address of our hook
*(void **)(boing + 2) = &_LdrLoadDll;
// write the hook
VirtualProtect(lpAddr, 13, PAGE_EXECUTE_READWRITE, &oldProtect);
memcpy(lpAddr, boing, sizeof(boing));
VirtualProtect(lpAddr, 13, oldProtect, &oldProtect);
return;
}
int main(int argc, char const *argv[])
{
printf("LdrLoadDll hook example - @_batsec_\n\n");
// get addresss of where the hook should be
lpAddr = (LPVOID)GetProcAddress(GetModuleHandle("ntdll.dll"), "LdrLoadDll");
// save the original bytes
memcpy(OriginalBytes, lpAddr, 50);
// set the hook
HookLoadDll(lpAddr);
while (TRUE)
{
continue;
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment