Last active
October 20, 2024 10:39
-
-
Save bats3c/59932dfa1f5bb23dd36071119b91af0f to your computer and use it in GitHub Desktop.
Hook LdrLoadDll to whitelist DLLs being loaded into a process
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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