I tried loading the DLL file "bcryptprimitives.dll" (which in my case, originally sits under "C:\Windows\syswow64\bcryptprimitives.dll") from another location, with this snippet of code:
LoadLibraryW(L"<altered path>\\bcryptprimitives.dll");
However, right after executing this line of code I get the following error:
C:\Program Files (x86)\Notepad++\bcryptprimitives.dll is either not designed to run on Windows or it contains an error. Try installing the program again using the original installation media or contact your system administrator or the software vendor for support. Error status 0xc0000428.
I searched the 0xc0000428 NTSTATUS in the following dictionary: https://msdn.microsoft.com/en-us/library/cc704588.aspx
and apparently this status means STATUS_INVALID_IMAGE_HASH
.
The error at first makes sense, because I changed the "LoaderFlags" field in the image PE header from 0x00000000 to 0x00000001 (which doesn't need to affect anything because this field is deprecated), but even though I changed the field, I fixed the PE checksum.
However, LoadLibrary still refuses to load the DLL.
Diving deep into ntdll
reveals that the error is returned from kernel:
It makes me think that the DLL is somehow signed and the kernel checks whether the DLL was altered. So to my point, how can I load this DLL from another location anyway and remove the sign check?
If a DLL is signed, then by changing a single byte in the file will invalidate the signature. It appears you are doing exactly that by modifying PE header.
This blog post might be of interest to for deeper insight how this technology works:
Code Integrity is a feature that improves the security of the operating system by validating the integrity of a driver or system file each time it is loaded into memory. Code Integrity detects whether an unsigned driver or system file is being loaded into the kernel, or whether a system file has been modified by malicious software that is being run by a user account with administrative permissions. On x64-based versions of the operating system, kernel-mode drivers must be digitally signed.
Found a quick solution:
DWORD dwIndex = 0;
hFile = CreateFileW(L"C:\\Program Files (x86)\\Notepad++\\bcryptprimitives.dll", FILE_READ_DATA | FILE_WRITE_DATA, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
while (ImageRemoveCertificate(hFile, dwIndex))
{
++dwIndex;
}
LoadLibraryW(L"C:\\Program Files (x86)\\Notepad++\\bcryptprimitives.dll");
It is working like a charm :)
This is how the API works:
User contributions licensed under CC BY-SA 3.0