Showing preview only (343K chars total). Download the full file or copy to clipboard to get everything.
Repository: paskalian/WID_LoadLibrary
Branch: main
Commit: e3f55b6f40ba
Files: 18
Total size: 331.5 KB
Directory structure:
gitextract_m362muyh/
├── .gitignore
├── LICENSE
├── README.md
├── Src/
│ ├── Functions/
│ │ ├── KERNEL32.cpp
│ │ ├── KERNEL32.h
│ │ ├── NT.cpp
│ │ ├── NT.h
│ │ ├── Syscalls.asm
│ │ └── Undocumented.h
│ ├── Includes.h
│ ├── Loader/
│ │ ├── Loader.cpp
│ │ └── Loader.h
│ ├── Main.cpp
│ ├── WID.cpp
│ └── WID.h
├── WID_LoadLibrary.sln
├── WID_LoadLibrary.vcxproj
└── WID_LoadLibrary.vcxproj.filters
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
################################################################################
# Bu .gitignore dosyası Microsoft(R) Visual Studio tarafından otomatik olarak oluşturulmuştur.
################################################################################
/.vs
/WID_LoadLibrary.vcxproj.user
/x64/Debug
/Debug/WID_LoadLibrary.tlog
/Debug
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2023 Paskalian
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: README.md
================================================

<br>
# LEGAL NOTICE
<ins><b>I do not take responsibility for any misuse of these information in any way.</b></ins>
The purpose of these series are **only** to understand Windows better, there is a lot to discover.
# Information
### Compatibility
The project is designed specifically for x64 architecture, not tested in x86 architecture.
### Functions
All the function implementations given are my own, they are not guaranteed to represent the exact functionality.
# Usage
Pretty easy, you first include "WID.h" into your source file. Then you create a LOADLIBRARY instance with a path given, and that's it. Now you can almost see the entire loading process!
```cpp
#include "WID.h"
using namespace WID::Loader;
int main()
{
LOADLIBRARY LoadDll(TEXT("PATH_TO_DLL.dll"));
}
```
The constructor takes in 3 arguments, which the last 2 are set by default.
#### PATH
Dll path, can be absolute or relative. **Must** be given.
#### FLAGS
Same flags as in LoadLibraryExW, you can check the possible values in [here](https://learn.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-loadlibraryexw). Set to 0 by default.
#### LOAD TYPE (NOT USEFUL CURRENTLY)
If set to LOADTYPE::HIDDEN, Windows will not be informed about the loading of the dll. Set to LOADTYPE::DEFAULT by default.
<hr>
# What is LoadLibrary?
LoadLibrary is an easy to use Windows API function for loading Dynamic Link Libraries (DLLs) into programs.
To be able to use it you must first include <Windows.h> into your source file.
There are 4 widely used LoadLibrary functions
- [LoadLibraryA](https://learn.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-loadlibrarya "MSDN Reference")
- [LoadLibraryW](https://learn.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-loadlibraryw "MSDN Reference")
- [LoadLibraryExA](https://learn.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-loadlibraryexa "MSDN Reference")
- [LoadLibraryExW](https://learn.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-loadlibraryexw "MSDN Reference")
Even if they look like seperate, they all end up in **LoadLibraryExW** finally, wanna learn how? Keep reading.
<hr>
Here is a basic diagram to show what functions are called in order to load a module into a process (maybe not exact represantation).<br>
<p align="center">
<b>The path was given absolute and no flags were given</b>
<img src="https://github.com/paskalian/WID_LoadLibrary/blob/main/Images/Diagram.svg" alt="Diagram"/>
</p>
# Basic Explanations
## LoadLibrary
```cpp
#ifdef UNICODE
#define LoadLibrary LoadLibraryW
#else
#define LoadLibrary LoadLibraryA
#endif // !UNICODE
```
Not a function by itself but a macro instead, resolved into one of the according functions **LoadLibraryA** or **LoadLibraryW** depending on your character set being **Multi-byte** or **Unicode** respectively.
<br>
## LoadLibraryA
```cpp
HMODULE __fastcall LOADLIBRARY::fLoadLibraryA(LPCSTR lpLibFileName)
{
// If no path was given.
if (!lpLibFileName)
//return LoadLibraryExA(lpLibFileName, 0, 0);
return NULL;
// If path isn't 'twain_32.dll'
// This is where our LoadLibrary calls mostly end up.
if (_stricmp(lpLibFileName, "twain_32.dll"))
return fLoadLibraryExA(lpLibFileName, 0, 0);
// If path is 'twain_32.dll'
// Windows probably uses this to make itself a shortcut, while we are using it the code won't reach here.
PCHAR Heap = (PCHAR)RtlAllocateHeap(NtCurrentPeb()->ProcessHeap, *KernelBaseGlobalData, MAX_PATH);
if (!Heap)
return fLoadLibraryExA(lpLibFileName, 0, 0);
HMODULE Module;
// Heap receives the Windows path (def: C:\Windows)
// The BufferSize check made against GetWindowsDirectoryA is to see if it actually received. If it's bigger than BufferSize
// then GetWindowsDirectoryA returned the size needed (in summary it fails)
// If this check doesn't fail '\twain_32.dll' is appended to the Windows path (def: C:\Windows\twain_32.dll)
// Then this final module is loaded into the program.
// If it can't load, it tries to load it directly and returns from there.
if (GetWindowsDirectoryA(Heap, 0xF7) - 1 > 0xF5 ||
(strncat_s(Heap, MAX_PATH, "\\twain_32.dll", strlen("\\twain_32.dll")), (Module = fLoadLibraryA(Heap)) == 0))
{
RtlFreeHeap(NtCurrentPeb()->ProcessHeap, 0, Heap);
return fLoadLibraryExA(lpLibFileName, 0, 0);
}
RtlFreeHeap(NtCurrentPeb()->ProcessHeap, 0, Heap);
return Module;
}
```
In our use case it's just a small wrapper around LoadLibraryExA. Other way around you can see it provides a shortcut mechanism for loading "**twain_32.dll**".
<br>
## LoadLibraryW
```cpp
HMODULE __fastcall LOADLIBRARY::fLoadLibraryW(LPCWSTR lpLibFileName)
{
return fLoadLibraryExW(lpLibFileName, 0, 0);
}
```
A wrapper for LoadLibraryExW.
<br>
## LoadLibraryExA
```cpp
HMODULE __fastcall LOADLIBRARY::fLoadLibraryExA(LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
{
UNICODE_STRING Unicode;
if (!Basep8BitStringToDynamicUnicodeString(&Unicode, lpLibFileName))
return NULL;
HMODULE Module = fLoadLibraryExW(Unicode.Buffer, hFile, dwFlags);
RtlFreeUnicodeString(&Unicode);
return Module;
}
```
Converts our ANSI given lpLibFileName into Unicode then calls LoadLibraryExW with it. In summary it's a wrapper for LoadLibraryExW, that's what I meant when I said all of the 4 functions end up in LoadLibraryExW.
<br>
## LoadLibraryExW
```cpp
HMODULE __fastcall LOADLIBRARY::fLoadLibraryExW(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
{
NTSTATUS Status;
DWORD ConvertedFlags;
HMODULE BaseOfLoadedDll;
DWORD DatafileFlags = dwFlags & LLEXW_ASDATAFILE;
// If no DllName was given OR hFile was given (msdn states that hFile must be 0) OR dwFlags is set to an unknown value OR *both* the Datafile flags are set (they cannot be used together).
if (!lpLibFileName || hFile || ((dwFlags & 0xFFFF0000) != 0) || (DatafileFlags == LLEXW_ASDATAFILE))
{
BaseSetLastNTError(STATUS_INVALID_PARAMETER);
return NULL;
}
UNICODE_STRING DllName;
Status = RtlInitUnicodeStringEx(&DllName, lpLibFileName);
if (!NT_SUCCESS(Status))
{
BaseSetLastNTError(Status);
return NULL;
}
USHORT DllNameLen = DllName.Length;
if (!DllName.Length)
{
BaseSetLastNTError(STATUS_INVALID_PARAMETER);
return NULL;
}
// If the DllName given had empty (space) chars as their last chars, this do-while loop excludes them and sets the excluded length.
do
{
DWORD WchAmount = DllNameLen / 2;
if (DllName.Buffer[WchAmount - 1] != ' ' /* 0x20 is space char */)
break;
DllNameLen -= 2;
DllName.Length = DllNameLen;
} while (DllNameLen != 2);
// In case the above do-while loop misbehaves.
if (DllNameLen == 0)
{
BaseSetLastNTError(STATUS_INVALID_PARAMETER);
return NULL;
}
BaseOfLoadedDll = 0;
// If the dll is not getting loaded as a datafile.
if ((dwFlags & LLEXW_ISDATAFILE) == 0)
{
// Converts the actual flags into it's own flag format. Most flags are discarded (only used if loaded as datafile).
// Only flags that can go through are DONT_RESOLVE_DLL_REFERENCES, LOAD_PACKAGED_LIBRARY, LOAD_LIBRARY_REQUIRE_SIGNED_TARGET and LOAD_LIBRARY_OS_INTEGRITY_CONTINUITY
ConvertedFlags = 0;
if ((dwFlags & DONT_RESOLVE_DLL_REFERENCES) != 0)
ConvertedFlags |= CNVTD_DONT_RESOLVE_DLL_REFERENCES;
if ((dwFlags & LOAD_PACKAGED_LIBRARY) != 0)
ConvertedFlags |= LOAD_PACKAGED_LIBRARY;
if ((dwFlags & LOAD_LIBRARY_REQUIRE_SIGNED_TARGET) != 0)
ConvertedFlags |= CNVTD_LOAD_LIBRARY_REQUIRE_SIGNED_TARGET;
if ((dwFlags & LOAD_LIBRARY_OS_INTEGRITY_CONTINUITY) != 0)
ConvertedFlags |= CNVTD_LOAD_LIBRARY_OS_INTEGRITY_CONTINUITY;
// Evaluates dwFlags to get meaningful flags, includes DONT_RESOLVE_DLL_REFERENCES finally.
// But it doesn't matter because the first param LdrLoadDll takes actually a (PWCHAR PathToFile), so I have no idea why that's done.
Status = fLdrLoadDll((PWCHAR)((dwFlags & LLEXW_7F08) | 1), &ConvertedFlags, &DllName, (PVOID*)&BaseOfLoadedDll);
if (NT_SUCCESS(Status))
return BaseOfLoadedDll;
BaseSetLastNTError(Status);
return NULL;
}
PWSTR Path;
PWSTR Unknown;
// Gets the Dll path.
Status = LdrGetDllPath(DllName.Buffer, (dwFlags & LLEXW_7F08), &Path, &Unknown);
if (!NT_SUCCESS(Status))
{
BaseSetLastNTError(Status);
return NULL;
}
// First step into loading a module as datafile.
Status = fBasepLoadLibraryAsDataFileInternal(&DllName, Path, Unknown, dwFlags, &BaseOfLoadedDll);
// If the Status is only success (excludes warnings) AND if the module is image resource, loads again. I don't know why.
if (NT_SUCCESS(Status + 0x80000000) && Status != STATUS_NO_SUCH_FILE && (dwFlags & LOAD_LIBRARY_AS_IMAGE_RESOURCE))
{
if (DatafileFlags)
Status = fBasepLoadLibraryAsDataFileInternal(&DllName, Path, Unknown, DatafileFlags, &BaseOfLoadedDll);
}
RtlReleasePath(Path);
BaseSetLastNTError(Status);
return NULL;
}
```
Converts our given flags to it's own converted flags and calls LdrLoadDll, other way around requires the dll to be loaded as a datafile, which we are not interested in right now.
<br>
## LdrLoadDll
```cpp
NTSTATUS __fastcall LOADLIBRARY::fLdrLoadDll(PWSTR DllPath, PULONG pFlags, PUNICODE_STRING DllName, PVOID* BaseAddress)
{
NTSTATUS Status;
// DllPath can also be used as Flags if called from LoadLibraryExW
UINT_PTR FlagUsed = 0;
if (pFlags)
{
// Only flags that could go through *LoadLibraryExW* were;
// CNVTD_DONT_RESOLVE_DLL_REFERENCES (0x2)
// LOAD_PACKAGED_LIBRARY (0x4)
// CNVTD_LOAD_LIBRARY_REQUIRE_SIGNED_TARGET (0x800000)
// CNVTD_LOAD_LIBRARY_OS_INTEGRITY_CONTINUITY (0x80000000)
// So I am assuming the rest of the flags are 0.
UINT_PTR ActualFlags = *pFlags;
// If LOAD_PACKAGED_LIBRARY (0x4) flag is set (1) FlagUsed becomes CNVTD_DONT_RESOLVE_DLL_REFERENCES (0x2), if not set (0) FlagUsed becomes 0.
FlagUsed = CNVTD_DONT_RESOLVE_DLL_REFERENCES * (ActualFlags & LOAD_PACKAGED_LIBRARY);
// (MSDN about DONT_RESOLVE_DLL_REFERENCES) Note Do not use this value; it is provided only for backward compatibility.
// If you are planning to access only data or resources in the DLL, use LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE
// or LOAD_LIBRARY_AS_IMAGE_RESOURCE or both. Otherwise, load the library as a DLL or executable module using the LoadLibrary function.
FlagUsed |= ((ActualFlags & CNVTD_DONT_RESOLVE_DLL_REFERENCES) ? LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE : NULL);
FlagUsed |= ((ActualFlags & CNVTD_LOAD_LIBRARY_REQUIRE_SIGNED_TARGET) ? LOAD_LIBRARY_REQUIRE_SIGNED_TARGET : NULL);
// Ignored because ActualFlags can't have 0x1000 (if called from LoadLibraryExW), this value is used probably in calls from different functions.
FlagUsed |= ((ActualFlags & 0x1000) ? 0x100 : 0x0);
// Ignored because ActualFlags can't be negative (if called from LoadLibraryExW), this value is used probably in calls from different functions.
FlagUsed |= ((ActualFlags < 0) ? 0x400000 : 0x0);
// To sum up, in case we are called from LoadLibraryExW, the most flags we can have are;
// CNVTD_DONT_RESOLVE_DLL_REFERENCES (0x2) | LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE (0x40) | LOAD_LIBRARY_REQUIRE_SIGNED_TARGET (0x80)
}
WID_HIDDEN( LdrpLogInternal("minkernel\\ntdll\\ldrapi.c", 0x244, "LdrLoadDll", 3u, "DLL name: %wZ\n", DllName); )
if ((*LdrpPolicyBits & 4) == 0 && ((USHORT)DllPath & LLDLL_401) == LLDLL_401)
return STATUS_INVALID_PARAMETER;
// In here it will go in by the first condition, because 8 couldn't be set by LoadLibraryExW.
if ((FlagUsed & LOAD_WITH_ALTERED_SEARCH_PATH) == 0 || (*LdrpPolicyBits & 8) != 0)
{
// If the current thread is a Worker Thread it fails.
if (NtCurrentTeb()->SameTebFlags & LoaderWorker)
{
Status = STATUS_INVALID_THREAD;
}
else
{
LDR_UNKSTRUCT DllPathInited;
// There's another LdrpLogInternal inside this function, gonna mess with that later on.
LdrpInitializeDllPath(DllName->Buffer, DllPath, &DllPathInited);
LDR_DATA_TABLE_ENTRY* DllEntry;
Status = fLdrpLoadDll(DllName, &DllPathInited, FlagUsed, &DllEntry);
if (DllPathInited.IsInitedMaybe)
RtlReleasePath(DllPathInited.pInitNameMaybe);
if (NT_SUCCESS(Status))
{
// Changes the actual return value and dereferences the module.
*BaseAddress = DllEntry->DllBase;
LdrpDereferenceModule(DllEntry);
}
}
}
else
{
// LdrpLogInternal("minkernel\\ntdll\\ldrapi.c", 601, "LdrLoadDll", 0, &LdrEntry[176]);
WID_HIDDEN( LdrpLogInternal("minkernel\\ntdll\\ldrapi.c", 0x259, "LdrLoadDll", 0, "Nonpackaged process attempted to load a packaged DLL.\n"); )
Status = STATUS_NO_APPLICATION_PACKAGE;
}
WID_HIDDEN( LdrpLogInternal("minkernel\\ntdll\\ldrapi.c", 0x279, "LdrLoadDll", 4, "Status: 0x%08lx\n", Status); )
return Status;
}
```
Flags are re-converted, a check is made to see if the current thread is a worker thread, our path is initialized then LdrpLoadDll is getting called.
<br>
## LdrpLoadDll
```cpp
NTSTATUS __fastcall LOADLIBRARY::fLdrpLoadDll(PUNICODE_STRING DllName, LDR_UNKSTRUCT* DllPathInited, ULONG Flags, LDR_DATA_TABLE_ENTRY** DllEntry)
{
NTSTATUS Status;
WID_HIDDEN( LdrpLogDllState(0, DllName, 0x14A8); )
// Flags is passed by value so no need to create a backup, it's already a backup by itself.
// MOST FLAGS = CNVTD_DONT_RESOLVE_DLL_REFERENCES (0x2) | LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE (0x40) | LOAD_LIBRARY_REQUIRE_SIGNED_TARGET (0x80)
// Creates a new unicode_string and allocates it some buffer.
UNICODE_STRING FullDllPath;
WCHAR Buffer[128];
FullDllPath.Length = 0;
FullDllPath.MaximumLength = MAX_PATH - 4;
FullDllPath.Buffer = Buffer;
Buffer[0] = 0;
// Returns the Absolute path
// If a non-relative path was given then the flags will be ORed with LOAD_LIBRARY_SEARCH_APPLICATION_DIR (0x200) | LOAD_LIBRARY_SEARCH_USER_DIRS (0x400)
// resulting in the MOST FLAGS being:
// CNVTD_DONT_RESOLVE_DLL_REFERENCES (0x2) | LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE (0x40) | LOAD_LIBRARY_REQUIRE_SIGNED_TARGET (0x80) |
// LOAD_LIBRARY_SEARCH_APPLICATION_DIR (0x200) | LOAD_LIBRARY_SEARCH_USER_DIRS (0x400)
Status = LdrpPreprocessDllName(DllName, &FullDllPath, 0, &Flags);
if (NT_SUCCESS(Status))
// A even deeper function, by far we can see Windows is kinda all *wrapped* around each other.
fLdrpLoadDllInternal(&FullDllPath, DllPathInited, Flags, ImageDll, 0, 0, DllEntry, &Status, 0);
if (Buffer != FullDllPath.Buffer)
NtdllpFreeStringRoutine(FullDllPath.Buffer);
// I don't see no point in this but anyways.
FullDllPath.Length = 0;
FullDllPath.MaximumLength = MAX_PATH - 4;
FullDllPath.Buffer = Buffer;
Buffer[0] = 0;
WID_HIDDEN( LdrpLogDllState(0, DllName, 0x14A9); )
return Status;
}
```
A fairly smaller one than the last, the main purpose of it is to divide our path given into meaningful parts by LdrpPreprocessDllName then calling LdrpLoadDllInternal using that.
<br>
## LdrpLoadDllInternal
```cpp
NTSTATUS __fastcall LOADLIBRARY::fLdrpLoadDllInternal(PUNICODE_STRING FullPath, LDR_UNKSTRUCT* DllPathInited, ULONG Flags, ULONG LdrFlags, PLDR_DATA_TABLE_ENTRY LdrEntry, PLDR_DATA_TABLE_ENTRY LdrEntry2, PLDR_DATA_TABLE_ENTRY* DllEntry, NTSTATUS* pStatus, ULONG Zero)
{
NTSTATUS Status;
// NOTES:
// I assumed that LdrFlags (which was sent as 0x4 (ImageDll) by LdrpLoadDll) is the same flags inside LDR_DATA_TABLE_ENTRY.
// LdrEntry & LdrEntry2 were both sent as 0s by LdrpLoadDll.
//
// Instead of using gotos which causes the local variables to be initialized in the start of the function (making it look not good in my opinion)
// I created a do-while loop. The outcome won't be affected.
//
// MOST FLAGS = CONVERTED_DONT_RESOLVE_DLL_REFERENCES (0x2) | LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE (0x40) | LOAD_LIBRARY_REQUIRE_SIGNED_TARGET (0x80)
// LOAD_LIBRARY_SEARCH_APPLICATION_DIR (0x200) | LOAD_LIBRARY_SEARCH_USER_DIRS (0x400)
WID_HIDDEN(LdrpLogInternal("minkernel\\ntdll\\ldrapi.c", 0x379, "LdrpLoadDllInternal", 3, "DLL name: %wZ\n", FullPath); )
bool IsWorkerThread = false;
do
{
*DllEntry = 0;
LdrEntry = LdrEntry2;
// This will go in.
if (LdrFlags != (PackagedBinary | LoadNotificationsSent))
{
// This function does some prior setup, incrementing the module load count is done inside here.
Status = LdrpFastpthReloadedDll(FullPath, Flags, LdrEntry2, DllEntry); // returns STATUS_DLL_NOT_FOUND in normal circumstances.
// If not an actual nt success (excludes warnings)
if (!(NT_SUCCESS((int)(Status + 0x80000000))) || Status == STATUS_IMAGE_LOADED_AS_PATCH_IMAGE)
{
*pStatus = Status;
break;
}
}
IsWorkerThread = ((NtCurrentTeb()->SameTebFlags & LoadOwner) == 0);
if (IsWorkerThread)
LdrpDrainWorkQueue(WaitLoadComplete);
// This won't go in so we can ignore it. I still did simplifying though.
// Because the LdrFlags was sent 0x4 (ImageDll), we can ignore this one.
if (LdrFlags == (PackagedBinary | LoadNotificationsSent))
{
Status = LdrpFindLoadedDllByHandle(Zero, &LdrEntry, 0);
if (!NT_SUCCESS(Status))
{
if (FullPath->Buffer)
LdrpFreeUnicodeString(FullPath);
*pStatus = Status;
if (IsWorkerThread)
LdrpDropLastInProgressCount();
break;
}
if (LdrEntry->HotPatchState == LdrHotPatchFailedToPatch)
{
Status = STATUS_PATCH_CONFLICT;
// goto FREE_DLLNAMEPREPROCANDRETURN;
if (FullPath->Buffer)
LdrpFreeUnicodeString(FullPath);
*pStatus = Status;
if (IsWorkerThread)
LdrpDropLastInProgressCount();
break;
}
Status = LdrpQueryCurrentPatch(LdrEntry->CheckSum, LdrEntry->TimeDateStamp, FullPath);
if (!NT_SUCCESS(Status))
{
// goto FREE_DLLNAMEPREPROCANDRETURN;
if (FullPath->Buffer)
LdrpFreeUnicodeString(FullPath);
*pStatus = Status;
if (IsWorkerThread)
LdrpDropLastInProgressCount();
break;
}
if (!FullPath->Length)
{
if (LdrEntry->ActivePatchImageBase)
Status = LdrpUndoPatchImage(LdrEntry);
// goto FREE_DLLNAMEPREPROCANDRETURN;
if (FullPath->Buffer)
LdrpFreeUnicodeString(FullPath);
*pStatus = Status;
if (IsWorkerThread)
LdrpDropLastInProgressCount();
break;
}
// LdrpLogInternal("minkernel\\ntdll\\ldrapi.c", 0x3FA, "LdrpLoadDllInternal", 2u, &::LdrEntry[232], FullPath);
WID_HIDDEN( LdrpLogInternal("minkernel\\ntdll\\ldrapi.c", 0x3FA, "LdrpLoadDllInternal", 2, "Loading patch image: %wZ\n", FullPath); )
}
// Opens a token to the current thread and sets GLOBAL variable LdrpMainThreadToken with that token.
LdrpThreadTokenSetMainThreadToken(); // returns STATUS_NO_TOKEN in normal circumstances.
LDR_DATA_TABLE_ENTRY* pLdrEntryLoaded = 0;
// This will go in by the first check LdrEntry2 because it was sent as 0 in LdrpLoadDll.
if (!LdrEntry || !IsWorkerThread || LdrEntry->DdagNode->LoadCount)
{
// I checked the function, it detects a hook by byte scanning these following functions;
// • ntdll!NtOpenFile
// • ntdll!NtCreateSection
// • ntdll!ZqQueryAttributes
// • ntdll!NtOpenSection
// • ntdll!ZwMapViewOfSection
// Resulting in the global variable LdrpDetourExist to be set if there's a hook, didn't checked what's done with it though.
LdrpDetectDetour();
// [IGNORE THIS] Finds the module, increments the loaded module count. [IGNORE THIS]
// [IGNORE THIS] It can go to another direction if the Flag LOAD_LIBRARY_SEARCH_APPLICATION_DIR was set, but that couldn't be set coming from LoadLibraryExW. [IGNORE THIS]
// If LoadLibrary was given an absolute path, Flags will have LOAD_LIBRARY_SEARCH_APPLICATION_DIR causing this function to call LdrpLoadKnownDll.
// In our case LdrpFindOrPrepareLoadingModule actually returns STATUS_DLL_NOT_FOUND, which I thought was a bad thing but after checking up inside
// inside LdrpProcessWork it didn't looked that bad.
// So our dll loading part is actually inside LdrpProcessWork (for calling LoadLibraryExW with an absolute path and 0 flags at least)
//Status = LdrpFindOrPrepareLoadingModule(FullPath, DllPathInited, Flags, LdrFlags, LdrEntry, &pLdrEntryLoaded, pStatus);
Status = LdrpFindOrPrepareLoadingModule(FullPath, DllPathInited, Flags, LdrFlags, LdrEntry, &pLdrEntryLoaded, pStatus);
if (Status == STATUS_DLL_NOT_FOUND)
// Even if the DllMain call succeeds, there's still runtime bugs on the dll side, like the dll not being able to unload itself and such. So I still got
// a lot of work to do.
fLdrpProcessWork(pLdrEntryLoaded->LoadContext, TRUE);
else if (Status != STATUS_RETRY && !NT_SUCCESS(Status))
*pStatus = Status;
}
else
{
*pStatus = STATUS_DLL_NOT_FOUND;
}
LdrpDrainWorkQueue(WaitWorkComplete);
if (*LdrpMainThreadToken)
// Closes the token handle, and sets GLOBAL variable LdrpMainThreadToken to 0.
LdrpThreadTokenUnsetMainThreadToken();
if (pLdrEntryLoaded)
{
*DllEntry = LdrpHandleReplacedModule(pLdrEntryLoaded);
if (pLdrEntryLoaded != *DllEntry)
{
LdrpFreeReplacedModule(pLdrEntryLoaded);
pLdrEntryLoaded = *DllEntry;
if (pLdrEntryLoaded->LoadReason == LoadReasonPatchImage && LdrFlags != (PackagedBinary | LoadNotificationsSent))
*pStatus = STATUS_IMAGE_LOADED_AS_PATCH_IMAGE;
}
if (pLdrEntryLoaded->LoadContext)
LdrpCondenseGraph(pLdrEntryLoaded->DdagNode);
if (NT_SUCCESS(*pStatus))
{
// [IGNORE THIS] In here I realized that the module must have already been loaded to be prepared for execution.
// [IGNORE THIS] So I've gone a little back and realized the actual loading was done in the LdrpDrainWorkQueue function.
// Doing more research revealed it was inside LdrpProcessWork after LdrpFindOrPrepareLoadingModule returning STATUS_DLL_NOT_FOUND.
Status = fLdrpPrepareModuleForExecution(pLdrEntryLoaded, pStatus);
*pStatus = Status;
if (NT_SUCCESS(Status))
{
Status = LdrpBuildForwarderLink(LdrEntry, pLdrEntryLoaded);
*pStatus = Status;
if (NT_SUCCESS(Status) && !*LdrInitState)
LdrpPinModule(pLdrEntryLoaded);
}
// Because the LdrFlags was sent 0x4 (ImageDll), we can ignore this one too.
if (LdrFlags == (PackagedBinary | LoadNotificationsSent) && LdrEntry->ActivePatchImageBase != pLdrEntryLoaded->DllBase)
{
if (pLdrEntryLoaded->HotPatchState == LdrHotPatchFailedToPatch)
{
*pStatus = STATUS_DLL_INIT_FAILED;
}
else
{
Status = LdrpApplyPatchImage(pLdrEntryLoaded);
*pStatus = Status;
if (!NT_SUCCESS(Status))
{
//UNICODE_STRING Names[4];
//Names[0] = pLdrEntryLoaded->FullDllName;
//WID_HIDDEN( LdrpLogInternal("minkernel\\ntdll\\ldrapi.c", 0x4AF, "LdrpLoadDllInternal", 0, "Applying patch \"%wZ\" failed\n", Names); )
WID_HIDDEN( LdrpLogInternal("minkernel\\ntdll\\ldrapi.c", 0x4AF, "LdrpLoadDllInternal", 0, "Applying patch \"%wZ\" failed\n", pLdrEntryLoaded->FullDllName); )
}
}
}
}
LdrpFreeLoadContextOfNode(pLdrEntryLoaded->DdagNode, pStatus);
if (!NT_SUCCESS(*pStatus) && (LdrFlags != (PackagedBinary | LoadNotificationsSent) || pLdrEntryLoaded->HotPatchState != LdrHotPatchAppliedReverse))
{
*DllEntry = 0;
LdrpDecrementModuleLoadCountEx(pLdrEntryLoaded, 0);
LdrpDereferenceModule(pLdrEntryLoaded);
}
}
else
{
*pStatus = STATUS_NO_MEMORY;
}
} while (FALSE);
// LoadNotificationsSent (0x8) | PackagedBinary (0x1)
// Because the LdrFlags was sent 0x4 (ImageDll), we can ignore this one too.
if (LdrFlags == (LoadNotificationsSent | PackagedBinary) && LdrEntry)
LdrpDereferenceModule(LdrEntry);
// Actually returns what LdrpLogInternal returns.
WID_HIDDEN( LdrpLogInternal("minkernel\\ntdll\\ldrapi.c", 0x52E, "LdrpLoadDllInternal", 4, "Status: 0x%08lx\n", *pStatus); )
return *pStatus;
}
```
The main course of action of this function is to check whether the dll was already loaded and waiting to be executed, or is going to be patched, or a new dll is going to be loaded, if it's a new dll (which is our case) it first goes by LdrpProcessWork to start the mapping process, then after that call succeeds goes on by LdrpPrepareModuleForExecution to execute the mapped dll.
<br>
## LdrpProcessWork
```cpp
NTSTATUS __fastcall LOADLIBRARY::fLdrpProcessWork(PLDRP_LOAD_CONTEXT LoadContext, BOOLEAN IsLoadOwner)
{
NTSTATUS Status;
// Converted goto to do-while loop.
do
{
Status = *LoadContext->pStatus;
if (!NT_SUCCESS(Status))
break;
// Caused most likely because CONTAINING_RECORD macro was used, I have no idea what's going on.
// Also the structure used (LDRP_LOAD_CONTEXT) isn't documented, that's what I've got out of it so far.
if ((UINT_PTR)LoadContext->WorkQueueListEntry.Flink[9].Blink[3].Blink & UINT_MAX)
{
Status = fLdrpSnapModule(LoadContext);
}
else
{
if (LoadContext->Flags & 0x100000)
{
Status = fLdrpMapDllRetry(LoadContext);
}
// We will continue from here since we have the LOAD_LIBRARY_SEARCH_APPLICATION_DIR flag, and also the function name is exactly representing
// what we are expecting to happen.
else if (LoadContext->Flags & LOAD_LIBRARY_SEARCH_APPLICATION_DIR)
{
Status = fLdrpMapDllFullPath(LoadContext);
}
else
{
Status = fLdrpMapDllSearchPath(LoadContext);
}
if (NT_SUCCESS(Status) || Status == STATUS_RETRY)
break;
WID_HIDDEN( Status = LdrpLogInternal("minkernel\\ntdll\\ldrmap.c", 0x7D2, "LdrpProcessWork", 0, "Unable to load DLL: \"%wZ\", Parent Module: \"%wZ\", Status: 0x%x\n", LoadContext, ((UINT_PTR)&LoadContext->Entry->FullDllName & (UINT_PTR)LoadContext->Entry >> 64), Status); )
// This part is for failed cases so we can ignore it.
if (Status == STATUS_DLL_NOT_FOUND)
{
WID_HIDDEN( LdrpLogError(STATUS_DLL_NOT_FOUND, 0x19, 0, LoadContext); )
WID_HIDDEN( LdrpLogDeprecatedDllEtwEvent(LoadContext); )
WID_HIDDEN( LdrpLogLoadFailureEtwEvent((PVOID)LoadContext, (PVOID)(((UINT_PTR)(LoadContext->Entry->EntryPointActivationContext) & ((UINT_PTR)(LoadContext->Entry) >> 64))), STATUS_DLL_NOT_FOUND, LoadFailure, 0); )
//PLDR_DATA_TABLE_ENTRY DllEntry = (PLDR_DATA_TABLE_ENTRY)LoadContext->WorkQueueListEntry.Flink;
LDR_DATA_TABLE_ENTRY* DllEntry = CONTAINING_RECORD(LoadContext->WorkQueueListEntry.Flink, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
if (DllEntry->FlagGroup[0] & ProcessStaticImport)
{
WID_HIDDEN( Status = LdrpReportError(LoadContext, 0, STATUS_DLL_NOT_FOUND); )
}
}
}
if (!NT_SUCCESS(Status))
{
*LoadContext->pStatus = Status;
}
} while (FALSE);
if (!IsLoadOwner)
{
bool SetWorkCompleteEvent;
RtlEnterCriticalSection(LdrpWorkQueueLock);
--(*LdrpWorkInProgress);
if (*LdrpWorkQueue != (LIST_ENTRY*)LdrpWorkQueue || (SetWorkCompleteEvent = TRUE, *LdrpWorkInProgress != 1))
SetWorkCompleteEvent = FALSE;
Status = RtlLeaveCriticalSection(LdrpWorkQueueLock);
if (SetWorkCompleteEvent)
Status = ZwSetEvent(*LdrpWorkCompleteEvent, 0);
}
return Status;
}
```
Goes in an according direction depending by the path type given, in our case we have an absolute path, so we continue by LdrpMapDllFullPath.
<br>
## LdrpMapDllFullPath
```cpp
NTSTATUS __fastcall LOADLIBRARY::fLdrpMapDllFullPath(PLDRP_LOAD_CONTEXT LoadContext)
{
NTSTATUS Status;
//LDR_DATA_TABLE_ENTRY* DllEntry = (LDR_DATA_TABLE_ENTRY*)LoadContext->WorkQueueListEntry.Flink;
LDR_DATA_TABLE_ENTRY* DllEntry = CONTAINING_RECORD(LoadContext->WorkQueueListEntry.Flink, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
LDRP_FILENAME_BUFFER FileNameBuffer;
FileNameBuffer.pFileName.Buffer = FileNameBuffer.FileName;
FileNameBuffer.pFileName.Length = 0;
FileNameBuffer.pFileName.MaximumLength = MAX_PATH - 4;
FileNameBuffer.FileName[0] = 0;
// Sets the according members of the DllEntry
Status = LdrpResolveDllName(LoadContext, &FileNameBuffer, &DllEntry->BaseDllName, &DllEntry->FullDllName, LoadContext->Flags);
do
{
if (LoadContext->UnknownPtr)
{
if (!NT_SUCCESS(Status))
break;
}
else
{
Status = LdrpAppCompatRedirect(LoadContext, &DllEntry->FullDllName, &DllEntry->BaseDllName, &FileNameBuffer, Status);
if (!NT_SUCCESS(Status))
break;
// Hashes the dll name
ULONG BaseDllNameHash = LdrpHashUnicodeString(&DllEntry->BaseDllName);
DllEntry->BaseNameHashValue = BaseDllNameHash;
LDR_DATA_TABLE_ENTRY* LoadedDll = nullptr;
// Most likely checks if the dll was already mapped/loaded.
LdrpFindExistingModule(&DllEntry->BaseDllName, &DllEntry->FullDllName, LoadContext->Flags, BaseDllNameHash, &LoadedDll);
if (LoadedDll)
{
LdrpLoadContextReplaceModule(LoadContext, LoadedDll);
break;
}
}
// After this function the dll is mapped.
Status = fLdrpMapDllNtFileName(LoadContext, &FileNameBuffer);
if (Status == STATUS_IMAGE_MACHINE_TYPE_MISMATCH)
Status = STATUS_INVALID_IMAGE_FORMAT;
} while (FALSE);
if (FileNameBuffer.FileName != FileNameBuffer.pFileName.Buffer)
NtdllpFreeStringRoutine(FileNameBuffer.pFileName.Buffer);
return Status;
}
```
Sets up a LDRP_FILENAME_BUFFER structure, basically representing each portion of a path (base part, absolute part, etc.), hashes the **base** dll name and checks if it was already loaded, if it's not (our case) it goes on by calling LdrpMapDllNtFileName.
<br>
## LdrpMapDllNtFileName
```cpp
NTSTATUS __fastcall LOADLIBRARY::fLdrpMapDllNtFileName(PLDRP_LOAD_CONTEXT LoadContext, LDRP_FILENAME_BUFFER* FileNameBuffer) // CHECKED.
{
NTSTATUS Status;
//LDR_DATA_TABLE_ENTRY* DllEntry = (LDR_DATA_TABLE_ENTRY*)LoadContext->WorkQueueListEntry.Flink;
LDR_DATA_TABLE_ENTRY* DllEntry = CONTAINING_RECORD(LoadContext->WorkQueueListEntry.Flink, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
INT64 UnknownPtr = LoadContext->UnknownPtr;
LONG Unknown = 0;
if (LdrpCheckForRetryLoading(LoadContext, 0))
return STATUS_RETRY;
PUNICODE_STRING FullDllName = &DllEntry->FullDllName;
WID_HIDDEN( LdrpLogDllState((ULONGLONG)DllEntry->DllBase, &DllEntry->FullDllName, 0x14A5); )
//OBJ_CASE_INSENSITIVE
ULONG ObjAttributes = OBJ_CASE_INSENSITIVE;
if (!*LdrpUseImpersonatedDeviceMap)
ObjAttributes = (OBJ_IGNORE_IMPERSONATED_DEVICEMAP | OBJ_CASE_INSENSITIVE);
OBJECT_ATTRIBUTES ObjectAttributes;
ObjectAttributes.Length = 0x30;
ObjectAttributes.RootDirectory = 0;
ObjectAttributes.Attributes = ObjAttributes;
ObjectAttributes.ObjectName = &FileNameBuffer->pFileName;
ObjectAttributes.SecurityDescriptor = 0;
ObjectAttributes.SecurityQualityOfService = 0;
PCHAR NtPathStuff = (PCHAR)&kUserSharedData->UserModeGlobalLogger[2];
PCHAR Unknown2 = 0;
if (RtlGetCurrentServiceSessionId())
Unknown2 = (PCHAR)&NtCurrentPeb()->SharedData->NtSystemRoot[253];
else
Unknown2 = (PCHAR)&kUserSharedData->UserModeGlobalLogger[2];
PCHAR NtPathStuff2 = (PCHAR)&kUserSharedData->UserModeGlobalLogger[2] + 1;
if (*Unknown2 && (NtCurrentPeb()->TracingFlags & LibLoaderTracingEnabled))
{
//: (char*)0x7FFE0385;
PCHAR NtPathStuff3 = RtlGetCurrentServiceSessionId() ? (PCHAR)&NtCurrentPeb()->SharedData->NtSystemRoot[253] + 1 : (PCHAR)&kUserSharedData->UserModeGlobalLogger[2] + 1;
// 0x20 is SPACE char
if ((*NtPathStuff3 & ' '))
LdrpLogEtwEvent(0x1485, -1, 0xFFu, 0xFFu);
}
// SYSTEM_FLAGS_INFORMATION
if ((NtCurrentPeb()->NtGlobalFlag & FLG_ENABLE_KDEBUG_SYMBOL_LOAD))
{
WID_HIDDEN( ZwSystemDebugControl(); )
}
HANDLE FileHandle;
while (TRUE)
{
IO_STATUS_BLOCK IoStatusBlock;
Status = NtOpenFile(&FileHandle, SYNCHRONIZE | FILE_TRAVERSE | FILE_LIST_DIRECTORY, &ObjectAttributes, &IoStatusBlock, 5, 0x60);
if (NT_SUCCESS(Status))
break;
if (Status == STATUS_OBJECT_NAME_NOT_FOUND || Status == STATUS_OBJECT_PATH_NOT_FOUND)
return STATUS_DLL_NOT_FOUND;
if (Status != STATUS_ACCESS_DENIED || Unknown || !LdrpCheckComponentOnDemandEtwEvent(LoadContext))
return Status;
Unknown = TRUE;
}
ULONG SigningLevel;
ULONG AllocationAttributes = 0;
if (*LdrpAuditIntegrityContinuity && (Status = LdrpValidateIntegrityContinuity(LoadContext, FileHandle), !NT_SUCCESS(Status)) && *LdrpEnforceIntegrityContinuity ||
(AllocationAttributes = MEM_IMAGE, (LoadContext->Flags & MEM_IMAGE)) && (NtCurrentPeb()->BitField & IsPackagedProcess) == 0 &&
// (Status = LdrpSetModuleSigningLevel(FileHandle, (PLDR_DATA_TABLE_ENTRY)LoadContext->WorkQueueListEntry.Flink, &SigningLevel, 8), !NT_SUCCESS(Status)))
(Status = LdrpSetModuleSigningLevel(FileHandle, CONTAINING_RECORD(LoadContext->WorkQueueListEntry.Flink, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks), &SigningLevel, 8), !NT_SUCCESS(Status)))
{
NtClose(FileHandle);
return Status;
}
if (*UseWOW64 && (LoadContext->Flags & 0x800) == 0)
AllocationAttributes = MEM_IMAGE | MEM_TOP_DOWN;
HANDLE SectionHandle;
Status = NtCreateSection(&SectionHandle, SECTION_QUERY | SECTION_MAP_READ | SECTION_MAP_EXECUTE, 0, 0, PAGE_EXECUTE, AllocationAttributes, FileHandle);
if (!NT_SUCCESS(Status))
{
if (Status == STATUS_NEEDS_REMEDIATION || (Status + 0x3FFFFB82) <= 1)
{
Status = LdrAppxHandleIntegrityFailure(Status);
}
else if (Status != STATUS_NO_MEMORY && Status != STATUS_INSUFFICIENT_RESOURCES && Status != STATUS_COMMITMENT_LIMIT)
{
LDR_UNKSTRUCT2 NtHardParameters;
NtHardParameters.Name = FullDllName;
NtHardParameters.Status = Status;
// Semi-documented in http://undocumented.ntinternals.net/
HARDERROR_RESPONSE Response;
if (NT_SUCCESS(NtRaiseHardError(STATUS_INVALID_IMAGE_FORMAT, 2, 1, (INT*)&NtHardParameters, OptionOk, &Response)) && *LdrInitState != 3)
{
++(*LdrpFatalHardErrorCount);
}
}
WID_HIDDEN( LdrpLogError(Status, 0x1485u, 0, FullDllName); )
NtClose(FileHandle);
return Status;
}
if (RtlGetCurrentServiceSessionId())
NtPathStuff = (PCHAR)&NtCurrentPeb()->SharedData->NtSystemRoot[253];
if (*NtPathStuff && (NtCurrentPeb()->TracingFlags & LibLoaderTracingEnabled) != 0)
{
if (RtlGetCurrentServiceSessionId())
NtPathStuff2 = (PCHAR)&NtCurrentPeb()->SharedData->NtSystemRoot[253] + 1;
// 0x20 is SPACE char.
if ((*NtPathStuff2 & ' ') != 0)
WID_HIDDEN( LdrpLogEtwEvent(0x1486, -1, 0xFFu, 0xFFu); )
}
if (!*UseWOW64 && (LoadContext->Flags & 0x100) == 0 && (Status = LdrpCodeAuthzCheckDllAllowed(FileNameBuffer, FileHandle), NT_SUCCESS((LONG)(Status + 0x80000000))) && Status != STATUS_NOT_FOUND || (Status = fLdrpMapDllWithSectionHandle(LoadContext, SectionHandle), !UnknownPtr) || !NT_SUCCESS(Status))
{
NtClose(SectionHandle);
NtClose(FileHandle);
return Status;
}
LoadContext->FileHandle = FileHandle;
LoadContext->SectionHandle = SectionHandle;
return Status;
}
```
Opens the file with NtOpenFile, creates a section using NtCreateSection to be able to map the dll, continues with calling LdrpMapDllWithSectionHandle.
<br>
## LdrpMapDllWithSectionHandle
```cpp
NTSTATUS __fastcall LOADLIBRARY::fLdrpMapDllWithSectionHandle(PLDRP_LOAD_CONTEXT LoadContext, HANDLE SectionHandle) // CHECKED.
{
NTSTATUS Status;
NTSTATUS Status2;
NTSTATUS Status3;
NTSTATUS Status4;
int v19[14];
LDR_DATA_TABLE_ENTRY* LdrEntry2;
// Mapping mechanism.
Status = fLdrpMinimalMapModule(LoadContext, SectionHandle);
Status2 = Status;
if (Status == STATUS_IMAGE_MACHINE_TYPE_MISMATCH)
return Status2;
if (!NT_SUCCESS(Status))
return Status2;
//LDR_DATA_TABLE_ENTRY* DllEntry = (LDR_DATA_TABLE_ENTRY*)LoadContext->WorkQueueListEntry.Flink;
LDR_DATA_TABLE_ENTRY* DllEntry = CONTAINING_RECORD(LoadContext->WorkQueueListEntry.Flink, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
SIZE_T Size = LoadContext->Size;
LDR_DATA_TABLE_ENTRY* LdrEntry = nullptr;
Status3 = Status;
PIMAGE_NT_HEADERS OutHeaders;
Status2 = RtlImageNtHeaderEx(0, DllEntry->DllBase, Size, &OutHeaders);
if (!NT_SUCCESS(Status2))
return Status2;
if (LoadContext->Flags & SEC_FILE)
{
Status3 = STATUS_SUCCESS;
DllEntry->TimeDateStamp = OutHeaders->FileHeader.TimeDateStamp;
DllEntry->CheckSum = OutHeaders->OptionalHeader.CheckSum;
DllEntry->SizeOfImage = OutHeaders->OptionalHeader.SizeOfImage;
}
else
{
RtlAcquireSRWLockExclusive(LdrpModuleDatatableLock);
UINT_PTR Flags = (LoadContext->Flags) & UINT_MAX;
PUNICODE_STRING FullDllName_2 = 0;
if ((Flags & 0x20) == 0)
FullDllName_2 = &DllEntry->FullDllName;
// Returns STATUS_DLL_NOT_FOUND is normal situations.
Status4 = LdrpFindLoadedDllByNameLockHeld(&DllEntry->BaseDllName, FullDllName_2, Flags, &LdrEntry, DllEntry->BaseNameHashValue);
if (Status4 == STATUS_DLL_NOT_FOUND)
{
PIMAGE_DOS_HEADER DllBase = DllEntry->DllBase;
v19[0] = OutHeaders->FileHeader.TimeDateStamp;
v19[1] = OutHeaders->OptionalHeader.SizeOfImage;
LdrpFindLoadedDllByMappingLockHeld(DllBase, OutHeaders, (ULONG*)v19, &LdrEntry);
}
if (!LdrEntry)
{
LdrpInsertDataTableEntry(DllEntry);
LdrpInsertModuleToIndexLockHeld(DllEntry, OutHeaders);
}
RtlReleaseSRWLockExclusive(LdrpModuleDatatableLock);
if (LdrEntry)
{
if (DllEntry->LoadReason != LoadReasonPatchImage || LdrEntry->LoadReason == LoadReasonPatchImage)
{
LdrpLoadContextReplaceModule(LoadContext, LdrEntry);
}
else
{
Status2 = STATUS_IMAGE_LOADED_AS_PATCH_IMAGE;
WID_HIDDEN( LdrpLogEtwHotPatchStatus(&(*LdrpImageEntry)->BaseDllName, LoadContext->Entry, &DllEntry->FullDllName, STATUS_IMAGE_LOADED_AS_PATCH_IMAGE, 3); )
LdrpDereferenceModule(LdrEntry);
}
return Status2;
}
}
if (*qword_17E238 == NtCurrentTeb()->ClientId.UniqueThread)
return STATUS_NOT_FOUND;
Status2 = fLdrpCompleteMapModule(LoadContext, OutHeaders, Status3);
if (NT_SUCCESS(Status2))
{
Status2 = fLdrpProcessMappedModule(DllEntry, LoadContext->Flags & UINT_MAX, 1);
if (NT_SUCCESS(Status2))
{
WID_HIDDEN( LdrpLogNewDllLoad(LoadContext->Entry, DllEntry); )
LdrEntry2 = LoadContext->Entry;
if (LdrEntry2)
DllEntry->ParentDllBase = LdrEntry2->DllBase;
BOOLEAN DllBasesEqual = FALSE;
if (DllEntry->LoadReason == LoadReasonPatchImage && *LdrpImageEntry)
DllBasesEqual = DllEntry->ParentDllBase == (*LdrpImageEntry)->DllBase;
if ((LoadContext->Flags & SEC_FILE) || (DllEntry->FlagGroup[0] & ImageDll) || DllBasesEqual)
{
if ((DllEntry->Flags & CorILOnly))
{
return fLdrpCorProcessImports(DllEntry);
}
else
{
fLdrpMapAndSnapDependency(LoadContext);
return *LoadContext->pStatus;
}
}
else
{
WID_HIDDEN( LdrpLogDllState((ULONG)DllEntry->DllBase, &DllEntry->FullDllName, 0x14AEu); )
Status2 = STATUS_SUCCESS;
DllEntry->DdagNode->State = LdrModulesReadyToRun;
}
}
}
return Status2;
}
```
Maps a view of section inside LdrpMinimalMapModule, validates the image inside LdrpCompleteMapModule, handles relocations inside LdrpProcessMappedModule, updates state inside LdrpCorProcessImports, goes on by calling LdrpMapAndSnapDependency.
<br>
## LdrpMapAndSnapDependency
```cpp
NTSTATUS __fastcall LOADLIBRARY::fLdrpMapAndSnapDependency(PLDRP_LOAD_CONTEXT LoadContext)
{
NTSTATUS Status;
LDR_DATA_TABLE_ENTRY* DllEntry = CONTAINING_RECORD(LoadContext->WorkQueueListEntry.Flink, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
BOOLEAN IsFile = (LoadContext->Flags & SEC_FILE);
BOOLEAN FullPathExists = 0;
UNICODE_STRING FullPath;
memset(&FullPath, 0, sizeof(FullPath));
do
{
if (!IsFile)
{
if (DllEntry->LoadReason != LoadReasonPatchImage)
{
Status = LdrpFindDllActivationContext(DllEntry);
if (!NT_SUCCESS(Status))
break;
}
}
Status = fLdrpPrepareImportAddressTableForSnap(LoadContext);
if (!NT_SUCCESS(Status))
break;
ULONG CurrentDllDecremented = 0;
ULONG OldCurrentDll = 0;
if (*LdrpIsHotPatchingEnabled)
{
DllEntry = (LDR_DATA_TABLE_ENTRY*)LoadContext->WorkQueueListEntry.Flink;
if (DllEntry)
{
Status = LdrpQueryCurrentPatch(DllEntry->CheckSum, DllEntry->TimeDateStamp, &FullPath);
if (!NT_SUCCESS(Status))
break;
if (FullPath.Length)
FullPathExists = TRUE;
}
}
PIMAGE_IMPORT_DESCRIPTOR ImageImportDescriptor = nullptr;
if (LoadContext->pImageImportDescriptor || FullPathExists)
{
if (LdrpShouldModuleImportBeRedirected(DllEntry))
LoadContext->Flags |= 0x2000000u;
ImageImportDescriptor = LdrpGetImportDescriptorForSnap(LoadContext);
ULONG IATSize = 0;
PIMAGE_THUNK_DATA32 FirstThunk = (PIMAGE_THUNK_DATA32)&ImageImportDescriptor->FirstThunk;
BOOLEAN JumpIn = FALSE;
if (ImageImportDescriptor)
{
PIMAGE_THUNK_DATA32 FirstThunk2 = (IMAGE_THUNK_DATA32*)&ImageImportDescriptor->FirstThunk;
ULONG DllBaseIncremented = 0;
do
{
if (!FirstThunk2[-1].u1.ForwarderString)
break;
ULONG ForwarderString = FirstThunk2->u1.ForwarderString;
if (!FirstThunk2->u1.ForwarderString)
break;
ULONG DllBaseIncremented_2 = DllBaseIncremented + 1;
FirstThunk2 += 5;
++IATSize;
if (!*(UINT_PTR*)((char*)&DllEntry->DllBase->e_magic + ForwarderString))
DllBaseIncremented_2 = DllBaseIncremented;
DllBaseIncremented = DllBaseIncremented_2;
} while (FirstThunk2 != (IMAGE_THUNK_DATA32*)16);
OldCurrentDll = DllBaseIncremented;
if (DllBaseIncremented)
JumpIn = TRUE;
}
BOOLEAN JumpOut = FALSE;
if (JumpIn || FullPathExists)
{
PVOID* Heap = (PVOID*)RtlAllocateHeap(*LdrpHeap, (*NtdllBaseTag + 0x180000) | 8u, 8 * IATSize);
LoadContext->IATCheck = (LDR_DATA_TABLE_ENTRY**)Heap;
if (Heap)
{
LoadContext->SizeOfIAT = IATSize;
LoadContext->GuardCFCheckFunctionPointer = ImageImportDescriptor;
LoadContext->CurrentDll = OldCurrentDll + 1;
if (FullPathExists)
LoadContext->CurrentDll = OldCurrentDll + 2;
PIMAGE_THUNK_DATA pThunk = nullptr;
UINT_PTR IATAmount = 0;
if (ImageImportDescriptor)
{
while (FirstThunk[-1].u1.ForwarderString && FirstThunk->u1.ForwarderString)
{
PIMAGE_DOS_HEADER DllBase = DllEntry->DllBase;
if (*(UINT_PTR*)((char*)&DllBase->e_magic + FirstThunk->u1.ForwarderString))
{
ULONG ForwarderString_2 = FirstThunk[-1].u1.ForwarderString;
IsFile = (PIMAGE_IMPORT_BY_NAME)(ForwarderString_2 + (UINT_PTR)DllBase) != 0;
PCHAR ForwarderBuffer = (PCHAR)(ForwarderString_2 + (UINT_PTR)DllBase);
STRING SourceString = {};
*(UINT_PTR*)&SourceString.Length = 0;
SourceString.Buffer = ForwarderBuffer;
if (IsFile)
{
SIZE_T SourceLen = -1;
do
{
++SourceLen;
} while (ForwarderBuffer[SourceLen]);
if (SourceLen > 0xFFFE)
{
Status = STATUS_NAME_TOO_LONG;
break;
}
SourceString.Length = SourceLen;
SourceString.MaximumLength = SourceLen + 1;
}
Status = LdrpLoadDependentModuleA((PUNICODE_STRING)&SourceString, LoadContext, DllEntry, 0, &LoadContext->IATCheck[IATAmount], (UINT_PTR)&pThunk);
if (!NT_SUCCESS(Status))
break;
}
FirstThunk += 5;
IATAmount = (ULONG)(IATAmount + 1);
if (FirstThunk == (PIMAGE_THUNK_DATA32)16)
break;
}
}
if (FullPathExists)
{
// Loads Imports dlls.
Status = LdrpLoadDependentModuleW(&FullPath, LoadContext, DllEntry);
if (!NT_SUCCESS(Status))
WID_HIDDEN(LdrpLogEtwHotPatchStatus(&(*LdrpImageEntry)->BaseDllName, DllEntry, &FullPath, Status, 5u); )
}
if (pThunk)
RtlFreeHeap(*LdrpHeap, 0, pThunk);
if (NT_SUCCESS(Status))
{
RtlAcquireSRWLockExclusive(LdrpModuleDatatableLock);
CurrentDllDecremented = --LoadContext->CurrentDll;
RtlReleaseSRWLockExclusive(LdrpModuleDatatableLock);
JumpOut = TRUE;
}
}
else
{
Status = STATUS_NO_MEMORY;
}
}
if (!JumpOut)
CurrentDllDecremented = OldCurrentDll;
}
PLDR_DDAG_NODE DdagNode = nullptr;
PIMAGE_IMPORT_DESCRIPTOR pImageImportDescriptor = LoadContext->pImageImportDescriptor;
if (pImageImportDescriptor || !FullPathExists)
{
if (CurrentDllDecremented)
break;
DdagNode = DllEntry->DdagNode;
if (pImageImportDescriptor)
{
DdagNode->State = LdrModulesSnapping;
if (LoadContext->Entry)
LdrpQueueWork(LoadContext);
else
Status = fLdrpSnapModule(LoadContext);
break;
}
}
else
{
DdagNode = DllEntry->DdagNode;
}
DdagNode->State = LdrModulesSnapped;
} while (FALSE);
LdrpFreeUnicodeString(&FullPath);
if (!NT_SUCCESS(Status))
{
*LoadContext->pStatus = Status;
}
return *LoadContext->pStatus;
}
```
Prepares the Import Address Table (IAT) by calling LdrpPrepareImportAddressTableForSnap, loads the imports of the dll getting loaded, sets the state, continues on by calling LdrpSnapModule which I am quite frank about the actual functionality, but I've seen it handling exports.
<br>
## LdrpPrepareImportAddressTableForSnap
```cpp
NTSTATUS __fastcall LOADLIBRARY::fLdrpPrepareImportAddressTableForSnap(LDRP_LOAD_CONTEXT* LoadContext)
{
NTSTATUS Status;
LDR_DATA_TABLE_ENTRY* DllEntry = CONTAINING_RECORD(LoadContext->WorkQueueListEntry.Flink, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
PIMAGE_IMPORT_DESCRIPTOR ImageImportDescriptor = nullptr;
UINT_PTR* pImageImportDescriptorLen = (UINT_PTR*)&LoadContext->ImageImportDescriptorLen;
Status = RtlpImageDirectoryEntryToDataEx(DllEntry->DllBase, 1u, IMAGE_DIRECTORY_ENTRY_IAT, (UINT_PTR*)&LoadContext->ImageImportDescriptorLen, &ImageImportDescriptor);
if (!NT_SUCCESS(Status))
ImageImportDescriptor = nullptr;
BOOLEAN IsFile = (LoadContext->Flags & SEC_FILE);
LoadContext->pImageImportDescriptor = ImageImportDescriptor;
if (IsFile)
return STATUS_SUCCESS;
BOOLEAN JumpOver = FALSE;
PIMAGE_NT_HEADERS OutHeaders = nullptr;
RtlImageNtHeaderEx(3, DllEntry->DllBase, 0, &OutHeaders);
PIMAGE_LOAD_CONFIG_DIRECTORY ImageConfigDirectory = LdrImageDirectoryEntryToLoadConfig(DllEntry->DllBase);
if (!ImageConfigDirectory || ImageConfigDirectory->Size < 0x94)
JumpOver = TRUE;
if (!JumpOver)
{
if ((OutHeaders->OptionalHeader.DllCharacteristics & IMAGE_DLLCHARACTERISTICS_GUARD_CF) != 0 && (ImageConfigDirectory->GuardFlags & IMAGE_GUARD_CF_INSTRUMENTED) != 0)
{
UINT_PTR* GuardCFCheckFunctionPointer = (UINT_PTR*)ImageConfigDirectory->GuardCFCheckFunctionPointer;
LoadContext->UnknownFunc = (__int64)GuardCFCheckFunctionPointer;
if (GuardCFCheckFunctionPointer)
{
LoadContext->DllNameLenCompare = *GuardCFCheckFunctionPointer;
}
}
}
do
{
if (!LoadContext->pImageImportDescriptor)
{
ULONG ImportDirectoryVA = OutHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
PIMAGE_SECTION_HEADER FirstSection = (PIMAGE_SECTION_HEADER)((char*)&OutHeaders->OptionalHeader + OutHeaders->FileHeader.SizeOfOptionalHeader);
if (ImportDirectoryVA)
{
ULONG SectionIdx = 0;
if (OutHeaders->FileHeader.NumberOfSections)
{
ULONG SectionVA = 0;
while (TRUE)
{
SectionVA = FirstSection->VirtualAddress;
if (ImportDirectoryVA >= SectionVA && ImportDirectoryVA < SectionVA + FirstSection->SizeOfRawData)
break;
++SectionIdx;
++FirstSection;
if (SectionIdx >= OutHeaders->FileHeader.NumberOfSections)
break;
}
LoadContext->pImageImportDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)((char*)DllEntry->DllBase + SectionVA);
ULONG SectionFA = FirstSection->Misc.PhysicalAddress;
*pImageImportDescriptorLen = SectionFA;
if (!SectionFA)
*pImageImportDescriptorLen = FirstSection->SizeOfRawData;
}
}
}
} while (FALSE);
PIMAGE_IMPORT_DESCRIPTOR pImageImportDescriptor = LoadContext->pImageImportDescriptor;
if (pImageImportDescriptor && *pImageImportDescriptorLen)
{
UINT_PTR ImageImportDescriptorLen = *pImageImportDescriptorLen;
NTSTATUS Status_2 = ZwProtectVirtualMemory((HANDLE)-1, (PVOID*)&pImageImportDescriptor, (PULONG)&ImageImportDescriptorLen, PAGE_READWRITE, (PULONG)&LoadContext->GuardFlags);
if (!NT_SUCCESS(Status_2))
return Status_2;
PIMAGE_IMPORT_DESCRIPTOR pNextSectionMaybe = pImageImportDescriptor;
PIMAGE_IMPORT_DESCRIPTOR pNextImageImportDescriptor = (IMAGE_IMPORT_DESCRIPTOR*)((char*)pImageImportDescriptor + ImageImportDescriptorLen);
do
{
pNextSectionMaybe = (PIMAGE_IMPORT_DESCRIPTOR)((char*)pNextSectionMaybe + 0x1000);
} while (pNextSectionMaybe < pNextImageImportDescriptor);
}
return STATUS_SUCCESS;
}
```
As the function name, prepares the Import Address Table (IAT) for our loaded dll. After this function we go back to LdrpLoadDllInternal because the mapping process is complete. Proceeding with calling LdrpPrepareModuleForExecution.
<br>
## LdrpPrepareModuleForExecution
```cpp
NTSTATUS __fastcall LOADLIBRARY::fLdrpPrepareModuleForExecution(PLDR_DATA_TABLE_ENTRY LdrEntry, NTSTATUS* pStatus)
{
NTSTATUS Status;
Status = STATUS_SUCCESS;
if (*qword_17E238 == NtCurrentTeb()->ClientId.UniqueThread)
return Status;
BOOLEAN Skip = FALSE;
LDR_DDAG_NODE* DdagNode = LdrEntry->DdagNode;
switch (DdagNode->State)
{
case LdrModulesSnapped:
LdrpCondenseGraph(DdagNode);
case LdrModulesCondensed:
{
// This is where we'll start from normally.
if ((LdrEntry->FlagGroup[0] & ProcessStaticImport) == 0)
{
UINT_PTR SubProcessTag = (UINT_PTR)NtCurrentTeb()->SubProcessTag;
LdrpAddNodeServiceTag(DdagNode, SubProcessTag);
}
Status = LdrpNotifyLoadOfGraph(DdagNode);
if (NT_SUCCESS(Status))
{
Status = LdrpDynamicShimModule(DdagNode);
if (!NT_SUCCESS(Status))
{
WID_HIDDEN( LdrpLogInternal("minkernel\\ntdll\\ldrsnap.c", 0x9F3, "LdrpPrepareModuleForExecution", 1u, "Failed to load for appcompat reasons\n"); )
return Status;
}
Skip = TRUE;
}
if (!Skip)
return Status;
}
case LdrModulesReadyToInit:
LDRP_LOAD_CONTEXT* LoadContext = (LDRP_LOAD_CONTEXT*)LdrEntry->LoadContext;
if (LoadContext && (LoadContext->Flags & 1) == 0)
{
LdrpAcquireLoaderLock();
UINT64 Unknown = 0;
Status = fLdrpInitializeGraphRecurse(DdagNode, pStatus, (char*)&Unknown);
ULONG64 Unused = 0;
LdrpReleaseLoaderLock(Unused, 2, Status);
}
return Status;
}
// States end at 9.
if (DdagNode->State > LdrModulesReadyToRun)
return STATUS_INTERNAL_ERROR;
return Status;
}
```
Adds a service tag to our module by LdrModulesCondensed, continues by LdrModulesReadyToInit acquiring a Loader lock first then calling LdrpInitializeGraphRecurse.
<br>
## LdrpInitializeGraphRecurse
```cpp
NTSTATUS __fastcall LOADLIBRARY::fLdrpInitializeGraphRecurse(LDR_DDAG_NODE* DdagNode, NTSTATUS* pStatus, char* Unknown)
{
NTSTATUS Status = STATUS_SUCCESS;
if (DdagNode->State == LdrModulesInitError)
return STATUS_DLL_INIT_FAILED;
LDR_DDAG_NODE* DdagNode2 = (LDR_DDAG_NODE*)DdagNode->Dependencies.Tail;
CHAR Unknown2_2 = 0;
CHAR Unknown2 = 0;
BOOLEAN JumpIn = FALSE;
do
{
if (DdagNode2)
{
LDR_DDAG_NODE* DdagNode2_2 = DdagNode2;
do
{
DdagNode2_2 = (LDR_DDAG_NODE*)DdagNode2_2->Modules.Flink;
if ((DdagNode2_2->LoadCount & 1) == 0)
{
LDR_DDAG_NODE* Blink = (LDR_DDAG_NODE*)DdagNode2_2->Modules.Blink;
if (Blink->State == LdrModulesReadyToInit)
{
Status = fLdrpInitializeGraphRecurse(Blink, pStatus, &Unknown2);
if (!NT_SUCCESS(Status))
{
JumpIn = TRUE;
break;
}
Unknown2_2 = Unknown2;
}
else
{
if (Blink->State == LdrModulesInitError)
{
Status = STATUS_DLL_INIT_FAILED;
{
JumpIn = TRUE;
break;
}
}
if (Blink->State == LdrModulesInitializing)
Unknown2_2 = 1;
Unknown2 = Unknown2_2;
}
}
} while (DdagNode2_2 != DdagNode2);
if (JumpIn)
break;
if (Unknown2_2)
{
LDR_DDAG_NODE* DdagNode3 = (LDR_DDAG_NODE*)DdagNode->Modules.Flink;
*Unknown = 1;
LDR_SERVICE_TAG_RECORD* ServiceTagList = DdagNode3->ServiceTagList;
if (ServiceTagList)
{
if (pStatus != *(NTSTATUS**)&ServiceTagList[2].ServiceTag)
return STATUS_SUCCESS;
}
}
}
} while (FALSE);
if (!JumpIn)
Status = fLdrpInitializeNode(DdagNode);
if (JumpIn || !NT_SUCCESS(Status))
DdagNode->State = LdrModulesInitError;
return Status;
}
```
Does some prior check on the upper area of the function if our DdagNode had dependencies (in our loading case it doesn't so we skip over all the do-while loop), checks for errors and if there are any, sets the state to failed and returns. Otherwise (our case) continues on by calling LdrpInitializeNode.
<br>
## LdrpInitializeNode
```cpp
NTSTATUS __fastcall LOADLIBRARY::fLdrpInitializeNode(LDR_DDAG_NODE* DdagNode)
{
NTSTATUS Status;
NTSTATUS Status_2;
NTSTATUS Status_3;
LDR_DDAG_STATE* pState = &DdagNode->State;
UNICODE_STRING FullDllName;
*(UINT_PTR*)&FullDllName.Length = (UINT_PTR)&DdagNode->State;
DdagNode->State = LdrModulesInitializing;
LDR_DATA_TABLE_ENTRY* Blink = (LDR_DATA_TABLE_ENTRY*)DdagNode->Modules.Blink;
LDR_DATA_TABLE_ENTRY* LdrEntry = *LdrpImageEntry;
UINT_PTR** v4 = (UINT_PTR**)*qword_1843B8;
while (Blink != (LDR_DATA_TABLE_ENTRY*)DdagNode)
{
if (&Blink[-1].DdagNode != (LDR_DDAG_NODE**)LdrEntry)
{
PVOID* p_ParentDllBase = &Blink[-1].ParentDllBase;
if (*v4 != qword_1843B0)
__fastfail(3u);
*p_ParentDllBase = qword_1843B0;
Blink[-1].SwitchBackContext = v4;
*v4 = (UINT_PTR*)p_ParentDllBase;
v4 = (UINT_PTR**)&Blink[-1].ParentDllBase;
*qword_1843B8 = (UINT_PTR**)v4;
}
Blink = (LDR_DATA_TABLE_ENTRY*)Blink->InLoadOrderLinks.Blink;
}
Status = STATUS_SUCCESS;
for (LDR_DATA_TABLE_ENTRY* i = (LDR_DATA_TABLE_ENTRY*)DdagNode->Modules.Blink; i != (LDR_DATA_TABLE_ENTRY*)DdagNode; i = (LDR_DATA_TABLE_ENTRY*)i->InLoadOrderLinks.Blink)
{
LDR_DATA_TABLE_ENTRY* LdrEntry_2 = (LDR_DATA_TABLE_ENTRY*)((char*)i - 160);
if (&i[-1].DdagNode != (LDR_DDAG_NODE**)LdrEntry)
{
if (LdrEntry_2->LoadReason == LoadReasonPatchImage)
{
Status_2 = LdrpApplyPatchImage((PLDR_DATA_TABLE_ENTRY)&i[-1].DdagNode);
Status = Status_2;
if (!NT_SUCCESS(Status_2))
{
FullDllName = LdrEntry_2->FullDllName;
Status_3 = Status_2;
WID_HIDDEN( LdrpLogInternal("minkernel\\ntdll\\ldrsnap.c", 1392, "LdrpInitializeNode", 0, "Applying patch \"%wZ\" failed - Status = 0x%x\n", &FullDllName, *(UINT_PTR*)&Status_3); )
break;
}
}
UINT_PTR CurrentDllIniter = *LdrpCurrentDllInitializer;
*LdrpCurrentDllInitializer = (UINT_PTR)&i[-1].DdagNode;
PVOID EntryPoint = LdrEntry_2->EntryPoint;
PUNICODE_STRING pFullDllName = &LdrEntry_2->FullDllName;
WID_HIDDEN( LdrpLogInternal("minkernel\\ntdll\\ldrsnap.c", 1411, "LdrpInitializeNode", 2u, "Calling init routine %p for DLL \"%wZ\"\n", EntryPoint, &LdrEntry_2->FullDllName); )
RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED StackFrameExtended;
StackFrameExtended.Size = 0x48;
StackFrameExtended.Format = 1;
memset((char*)&StackFrameExtended.Frame.Previous + 4, 0, 48);
UINT_PTR v20 = 0;
RtlActivateActivationContextUnsafeFast(&StackFrameExtended, LdrEntry_2->EntryPointActivationContext);
if (LdrEntry_2->TlsIndex)
fLdrpCallTlsInitializers(1i64, (LDR_DATA_TABLE_ENTRY*)&i[-1].DdagNode);
BOOLEAN CallSuccess = TRUE;
if (EntryPoint)
{
LPVOID ContextRecord = nullptr;
if ((LdrEntry_2->FlagGroup[0] & ProcessStaticImport) != 0)
ContextRecord = *LdrpProcessInitContextRecord;
CallSuccess = fLdrpCallInitRoutine((BOOL(__stdcall*)(HINSTANCE, DWORD, LPVOID))EntryPoint, LdrEntry_2->DllBase, DLL_PROCESS_ATTACH, ContextRecord);
}
RtlDeactivateActivationContextUnsafeFast(&StackFrameExtended);
*LdrpCurrentDllInitializer = CurrentDllIniter;
LdrEntry_2->Flags |= ProcessAttachCalled;
if (!CallSuccess)
{
WID_HIDDEN( LdrpLogInternal("minkernel\\ntdll\\ldrsnap.c", 0x5B7, "LdrpInitializeNode", 0, "Init routine %p for DLL \"%wZ\" failed during DLL_PROCESS_ATTACH\n", EntryPoint, pFullDllName); )
Status = STATUS_DLL_INIT_FAILED;
LdrEntry_2->Flags |= ProcessAttachFailed;
break;
}
WID_HIDDEN( LdrpLogDllState((UINT_PTR)LdrEntry_2->DllBase, pFullDllName, 0x14AEu); )
LdrEntry = *LdrpImageEntry;
}
}
*pState = Status != 0 ? LdrModulesInitError : LdrModulesReadyToRun;
return Status;
}
```
Sets the state to initializing, goes on by checking if it's purpose is to patch the image (not in our case), if it is, it patches the image by calling LdrpApplyPatchImage, if it's not it goes on by calling LdrpCallTlsInitializers which is self explanatory and finally it calls LdrpCallInitRoutine.
<br>
## LdrpCallInitRoutine
```cpp
BOOLEAN __fastcall LOADLIBRARY::fLdrpCallInitRoutine(BOOL(__fastcall* DllMain)(HINSTANCE hInstDll, DWORD fdwReason, LPVOID lpvReserved), PIMAGE_DOS_HEADER DllBase, unsigned int One, LPVOID ContextRecord)
{
BOOLEAN ReturnVal = TRUE;
PCHAR LoggingVar = (PCHAR)&kUserSharedData->UserModeGlobalLogger[2];
PCHAR LoggingVar2 = 0;
if (RtlGetCurrentServiceSessionId())
LoggingVar2 = (PCHAR)&NtCurrentPeb()->SharedData->NtSystemRoot[253];
else
LoggingVar2 = (PCHAR)&kUserSharedData->UserModeGlobalLogger[2];
PCHAR LoggingVar3 = 0;
PCHAR LoggingVar4 = 0;
if (*LoggingVar2 && (NtCurrentPeb()->TracingFlags & LibLoaderTracingEnabled) != 0)
{
LoggingVar3 = (PCHAR)&kUserSharedData->UserModeGlobalLogger[2] + 1;
if (RtlGetCurrentServiceSessionId())
LoggingVar4 = (char*)&NtCurrentPeb()->SharedData->NtSystemRoot[253] + 1;
else
LoggingVar4 = (PCHAR)&kUserSharedData->UserModeGlobalLogger[2] + 1;
// 0x20 is SPACE char.
if ((*LoggingVar4 & ' ') != 0)
WID_HIDDEN( LdrpLogEtwEvent(0x14A3u, (ULONGLONG)DllBase, 0xFF, 0xFF); )
}
else
{
LoggingVar3 = (PCHAR)&kUserSharedData->UserModeGlobalLogger[2] + 1;
}
// DLL_PROCESS_ATTACH (1)
ReturnVal = DllMain((HINSTANCE)DllBase, One, ContextRecord);
if (RtlGetCurrentServiceSessionId())
LoggingVar = (PCHAR)&NtCurrentPeb()->SharedData->NtSystemRoot[253];
if (*LoggingVar && (NtCurrentPeb()->TracingFlags & LibLoaderTracingEnabled) != 0)
{
if (RtlGetCurrentServiceSessionId())
LoggingVar3 = (char*)&NtCurrentPeb()->SharedData->NtSystemRoot[253] + 1;
// 0x20 is SPACE char.
if ((*LoggingVar3 & ' ') != 0)
WID_HIDDEN( LdrpLogEtwEvent(0x1496u, (ULONGLONG)DllBase, 0xFF, 0xFF); )
}
ULONG LoggingVar5 = 0;
if (!ReturnVal && One == 1)
{
LoggingVar5 = 1;
WID_HIDDEN( LdrpLogError(STATUS_DLL_INIT_FAILED, 0x1496u, LoggingVar5, 0i64); )
}
return ReturnVal;
}
```
Does prior checks and calls DllMain which finishes the loading process.
================================================
FILE: Src/Functions/KERNEL32.cpp
================================================
#include "KERNEL32.h"
ULONG* KernelBaseGlobalData = nullptr;
tBasep8BitStringToDynamicUnicodeString Basep8BitStringToDynamicUnicodeString = nullptr;
tBaseSetLastNTError BaseSetLastNTError = nullptr;
// Signatured
tBasepLoadLibraryAsDataFileInternal BasepLoadLibraryAsDataFileInternal = nullptr;
================================================
FILE: Src/Functions/KERNEL32.h
================================================
#pragma once
#include "..\Includes.h"
#include "Undocumented.h"
extern ULONG* KernelBaseGlobalData;
typedef BOOLEAN(WINAPI* tBasep8BitStringToDynamicUnicodeString)(PUNICODE_STRING pConvertedStr, LPCSTR pszAnsiStr);
extern tBasep8BitStringToDynamicUnicodeString Basep8BitStringToDynamicUnicodeString;
typedef DWORD(WINAPI* tBaseSetLastNTError)(IN NTSTATUS Status);
extern tBaseSetLastNTError BaseSetLastNTError;
// Signatured
#define BASEP_LLASDATAFILE_INTERNAL_PATTERN "\x48\x89\x5C\x24\x20\x55\x56\x57\x41\x54\x41\x55\x41\x56\x41\x57\x48\x8D\xAC\x24\x10\xFF\xFF\xFF"
typedef NTSTATUS(__fastcall* tBasepLoadLibraryAsDataFileInternal)(PUNICODE_STRING DllName, PWSTR Path, PWSTR Unknown, DWORD dwFlags, HMODULE* pBaseOfLoadedModule);
extern tBasepLoadLibraryAsDataFileInternal BasepLoadLibraryAsDataFileInternal;
================================================
FILE: Src/Functions/NT.cpp
================================================
#include "NT.h"
// Implemented.
// Variables
DWORD* LdrpPolicyBits = nullptr;
HANDLE* LdrpMainThreadToken = nullptr;
DWORD* LdrInitState = nullptr;
DWORD* LoadFailure = nullptr;
PRTL_CRITICAL_SECTION LdrpWorkQueueLock = nullptr;
DWORD* LdrpWorkInProgress = nullptr;
LIST_ENTRY** LdrpWorkQueue = nullptr;
PHANDLE LdrpWorkCompleteEvent = nullptr;
KUSER_SHARED_DATA* kUserSharedData = (KUSER_SHARED_DATA*)0x7FFE0000;
DWORD* LdrpUseImpersonatedDeviceMap = nullptr;
DWORD* LdrpAuditIntegrityContinuity = nullptr;
DWORD* LdrpEnforceIntegrityContinuity = nullptr;
DWORD* LdrpFatalHardErrorCount = nullptr;
DWORD* UseWOW64 = nullptr;
PRTL_SRWLOCK LdrpModuleDatatableLock = nullptr;
PHANDLE qword_17E238 = nullptr;
LDR_DATA_TABLE_ENTRY** LdrpImageEntry = nullptr;
PUNICODE_STRING LdrpKernel32DllName = nullptr;
UINT_PTR* LdrpAppHeaders = nullptr;
PHANDLE LdrpLargePageDllKeyHandle = nullptr;
ULONG** LdrpLockMemoryPrivilege = nullptr;
ULONG64* LdrpMaximumUserModeAddress = nullptr;
UINT_PTR* LdrpMapAndSnapWork = nullptr;
LIST_ENTRY* LdrpHashTable = nullptr;
PVOID* LdrpHeap = nullptr;
BOOLEAN* LdrpIsHotPatchingEnabled = nullptr;
LDR_DATA_TABLE_ENTRY** LdrpRedirectionModule = nullptr;
ULONG64** qword_1993A8 = nullptr;
LONG* NtdllBaseTag = nullptr;
FUNCTION_TABLE_DATA* stru_199520 = nullptr;
UINT_PTR* qword_199530 = nullptr;
LDR_DATA_TABLE_ENTRY** LdrpNtDllDataTableEntry = nullptr;
UINT_PTR* qword_1993B8 = nullptr;
DWORD* dword_19939C = nullptr;
DWORD* LoadFailureOperational = nullptr;
DWORD* dword_199398 = nullptr;
UINT_PTR*** qword_1843B8 = nullptr;
UINT_PTR* qword_1843B0 = nullptr;
UINT_PTR* LdrpCurrentDllInitializer = nullptr;
LPVOID** LdrpProcessInitContextRecord = nullptr;
PRTL_SRWLOCK LdrpTlsLock = nullptr;
TLS_ENTRY** LdrpTlsList = nullptr;
tLdrpManifestProberRoutine LdrpManifestProberRoutine = nullptr;
tLdrpRedirectionCalloutFunc LdrpRedirectionCalloutFunc = nullptr;
// Functions
PEB* NtCurrentPeb()
{
return NtCurrentTeb()->ProcessEnvironmentBlock;
}
VOID __fastcall NtdllpFreeStringRoutine(PWCH Buffer) // CHECKED.
{
RtlFreeHeap(NtCurrentPeb()->ProcessHeap, 0, Buffer);
}
NTSTATUS __fastcall LdrpFastpthReloadedDll(PUNICODE_STRING FullPath, ULONG Flags, PLDR_DATA_TABLE_ENTRY LdrEntry, LDR_DATA_TABLE_ENTRY** DllEntry)
{
NTSTATUS Status;
PUNICODE_STRING PathUsed;
LDR_DATA_TABLE_ENTRY* pDllEntry;
LDR_DDAG_STATE DdagState;
DdagState = LdrModulesPlaceHolder;
Status = STATUS_NOT_FOUND;
if (Flags & LOAD_LIBRARY_AS_IMAGE_RESOURCE)
{
PathUsed = FullPath;
FullPath = 0;
}
else
{
// If an absolute path was sent from LoadLibrary it will have 0x200 (LOAD_LIBRARY_SEARCH_APPLICATION_DIR), but the if is checking for not so it can be ignored.
if ((Flags & LOAD_LIBRARY_SEARCH_APPLICATION_DIR) == 0)
return Status;
PathUsed = nullptr;
}
Status = LdrpFindLoadedDllByName(PathUsed, FullPath, Flags, DllEntry, &DdagState);
if (NT_SUCCESS(Status))
{
pDllEntry = *DllEntry;
if (pDllEntry->LoadReason == LoadReasonPatchImage)
{
Status = STATUS_IMAGE_LOADED_AS_PATCH_IMAGE;
LdrpLogEtwHotPatchStatus(&(*LdrpImageEntry)->BaseDllName, pDllEntry, 0, STATUS_IMAGE_LOADED_AS_PATCH_IMAGE, 2u);
}
else
{
Status = STATUS_NOT_FOUND;
if (DdagState == LdrModulesReadyToRun)
{
Status = LdrpIncrementModuleLoadCount(pDllEntry);
if (NT_SUCCESS(Status))
{
Status = LdrpBuildForwarderLink(LdrEntry, pDllEntry);
// This is where we most likely end up on a normal call from LoadLibraryExW
if (NT_SUCCESS(Status))
return Status;
BOOLEAN IsWorkerThread = (!(NtCurrentTeb()->SameTebFlags & LoadOwner));
if (IsWorkerThread)
LdrpDrainWorkQueue(WaitLoadComplete);
LdrpDecrementModuleLoadCountEx(pDllEntry, 0);
if (IsWorkerThread)
LdrpDropLastInProgressCount();
}
}
}
LdrpDereferenceModule(*DllEntry);
*DllEntry = nullptr;
}
return Status;
}
NTSTATUS __fastcall LdrpIncrementModuleLoadCount(LDR_DATA_TABLE_ENTRY* LdrEntry)
{
NTSTATUS Status = STATUS_SUCCESS;
RtlAcquireSRWLockExclusive(LdrpModuleDatatableLock);
LDR_DDAG_NODE* DdagNode = LdrEntry->DdagNode;
ULONG LoadCount = DdagNode->LoadCount;
if (LoadCount != -1)
{
if (LoadCount)
{
DdagNode->LoadCount = LoadCount + 1;
}
else if (NtCurrentTeb()->SameTebFlags & LoadOwner)
{
++DdagNode->LoadWhileUnloadingCount;
}
else
{
Status = STATUS_DLL_NOT_FOUND;
}
}
RtlReleaseSRWLockExclusive(LdrpModuleDatatableLock);
return Status;
}
VOID __fastcall RtlFreeUnicodeString(PUNICODE_STRING UnicodeString) // CHECKED.
{
WCHAR* Buffer;
Buffer = UnicodeString->Buffer;
if (Buffer)
{
NtdllpFreeStringRoutine(Buffer);
//*UnicodeString = 0;
memset(UnicodeString, 0, sizeof(UNICODE_STRING));
}
}
VOID __fastcall LdrpFreeUnicodeString(PUNICODE_STRING String)
{
WCHAR* Buffer;
Buffer = String->Buffer;
if (Buffer)
{
NtdllpFreeStringRoutine(Buffer);
String->Buffer = 0;
}
String->Length = 0;
String->MaximumLength = 0;
}
ULONG __fastcall RtlGetCurrentServiceSessionId(VOID) // CHECKED ?
{
LPVOID Return = NtCurrentPeb()->SharedData;
if (Return)
Return = (LPVOID)(*(DWORD*)Return);
return (ULONG)Return;
}
USHORT __fastcall LdrpGetBaseNameFromFullName(PUNICODE_STRING BaseName, PUNICODE_STRING FullName)
{
USHORT StrLen = BaseName->Length >> 1;
if (StrLen)
{
PWCHAR Buffer = BaseName->Buffer;
do
{
if (Buffer[StrLen - 1] == '\\')
break;
if (Buffer[StrLen - 1] == '/')
break;
--StrLen;
} while (StrLen);
}
USHORT ByteLen = 2 * StrLen;
USHORT Return = BaseName->MaximumLength - ByteLen;
FullName->Length = BaseName->Length - ByteLen;
FullName->MaximumLength = Return;
FullName->Buffer = &BaseName->Buffer[StrLen];
return Return;
}
PWCHAR __fastcall RtlGetNtSystemRoot()
{
if (RtlGetCurrentServiceSessionId())
return (PWCHAR)((char*)NtCurrentPeb()->SharedData + 30);
else
return kUserSharedData->NtSystemRoot;
}
BOOLEAN __fastcall LdrpHpatAllocationOptOut(PUNICODE_STRING FullDllName)
{
UNICODE_STRING NtString; // [rsp+30h] [rbp-18h] BYREF
if ((NtCurrentPeb()->ProcessParameters->Flags & 0x2000000) == 0 || *FullDllName->Buffer == '\\')
return 0;
PWSTR NtSystemRoot = RtlGetNtSystemRoot();
RtlInitUnicodeStringEx(&NtString, NtSystemRoot);
return FullDllName->Length < NtString.Length || RtlCompareUnicodeStrings(FullDllName->Buffer, NtString.Length >> 1, NtString.Buffer, NtString.Length >> 1, 1u) != 0;
}
NTSTATUS __fastcall LdrpCorValidateImage(PIMAGE_DOS_HEADER DosHeader)
{
NTSTATUS Status;
PIMAGE_FILE_HEADER ImageFileHeader;
UINT_PTR LastRVASection;
Status = RtlpImageDirectoryEntryToDataEx(DosHeader, TRUE, IMAGE_FILE_RELOCS_STRIPPED | IMAGE_FILE_LOCAL_SYMS_STRIPPED, &LastRVASection, (PIMAGE_FILE_HEADER*)&ImageFileHeader);
if (!NT_SUCCESS(Status))
ImageFileHeader = 0;
return ImageFileHeader != 0 ? STATUS_INVALID_IMAGE_FORMAT : 0;
}
NTSTATUS __fastcall LdrpCorFixupImage(PIMAGE_DOS_HEADER DosHeader)
{
NTSTATUS Status;
PIMAGE_NT_HEADERS NtHeader = RtlImageNtHeader(DosHeader);
ULONG64 LastRVASection;
PIMAGE_COR20_HEADER CorHeader = nullptr;
Status = RtlpImageDirectoryEntryToDataEx(DosHeader, 1, IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR, &LastRVASection, &CorHeader);
if (!NT_SUCCESS(Status) || !CorHeader)
return Status;
if (NtHeader->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC && NtHeader->FileHeader.Machine == IMAGE_FILE_MACHINE_I386 && (CorHeader->Flags & 2) == 0)
{
ULONG64* pSizeOfHeapCommit = &NtHeader->OptionalHeader.SizeOfHeapCommit;
PBYTE UnknownCalc = (PBYTE)&NtHeader->OptionalHeader +
(32 * NtHeader->FileHeader.NumberOfSections) +
(8 * NtHeader->FileHeader.NumberOfSections) +
NtHeader->FileHeader.SizeOfOptionalHeader;
UINT_PTR NumberOfBytesToProtect = 0x1000;
if ((unsigned __int64)(UnknownCalc - (PBYTE)DosHeader + 0x10) <= 0x1000)
{
ULONG OldAccessProtection;
Status = ZwProtectVirtualMemory((HANDLE)-1, (PVOID*)&DosHeader, (PULONG)&NumberOfBytesToProtect, PAGE_READWRITE, &OldAccessProtection);
if (NT_SUCCESS(Status))
{
memmove(NtHeader->OptionalHeader.DataDirectory, &NtHeader->OptionalHeader.SizeOfHeapCommit, UnknownCalc - (PBYTE)pSizeOfHeapCommit);
*(ULONG64*)&NtHeader->OptionalHeader.LoaderFlags = NtHeader->OptionalHeader.SizeOfHeapReserve;
*pSizeOfHeapCommit = (NtHeader->OptionalHeader.SizeOfStackCommit) & 0xFFFFFFFF00000000;
NtHeader->OptionalHeader.SizeOfHeapReserve = (NtHeader->OptionalHeader.SizeOfStackCommit) & UINT_MAX;
NtHeader->OptionalHeader.SizeOfStackCommit = (NtHeader->OptionalHeader.SizeOfStackReserve) & 0xFFFFFFFF00000000;
NtHeader->OptionalHeader.SizeOfStackReserve = (NtHeader->OptionalHeader.SizeOfStackReserve) & UINT_MAX;
NtHeader->OptionalHeader.ImageBase = (NtHeader->OptionalHeader.ImageBase) & 0xFFFFFFFF00000000;
NtHeader->FileHeader.SizeOfOptionalHeader += 0x10;
NtHeader->OptionalHeader.Magic = IMAGE_NT_OPTIONAL_HDR64_MAGIC;
ZwProtectVirtualMemory((HANDLE)-1, (PVOID*)&DosHeader, (PULONG)&NumberOfBytesToProtect, OldAccessProtection, &OldAccessProtection);
}
}
else
{
return STATUS_INVALID_IMAGE_FORMAT;
}
}
else
{
WORD Machine = NtHeader->FileHeader.Machine;
if (Machine < kUserSharedData->ImageNumberLow)
return STATUS_INVALID_IMAGE_FORMAT;
Status = STATUS_SUCCESS;
if (Machine > kUserSharedData->ImageNumberHigh)
return STATUS_INVALID_IMAGE_FORMAT;
}
return Status;
}
NTSTATUS __fastcall LdrpFindLoadedDllByNameLockHeld(PUNICODE_STRING BaseDllName, PUNICODE_STRING FullDllName, ULONG64 Flags, LDR_DATA_TABLE_ENTRY** pLdrEntry, ULONG BaseNameHashValue)
{
LIST_ENTRY* pHashIdx;
LDR_DDAG_NODE* DdagNode;
// Parse entire hash table. Maybe I use it later on.
//for (int idx = 0; idx < 32; idx++)
//{
// LIST_ENTRY* IdxHead = &LdrpHashTable[idx];
// LIST_ENTRY* IdxEntry = IdxHead->Flink;
// while (IdxEntry != IdxHead)
// {
// LDR_DATA_TABLE_ENTRY* IdxLdrEntry = CONTAINING_RECORD(IdxEntry, LDR_DATA_TABLE_ENTRY, HashLinks);
//
// printf("[Name: %ws]\n", IdxLdrEntry->BaseDllName.Buffer);
//
// LIST_ENTRY* LdrHead = &IdxLdrEntry->InLoadOrderLinks;
// LIST_ENTRY* LdrEntry = LdrHead->Flink;
// while (LdrEntry != LdrHead)
// {
// LDR_DATA_TABLE_ENTRY* IdxLdrEntryMod = CONTAINING_RECORD(LdrEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
//
// printf(" -> [Name: %ws]\n", IdxLdrEntryMod->BaseDllName.Buffer);
//
// LdrEntry = LdrEntry->Flink;
// }
//
// IdxEntry = IdxEntry->Flink;
// }
//}
pHashIdx = (LIST_ENTRY*)&(LdrpHashTable)[(BaseNameHashValue & 0x1F)];
BOOLEAN DllFound = FALSE;
for (LIST_ENTRY* HashEntry = pHashIdx->Flink; HashEntry != pHashIdx; HashEntry = HashEntry->Flink)
{
LDR_DATA_TABLE_ENTRY* DllEntry = (LDR_DATA_TABLE_ENTRY*)&HashEntry[-7];
//LDR_DATA_TABLE_ENTRY* DllEntry = CONTAINING_RECORD(HashEntry, LDR_DATA_TABLE_ENTRY, HashLinks);
//LDR_DATA_TABLE_ENTRY* DllEntry = (PLDR_DATA_TABLE_ENTRY)CONTAINING_RECORD(HashEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
if (BaseNameHashValue == (DllEntry->BaseNameHashValue) && ((Flags & 8) == 0 || (DllEntry->FlagGroup[0] & 1) != 0))
{
if (FullDllName)
{
DllFound = RtlEqualUnicodeString(FullDllName, &DllEntry->FullDllName, TRUE);
if (DllFound)
goto DLL_FOUND;
}
else
{
if ((DllEntry->Flags & Redirected) == 0 && RtlEqualUnicodeString(BaseDllName, &DllEntry->BaseDllName, TRUE))
{
DllFound = TRUE;
DLL_FOUND:
DdagNode = DllEntry->DdagNode;
if (DdagNode->LoadCount != -1 && ((__int64)DdagNode->Modules.Flink[-4].Blink & 0x20) == 0)
_InterlockedIncrement(&DllEntry->ReferenceCount);
*pLdrEntry = DllEntry;
return DllFound ? STATUS_SUCCESS : STATUS_DLL_NOT_FOUND;
}
DllFound = FALSE;
}
}
}
return DllFound ? STATUS_SUCCESS : STATUS_DLL_NOT_FOUND;
}
BOOLEAN __fastcall LdrpIsILOnlyImage(PIMAGE_DOS_HEADER DllBase)
{
NTSTATUS Status;
UINT_PTR LastRVASection;
PIMAGE_COR20_HEADER CorHeader;
Status = RtlpImageDirectoryEntryToDataEx(DllBase, 1u, 0xEu, &LastRVASection, (PVOID*)&CorHeader);
if (Status < 0)
return Status;
return CorHeader && LastRVASection >= 0x48 && (CorHeader->Flags & 1) != 0;
}
VOID __fastcall LdrpAddNodeServiceTag(LDR_DDAG_NODE* DdagNode, UINT_PTR ServiceTag)
{
//LDR_DATA_TABLE_ENTRY* LdrEntry = CONTAINING_RECORD(DdagNode->Modules.Flink, LDR_DATA_TABLE_ENTRY, DdagNode);
if (DdagNode->LoadCount != -1 && ((__int64)DdagNode->Modules.Flink[-4].Blink & 0x20) == 0)
//if (DdagNode->LoadCount != -1 && (LdrEntry->FlagGroup[0] & 0x20) == 0)
{
for (LDR_SERVICE_TAG_RECORD* i = DdagNode->ServiceTagList; i; i = i->Next)
{
if (i->ServiceTag == ServiceTag)
return;
}
LDR_SERVICE_TAG_RECORD* Heap = (LDR_SERVICE_TAG_RECORD*)RtlAllocateHeap(*LdrpHeap, 0, 0x10);
if (Heap)
{
Heap->ServiceTag = ServiceTag;
Heap->Next = DdagNode->ServiceTagList;
DdagNode->ServiceTagList = Heap;
SINGLE_LIST_ENTRY* Tail = DdagNode->Dependencies.Tail;
if (Tail)
{
SINGLE_LIST_ENTRY* Tail_2 = Tail;
do
{
Tail_2 = Tail_2->Next;
// LDR_DDAG_NODE* NextNode = CONTAINING_RECORD(Tail_2, LDR_DDAG_NODE, CondenseLink);
LdrpAddNodeServiceTag((LDR_DDAG_NODE*)Tail_2[1].Next, ServiceTag);
//LdrpAddNodeServiceTag(NextNode, ServiceTag);
} while (Tail_2 != Tail);
}
}
}
}
PIMAGE_LOAD_CONFIG_DIRECTORY LdrImageDirectoryEntryToLoadConfig(PIMAGE_DOS_HEADER DllBase)
{
NTSTATUS Status = STATUS_SUCCESS;
PIMAGE_NT_HEADERS OutHeaders = nullptr;
RtlImageNtHeaderEx(1u, DllBase, 0, &OutHeaders);
if (!DllBase)
return nullptr;
UINT_PTR LastRVASection = 0;
PIMAGE_LOAD_CONFIG_DIRECTORY LoadConfigDirectory = nullptr;
Status = RtlpImageDirectoryEntryToDataEx(DllBase, 1u, 0xAu, &LastRVASection, (PVOID*)&LoadConfigDirectory);
if (!NT_SUCCESS(Status))
return nullptr;
if (LoadConfigDirectory && (DWORD)LastRVASection && (DWORD)LastRVASection == LoadConfigDirectory->Size && OutHeaders->FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64)
return LoadConfigDirectory;
return nullptr;
}
BOOLEAN __fastcall LdrpShouldModuleImportBeRedirected(LDR_DATA_TABLE_ENTRY* DllEntry)
{
if (!DllEntry || !*LdrpRedirectionModule || *LdrpRedirectionModule == DllEntry)
return FALSE;
if ((NtCurrentPeb()->BitField & IsPackagedProcess) != 0)
return DllEntry->FlagGroup[0] & PackagedBinary;
// LdrpRedirectionCalloutFunc is a function pointer.
if (*LdrpRedirectionCalloutFunc)
return (*LdrpRedirectionCalloutFunc)(DllEntry->FullDllName.Buffer);
else
return TRUE;
}
PIMAGE_IMPORT_DESCRIPTOR __fastcall LdrpGetImportDescriptorForSnap(LDRP_LOAD_CONTEXT* LoadContext)
{
NTSTATUS Status;
// [CORRECT]
//LDR_DATA_TABLE_ENTRY* DllEntry = (LDR_DATA_TABLE_ENTRY*)LoadContext->WorkQueueListEntry.Flink;
LDR_DATA_TABLE_ENTRY* DllEntry = CONTAINING_RECORD(LoadContext->WorkQueueListEntry.Flink, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
UINT_PTR LastRVASection;
PIMAGE_IMPORT_DESCRIPTOR pImageImportDescriptor;
Status = RtlpImageDirectoryEntryToDataEx(DllEntry->DllBase, TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &LastRVASection, (PVOID*)&pImageImportDescriptor);
if (!NT_SUCCESS(Status))
return nullptr;
if (DllEntry == *LdrpImageEntry && (((ULONG64)(*qword_1993A8) >> 44) & 3) == 1)
{
PIMAGE_NT_HEADERS pImageNtHeaders = nullptr;
RtlImageNtHeaderEx(3, DllEntry->DllBase, 0, (PIMAGE_NT_HEADERS*)&pImageNtHeaders);
if (!((LdrpCheckPagesForTampering(&pImageNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT], 8) || LdrpCheckPagesForTampering((PIMAGE_DATA_DIRECTORY)pImageImportDescriptor, (ULONG)LastRVASection)) && NT_SUCCESS(LdrpMapCleanModuleView(LoadContext))))
{
return nullptr;
}
}
return pImageImportDescriptor;
}
NTSTATUS __fastcall LdrpMapCleanModuleView(LDRP_LOAD_CONTEXT* LoadContext)
{
NTSTATUS Status;
HANDLE ProcessInformation = 0;
PIMAGE_DOS_HEADER ImageDosHeader = nullptr;
ULONG64 ViewSize = 0;
if (CONTAINING_RECORD(LoadContext->WorkQueueListEntry.Flink, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks) != *LdrpImageEntry)
return STATUS_NOT_SUPPORTED;
Status = NtQueryInformationProcess((HANDLE)-1, ProcessImageSection, &ProcessInformation, 8, 0);
if (NT_SUCCESS(Status))
{
Status = ZwMapViewOfSection(ProcessInformation, (HANDLE)-1u, &ImageDosHeader, 0, 0, 0, (PULONG)&ViewSize, ViewShare, 0x40000u, 2u);
if (NT_SUCCESS(Status))
LoadContext->ImageBase = ImageDosHeader;
NtClose(ProcessInformation);
}
return Status;
}
LDR_DATA_TABLE_ENTRY* __fastcall LdrpHandleReplacedModule(LDR_DATA_TABLE_ENTRY* LdrEntry)
{
LDR_DATA_TABLE_ENTRY* DllEntry = LdrEntry;
if (LdrEntry)
{
LDRP_LOAD_CONTEXT* LoadContext = (LDRP_LOAD_CONTEXT*)LdrEntry->LoadContext;
if (LoadContext)
{
if ((LoadContext->Flags & 0x80000) == 0 && (LDR_DATA_TABLE_ENTRY*)LoadContext->WorkQueueListEntry.Flink != LdrEntry)
{
DllEntry = (LDR_DATA_TABLE_ENTRY*)LoadContext->WorkQueueListEntry.Flink;
LoadContext->WorkQueueListEntry.Flink = &LdrEntry->InLoadOrderLinks;
}
}
}
return DllEntry;
}
NTSTATUS __fastcall LdrpFreeReplacedModule(LDR_DATA_TABLE_ENTRY* LdrDataTableEntry)
{
LdrpFreeLoadContext(LdrDataTableEntry->LoadContext);
// Revokes ProcessStaticImport (0x20) flag.
LdrDataTableEntry->Flags &= ~ProcessStaticImport;
LdrDataTableEntry->ReferenceCount = 1;
return LdrpDereferenceModule(LdrDataTableEntry);
}
VOID __fastcall LdrpHandlePendingModuleReplaced(LDRP_LOAD_CONTEXT* LoadContext)
{
LDR_DATA_TABLE_ENTRY* Entry = (LDR_DATA_TABLE_ENTRY*)LoadContext->pvImports;
if (Entry)
{
LDR_DATA_TABLE_ENTRY* ReturnEntry = LdrpHandleReplacedModule(Entry);
LDR_DATA_TABLE_ENTRY** CompareEntry = LoadContext->pvImports;
if (ReturnEntry != (LDR_DATA_TABLE_ENTRY*)CompareEntry)
LdrpFreeReplacedModule((LDR_DATA_TABLE_ENTRY*)CompareEntry);
LoadContext->pvImports = nullptr;
}
}
PIMAGE_SECTION_HEADER __fastcall RtlSectionTableFromVirtualAddress(PIMAGE_NT_HEADERS NtHeader, PVOID Base, UINT_PTR Address)
{
PIMAGE_SECTION_HEADER SectionHeader = (PIMAGE_SECTION_HEADER)((char*)&NtHeader->OptionalHeader + NtHeader->FileHeader.SizeOfOptionalHeader);
if (!NtHeader->FileHeader.NumberOfSections)
return nullptr;
ULONG NumberOfSections = NtHeader->FileHeader.NumberOfSections;
ULONG SectionIdx = 0;
while (TRUE)
{
ULONG VirtualAddress = SectionHeader->VirtualAddress;
if ((unsigned int)Address >= VirtualAddress && (unsigned int)Address < SectionHeader->SizeOfRawData + VirtualAddress)
break;
++SectionHeader;
if (++SectionIdx >= NumberOfSections)
return nullptr;
}
return SectionHeader;
}
PIMAGE_SECTION_HEADER __fastcall RtlAddressInSectionTable(PIMAGE_NT_HEADERS NtHeader, PVOID Base, UINT_PTR Address)
{
PIMAGE_SECTION_HEADER SectionHeader;
SectionHeader = RtlSectionTableFromVirtualAddress(NtHeader, Base, Address);
if (SectionHeader)
return (PIMAGE_SECTION_HEADER)(SectionHeader->PointerToRawData - SectionHeader->VirtualAddress);
return SectionHeader;
}
BOOLEAN __fastcall LdrpValidateEntrySection(LDR_DATA_TABLE_ENTRY* DllEntry)
{
PIMAGE_NT_HEADERS OutHeaders;
RtlImageNtHeaderEx(3u, DllEntry->DllBase, 0, &OutHeaders);
ULONG AddressOfEntryPoint = OutHeaders->OptionalHeader.AddressOfEntryPoint;
return !AddressOfEntryPoint || !DllEntry->EntryPoint || AddressOfEntryPoint >= OutHeaders->OptionalHeader.SizeOfHeaders;
}
BOOL __fastcall LdrpIsExecutableRelocatedImage(PIMAGE_DOS_HEADER DllBase)
{
MEMORY_IMAGE_INFORMATION MemoryInformation; // [rsp+30h] [rbp-28h] BYREF
PIMAGE_NT_HEADERS OutHeaders; // [rsp+68h] [rbp+10h] BYREF
return NT_SUCCESS(RtlImageNtHeaderEx(3u, DllBase, 0i64, &OutHeaders)) && (PIMAGE_DOS_HEADER)OutHeaders->OptionalHeader.ImageBase == DllBase
&& NT_SUCCESS(ZwQueryVirtualMemory((HANDLE)-1, DllBase, MemoryImageInformation, &MemoryInformation, 0x18, 0))
&& MemoryInformation.ImageBase == DllBase
&& (MemoryInformation.ImageFlags & 2) == 0
&& (MemoryInformation.ImageFlags & 1) == 0;
}
TLS_ENTRY* __fastcall LdrpFindTlsEntry(LDR_DATA_TABLE_ENTRY* LdrEntry)
{
TLS_ENTRY* TlsEntry;
for (TlsEntry = *LdrpTlsList; TlsEntry != (TLS_ENTRY*)LdrpTlsList; TlsEntry = (TLS_ENTRY*)TlsEntry->TlsEntry.Flink)
{
if ((LDR_DATA_TABLE_ENTRY*)TlsEntry->ModuleEntry == LdrEntry)
return TlsEntry;
}
return nullptr;
}
BOOL __fastcall ImageTlsCallbackCaller(HINSTANCE hInstDll, DWORD fdwReason, LPVOID lpvReserved)
{
((void(__fastcall*)(HINSTANCE, DWORD, LPVOID))lpvReserved)(hInstDll, fdwReason, 0);
return 1;
}
// Implemented inside LOADLIBRARY class to use WID_HIDDEN
NTSTATUS __fastcall WID::Loader::LOADLIBRARY::LdrpThreadTokenSetMainThreadToken() // CHECKED.
{
NTSTATUS Status;
HANDLE ReturnToken = NULL;
Status = NtOpenThreadToken((HANDLE)-2, 0x2001C, 0, &ReturnToken);
*LdrpMainThreadToken = ReturnToken;
if (Status != STATUS_NO_TOKEN)
{
WID_HIDDEN( LdrpLogInternal("minkernel\\ntdll\\ldrapi.c", 0xDC8, "LdrpThreadTokenSetMainThreadToken", 2, "Status: 0x%x\n", Status); )
}
return Status;
}
NTSTATUS __fastcall WID::Loader::LOADLIBRARY::LdrpThreadTokenUnsetMainThreadToken() // CHECKED.
{
NTSTATUS Status;
Status = NtClose(*LdrpMainThreadToken);
*LdrpMainThreadToken = NULL;
WID_HIDDEN( LdrpLogInternal("minkernel\\ntdll\\ldrapi.c", 0xDEE, "LdrpThreadTokenUnsetMainThreadToken", 2u, "Status: 0x%x\n", Status); )
return Status;
}
LDR_DATA_TABLE_ENTRY* __fastcall WID::Loader::LOADLIBRARY::LdrpHandleReplacedModule(LDR_DATA_TABLE_ENTRY* LdrEntry) // CHECKED.
{
LDR_DATA_TABLE_ENTRY* DllEntry = LdrEntry;
if (LdrEntry)
{
LDRP_LOAD_CONTEXT* LoadContext = LdrEntry->LoadContext;
if (LoadContext)
{
DllEntry = CONTAINING_RECORD(LoadContext->WorkQueueListEntry.Flink, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
//if ((LoadContext->Flags & SEC_64K_PAGES) == 0 && (LDR_DATA_TABLE_ENTRY*)LoadContext->WorkQueueListEntry.Flink != LdrEntry)
if ((LoadContext->Flags & SEC_64K_PAGES) == 0 && DllEntry != LdrEntry)
{
//DllEntry = (LDR_DATA_TABLE_ENTRY*)LoadContext->WorkQueueListEntry.Flink;
LoadContext->WorkQueueListEntry.Flink = &LdrEntry->InLoadOrderLinks;
}
}
}
return DllEntry;
}
NTSTATUS __fastcall WID::Loader::LOADLIBRARY::LdrpFreeReplacedModule(LDR_DATA_TABLE_ENTRY* LdrEntry) // CHECKED.
{
LdrpFreeLoadContext(LdrEntry->LoadContext);
// Resets (sets to 0) flag ProcessStaticImport (0x20)
LdrEntry->Flags &= ~0x20u;
// Might change if hidden, not touching for now.
LdrEntry->ReferenceCount = 1;
return LdrpDereferenceModule(LdrEntry);
}
NTSTATUS __fastcall WID::Loader::LOADLIBRARY::LdrpResolveDllName(LDRP_LOAD_CONTEXT* LoadContext, LDRP_FILENAME_BUFFER* FileNameBuffer, PUNICODE_STRING BaseDllName, PUNICODE_STRING FullDllName, DWORD Flags) // CHECKED.
{
NTSTATUS Status;
PWCHAR FileName;
UNICODE_STRING DllName;
BOOLEAN FileNamesNotEqual = FALSE;
WID_HIDDEN( LdrpLogInternal("minkernel\\ntdll\\ldrfind.c", 0x6B9, "LdrpResolveDllName", 3u, "DLL name: %wZ\n", LoadContext); )
// Converted goto to do-while loop.
do
{
// This if will go in if call stack starts back from LoadLibraryExW with an absolute path.
if (Flags & LOAD_LIBRARY_SEARCH_APPLICATION_DIR)
{
DllName = LoadContext->BaseDllName;
}
else
{
Status = LdrpGetFullPath(LoadContext, &FileNameBuffer->pFileName);
if (!NT_SUCCESS(Status))
{
if (FileNamesNotEqual)
LdrpFreeUnicodeString(&DllName);
WID_HIDDEN(LdrpLogInternal("minkernel\\ntdll\\ldrfind.c", 0x742, "LdrpResolveDllName", 4, "Status: 0x%08lx\n", Status); )
return Status;
}
FileName = FileNameBuffer->FileName;
DllName = FileNameBuffer->pFileName;
FileNamesNotEqual = (FileNameBuffer->FileName != FileNameBuffer->pFileName.Buffer);
if (FileNamesNotEqual)
{
FileNameBuffer->pFileName.Buffer = FileName;
FileNameBuffer->pFileName.MaximumLength = MAX_PATH - 4;
*FileName = 0;
break;
}
}
USHORT Length = DllName.Length;
PWCHAR Buffer = DllName.Buffer;
Status = LdrpAllocateUnicodeString(&DllName, DllName.Length);
if (!NT_SUCCESS(Status))
{
if (FileNamesNotEqual)
LdrpFreeUnicodeString(&DllName);
WID_HIDDEN(LdrpLogInternal("minkernel\\ntdll\\ldrfind.c", 0x742, "LdrpResolveDllName", 4, "Status: 0x%08lx\n", Status); )
return Status;
}
FileNamesNotEqual = TRUE;
memmove(DllName.Buffer, Buffer, Length + 2);
DllName.Length = Length;
} while (FALSE);
FileNameBuffer->pFileName.Length = 0;
if (Flags & 0x10000000)
Status = LdrpAppendUnicodeStringToFilenameBuffer(&FileNameBuffer->pFileName, LoadContext);
else
Status = LdrpGetNtPathFromDosPath(&DllName, FileNameBuffer);
if (NT_SUCCESS(Status))
{
*FullDllName = DllName;
LdrpGetBaseNameFromFullName(&DllName, BaseDllName);
WID_HIDDEN(LdrpLogInternal("minkernel\\ntdll\\ldrfind.c", 0x742, "LdrpResolveDllName", 4, "Status: 0x%08lx\n", Status); )
return Status;
}
NTSTATUS StatusAdded = (Status + 0x3FFFFFF1);
//LONGLONG BitTestVar = 0x1C3000000011;
LONGLONG BitTestVar = 0b0001'1100'0011'0000'0000'0000'0000'0000'0000'0000'0001'0001;
if (StatusAdded <= 0x2C && (_bittest64(&BitTestVar, StatusAdded)) || Status == STATUS_DEVICE_OFF_LINE || Status == STATUS_DEVICE_NOT_READY)
{
WID_HIDDEN( LdrpLogInternal("minkernel\\ntdll\\ldrfind.c", 0x72D, "LdrpResolveDllName", 2, "Original status: 0x%08lx\n", Status); )
Status = STATUS_DLL_NOT_FOUND;
}
if (FileNamesNotEqual)
LdrpFreeUnicodeString(&DllName);
WID_HIDDEN( LdrpLogInternal("minkernel\\ntdll\\ldrfind.c", 0x742, "LdrpResolveDllName", 4, "Status: 0x%08lx\n", Status); )
return Status;
}
NTSTATUS __fastcall WID::Loader::LOADLIBRARY::LdrpFindDllActivationContext(LDR_DATA_TABLE_ENTRY* LdrEntry) // CHECKED.
{
NTSTATUS Status = STATUS_SUCCESS;
if (*(UINT_PTR*)(*LdrpManifestProberRoutine))
{
PEB* PEB = NtCurrentPeb();
if (LdrEntry != *LdrpImageEntry || !PEB->ActivationContextData)
{
PWCHAR Buffer = LdrEntry->FullDllName.Buffer;
if (LdrEntry == *LdrpImageEntry && *Buffer == '\\' && Buffer[1] == '?' && Buffer[2] == '?' && Buffer[3] == '\\' && Buffer[4] && Buffer[5] == ':' && Buffer[6] == '\\')
{
Buffer += 4;
}
// LdrpManifestProberRoutine is a function pointer.
ACTIVATION_CONTEXT* pActivationCtx = nullptr;
Status = (*LdrpManifestProberRoutine)(LdrEntry->DllBase, Buffer, &pActivationCtx);
if ((unsigned int)(Status + 0x3FFFFF77) <= 2 || Status == STATUS_NOT_SUPPORTED || Status == STATUS_NO_SUCH_FILE || Status == STATUS_NOT_IMPLEMENTED || Status == STATUS_RESOURCE_LANG_NOT_FOUND)
{
WID_HIDDEN(LdrpLogInternal("minkernel\\ntdll\\ldrsnap.c", 733, "LdrpFindDllActivationContext", 2u, "Probing for the manifest of DLL \"%wZ\" failed with status 0x%08lx\n", &LdrEntry->FullDllName, Status); )
Status = STATUS_SUCCESS;
}
if (pActivationCtx)
{
if (LdrEntry->EntryPointActivationContext)
{
RtlReleaseActivationContext(LdrEntry->EntryPointActivationContext);
}
LdrEntry->EntryPointActivationContext = pActivationCtx;
}
if (!NT_SUCCESS(Status))
{
WID_HIDDEN(LdrpLogInternal("minkernel\\ntdll\\ldrsnap.c", 0x2FA, "LdrpFindDllActivationContext", 0, "Querying the active activation context failed with status 0x%08lx\n", Status); )
}
}
}
return Status;
}
// Planning to implement them all in the future.
tNtOpenThreadToken NtOpenThreadToken = nullptr;
tNtClose NtClose = nullptr;
tRtlAllocateHeap RtlAllocateHeap = nullptr;
tRtlFreeHeap RtlFreeHeap = nullptr;
tLdrGetDllPath LdrGetDllPath = nullptr;
tRtlReleasePath RtlReleasePath = nullptr;
tRtlInitUnicodeStringEx RtlInitUnicodeStringEx = nullptr;
tRtlEnterCriticalSection RtlEnterCriticalSection = nullptr;
tRtlLeaveCriticalSection RtlLeaveCriticalSection = nullptr;
tZwSetEvent ZwSetEvent = nullptr;
tNtOpenFile NtOpenFile = nullptr;
tLdrAppxHandleIntegrityFailure LdrAppxHandleIntegrityFailure = nullptr;
tNtRaiseHardError NtRaiseHardError = nullptr;
tRtlImageNtHeaderEx RtlImageNtHeaderEx = nullptr;
tRtlAcquireSRWLockExclusive RtlAcquireSRWLockExclusive = nullptr;
tRtlReleaseSRWLockExclusive RtlReleaseSRWLockExclusive = nullptr;
tRtlEqualUnicodeString RtlEqualUnicodeString = nullptr;
tRtlAcquirePrivilege RtlAcquirePrivilege = nullptr;
tRtlReleasePrivilege RtlReleasePrivilege = nullptr;
tRtlCompareUnicodeStrings RtlCompareUnicodeStrings = nullptr;
tRtlImageNtHeader RtlImageNtHeader = nullptr;
tRtlReleaseActivationContext RtlReleaseActivationContext = nullptr;
tRtlCharToInteger RtlCharToInteger = nullptr;
tRtlActivateActivationContextUnsafeFast RtlActivateActivationContextUnsafeFast = nullptr;
tRtlDeactivateActivationContextUnsafeFast RtlDeactivateActivationContextUnsafeFast = nullptr;
tRtlAcquireSRWLockShared RtlAcquireSRWLockShared = nullptr;
tRtlReleaseSRWLockShared RtlReleaseSRWLockShared = nullptr;
// Signatured
tLdrpLogInternal LdrpLogInternal = nullptr;
tLdrpInitializeDllPath LdrpInitializeDllPath = nullptr;
tLdrpDereferenceModule LdrpDereferenceModule = nullptr;
tLdrpLogDllState LdrpLogDllState = nullptr;
tLdrpPreprocessDllName LdrpPreprocessDllName = nullptr;
tLdrpFindLoadedDllByName LdrpFindLoadedDllByName = nullptr;
tLdrpDrainWorkQueue LdrpDrainWorkQueue = nullptr;
tLdrpFindLoadedDllByHandle LdrpFindLoadedDllByHandle = nullptr;
tLdrpDropLastInProgressCount LdrpDropLastInProgressCount = nullptr;
tLdrpQueryCurrentPatch LdrpQueryCurrentPatch = nullptr;
tLdrpUndoPatchImage LdrpUndoPatchImage = nullptr;
tLdrpDetectDetour LdrpDetectDetour = nullptr;
tLdrpFindOrPrepareLoadingModule LdrpFindOrPrepareLoadingModule = nullptr;
tLdrpFreeLoadContext LdrpFreeLoadContext = nullptr;
tLdrpCondenseGraph LdrpCondenseGraph = nullptr;
tLdrpBuildForwarderLink LdrpBuildForwarderLink = nullptr;
tLdrpPinModule LdrpPinModule = nullptr;
tLdrpApplyPatchImage LdrpApplyPatchImage = nullptr;
tLdrpFreeLoadContextOfNode LdrpFreeLoadContextOfNode = nullptr;
tLdrpDecrementModuleLoadCountEx LdrpDecrementModuleLoadCountEx = nullptr;
tLdrpLogError LdrpLogError = nullptr;
tLdrpLogDeprecatedDllEtwEvent LdrpLogDeprecatedDllEtwEvent = nullptr;
tLdrpLogLoadFailureEtwEvent LdrpLogLoadFailureEtwEvent = nullptr;
tLdrpReportError LdrpReportError = nullptr;
tLdrpResolveDllName LdrpResolveDllName = nullptr;
tLdrpAppCompatRedirect LdrpAppCompatRedirect = nullptr;
tLdrpHashUnicodeString LdrpHashUnicodeString = nullptr;
tLdrpFindExistingModule LdrpFindExistingModule = nullptr;
tLdrpLoadContextReplaceModule LdrpLoadContextReplaceModule = nullptr;
tLdrpSearchPath LdrpSearchPath = nullptr;
tLdrpIsSecurityEtwLoggingEnabled LdrpIsSecurityEtwLoggingEnabled = nullptr;
tLdrpLogEtwDllSearchResults LdrpLogEtwDllSearchResults = nullptr;
tLdrpCheckForRetryLoading LdrpCheckForRetryLoading = nullptr;
tLdrpLogEtwEvent LdrpLogEtwEvent = nullptr;
tLdrpCheckComponentOnDemandEtwEvent LdrpCheckComponentOnDemandEtwEvent = nullptr;
tLdrpValidateIntegrityContinuity LdrpValidateIntegrityContinuity = nullptr;
tLdrpSetModuleSigningLevel LdrpSetModuleSigningLevel = nullptr;
tLdrpCodeAuthzCheckDllAllowed LdrpCodeAuthzCheckDllAllowed = nullptr;
tLdrpGetFullPath LdrpGetFullPath = nullptr;
tLdrpAllocateUnicodeString LdrpAllocateUnicodeString = nullptr;
tLdrpAppendUnicodeStringToFilenameBuffer LdrpAppendUnicodeStringToFilenameBuffer = nullptr;
tLdrpGetNtPathFromDosPath LdrpGetNtPathFromDosPath = nullptr;
tLdrpFindLoadedDllByMappingLockHeld LdrpFindLoadedDllByMappingLockHeld = nullptr;
tLdrpInsertDataTableEntry LdrpInsertDataTableEntry = nullptr;
tLdrpInsertModuleToIndexLockHeld LdrpInsertModuleToIndexLockHeld = nullptr;
tLdrpLogEtwHotPatchStatus LdrpLogEtwHotPatchStatus = nullptr;
tLdrpLogNewDllLoad LdrpLogNewDllLoad = nullptr;
tLdrpProcessMachineMismatch LdrpProcessMachineMismatch = nullptr;
tRtlQueryImageFileKeyOption RtlQueryImageFileKeyOption = nullptr;
tRtlpImageDirectoryEntryToDataEx RtlpImageDirectoryEntryToDataEx = nullptr;
tLdrpLogDllRelocationEtwEvent LdrpLogDllRelocationEtwEvent = nullptr;
tLdrpNotifyLoadOfGraph LdrpNotifyLoadOfGraph = nullptr;
tLdrpDynamicShimModule LdrpDynamicShimModule = nullptr;
tLdrpAcquireLoaderLock LdrpAcquireLoaderLock = nullptr;
tLdrpReleaseLoaderLock LdrpReleaseLoaderLock = nullptr;
tLdrpCheckPagesForTampering LdrpCheckPagesForTampering = nullptr;
tLdrpLoadDependentModuleA LdrpLoadDependentModuleA = nullptr;
tLdrpLoadDependentModuleW LdrpLoadDependentModuleW = nullptr;
tLdrpQueueWork LdrpQueueWork = nullptr;
tLdrpHandleTlsData LdrpHandleTlsData = nullptr;
tLdrControlFlowGuardEnforcedWithExportSuppression LdrControlFlowGuardEnforcedWithExportSuppression = nullptr;
tLdrpUnsuppressAddressTakenIat LdrpUnsuppressAddressTakenIat = nullptr;
tLdrControlFlowGuardEnforced LdrControlFlowGuardEnforced = nullptr;
tRtlpxLookupFunctionTable RtlpxLookupFunctionTable = nullptr;
tLdrpCheckRedirection LdrpCheckRedirection = nullptr;
tCompatCachepLookupCdb CompatCachepLookupCdb = nullptr;
tLdrpGenRandom LdrpGenRandom = nullptr;
tLdrInitSecurityCookie LdrInitSecurityCookie = nullptr;
tLdrpCfgProcessLoadConfig LdrpCfgProcessLoadConfig = nullptr;
tRtlInsertInvertedFunctionTable RtlInsertInvertedFunctionTable = nullptr;
tLdrpSignalModuleMapped LdrpSignalModuleMapped = nullptr;
tAVrfDllLoadNotification AVrfDllLoadNotification = nullptr;
tLdrpSendDllNotifications LdrpSendDllNotifications = nullptr;
tLdrpCallTlsInitializers LdrpCallTlsInitializers = nullptr;
================================================
FILE: Src/Functions/NT.h
================================================
#pragma once
#include "..\Includes.h"
#include "..\WID.h"
#include "Undocumented.h"
#define NT_SUCCESS(x) ((x)>=0)
#define STATUS_SUCCESS 0x0
#define STATUS_IMAGE_NOT_AT_BASE 0x40000003
#define STATUS_IMAGE_AT_DIFFERENT_BASE 0x40000036
#define STATUS_IMAGE_MACHINE_TYPE_MISMATCH 0x4000000E
#define STATUS_DEVICE_OFF_LINE 0x80000010
#define STATUS_UNSUCCESSFUL 0xC0000001
#define STATUS_NOT_IMPLEMENTED 0xC0000002
#define STATUS_NO_SUCH_FILE 0xC000000F
#define STATUS_CONFLICTING_ADDRESSES 0xC0000018
#define STATUS_ACCESS_DENIED 0xC0000022
#define STATUS_OBJECT_NAME_NOT_FOUND 0xC0000034
#define STATUS_OBJECT_PATH_NOT_FOUND 0xC000003A
#define STATUS_PROCEDURE_NOT_FOUND 0xC000007A
#define STATUS_DEVICE_NOT_READY 0xC00000A3
#define STATUS_INVALID_IMAGE_FORMAT 0xC000007B
#define STATUS_NO_TOKEN 0xC000007C
#define STATUS_INSUFFICIENT_RESOURCES 0xC000009A
#define STATUS_NOT_SUPPORTED 0xC00000BB
#define STATUS_INTERNAL_ERROR 0xC00000E5
#define STATUS_NAME_TOO_LONG 0xC0000106
#define STATUS_COMMITMENT_LIMIT 0xC000012D
#define STATUS_NO_APPLICATION_PACKAGE 0xC00001AA
#define STATUS_RESOURCE_LANG_NOT_FOUND 0xC0000204
#define STATUS_NOT_FOUND 0xC0000225
#define STATUS_RETRY 0xC000022D
#define STATUS_INVALID_IMAGE_HASH 0xC0000428
#define STATUS_NEEDS_REMEDIATION 0xC0000462
#define STATUS_PATCH_CONFLICT 0xC00004AC
#define STATUS_IMAGE_LOADED_AS_PATCH_IMAGE 0xC00004C0
#define STATUS_INVALID_THREAD 0xC000071C
// Implemented.
extern DWORD* LdrpPolicyBits;
extern HANDLE* LdrpMainThreadToken;
extern DWORD* LdrInitState;
extern DWORD* LoadFailure;
extern PRTL_CRITICAL_SECTION LdrpWorkQueueLock;
extern DWORD* LdrpWorkInProgress;
extern LIST_ENTRY** LdrpWorkQueue;
extern PHANDLE LdrpWorkCompleteEvent;
extern KUSER_SHARED_DATA* kUserSharedData;
extern DWORD* LdrpUseImpersonatedDeviceMap;
extern DWORD* LdrpAuditIntegrityContinuity;
extern DWORD* LdrpEnforceIntegrityContinuity;
extern DWORD* LdrpFatalHardErrorCount;
extern DWORD* UseWOW64;
extern PRTL_SRWLOCK LdrpModuleDatatableLock;
extern PHANDLE qword_17E238;
extern LDR_DATA_TABLE_ENTRY** LdrpImageEntry;
extern PUNICODE_STRING LdrpKernel32DllName;
extern UINT_PTR* LdrpAppHeaders;
extern PHANDLE LdrpLargePageDllKeyHandle;
extern ULONG** LdrpLockMemoryPrivilege;
extern ULONG64* LdrpMaximumUserModeAddress;
extern UINT_PTR* LdrpMapAndSnapWork;
extern LIST_ENTRY* LdrpHashTable;
extern PVOID* LdrpHeap;
extern BOOLEAN* LdrpIsHotPatchingEnabled;
extern LDR_DATA_TABLE_ENTRY** LdrpRedirectionModule;
extern ULONG64** qword_1993A8;
extern LONG* NtdllBaseTag;
extern FUNCTION_TABLE_DATA* stru_199520;
extern UINT_PTR* qword_199530;
extern LDR_DATA_TABLE_ENTRY** LdrpNtDllDataTableEntry;
extern UINT_PTR* qword_1993B8;
extern DWORD* dword_19939C;
extern DWORD* LoadFailureOperational;
extern DWORD* dword_199398;
extern UINT_PTR*** qword_1843B8;
extern UINT_PTR* qword_1843B0;
extern UINT_PTR* LdrpCurrentDllInitializer;
extern LPVOID** LdrpProcessInitContextRecord;
extern PRTL_SRWLOCK LdrpTlsLock;
extern TLS_ENTRY** LdrpTlsList;
typedef NTSTATUS(__fastcall** tLdrpManifestProberRoutine)(PIMAGE_DOS_HEADER Base, PWCHAR, PVOID);
extern tLdrpManifestProberRoutine LdrpManifestProberRoutine;
typedef BOOLEAN(__fastcall** tLdrpRedirectionCalloutFunc)(PWCHAR Buffer);
extern tLdrpRedirectionCalloutFunc LdrpRedirectionCalloutFunc;
PEB* NtCurrentPeb();
VOID __fastcall NtdllpFreeStringRoutine(PWCH Buffer); // CHECKED.
NTSTATUS __fastcall LdrpFastpthReloadedDll(PUNICODE_STRING FullPath, ULONG Flags, PLDR_DATA_TABLE_ENTRY LdrEntry, LDR_DATA_TABLE_ENTRY** DllEntry);
NTSTATUS __fastcall LdrpIncrementModuleLoadCount(LDR_DATA_TABLE_ENTRY* LdrEntry);
VOID __fastcall RtlFreeUnicodeString(PUNICODE_STRING UnicodeString); // CHECKED.
VOID __fastcall LdrpFreeUnicodeString(PUNICODE_STRING String);
ULONG __fastcall RtlGetCurrentServiceSessionId(VOID); // CHECKED ?
USHORT __fastcall LdrpGetBaseNameFromFullName(PUNICODE_STRING BaseName, PUNICODE_STRING FullName);
PWCHAR __fastcall RtlGetNtSystemRoot();
BOOLEAN __fastcall LdrpHpatAllocationOptOut(PUNICODE_STRING FullDllName);
NTSTATUS __fastcall LdrpCorValidateImage(PIMAGE_DOS_HEADER DosHeader);
NTSTATUS __fastcall LdrpCorFixupImage(PIMAGE_DOS_HEADER DosHeader);
NTSTATUS __fastcall LdrpFindLoadedDllByNameLockHeld(PUNICODE_STRING BaseDllName, PUNICODE_STRING FullDllName, ULONG64 Flags, LDR_DATA_TABLE_ENTRY** pLdrEntry, ULONG BaseNameHashValue);
BOOLEAN __fastcall LdrpIsILOnlyImage(PIMAGE_DOS_HEADER DllBase);
VOID __fastcall LdrpAddNodeServiceTag(LDR_DDAG_NODE* DdagNode, UINT_PTR ServiceTag);
PIMAGE_LOAD_CONFIG_DIRECTORY LdrImageDirectoryEntryToLoadConfig(PIMAGE_DOS_HEADER DllBase);
BOOLEAN __fastcall LdrpShouldModuleImportBeRedirected(LDR_DATA_TABLE_ENTRY* DllEntry);
PIMAGE_IMPORT_DESCRIPTOR __fastcall LdrpGetImportDescriptorForSnap(LDRP_LOAD_CONTEXT* LoadContext);
NTSTATUS __fastcall LdrpMapCleanModuleView(LDRP_LOAD_CONTEXT* LoadContext);
LDR_DATA_TABLE_ENTRY* __fastcall LdrpHandleReplacedModule(LDR_DATA_TABLE_ENTRY* LdrEntry);
NTSTATUS __fastcall LdrpFreeReplacedModule(LDR_DATA_TABLE_ENTRY* LdrDataTableEntry);
VOID __fastcall LdrpHandlePendingModuleReplaced(LDRP_LOAD_CONTEXT* LoadContext);
PIMAGE_SECTION_HEADER __fastcall RtlSectionTableFromVirtualAddress(PIMAGE_NT_HEADERS NtHeader, PVOID Base, UINT_PTR Address);
PIMAGE_SECTION_HEADER __fastcall RtlAddressInSectionTable(PIMAGE_NT_HEADERS NtHeader, PVOID Base, UINT_PTR Address);
BOOLEAN __fastcall LdrpValidateEntrySection(LDR_DATA_TABLE_ENTRY* DllEntry);
BOOL __fastcall LdrpIsExecutableRelocatedImage(PIMAGE_DOS_HEADER DllBase);
TLS_ENTRY* __fastcall LdrpFindTlsEntry(LDR_DATA_TABLE_ENTRY* LdrEntry);
BOOL __fastcall ImageTlsCallbackCaller(HINSTANCE hInstDll, DWORD fdwReason, LPVOID lpvReserved);
extern "C" NTSTATUS __fastcall ZwSystemDebugControl();
extern "C" NTSTATUS __fastcall NtCreateSection(PHANDLE SectionHandle, ACCESS_MASK DesiredAccess, OBJECT_ATTRIBUTES * ObjectAttributes, PLARGE_INTEGER MaximumSize, ULONG SectionPageProtection, ULONG AllocationAttributes, HANDLE FileHandle);
extern "C" NTSTATUS __fastcall ZwMapViewOfSection(HANDLE SectionHandle, HANDLE ProcessHandle, PIMAGE_DOS_HEADER * BaseAddress, ULONG64 ZeroBits, ULONG64 CommitSize, PLARGE_INTEGER SectionOffset, PULONG ViewSize, SECTION_INHERIT InheritDisposition, ULONG64 AllocationType, ULONG64 Protect);
extern "C" NTSTATUS __fastcall ZwMapViewOfSectionEx(HANDLE SectionHandle, HANDLE ProcessHandle, PIMAGE_DOS_HEADER * DllBase, PLARGE_INTEGER a4, PULONG ViewSize, ULONG a6, ULONG a7, MEM_EXTENDED_PARAMETER * MemExtendedParam, ULONG a9);
extern "C" NTSTATUS __fastcall NtUnmapViewOfSection(HANDLE ProcessHandle, PVOID BaseAddress);
extern "C" NTSTATUS __fastcall ZwProtectVirtualMemory(HANDLE ProcessHandle, PVOID * BaseAddress, PULONG ProtectSize, ULONG NewProtect, PULONG OldProtect);
extern "C" NTSTATUS __fastcall ZwQueryVirtualMemory(HANDLE ProcessHandle, PVOID BaseAddress, MEMORY_INFORMATION_CLASS MemoryInformationClass, PVOID MemoryInformation, SIZE_T MemoryInformationLength, PSIZE_T ReturnLength);
extern "C" NTSTATUS __fastcall NtQueryInformationProcess(HANDLE ProcessHandle, PROCESSINFOCLASS ProcessInformationClass, PVOID ProcessInformation, ULONG ProcessInformationLength, PULONG ReturnLength);
// Planning to implement them all in the future.
typedef NTSTATUS(__fastcall* tNtOpenThreadToken)(IN HANDLE ThreadHandle, IN ACCESS_MASK DesiredAccess, IN BOOLEAN OpenAsSelf, OUT PHANDLE TokenHandle);
extern tNtOpenThreadToken NtOpenThreadToken;
typedef NTSTATUS(__fastcall* tNtClose)(HANDLE Handle);
extern tNtClose NtClose;
typedef PVOID(__fastcall* tRtlAllocateHeap)(IN PVOID HeapHandle, IN OPTIONAL ULONG Flags, IN SIZE_T Size);
extern tRtlAllocateHeap RtlAllocateHeap;
typedef BOOLEAN(__fastcall* tRtlFreeHeap)(IN PVOID HeapHandle, IN OPTIONAL ULONG Flags, _Frees_ptr_opt_ PVOID BaseAddress);
extern tRtlFreeHeap RtlFreeHeap;
typedef NTSTATUS(__fastcall* tLdrGetDllPath)(PWCH DllName, DWORD dwFlags, PWSTR* Path, PWSTR* Unknown);
extern tLdrGetDllPath LdrGetDllPath;
typedef VOID(__fastcall* tRtlReleasePath)(IN PWSTR);
extern tRtlReleasePath RtlReleasePath;
typedef NTSTATUS(__fastcall* tRtlInitUnicodeStringEx)(PUNICODE_STRING target, PCWSTR source);
extern tRtlInitUnicodeStringEx RtlInitUnicodeStringEx;
typedef NTSTATUS(__fastcall* tRtlEnterCriticalSection)(PRTL_CRITICAL_SECTION CriticalSection);
extern tRtlEnterCriticalSection RtlEnterCriticalSection;
typedef NTSTATUS(__fastcall* tRtlLeaveCriticalSection)(PRTL_CRITICAL_SECTION CriticalSection);
extern tRtlLeaveCriticalSection RtlLeaveCriticalSection;
typedef NTSTATUS(__fastcall* tZwSetEvent)(HANDLE EventHandle, PLONG PreviousState);
extern tZwSetEvent ZwSetEvent;
typedef NTSTATUS(__fastcall* tNtOpenFile)(PHANDLE FileHandle, ACCESS_MASK DesiredAccess, OBJECT_ATTRIBUTES* ObjectAttributes, PIO_STATUS_BLOCK IoStatusBlock, ULONG ShareAccess, ULONG OpenOptions);
extern tNtOpenFile NtOpenFile;
typedef NTSTATUS(__fastcall* tLdrAppxHandleIntegrityFailure)(NTSTATUS Status);
extern tLdrAppxHandleIntegrityFailure LdrAppxHandleIntegrityFailure;
typedef NTSTATUS(__fastcall* tNtRaiseHardError)(NTSTATUS Status, ULONG NumberOfParameters, ULONG UnicodeStringParameterMask, INT* Parameters, HARDERROR_RESPONSE_OPTION ValidResponseOption, HARDERROR_RESPONSE* Response);
extern tNtRaiseHardError NtRaiseHardError;
typedef NTSTATUS(__fastcall* tRtlImageNtHeaderEx)(ULONG Flags, PVOID Base, ULONG64 Size, PIMAGE_NT_HEADERS* OutHeaders);
extern tRtlImageNtHeaderEx RtlImageNtHeaderEx;
typedef VOID(__fastcall* tRtlAcquireSRWLockExclusive)(PRTL_SRWLOCK SRWLock);
extern tRtlAcquireSRWLockExclusive RtlAcquireSRWLockExclusive;
typedef NTSTATUS(__fastcall* tRtlReleaseSRWLockExclusive)(PRTL_SRWLOCK SRWLock);
extern tRtlReleaseSRWLockExclusive RtlReleaseSRWLockExclusive;
typedef NTSTATUS(__fastcall* tRtlEqualUnicodeString)(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive);
extern tRtlEqualUnicodeString RtlEqualUnicodeString;
typedef NTSTATUS(__fastcall* tRtlAcquirePrivilege)(ULONG* Privilege,ULONG NumPriv,ULONG Flags,PVOID * ReturnedState);
extern tRtlAcquirePrivilege RtlAcquirePrivilege;
typedef VOID(__fastcall* tRtlReleasePrivilege)(PVOID ReturnedState);
extern tRtlReleasePrivilege RtlReleasePrivilege;
typedef NTSTATUS(__fastcall* tRtlCompareUnicodeStrings)(PWCH String1, UINT_PTR String1Length, PWCH String2, UINT_PTR String2Length, BOOLEAN CaseInSensitive);
extern tRtlCompareUnicodeStrings RtlCompareUnicodeStrings;
typedef PIMAGE_NT_HEADERS(__fastcall* tRtlImageNtHeader)(PIMAGE_DOS_HEADER DosHeader);
extern tRtlImageNtHeader RtlImageNtHeader;
typedef UINT_PTR(__fastcall* tRtlReleaseActivationContext)(ACTIVATION_CONTEXT* ActivationContext);
extern tRtlReleaseActivationContext RtlReleaseActivationContext;
typedef NTSTATUS(__fastcall* tRtlCharToInteger)(const PCHAR String, ULONG Base, PULONG Value);
extern tRtlCharToInteger RtlCharToInteger;
typedef NTSTATUS(__fastcall* tRtlActivateActivationContextUnsafeFast)(RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED* StackFrameExtended, ACTIVATION_CONTEXT* ActivationContext);
extern tRtlActivateActivationContextUnsafeFast RtlActivateActivationContextUnsafeFast;
typedef VOID(__fastcall* tRtlDeactivateActivationContextUnsafeFast)(RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED* StackFrameExtended);
extern tRtlDeactivateActivationContextUnsafeFast RtlDeactivateActivationContextUnsafeFast;
typedef NTSTATUS(__fastcall* tRtlAcquireSRWLockShared)(PRTL_SRWLOCK SrwLock);
extern tRtlAcquireSRWLockShared RtlAcquireSRWLockShared;
typedef NTSTATUS(__fastcall* tRtlReleaseSRWLockShared)(PRTL_SRWLOCK SrwLock);
extern tRtlReleaseSRWLockShared RtlReleaseSRWLockShared;
// Signatured
#define LDRP_LOG_INTERNAL_PATTERN "\x89\x54\x24\x10\x4C\x8B\xDC\x49\x89\x4B\x08"
typedef NTSTATUS(__fastcall* tLdrpLogInternal)(PCHAR, ULONG, PCHAR, ULONG, PCHAR, ...);
extern tLdrpLogInternal LdrpLogInternal;
#define LDRP_INITIALIZE_DLLPATH_PATTERN "\x48\x89\x5C\x24\x08\x48\x89\x74\x24\x10\x57\x48\x83\xEC\x30\x49\x8B\xF8\x48\x8B\xDA\x48\x8B\xF1"
typedef NTSTATUS(__fastcall* tLdrpInitializeDllPath)(PWSTR DllName, PWSTR DllPath, LDR_UNKSTRUCT* ReturnPath);
extern tLdrpInitializeDllPath LdrpInitializeDllPath;
#define LDRP_DEREFERENCE_MODULE_PATTERN "\x48\x89\x5C\x24\x08\x48\x89\x6C\x24\x10\x48\x89\x74\x24\x18\x57\x48\x83\xEC\x20\x48\x8B\x81\x98\x00\x00\x00"
typedef NTSTATUS(__fastcall* tLdrpDereferenceModule)(LDR_DATA_TABLE_ENTRY* DllEntry);
extern tLdrpDereferenceModule LdrpDereferenceModule;
#define LDRP_LOG_DLLSTATE_PATTERN "\x48\x89\x5C\x24\x08\x48\x89\x74\x24\x10\x57\x48\x83\xEC\x30\x65\x48\x8B\x04\x25\x60\x00\x00\x00\x41"
typedef NTSTATUS(__fastcall* tLdrpLogDllState)(UINT_PTR, PUNICODE_STRING, ULONG);
extern tLdrpLogDllState LdrpLogDllState;
#define LDRP_PREPROCESS_DLLNAME_PATTERN "\x4C\x8B\xDC\x49\x89\x5B\x08\x49\x89\x6B\x10\x49\x89\x73\x18\x57\x41\x54\x41\x55\x41\x56\x41\x57\x48\x83\xEC\x40"
typedef NTSTATUS(__fastcall* tLdrpPreprocessDllName)(PUNICODE_STRING DllName, PUNICODE_STRING ResName, PULONG pZero, PULONG pFlags);
extern tLdrpPreprocessDllName LdrpPreprocessDllName;
#define LDRP_FIND_LOADEDDLLBYNAME_PATTERN "\x48\x8B\xC4\x53\x55\x41\x57\x48\x83\xEC\x50"
typedef NTSTATUS(__fastcall* tLdrpFindLoadedDllByName)(PUNICODE_STRING FullPath, PUNICODE_STRING DllName, USHORT Flags, LDR_DATA_TABLE_ENTRY** DllEntry, LDR_DDAG_STATE* ReturnStatus);
extern tLdrpFindLoadedDllByName LdrpFindLoadedDllByName;
#define LDRP_DRAIN_WORKQUEUE_PATTERN "\x48\x89\x5C\x24\x08\x48\x89\x6C\x24\x10\x48\x89\x74\x24\x18\x57\x41\x54\x41\x56\x48\x83\xEC\x20\x4C\x8B\x35\x35\xA3\x15\x00"
typedef TEB* (__fastcall* tLdrpDrainWorkQueue)(DRAIN_TASK DrainTask);
extern tLdrpDrainWorkQueue LdrpDrainWorkQueue;
#define LDRP_FIND_LOADEDDLL_BYHANDLE_PATTERN "\x48\x89\x5C\x24\x08\x48\x89\x74\x24\x10\x48\x89\x7C\x24\x18\x41\x56\x48\x83\xEC\x20\x33\xDB\x49\x8B\xF8\x4C\x8B\xF2"
typedef NTSTATUS(__fastcall* tLdrpFindLoadedDllByHandle)(unsigned __int64 a1, PLDR_DATA_TABLE_ENTRY* ppLdrEntry, DWORD* a3);
extern tLdrpFindLoadedDllByHandle LdrpFindLoadedDllByHandle;
#define LDRP_DROP_LASTINPROGRESS_COUNT_PATTERN "\x48\x83\xEC\x28\x65\x48\x8B\x04\x25\x30\x00\x00\x00\xB9\xFF\xEF\x00\x00"
typedef NTSTATUS(__fastcall* tLdrpDropLastInProgressCount)();
extern tLdrpDropLastInProgressCount LdrpDropLastInProgressCount;
#define LDRP_QUERY_CURRENT_PATCH_PATTERN "\x48\x8B\xC4\x48\x89\x58\x08\x48\x89\x70\x10\x48\x89\x78\x20\x55\x41\x56"
typedef NTSTATUS(__fastcall* tLdrpQueryCurrentPatch)(ULONG Checksum, ULONG TimeDateStamp, PUNICODE_STRING FullPath);
extern tLdrpQueryCurrentPatch LdrpQueryCurrentPatch;
#define LDRP_UNDO_PATCH_IMAGE_PATTERN "\x4C\x8B\xDC\x53\x48\x83\xEC\x40\x48\x8B\x41\x30\x4D\x8D\x4B\x08"
typedef NTSTATUS(__fastcall* tLdrpUndoPatchImage)(PLDR_DATA_TABLE_ENTRY LdrEntry);
extern tLdrpUndoPatchImage LdrpUndoPatchImage;
#define LDRP_DETECT_DETOUR_PATTERN "\x40\x57\x48\x83\xEC\x30\x80\x3D\x87\x32\x11\x00\x00\x75\x7B"
typedef VOID(__fastcall* tLdrpDetectDetour)();
extern tLdrpDetectDetour LdrpDetectDetour;
#define LDRP_FINDORPREPARE_LOADINGMODULE_PATTERN "\x48\x8B\xC4\x48\x89\x58\x08\x48\x89\x68\x10\x48\x89\x70\x20\x57\x41\x56\x41\x57\x48\x83\xEC\x50"
typedef NTSTATUS(__fastcall* tLdrpFindOrPrepareLoadingModule)(PUNICODE_STRING FullPath, LDR_UNKSTRUCT* DllPathInited, ULONG Flags, ULONG LdrFlags, PLDR_DATA_TABLE_ENTRY LdrEntry, PLDR_DATA_TABLE_ENTRY* pLdrEntryLoaded, NTSTATUS* pStatus);
extern tLdrpFindOrPrepareLoadingModule LdrpFindOrPrepareLoadingModule;
#define LDRP_FREE_LOAD_CONTEXT_PATTERN "\x48\x89\x5C\x24\x08\x57\x48\x83\xEC\x20\x48\x8B\x41\x38\x48\x8B\xD9\x48\x83\xA0\xB0\x00\x00\x00"
typedef VOID(__fastcall* tLdrpFreeLoadContext)(PLDRP_LOAD_CONTEXT LoadContext);
extern tLdrpFreeLoadContext LdrpFreeLoadContext;
#define LDRP_CONDENSE_GRAPH_PATTERN "\x48\x8B\xC4\x48\x83\xEC\x28\x83\x79\x38\x06\x7D\x19"
typedef PVOID* (__fastcall* tLdrpCondenseGraph)(LDR_DDAG_NODE* DdagNode);
extern tLdrpCondenseGraph LdrpCondenseGraph;
#define LDRP_BUILD_FORWARDER_LINK_PATTERN "\x48\x89\x5C\x24\x10\x48\x89\x74\x24\x18\x57\x48\x83\xEC\x20\x33\xDB\x48\x8B\xF2"
typedef NTSTATUS(__fastcall* tLdrpBuildForwarderLink)(PLDR_DATA_TABLE_ENTRY LdrEntry, PLDR_DATA_TABLE_ENTRY LdrEntry2);
extern tLdrpBuildForwarderLink LdrpBuildForwarderLink;
#define LDRP_PIN_MODULE_PATTERN "\x48\x89\x5C\x24\x08\x57\x48\x83\xEC\x20\x48\x8B\xD9\x33\xFF\x48\x8D\x0D\x02\xBB\x10\x00"
typedef NTSTATUS(__fastcall* tLdrpPinModule)(PLDR_DATA_TABLE_ENTRY LdrEntry);
extern tLdrpPinModule LdrpPinModule;
#define LDRP_APPLY_PATCH_IMAGE_PATTERN "\x48\x89\x5C\x24\x10\x48\x89\x7C\x24\x18\x55\x41\x56\x41\x57\x48\x8B\xEC"
typedef NTSTATUS(__fastcall* tLdrpApplyPatchImage)(PLDR_DATA_TABLE_ENTRY LdrEntry);
extern tLdrpApplyPatchImage LdrpApplyPatchImage;
#define LDRP_FREE_LOADCONTEXT_NODE_PATTERN "\x48\x89\x5C\x24\x08\x48\x89\x74\x24\x10\x57\x48\x83\xEC\x20\x48\x8B\x19\x48\x8B\xF2"
typedef NTSTATUS(__fastcall* tLdrpFreeLoadContextOfNode)(PLDR_DDAG_NODE DdagNode, NTSTATUS* pStatus);
extern tLdrpFreeLoadContextOfNode LdrpFreeLoadContextOfNode;
#define LDRP_DECREMENT_MODULELOADCOUNTEX_PATTERN "\x48\x89\x5C\x24\x08\x57\x48\x83\xEC\x20\x8B\xFA\x48\x8B\xD9\x85\xD2"
typedef NTSTATUS(__fastcall* tLdrpDecrementModuleLoadCountEx)(PLDR_DATA_TABLE_ENTRY LdrEntry, PLDR_DATA_TABLE_ENTRY LdrEntry2);
extern tLdrpDecrementModuleLoadCountEx LdrpDecrementModuleLoadCountEx;
#define LDRP_LOG_ERROR_PATTERN "\x48\x89\x5C\x24\x08\x48\x89\x6C\x24\x10\x48\x89\x74\x24\x18\x57\x48\x83\xEC\x30\x49\x8B\xD9"
typedef PEB*(__fastcall* tLdrpLogError)(NTSTATUS Status, ULONG, ULONG, PVOID);
extern tLdrpLogError LdrpLogError;
#define LDRP_LOG_DEPRECATED_DLL_PATTERN "\x48\x89\x5C\x24\x10\x48\x89\x6C\x24\x18\x48\x89\x74\x24\x20\x57\x48\x83\xEC\x40"
typedef WCHAR*(__fastcall* tLdrpLogDeprecatedDllEtwEvent)(PLDRP_LOAD_CONTEXT LoadContext);
extern tLdrpLogDeprecatedDllEtwEvent LdrpLogDeprecatedDllEtwEvent;
#define LDRP_LOG_LOAD_FAILURE_PATTERN "\x48\x89\x5C\x24\x08\x44\x89\x44\x24\x18\x55\x56\x57\x48\x8B\xEC\x48\x83\xEC\x70"
typedef VOID(__fastcall* tLdrpLogLoadFailureEtwEvent)(PVOID Unknown, PVOID Unknown2, NTSTATUS Status, PVOID LoadFailure, ULONG Unknown3);
extern tLdrpLogLoadFailureEtwEvent LdrpLogLoadFailureEtwEvent;
#define LDRP_REPORT_ERROR_PATTERN "\x48\x89\x5C\x24\x20\x55\x56\x57\x41\x54\x41\x55\x41\x56\x41\x57\x48\x8D\xAC\x24\x50\xFF\xFF\xFF\x48\x81\xEC\xB0\x01\x00\x00\x48\x8B\x05\xEE\x08\x19\x00"
typedef NTSTATUS(__fastcall* tLdrpReportError)(PVOID Report, ULONG Unknown, NTSTATUS Status);
extern tLdrpReportError LdrpReportError;
#define LDRP_RESOLVE_DLLNAME_PATTERN "\x4C\x8B\xDC\x49\x89\x5B\x08\x49\x89\x6B\x10\x49\x89\x73\x20\x4D\x89\x43\x18\x57\x41\x54\x41\x55\x41\x56"
typedef NTSTATUS(__fastcall* tLdrpResolveDllName)(PLDRP_LOAD_CONTEXT FileName, LDRP_FILENAME_BUFFER* FileNameBuffer, PUNICODE_STRING FullName, PUNICODE_STRING ResolvedName, DWORD Flags);
extern tLdrpResolveDllName LdrpResolveDllName;
#define LDRP_APP_COMPAT_REDIRECT_PATTERN "\x48\x89\x5C\x24\x08\x48\x89\x6C\x24\x10\x48\x89\x74\x24\x18\x57\x41\x56\x41\x57\x48\x83\xEC\x50\x45\x33\xFF\x49\x8B\xF1\x44\x38\x3D\xC3\x3A\x17\x00"
typedef NTSTATUS(__fastcall* tLdrpAppCompatRedirect)(PLDRP_LOAD_CONTEXT LoadContext, PUNICODE_STRING FullDllName, PUNICODE_STRING BaseDllName, LDRP_FILENAME_BUFFER* FileNameBuffer, NTSTATUS Status);
extern tLdrpAppCompatRedirect LdrpAppCompatRedirect;
#define LDRP_HASH_UNICODE_STRING_PATTERN "\x48\x89\x5C\x24\x08\x57\x48\x83\xEC\x20\x45\x33\xDB"
typedef ULONG(__fastcall* tLdrpHashUnicodeString)(PUNICODE_STRING BaseDllName);
extern tLdrpHashUnicodeString LdrpHashUnicodeString;
#define LDRP_FIND_EXISTING_MODULE_PATTERN "\x48\x8B\xC4\x48\x89\x58\x08\x48\x89\x68\x10\x48\x89\x70\x18\x48\x89\x78\x20\x41\x56\x48\x83\xEC\x30\x48\x8B\x7C\x24\x60\x48\x8B\xD9"
typedef NTSTATUS(__fastcall* tLdrpFindExistingModule)(PUNICODE_STRING BaseDllName, PUNICODE_STRING FullDllName, UINT64 Flags, ULONG BaseDllNameHash, PLDR_DATA_TABLE_ENTRY* LoadedDll);
extern tLdrpFindExistingModule LdrpFindExistingModule;
#define LDRP_LOADCONTEXT_REPLACE_MODULE_PATTERN "\x48\x89\x5C\x24\x08\x48\x89\x6C\x24\x10\x48\x89\x74\x24\x18\x57\x48\x83\xEC\x20\x48\x8B\xD9\x48\x8B\xF2"
typedef NTSTATUS(__fastcall* tLdrpLoadContextReplaceModule)(PLDRP_LOAD_CONTEXT LoadContext, PLDR_DATA_TABLE_ENTRY LoadedDll);
extern tLdrpLoadContextReplaceModule LdrpLoadContextReplaceModule;
#define LDRP_SEARCHPATH_PATTERN "\x48\x89\x5C\x24\x18\x55\x56\x57\x41\x54\x41\x55\x41\x56\x41\x57\x48\x8D\x6C\x24\xF9\x48\x81\xEC\xD0\x00\x00\x00"
typedef NTSTATUS(__fastcall* tLdrpSearchPath)(LDRP_LOAD_CONTEXT* LoadContext, LDR_UNKSTRUCT* UnkStruct, ULONG Flags, PUNICODE_STRING ReturnPath, LDRP_FILENAME_BUFFER* FileName, PUNICODE_STRING BaseDllName, PUNICODE_STRING UnkStruct3_String, BOOL* a8, LDR_UNKSTRUCT3* UnkStruct3);
extern tLdrpSearchPath LdrpSearchPath;
#define LDRP_ISSECURITYETW_LOGG_ENABLED_PATTERN "\x48\x89\x5C\x24\x08\x48\x89\x74\x24\x10\x57\x48\x83\xEC\x20\xE8\x04\xA2\x02\x00"
typedef BOOLEAN(__fastcall* tLdrpIsSecurityEtwLoggingEnabled)();
extern tLdrpIsSecurityEtwLoggingEnabled LdrpIsSecurityEtwLoggingEnabled;
#define LDRP_LOGETW_DLL_SEARCHRESULTS_PATTERN "\x48\x89\x5C\x24\x08\x55\x56\x57\x41\x54\x41\x55\x41\x56\x41\x57\x48\x8B\xEC\x48\x83\xEC\x60\x44\x8B\xF9"
typedef VOID(__fastcall* tLdrpLogEtwDllSearchResults)(ULONG Flags, LDRP_LOAD_CONTEXT* LoadContext);
extern tLdrpLogEtwDllSearchResults LdrpLogEtwDllSearchResults;
#define LDRP_CHECKFORRETRY_LOADING_PATTERN "\x48\x89\x5C\x24\x08\x48\x89\x6C\x24\x10\x48\x89\x74\x24\x18\x57\x41\x54\x41\x55\x41\x56\x41\x57\x48\x83\xEC\x20\x33\xDB\x44\x8A\xFA"
typedef BOOLEAN(__fastcall* tLdrpCheckForRetryLoading)(PLDRP_LOAD_CONTEXT LoadContext, BOOLEAN Unknown);
extern tLdrpCheckForRetryLoading LdrpCheckForRetryLoading;
#define LDRP_LOG_ETWEVENT_PATTERN "\x48\x89\x5C\x24\x08\x48\x89\x6C\x24\x10\x48\x89\x74\x24\x18\x57\x41\x54\x41\x55\x41\x56\x41\x57\x48\x81\xEC\x80\x02\x00\x00"
typedef NTSTATUS(__fastcall* tLdrpLogEtwEvent)(ULONG a1, ULONGLONG a2, ULONG a3, ULONG a4);
extern tLdrpLogEtwEvent LdrpLogEtwEvent;
#define LDRP_CHECK_COMPONENTONDEMAND_PATTERN "\x48\x89\x5C\x24\x10\x48\x89\x74\x24\x18\x55\x57\x41\x56\x48\x8B\xEC\x48\x81\xEC\x80\x00\x00\x00"
typedef BOOLEAN(__fastcall* tLdrpCheckComponentOnDemandEtwEvent)(LDRP_LOAD_CONTEXT* LoadContext);
extern tLdrpCheckComponentOnDemandEtwEvent LdrpCheckComponentOnDemandEtwEvent;
#define LDRP_VALIDATE_INTEGRITY_PATTERN "\x44\x88\x44\x24\x18\x53\x56\x57\x48\x83\xEC\x30"
typedef NTSTATUS(__fastcall* tLdrpValidateIntegrityContinuity)(PLDRP_LOAD_CONTEXT LoadContext, HANDLE FileHandle);
extern tLdrpValidateIntegrityContinuity LdrpValidateIntegrityContinuity;
#define LDRP_SET_MODULE_SIGNINGLEVEL_PATTERN "\x4C\x8B\xDC\x49\x89\x5B\x10\x49\x89\x73\x18\x49\x89\x7B\x20\x49\x89\x4B\x08\x41\x56"
typedef NTSTATUS(__fastcall* tLdrpSetModuleSigningLevel)(HANDLE FileHandle, PLDR_DATA_TABLE_ENTRY LoadContext, PULONG pSigningLevel, ULONG NewSigningLevelMaybe);
extern tLdrpSetModuleSigningLevel LdrpSetModuleSigningLevel;
#define LDRP_CODE_AUTHZCHECKDLL_ALLOWED_PATTERN "\x48\x83\x3D\xC8\x44\x17\x00\x00\x4C\x8B\xCA"
typedef NTSTATUS(__fastcall* tLdrpCodeAuthzCheckDllAllowed)(LDRP_FILENAME_BUFFER* pFileNameBuffer, HANDLE FileHandle);
extern tLdrpCodeAuthzCheckDllAllowed LdrpCodeAuthzCheckDllAllowed;
#define LDRP_GET_FULLPATH_PATTERN "\x4C\x8B\xDC\x49\x89\x5B\x08\x55\x56\x57\x41\x56\x41\x57\x48\x83\xEC\x30"
typedef NTSTATUS(__fastcall* tLdrpGetFullPath)(PLDRP_LOAD_CONTEXT LoadContext, PUNICODE_STRING FullPath);
extern tLdrpGetFullPath LdrpGetFullPath;
#define LDRP_ALLOCATE_UNICODESTRING_PATTERN "\x48\x89\x5C\x24\x08\x48\x89\x74\x24\x10\x57\x48\x83\xEC\x20\x33\xDB\x8D\x7A\x02"
typedef NTSTATUS(__fastcall* tLdrpAllocateUnicodeString)(PUNICODE_STRING Allocated, USHORT Length);
extern tLdrpAllocateUnicodeString LdrpAllocateUnicodeString;
#define LDRP_APPEND_UNICODETOFILENAME_PATTERN "\x48\x8B\xC4\x48\x89\x58\x08\x48\x89\x68\x10\x48\x89\x70\x18\x48\x89\x78\x20\x41\x56\x48\x83\xEC\x20\x45\x33\xF6\x48\x8B\xEA"
typedef NTSTATUS(__fastcall* tLdrpAppendUnicodeStringToFilenameBuffer)(PUNICODE_STRING FileName, PLDRP_LOAD_CONTEXT LoadContext);
extern tLdrpAppendUnicodeStringToFilenameBuffer LdrpAppendUnicodeStringToFilenameBuffer;
#define LDRP_GET_NTPATH_FROM_DOSPATH_PATTERN "\x48\x89\x5C\x24\x18\x55\x56\x57\x48\x8D\x6C\x24\xB9\x48\x81\xEC\xC0\x00\x00\x00"
typedef NTSTATUS(__fastcall* tLdrpGetNtPathFromDosPath)(PUNICODE_STRING DosPath, LDRP_FILENAME_BUFFER* NtPath);
extern tLdrpGetNtPathFromDosPath LdrpGetNtPathFromDosPath;
#define LDRP_FIND_LOADEDDLL_MAPLOCK_PATTERN "\x48\x89\x5C\x24\x08\x48\x89\x6C\x24\x10\x48\x89\x74\x24\x18\x57\x41\x56\x41\x57\x48\x83\xEC\x30\x4C\x8B\x15\xFD\x89\x15\x00"
typedef NTSTATUS(__fastcall* tLdrpFindLoadedDllByMappingLockHeld)(PIMAGE_DOS_HEADER DllBase, PIMAGE_NT_HEADERS OutHeaders, PVOID Unknown, PLDR_DATA_TABLE_ENTRY* pLdrEntry);
extern tLdrpFindLoadedDllByMappingLockHeld LdrpFindLoadedDllByMappingLockHeld;
#define LDRP_INSERT_DATATABLEENTRY_PATTERN "\x40\x53\x48\x83\xEC\x20\xF6\x41\x68\x40"
typedef VOID(__fastcall* tLdrpInsertDataTableEntry)(PLDR_DATA_TABLE_ENTRY LdrEntry);
extern tLdrpInsertDataTableEntry LdrpInsertDataTableEntry;
#define LDRP_INSERT_MODTOIDX_LOCKHELD_PATTERN "\x48\x89\x5C\x24\x08\x57\x48\x83\xEC\x20\x44\x8B\x4A\x08"
typedef NTSTATUS(__fastcall* tLdrpInsertModuleToIndexLockHeld)(PLDR_DATA_TABLE_ENTRY LdrEntry, PIMAGE_NT_HEADERS OutHeaders);
extern tLdrpInsertModuleToIndexLockHeld LdrpInsertModuleToIndexLockHeld;
#define LDRP_LOGETW_HOTPATCHSTATUS_PATTERN "\x48\x8B\xC4\x48\x89\x58\x08\x48\x89\x70\x10\x48\x89\x78\x18\x4C\x89\x60\x20\x55\x41\x56\x41\x57\x48\x8D\x68\x98"
typedef NTSTATUS(__fastcall* tLdrpLogEtwHotPatchStatus)(PUNICODE_STRING BaseDllName, LDR_DATA_TABLE_ENTRY* LdrEntry, PUNICODE_STRING FullDllName, NTSTATUS Status, ULONG Unknown);
extern tLdrpLogEtwHotPatchStatus LdrpLogEtwHotPatchStatus;
#define LDRP_LOG_NEWDLL_LOAD_PATTERN "\x48\x8B\xC4\x48\x89\x58\x08\x48\x89\x68\x10\x48\x89\x70\x18\x48\x89\x78\x20\x41\x56\x48\x83\xEC\x30\x48\x8B\xEA\x4C\x8B\xF1"
typedef PEB*(__fastcall* tLdrpLogNewDllLoad)(LDR_DATA_TABLE_ENTRY* LdrEntry, LDR_DATA_TABLE_ENTRY* LdrEntry2);
extern tLdrpLogNewDllLoad LdrpLogNewDllLoad;
#define LDRP_PROCESS_MACHINE_MISMATCH_PATTERN "\x40\x53\x55\x57\x48\x83\xEC\x40\x48\x8B\x59\x38"
typedef NTSTATUS(__fastcall* tLdrpProcessMachineMismatch)(PLDRP_LOAD_CONTEXT LoadContext);
extern tLdrpProcessMachineMismatch LdrpProcessMachineMismatch;
#define RTL_QUERY_IMAGEFILE_KEYOPT_PATTERN "\x48\x89\x5C\x24\x10\x55\x56\x57\x41\x54\x41\x55\x41\x56\x41\x57\x48\x8D\xAC\x24\xA0\xFC\xFF\xFF"
typedef NTSTATUS(__fastcall* tRtlQueryImageFileKeyOption)(HANDLE hKey, PCWSTR lpszOption, ULONG dwType, PVOID lpData, ULONG cbData, ULONG* lpcbData);
extern tRtlQueryImageFileKeyOption RtlQueryImageFileKeyOption;
#define RTLP_IMAGEDIR_ENTRYTODATA_PATTERN "\x4C\x8B\xDC\x49\x89\x5B\x10\x49\x89\x6B\x18\x49\x89\x73\x20\x57\x41\x56\x41\x57\x48\x83\xEC\x20\x4C\x8B\x74\x24\x60"
typedef NTSTATUS(__fastcall* tRtlpImageDirectoryEntryToDataEx)(PIMAGE_DOS_HEADER DllBase, BOOLEAN Unknown, WORD Characteristics, ULONG64* LastRVASection, PVOID OutHeader);
extern tRtlpImageDirectoryEntryToDataEx RtlpImageDirectoryEntryToDataEx;
#define LDRP_LOG_DLLRELOCATION_PATTERN "\x48\x89\x5C\x24\x08\x48\x89\x6C\x24\x10\x48\x89\x74\x24\x18\x57\x41\x54\x41\x55\x41\x56\x41\x57\x48\x83\xEC\x20\x4D\x8B\xF1"
typedef PVOID(__fastcall* tLdrpLogDllRelocationEtwEvent)(PUNICODE_STRING FullDllName, ULONGLONG ImageBase, PIMAGE_DOS_HEADER DllBase, SIZE_T Size);
extern tLdrpLogDllRelocationEtwEvent LdrpLogDllRelocationEtwEvent;
#define LDRP_NOTIFY_LOADOFGRAPH_PATTERN "\x48\x89\x5C\x24\x10\x48\x89\x74\x24\x18\x57\x48\x83\xEC\x20\x48\x8B\x71\x28\x48\x8B\xF9"
typedef NTSTATUS(__fastcall* tLdrpNotifyLoadOfGraph)(LDR_DDAG_NODE* DdagNode);
extern tLdrpNotifyLoadOfGraph LdrpNotifyLoadOfGraph;
#define LDRP_DYNAMIC_SHIMMODULE_PATTERN "\x48\x89\x5C\x24\x08\x48\x89\x6C\x24\x18\x48\x89\x74\x24\x20\x57\x41\x56\x41\x57\x48\x83\xEC\x40"
typedef NTSTATUS(__fastcall* tLdrpDynamicShimModule)(LDR_DDAG_NODE* DdagNode);
extern tLdrpDynamicShimModule LdrpDynamicShimModule;
#define LDRP_ACQUIRE_LOADERLOCK_PATTERN "\x48\x89\x5C\x24\x08\x48\x89\x74\x24\x10\x57\x48\x83\xEC\x30\xE8\xE4\x9E\xFE\xFF"
typedef NTSTATUS(__fastcall* tLdrpAcquireLoaderLock)();
extern tLdrpAcquireLoaderLock LdrpAcquireLoaderLock;
#define LDRP_RELEASE_LOADER_LOCK_PATTERN "\x48\x89\x5C\x24\x08\x48\x89\x74\x24\x10\x57\x48\x83\xEC\x30\x48\x8D\x0D\x2E\xD8\x12\x00"
typedef NTSTATUS(__fastcall* tLdrpReleaseLoaderLock)(ULONG64 Unused, ULONG Two, ULONG64 LdrFlags);
extern tLdrpReleaseLoaderLock LdrpReleaseLoaderLock;
#define LDRP_CHECKPAGES_FOR_TAMPERING_PATTERN "\x48\x8B\xC4\x48\x89\x58\x08\x48\x89\x68\x10\x48\x89\x70\x18\x48\x89\x78\x20\x41\x56\x48\x83\xEC\x30\x48\x8D\xBA\xFF\x0F\x00\x00"
typedef BOOLEAN(__fastcall* tLdrpCheckPagesForTampering)(PIMAGE_DATA_DIRECTORY pDataDir, ULONG64 Offset);
extern tLdrpCheckPagesForTampering LdrpCheckPagesForTampering;
#define LDRP_LOAD_DEPENDENTMODULEA_PATTERN "\x4C\x8B\xDC\x55\x53\x49\x8D\xAB\x48\xFF\xFF\xFF"
typedef NTSTATUS(__fastcall* tLdrpLoadDependentModuleA)(PUNICODE_STRING SourceString, LDRP_LOAD_CONTEXT* LoadContext, LDR_DATA_TABLE_ENTRY* LdrEntry, UINT_PTR Unknown, LDR_DATA_TABLE_ENTRY** pLdrEntry, UINT_PTR Unknown2);
extern tLdrpLoadDependentModuleA LdrpLoadDependentModuleA;
#define LDRP_LOAD_DEPENDENTMODULEW_PATTERN "\x48\x89\x5C\x24\x20\x55\x56\x57\x41\x56\x41\x57\x48\x81\xEC\x50\x01\x00\x00"
typedef NTSTATUS(__fastcall* tLdrpLoadDependentModuleW)(PUNICODE_STRING SourceString, LDRP_LOAD_CONTEXT* LoadContext, LDR_DATA_TABLE_ENTRY* DllEntry);
extern tLdrpLoadDependentModuleW LdrpLoadDependentModuleW;
#define LDRP_QUEUE_WORK_PATTERN "\x40\x53\x48\x83\xEC\x20\x48\x8B\x41\x28\x48\x8B\xD9"
typedef NTSTATUS(__fastcall* tLdrpQueueWork)(PLDRP_LOAD_CONTEXT LoadContext);
extern tLdrpQueueWork LdrpQueueWork;
#define LDRP_HANDLE_TLSDATA_PATTERN "\x48\x89\x5C\x24\x10\x48\x89\x74\x24\x18\x48\x89\x7C\x24\x20\x41\x55\x41\x56\x41\x57\x48\x81\xEC\x00\x01\x00\x00"
typedef NTSTATUS(__fastcall* tLdrpHandleTlsData)(LDR_DATA_TABLE_ENTRY* LdrDataTableEntry);
extern tLdrpHandleTlsData LdrpHandleTlsData;
#define LDR_CONTROLFLOWGUARD_ENFEXP_PATTERN "\x33\xC0\x48\x39\x05\x8F\x7D\x17\x00"
typedef BOOLEAN(__fastcall* tLdrControlFlowGuardEnforcedWithExportSuppression)();
extern tLdrControlFlowGuardEnforcedWithExportSuppression LdrControlFlowGuardEnforcedWithExportSuppression;
#define LDRP_UNSUPPRESS_ADDRESSIAT_PATTERN "\x48\x89\x5C\x24\x18\x55\x56\x57\x41\x54\x41\x55\x41\x56\x41\x57\x48\x8B\xEC\x48\x83\xEC\x70\x48\x8B\x05\x6E\xC6\x0B\x00"
typedef __int64(__fastcall* tLdrpUnsuppressAddressTakenIat)(PIMAGE_DOS_HEADER DllBase, ULONG Unknown, ULONG Unknown2);
extern tLdrpUnsuppressAddressTakenIat LdrpUnsuppressAddressTakenIat;
#define LDR_CONTROLFLOWGUARD_ENF_PATTERN "\x48\x83\x3D\x90\xD5\x16\x00\x00"
typedef BOOL(__fastcall* tLdrControlFlowGuardEnforced)();
extern tLdrControlFlowGuardEnforced LdrControlFlowGuardEnforced;
#define RTLP_LOOKUP_FUNCTIONTABLE_PATTERN "\x48\x89\x5C\x24\x08\x48\x89\x74\x24\x18\x48\x89\x7C\x24\x20\x41\x56\x48\x83\xEC\x20\x33\xDB"
typedef PIMAGE_RUNTIME_FUNCTION_ENTRY(__fastcall* tRtlpxLookupFunctionTable)(PIMAGE_DOS_HEADER DllBase, PIMAGE_RUNTIME_FUNCTION_ENTRY* ppImageFunctionEntry);
extern tRtlpxLookupFunctionTable RtlpxLookupFunctionTable;
#define LDRP_CHECK_REDIRECTION_PATTERN "\x48\x8B\xC4\x48\x89\x58\x08\x48\x89\x70\x10\x48\x89\x78\x18\x4C\x89\x68\x20\x55\x41\x56\x41\x57\x48\x8D\x68\xA1"
typedef PCHAR(__fastcall* tLdrpCheckRedirection)(LDR_DATA_TABLE_ENTRY* DllEntry, LDR_DATA_TABLE_ENTRY* NtLdrEntry, PCHAR StringToBeHashed);
extern tLdrpCheckRedirection LdrpCheckRedirection;
#define COMPAT_CACHE_LOOKUPCDB_PATTERN "\x48\x89\x5C\x24\x08\x48\x89\x74\x24\x10\x57\x48\x81\xEC\xB0\x01\x00\x00"
typedef BOOL(__fastcall* tCompatCachepLookupCdb)(PWCHAR Buffer, LONG Unknown);
extern tCompatCachepLookupCdb CompatCachepLookupCdb;
#define LDRP_GEN_RANDOM_PATTERN "\x48\x83\xEC\x28\xB9\x1C\x00\x00\x00\xE8\x0E\x0B\x00\x00"
typedef UINT_PTR(__fastcall* tLdrpGenRandom)();
extern tLdrpGenRandom LdrpGenRandom;
#define LDR_INIT_SECURITY_COOKIE_PATTERN "\x48\x89\x5C\x24\x08\x48\x89\x74\x24\x10\x48\x89\x7C\x24\x20\x55\x41\x54\x41\x56"
typedef BOOL(__fastcall* tLdrInitSecurityCookie)(PIMAGE_DOS_HEADER DllBase, INT_PTR ImageSize, UINT_PTR* Zero, UINT_PTR RandomNumberStuff, UINT_PTR* Zero_2);
extern tLdrInitSecurityCookie LdrInitSecurityCookie;
#define LDRP_CFG_PROCESS_LOADCFG_PATTERN "\x48\x89\x5C\x24\x20\x55\x56\x57\x41\x54\x41\x55\x41\x56\x41\x57\x48\x8D\x6C\x24\xD9\x48\x81\xEC\xF0\x00\x00\x00\x48\x8B\x05\x99\x11\x17\x00"
typedef NTSTATUS(__fastcall* tLdrpCfgProcessLoadConfig)(LDR_DATA_TABLE_ENTRY* DllEntry, PIMAGE_NT_HEADERS NtHeader, __int64 Zero);
extern tLdrpCfgProcessLoadConfig LdrpCfgProcessLoadConfig;
#define RTL_INSERT_INV_FUNCTIONTABLE_PATTERN "\x48\x89\x5C\x24\x08\x57\x48\x83\xEC\x30\x8B\xDA\x4C\x8D\x44\x24\x50"
typedef NTSTATUS(__fastcall* tRtlInsertInvertedFunctionTable)(PIMAGE_DOS_HEADER DllBase, ULONG ImageSize);
extern tRtlInsertInvertedFunctionTable RtlInsertInvertedFunctionTable;
#define LDRP_SIGNAL_MODULEMAPPED_PATTERN "\x48\x89\x5C\x24\x08\x57\x48\x83\xEC\x20\x48\x8B\x81\x98\x00\x00\x00\x48\x8B\x78\x30"
typedef LDR_DDAG_NODE*(__fastcall* tLdrpSignalModuleMapped)(LDR_DATA_TABLE_ENTRY* DllEntry);
extern tLdrpSignalModuleMapped LdrpSignalModuleMapped;
#define AVRF_DLL_LOADNOTIFICATION_PATTERN "\x48\x89\x5C\x24\x08\x48\x89\x6C\x24\x10\x48\x89\x74\x24\x18\x57\x48\x83\xEC\x30\x65\x48\x8B\x04\x25\x60\x00\x00\x00"
typedef NTSTATUS(__fastcall* tAVrfDllLoadNotification)(LDR_DATA_TABLE_ENTRY* DllEntry);
extern tAVrfDllLoadNotification AVrfDllLoadNotification;
#define LDRP_SEND_DLLNOTIFICATIONS_PATTERN "\x4C\x8B\xDC\x49\x89\x5B\x08\x49\x89\x73\x10\x57\x48\x83\xEC\x50\x83\x64\x24\x20\x00"
typedef NTSTATUS(__fastcall* tLdrpSendDllNotifications)(LDR_DATA_TABLE_ENTRY* DllEntry, UINT_PTR Unknown);
extern tLdrpSendDllNotifications LdrpSendDllNotifications;
#define LDRP_CALL_TLSINIT_PATTERN "\x48\x89\x5C\x24\x08\x48\x89\x74\x24\x10\x48\x89\x7C\x24\x20\x41\x56\x48\x83\xEC\x60"
typedef NTSTATUS(__fastcall* tLdrpCallTlsInitializers)(ULONG One, LDR_DATA_TABLE_ENTRY* LdrEntry);
extern tLdrpCallTlsInitializers LdrpCallTlsInitializers;
================================================
FILE: Src/Functions/Syscalls.asm
================================================
.code
ZwSystemDebugControl proc
mov r10, rcx
mov eax, 1CDh
test byte ptr [7FFE0308h], 1 ; KUSER_SHARED_DATA.SystemCall
jnz short SYSCALL_DEFINED
syscall
ret
SYSCALL_DEFINED:
int 2Eh
ZwSystemDebugControl endp
NtCreateSection proc
mov r10, rcx
mov eax, 4Ah
test byte ptr [7FFE0308h], 1 ; KUSER_SHARED_DATA.SystemCall
jnz short SYSCALL_DEFINED
syscall
ret
SYSCALL_DEFINED:
int 2Eh
NtCreateSection endp
ZwMapViewOfSection proc
mov r10, rcx
mov eax, 28h
test byte ptr [7FFE0308h], 1 ; KUSER_SHARED_DATA.SystemCall
jnz short SYSCALL_DEFINED
syscall
ret
SYSCALL_DEFINED:
int 2Eh
ZwMapViewOfSection endp
ZwMapViewOfSectionEx proc
mov r10, rcx
mov eax, 11Ch
test byte ptr [7FFE0308h], 1 ; KUSER_SHARED_DATA.SystemCall
jnz short SYSCALL_DEFINED
syscall
ret
SYSCALL_DEFINED:
int 2Eh
ZwMapViewOfSectionEx endp
NtUnmapViewOfSection proc
mov r10, rcx
mov eax, 2Ah
test byte ptr [7FFE0308h], 1 ; KUSER_SHARED_DATA.SystemCall
jnz short SYSCALL_DEFINED
syscall
ret
SYSCALL_DEFINED:
int 2Eh
NtUnmapViewOfSection endp
ZwProtectVirtualMemory proc
mov r10, rcx
mov eax, 50h
test byte ptr [7FFE0308h], 1 ; KUSER_SHARED_DATA.SystemCall
jnz short SYSCALL_DEFINED
syscall
ret
SYSCALL_DEFINED:
int 2Eh
ZwProtectVirtualMemory endp
ZwQueryVirtualMemory proc
mov r10, rcx
mov eax, 23h
test byte ptr [7FFE0308h], 1 ; KUSER_SHARED_DATA.SystemCall
jnz short SYSCALL_DEFINED
syscall
ret
SYSCALL_DEFINED:
int 2Eh
ZwQueryVirtualMemory endp
NtQueryInformationProcess proc
mov r10, rcx
mov eax, 19h
test byte ptr [7FFE0308h], 1 ; KUSER_SHARED_DATA.SystemCall
jnz short SYSCALL_DEFINED
syscall
ret
SYSCALL_DEFINED:
int 2Eh
NtQueryInformationProcess endp
end
================================================
FILE: Src/Functions/Undocumented.h
================================================
#pragma once
#include "..\Includes.h"
typedef void* PPS_POST_PROCESS_INIT_ROUTINE;
typedef struct _LSA_UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} LSA_UNICODE_STRING, * PLSA_UNICODE_STRING, UNICODE_STRING, * PUNICODE_STRING;
typedef struct _STRING {
USHORT Length;
USHORT MaximumLength;
PCHAR Buffer;
} STRING, * PSTRING, ANSI_STRING, * PANSI_STRING;
#define DOS_MAX_COMPONENT_LENGTH 255
#define DOS_MAX_PATH_LENGTH (DOS_MAX_COMPONENT_LENGTH + 5)
typedef struct _CURDIR
{
UNICODE_STRING DosPath;
HANDLE Handle;
} CURDIR, * PCURDIR;
#define RTL_USER_PROC_CURDIR_CLOSE 0x00000002
#define RTL_USER_PROC_CURDIR_INHERIT 0x00000003
typedef struct _RTL_DRIVE_LETTER_CURDIR
{
USHORT Flags;
USHORT Length;
ULONG TimeStamp;
STRING DosPath;
} RTL_DRIVE_LETTER_CURDIR, * PRTL_DRIVE_LETTER_CURDIR;
#define RTL_MAX_DRIVE_LETTERS 32
#define RTL_DRIVE_LETTER_VALID (USHORT)0x0001
typedef struct _RTL_USER_PROCESS_PARAMETERS
{
ULONG MaximumLength;
ULONG Length;
ULONG Flags;
ULONG DebugFlags;
HANDLE ConsoleHandle;
ULONG ConsoleFlags;
HANDLE StandardInput;
HANDLE StandardOutput;
HANDLE StandardError;
CURDIR CurrentDirectory;
UNICODE_STRING DllPath;
UNICODE_STRING ImagePathName;
UNICODE_STRING CommandLine;
PVOID Environment;
ULONG StartingX;
ULONG StartingY;
ULONG CountX;
ULONG CountY;
ULONG CountCharsX;
ULONG CountCharsY;
ULONG FillAttribute;
ULONG WindowFlags;
ULONG ShowWindowFlags;
UNICODE_STRING WindowTitle;
UNICODE_STRING DesktopInfo;
UNICODE_STRING ShellInfo;
UNICODE_STRING RuntimeData;
RTL_DRIVE_LETTER_CURDIR CurrentDirectories[RTL_MAX_DRIVE_LETTERS];
ULONG EnvironmentSize;
ULONG EnvironmentVersion;
PVOID PackageDependencyData;
ULONG ProcessGroupId;
ULONG LoaderThreads;
} RTL_USER_PROCESS_PARAMETERS, * PRTL_USER_PROCESS_PARAMETERS;
typedef struct _PEB_LDR_DATA {
ULONG Length;
BOOL Initialized;
LPVOID SsHandle;
LIST_ENTRY InLoadOrderModuleList;
LIST_ENTRY InMemoryOrderModuleList;
LIST_ENTRY InInitializationOrderModuleList;
} PEB_LDR_DATA, * PPEB_LDR_DATA;
typedef BOOLEAN(NTAPI* PLDR_INIT_ROUTINE)(
_In_ PVOID DllHandle,
_In_ ULONG Reason,
_In_opt_ PVOID Context
);
typedef struct _RTL_BALANCED_NODE
{
union
{
struct _RTL_BALANCED_NODE* Children[2]; //0x0
struct
{
struct _RTL_BALANCED_NODE* Left; //0x0
struct _RTL_BALANCED_NODE* Right; //0x4
};
};
union
{
struct
{
UCHAR Red : 1; //0x8
UCHAR Balance : 2; //0x8
};
ULONG ParentValue; //0x8
};
} RTL_BALANCED_NODE, *PRTL_BALANCED_NODE;
// symbols
typedef struct _LDR_SERVICE_TAG_RECORD
{
struct _LDR_SERVICE_TAG_RECORD* Next;
ULONG ServiceTag;
} LDR_SERVICE_TAG_RECORD, * PLDR_SERVICE_TAG_RECORD;
// symbols
typedef struct _LDRP_CSLIST
{
PSINGLE_LIST_ENTRY Tail;
} LDRP_CSLIST, * PLDRP_CSLIST;
// symbols
typedef enum _LDR_DDAG_STATE
{
LdrModulesMerged = -5,
LdrModulesInitError = -4,
LdrModulesSnapError = -3,
LdrModulesUnloaded = -2,
LdrModulesUnloading = -1,
LdrModulesPlaceHolder = 0,
LdrModulesMapping = 1,
LdrModulesMapped = 2,
LdrModulesWaitingForDependencies = 3,
LdrModulesSnapping = 4,
LdrModulesSnapped = 5,
LdrModulesCondensed = 6,
LdrModulesReadyToInit = 7,
LdrModulesInitializing = 8,
LdrModulesReadyToRun = 9
} LDR_DDAG_STATE;
// symbols
typedef struct _LDR_DDAG_NODE
{
LIST_ENTRY Modules;
PLDR_SERVICE_TAG_RECORD ServiceTagList;
ULONG LoadCount;
ULONG LoadWhileUnloadingCount;
ULONG LowestLink;
union
{
LDRP_CSLIST Dependencies;
SINGLE_LIST_ENTRY* RemovalLink;
};
LDRP_CSLIST IncomingDependencies;
LDR_DDAG_STATE State;
SINGLE_LIST_ENTRY* CondenseLink;
ULONG PreorderNumber;
ULONG Pad;
} LDR_DDAG_NODE, * PLDR_DDAG_NODE;
// rev
typedef struct _LDR_DEPENDENCY_RECORD
{
SINGLE_LIST_ENTRY DependencyLink;
PLDR_DDAG_NODE DependencyNode;
SINGLE_LIST_ENTRY IncomingDependencyLink;
PLDR_DDAG_NODE IncomingDependencyNode;
} LDR_DEPENDENCY_RECORD, * PLDR_DEPENDENCY_RECORD;
// symbols
typedef enum _LDR_DLL_LOAD_REASON
{
LoadReasonStaticDependency,
LoadReasonStaticForwarderDependency,
LoadReasonDynamicForwarderDependency,
LoadReasonDelayloadDependency,
LoadReasonDynamicLoad,
LoadReasonAsImageLoad,
LoadReasonAsDataLoad,
LoadReasonEnclavePrimary, // since REDSTONE3
LoadReasonEnclaveDependency,
LoadReasonPatchImage, // since WIN11
LoadReasonUnknown = -1
} LDR_DLL_LOAD_REASON, * PLDR_DLL_LOAD_REASON;
typedef enum _LDR_HOT_PATCH_STATE
{
LdrHotPatchBaseImage,
LdrHotPatchNotApplied,
LdrHotPatchAppliedReverse,
LdrHotPatchAppliedForward,
LdrHotPatchFailedToPatch,
LdrHotPatchStateMax,
} LDR_HOT_PATCH_STATE, * PLDR_HOT_PATCH_STATE;
// LDR_DATA_TABLE_ENTRY->Flags
#define LDRP_PACKAGED_BINARY 0x00000001
#define LDRP_MARKED_FOR_REMOVAL 0x00000002
#define LDRP_IMAGE_DLL 0x00000004
#define LDRP_LOAD_NOTIFICATIONS_SENT 0x00000008
#define LDRP_TELEMETRY_ENTRY_PROCESSED 0x00000010
#define LDRP_PROCESS_STATIC_IMPORT 0x00000020
#define LDRP_IN_LEGACY_LISTS 0x00000040
#define LDRP_IN_INDEXES 0x00000080
#define LDRP_SHIM_DLL 0x00000100
#define LDRP_IN_EXCEPTION_TABLE 0x00000200
#define LDRP_LOAD_IN_PROGRESS 0x00001000
#define LDRP_LOAD_CONFIG_PROCESSED 0x00002000
#define LDRP_ENTRY_PROCESSED 0x00004000
#define LDRP_PROTECT_DELAY_LOAD 0x00008000
#define LDRP_DONT_CALL_FOR_THREADS 0x00040000
#define LDRP_PROCESS_ATTACH_CALLED 0x00080000
#define LDRP_PROCESS_ATTACH_FAILED 0x00100000
#define LDRP_COR_DEFERRED_VALIDATE 0x00200000
#define LDRP_COR_IMAGE 0x00400000
#define LDRP_DONT_RELOCATE 0x00800000
#define LDRP_COR_IL_ONLY 0x01000000
#define LDRP_CHPE_IMAGE 0x02000000
#define LDRP_CHPE_EMULATOR_IMAGE 0x04000000
#define LDRP_REDIRECTED 0x10000000
#define LDRP_COMPAT_DATABASE_PROCESSED 0x80000000
#define LDR_DATA_TABLE_ENTRY_SIZE_WINXP FIELD_OFFSET(LDR_DATA_TABLE_ENTRY, DdagNode)
#define LDR_DATA_TABLE_ENTRY_SIZE_WIN7 FIELD_OFFSET(LDR_DATA_TABLE_ENTRY, BaseNameHashValue)
#define LDR_DATA_TABLE_ENTRY_SIZE_WIN8 FIELD_OFFSET(LDR_DATA_TABLE_ENTRY, ImplicitPathOptions)
#define LDR_DATA_TABLE_ENTRY_SIZE_WIN10 FIELD_OFFSET(LDR_DATA_TABLE_ENTRY, SigningLevel)
#define LDR_DATA_TABLE_ENTRY_SIZE_WIN11 sizeof(LDR_DATA_TABLE_ENTRY)
// symbols
typedef struct _LDR_DATA_TABLE_ENTRY
{
LIST_ENTRY InLoadOrderLinks;
LIST_ENTRY InMemoryOrderLinks;
union
{
LIST_ENTRY InInitializationOrderLinks;
LIST_ENTRY InProgressLinks;
};
PIMAGE_DOS_HEADER DllBase;
PLDR_INIT_ROUTINE EntryPoint;
ULONG SizeOfImage;
UNICODE_STRING FullDllName;
UNICODE_STRING BaseDllName;
union
{
UCHAR FlagGroup[4];
ULONG Flags;
struct
{
ULONG PackagedBinary : 1;
ULONG MarkedForRemoval : 1;
ULONG ImageDll : 1;
ULONG LoadNotificationsSent : 1;
ULONG TelemetryEntryProcessed : 1;
ULONG ProcessStaticImport : 1;
ULONG InLegacyLists : 1;
ULONG InIndexes : 1;
ULONG ShimDll : 1;
ULONG InExceptionTable : 1;
ULONG ReservedFlags1 : 2;
ULONG LoadInProgress : 1;
ULONG LoadConfigProcessed : 1;
ULONG EntryProcessed : 1;
ULONG ProtectDelayLoad : 1;
ULONG ReservedFlags3 : 2;
ULONG DontCallForThreads : 1;
ULONG ProcessAttachCalled : 1;
ULONG ProcessAttachFailed : 1;
ULONG CorDeferredValidate : 1;
ULONG CorImage : 1;
ULONG DontRelocate : 1;
ULONG CorILOnly : 1;
ULONG ChpeImage : 1;
ULONG ChpeEmulatorImage : 1;
ULONG ReservedFlags5 : 1;
ULONG Redirected : 1;
ULONG ReservedFlags6 : 2;
ULONG CompatDatabaseProcessed : 1;
};
};
USHORT ObsoleteLoadCount;
USHORT TlsIndex;
LIST_ENTRY HashLinks;
ULONG TimeDateStamp;
struct _ACTIVATION_CONTEXT* EntryPointActivationContext;
PVOID Lock; // RtlAcquireSRWLockExclusive
PLDR_DDAG_NODE DdagNode;
LIST_ENTRY NodeModuleLink;
struct _LDRP_LOAD_CONTEXT* LoadContext;
PVOID ParentDllBase;
PVOID SwitchBackContext;
RTL_BALANCED_NODE BaseAddressIndexNode;
RTL_BALANCED_NODE MappingInfoIndexNode;
ULONG_PTR OriginalBase;
LARGE_INTEGER LoadTime;
ULONG BaseNameHashValue;
LDR_DLL_LOAD_REASON LoadReason; // since WIN8
ULONG ImplicitPathOptions;
ULONG ReferenceCount; // since WIN10
ULONG DependentLoadFlags;
UCHAR SigningLevel; // since REDSTONE2
ULONG CheckSum; // since 22H1
PVOID ActivePatchImageBase;
LDR_HOT_PATCH_STATE HotPatchState;
} LDR_DATA_TABLE_ENTRY, * PLDR_DATA_TABLE_ENTRY;
#define PROCESSOR_FEATURE_MAX 64
typedef struct _KSYSTEM_TIME
{
ULONG LowPart;
LONG High1Time;
LONG High2Time;
} KSYSTEM_TIME, * PKSYSTEM_TIME;
typedef enum _NT_PRODUCT_TYPE
{
NtProductWinNt = 1,
NtProductLanManNt = 2,
NtProductServer = 3
} NT_PRODUCT_TYPE;
typedef enum _ALTERNATIVE_ARCHITECTURE_TYPE
{
StandardDesign = 0,
NEC98x86 = 1,
EndAlternatives = 2
} ALTERNATIVE_ARCHITECTURE_TYPE;
typedef struct _KUSER_SHARED_DATA {
ULONG TickCountLowDeprecated;
ULONG TickCountMultiplier;
KSYSTEM_TIME InterruptTime;
KSYSTEM_TIME SystemTime;
KSYSTEM_TIME TimeZoneBias;
USHORT ImageNumberLow;
USHORT ImageNumberHigh;
WCHAR NtSystemRoot[260];
ULONG MaxStackTraceDepth;
ULONG CryptoExponent;
ULONG TimeZoneId;
ULONG LargePageMinimum;
ULONG AitSamplingValue;
ULONG AppCompatFlag;
ULONGLONG RNGSeedVersion;
ULONG GlobalValidationRunlevel;
LONG TimeZoneBiasStamp;
ULONG NtBuildNumber;
NT_PRODUCT_TYPE NtProductType;
BOOLEAN ProductTypeIsValid;
BOOLEAN Reserved0[1];
USHORT NativeProcessorArchitecture;
ULONG NtMajorVersion;
ULONG NtMinorVersion;
BOOLEAN ProcessorFeatures[PROCESSOR_FEATURE_MAX];
ULONG Reserved1;
ULONG Reserved3;
ULONG TimeSlip;
ALTERNATIVE_ARCHITECTURE_TYPE AlternativeArchitecture;
ULONG BootId;
LARGE_INTEGER SystemExpirationDate;
ULONG SuiteMask;
BOOLEAN KdDebuggerEnabled;
union {
UCHAR MitigationPolicies;
struct {
UCHAR NXSupportPolicy : 2;
UCHAR SEHValidationPolicy : 2;
UCHAR CurDirDevicesSkippedForDlls : 2;
UCHAR Reserved : 2;
};
};
USHORT CyclesPerYield;
ULONG ActiveConsoleId;
ULONG DismountCount;
ULONG ComPlusPackage;
ULONG LastSystemRITEventTickCount;
ULONG NumberOfPhysicalPages;
BOOLEAN SafeBootMode;
union {
UCHAR VirtualizationFlags;
struct {
UCHAR ArchStartedInEl2 : 1;
UCHAR QcSlIsSupported : 1;
};
};
UCHAR Reserved12[2];
union {
ULONG SharedDataFlags;
struct {
ULONG DbgErrorPortPresent : 1;
ULONG DbgElevationEnabled : 1;
ULONG DbgVirtEnabled : 1;
ULONG DbgInstallerDetectEnabled : 1;
ULONG DbgLkgEnabled : 1;
ULONG DbgDynProcessorEnabled : 1;
ULONG DbgConsoleBrokerEnabled : 1;
ULONG DbgSecureBootEnabled : 1;
ULONG DbgMultiSessionSku : 1;
ULONG DbgMultiUsersInSessionSku : 1;
ULONG DbgStateSeparationEnabled : 1;
ULONG SpareBits : 21;
} DUMMYSTRUCTNAME2;
} DUMMYUNIONNAME2;
ULONG DataFlagsPad[1];
ULONGLONG TestRetInstruction;
LONGLONG QpcFrequency;
ULONG SystemCall;
ULONG Reserved2;
ULONGLONG SystemCallPad[2];
union {
KSYSTEM_TIME TickCount;
ULONG64 TickCountQuad;
struct {
ULONG ReservedTickCountOverlay[3];
ULONG TickCountPad[1];
} DUMMYSTRUCTNAME;
} DUMMYUNIONNAME3;
ULONG Cookie;
ULONG CookiePad[1];
LONGLONG ConsoleSessionForegroundProcessId;
ULONGLONG TimeUpdateLock;
ULONGLONG BaselineSystemTimeQpc;
ULONGLONG BaselineInterruptTimeQpc;
ULONGLONG QpcSystemTimeIncrement;
ULONGLONG QpcInterruptTimeIncrement;
UCHAR QpcSystemTimeIncrementShift;
UCHAR QpcInterruptTimeIncrementShift;
USHORT UnparkedProcessorCount;
ULONG EnclaveFeatureMask[4];
ULONG TelemetryCoverageRound;
USHORT UserModeGlobalLogger[16];
ULONG ImageFileExecutionOptions;
ULONG LangGenerationCount;
ULONGLONG Reserved4;
ULONGLONG InterruptTimeBias;
ULONGLONG QpcBias;
ULONG ActiveProcessorCount;
UCHAR ActiveGroupCount;
UCHAR Reserved9;
union {
USHORT QpcData;
struct {
UCHAR QpcBypassEnabled;
UCHAR QpcShift;
};
};
LARGE_INTEGER TimeZoneBiasEffectiveStart;
LARGE_INTEGER TimeZoneBiasEffectiveEnd;
XSTATE_CONFIGURATION XState;
KSYSTEM_TIME FeatureConfigurationChangeStamp;
ULONG Spare;
ULONG64 UserPointerAuthMask;
} KUSER_SHARED_DATA, * PKUSER_SHARED_DATA;
enum DRAIN_TASK
{
WaitLoadComplete = 0,
WaitWorkComplete
};
typedef struct _PEB {
BYTE InheritedAddressSpace;
BYTE ReadImageFileExecOptions;
BYTE BeingDebugged;
union {
UCHAR BitField;
struct {
/* bit fields, follow link */
};
};
LPVOID Mutant;
LPVOID ImageBaseAddress;
PPEB_LDR_DATA Ldr;
PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
LPVOID SubSystemData;
LPVOID ProcessHeap;
LPVOID FastPebLock;
LPVOID _SYSTEM_DEPENDENT_02;
LPVOID _SYSTEM_DEPENDENT_03;
LPVOID _SYSTEM_DEPENDENT_04;
union {
LPVOID KernelCallbackTable;
LPVOID UserSharedInfoPtr;
};
DWORD SystemReserved;
DWORD _SYSTEM_DEPENDENT_05;
LPVOID _SYSTEM_DEPENDENT_06;
LPVOID TlsExpansionCounter;
LPVOID TlsBitmap;
DWORD TlsBitmapBits[2];
LPVOID ReadOnlySharedMemoryBase;
KUSER_SHARED_DATA* SharedData;
LPVOID ReadOnlyStaticServerData;
LPVOID AnsiCodePageData;
LPVOID OemCodePageData;
LPVOID UnicodeCaseTableData;
DWORD NumberOfProcessors;
union
{
DWORD NtGlobalFlag;
LPVOID dummy02;
};
LARGE_INTEGER CriticalSectionTimeout;
LPVOID HeapSegmentReserve;
LPVOID HeapSegmentCommit;
LPVOID HeapDeCommitTotalFreeThreshold;
LPVOID HeapDeCommitFreeBlockThreshold;
DWORD NumberOfHeaps;
DWORD MaximumNumberOfHeaps;
LPVOID ProcessHeaps;
LPVOID GdiSharedHandleTable;
LPVOID ProcessStarterHelper;
LPVOID GdiDCAttributeList;
LPVOID LoaderLock;
DWORD OSMajorVersion;
DWORD OSMinorVersion;
WORD OSBuildNumber;
WORD OSCSDVersion;
DWORD OSPlatformId;
DWORD ImageSubsystem;
DWORD ImageSubsystemMajorVersion;
LPVOID ImageSubsystemMinorVersion;
union
{
LPVOID ImageProcessAffinityMask;
LPVOID ActiveProcessAffinityMask;
};
#ifdef _WIN64
LPVOID GdiHandleBuffer[64];
#else
LPVOID GdiHandleBuffer[32];
#endif
LPVOID PostProcessInitRoutine;
LPVOID TlsExpansionBitmap;
DWORD TlsExpansionBitmapBits[32];
LPVOID SessionId;
ULARGE_INTEGER AppCompatFlags;
ULARGE_INTEGER AppCompatFlagsUser;
LPVOID pShimData;
LPVOID AppCompatInfo;
PUNICODE_STRING CSDVersion;
LPVOID ActivationContextData;
LPVOID ProcessAssemblyStorageMap;
LPVOID SystemDefaultActivationContextData;
LPVOID SystemAssemblyStorageMap;
LPVOID MinimumStackCommit;
//Appended for Windows Server 2003
PVOID SparePointers[4];
LIST_ENTRY FlsListHead;
PVOID FlsBitmap;
ULONG SpareUlongs[5];
ULONG FlsHighIndex;
//Appended for Windows Vista
PVOID WerRegistrationData;
PVOID WerShipAssertPtr;
//Appended for Windows 7
PVOID pUnused;
PVOID pImageHeaderHash;
union {
ULONG TracingFlags;
struct {
/* bit fields, follow link */
};
};
} PEB, * PPEB;
struct FUNCTION_TABLE_DATA
{
UINT_PTR TableAddress;
PIMAGE_DOS_HEADER ImageBase;
DWORD ImageSize;
DWORD Size;
};
typedef struct _OBJECT_ATTRIBUTES {
ULONG Length;
HANDLE RootDirectory;
PUNICODE_STRING ObjectName;
ULONG Attributes;
PVOID SecurityDescriptor;
PVOID SecurityQualityOfService;
} OBJECT_ATTRIBUTES;
enum HARDERROR_RESPONSE_OPTION
{
OptionAbortRetryIgnore = 0x0,
OptionOk = 0x1,
OptionOkCancel = 0x2,
OptionRetryCancel = 0x3,
OptionYesNo = 0x4,
OptionYesNoCancel = 0x5,
OptionShutdownSystem = 0x6,
};
enum HARDERROR_RESPONSE
{
ResponseReturnToCaller = 0x0,
ResponseNotHandled = 0x1,
ResponseAbort = 0x2,
ResponseCancel = 0x3,
ResponseIgnore = 0x4,
ResponseNo = 0x5,
ResponseOk = 0x6,
ResponseRetry = 0x7,
ResponseYes = 0x8,
};
typedef struct _IO_STATUS_BLOCK {
union {
NTSTATUS Status;
PVOID Pointer;
};
ULONG_PTR Information;
} IO_STATUS_BLOCK, * PIO_STATUS_BLOCK;
typedef struct _CLIENT_ID {
HANDLE UniqueProcess;
HANDLE UniqueThread;
} CLIENT_ID, * PCLIENT_ID;
typedef struct _RTL_ACTIVATION_CONTEXT_STACK_FRAME* PRTL_ACTIVATION_CONTEXT_STACK_FRAME;
typedef struct _ACTIVATION_CONTEXT* PACTIVATION_CONTEXT;
typedef struct _TEB_ACTIVE_FRAME* PTEB_ACTIVE_FRAME;
typedef struct _TEB_ACTIVE_FRAME_CONTEXT* PTEB_ACTIVE_FRAME_CONTEXT;
typedef struct _RTL_ACTIVATION_CONTEXT_STACK_FRAME {
PRTL_ACTIVATION_CONTEXT_STACK_FRAME Previous;
PACTIVATION_CONTEXT* ActivationContext;
ULONG Flags;
} RTL_ACTIVATION_CONTEXT_STACK_FRAME, * PRTL_ACTIVATION_CONTEXT_STACK_FRAME;
typedef struct _ACTIVATION_CONTEXT_STACK
{
PRTL_ACTIVATION_CONTEXT_STACK_FRAME ActiveFrame;
LIST_ENTRY FrameListCache;
ULONG Flags;
ULONG NextCookieSequenceNumber;
ULONG StackId;
} ACTIVATION_CONTEXT_STACK, * PACTIVATION_CONTEXT_STACK;
typedef struct _RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_BASIC
{
SIZE_T Size;
ULONG Format;
RTL_ACTIVATION_CONTEXT_STACK_FRAME Frame;
} RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_BASIC, * PRTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_BASIC;
typedef struct _RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED
{
SIZE_T Size;
ULONG Format;
RTL_ACTIVATION_CONTEXT_STACK_FRAME Frame;
PVOID Extra1;
PVOID Extra2;
PVOID Extra3;
PVOID Extra4;
} RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED, * PRTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED;
#define GDI_BATCH_BUFFER_SIZE 310
typedef struct _GDI_TEB_BATCH
{
ULONG Offset;
ULONG_PTR HDC;
ULONG Buffer[GDI_BATCH_BUFFER_SIZE];
} GDI_TEB_BATCH, * PGDI_TEB_BATCH;
typedef struct _TEB_ACTIVE_FRAME_CONTEXT
{
ULONG Flags;
PSTR FrameName;
} TEB_ACTIVE_FRAME_CONTEXT, * PTEB_ACTIVE_FRAME_CONTEXT;
typedef struct _TEB_ACTIVE_FRAME
{
ULONG Flags;
struct _TEB_ACTIVE_FRAME* Previous;
PTEB_ACTIVE_FRAME_CONTEXT Context;
} TEB_ACTIVE_FRAME, * PTEB_ACTIVE_FRAME;
#if !defined(_MSC_VER)
typedef struct _PROCESSOR_NUMBER {
USHORT Group;
UCHAR Number;
UCHAR Reserved;
} PROCESSOR_NUMBER, * PPROCESSOR_NUMBER;
#endif
typedef struct _TEB
{
NT_TIB NtTib;
PVOID EnvironmentPointer;
CLIENT_ID ClientId;
PVOID ActiveRpcHandle;
PVOID ThreadLocalStoragePointer;
PPEB ProcessEnvironmentBlock;
ULONG LastErrorValue;
ULONG CountOfOwnedCriticalSections;
PVOID CsrClientThread;
PVOID Win32ThreadInfo;
ULONG User32Reserved[26];
ULONG UserReserved[5];
PVOID WOW32Reserved;
LCID CurrentLocale;
ULONG FpSoftwareStatusRegister;
PVOID SystemReserved1[54];
NTSTATUS ExceptionCode;
PVOID ActivationContextStackPointer;
#ifdef _M_X64
UCHAR SpareBytes[24];
#else
UCHAR SpareBytes[36];
#endif
ULONG TxFsContext;
GDI_TEB_BATCH GdiTebBatch;
CLIENT_ID RealClientId;
HANDLE GdiCachedProcessHandle;
ULONG GdiClientPID;
ULONG GdiClientTID;
PVOID GdiThreadLocalInfo;
ULONG_PTR Win32ClientInfo[62];
PVOID glDispatchTable[233];
ULONG_PTR glReserved1[29];
PVOID glReserved2;
PVOID glSectionInfo;
PVOID glSection;
PVOID glTable;
PVOID glCurrentRC;
PVOID glContext;
NTSTATUS LastStatusValue;
UNICODE_STRING StaticUnicodeString;
WCHAR StaticUnicodeBuffer[261];
PVOID DeallocationStack;
PVOID TlsSlots[64];
LIST_ENTRY TlsLinks;
PVOID Vdm;
PVOID ReservedForNtRpc;
PVOID DbgSsReserved[2];
ULONG HardErrorMode;
#ifdef _M_X64
PVOID Instrumentation[11];
#else
PVOID Instrumentation[9];
#endif
GUID ActivityId;
PVOID SubProcessTag;
PVOID EtwLocalData;
PVOID EtwTraceData;
PVOID WinSockData;
ULONG GdiBatchCount;
union
{
PROCESSOR_NUMBER CurrentIdealProcessor;
ULONG IdealProcessorValue;
struct
{
UCHAR ReservedPad0;
UCHAR ReservedPad1;
UCHAR ReservedPad2;
UCHAR IdealProcessor;
};
};
ULONG GuaranteedStackBytes;
PVOID ReservedForPerf;
PVOID ReservedForOle;
ULONG WaitingOnLoaderLock;
PVOID SavedPriorityState;
ULONG_PTR SoftPatchPtr1;
PVOID ThreadPoolData;
PVOID* TlsExpansionSlots;
#ifdef _M_X64
PVOID DeallocationBStore;
PVOID BStoreLimit;
#endif
ULONG MuiGeneration;
ULONG IsImpersonating;
PVOID NlsCache;
PVOID pShimData;
ULONG HeapVirtualAffinity;
HANDLE CurrentTransactionHandle;
PTEB_ACTIVE_FRAME ActiveFrame;
PVOID FlsData;
PVOID PreferredLanguages;
PVOID UserPrefLanguages;
PVOID MergedPrefLanguages;
ULONG MuiImpersonation;
union
{
USHORT CrossTebFlags;
USHORT SpareCrossTebBits : 16;
};
union
{
USHORT SameTebFlags;
struct
{
USHORT SafeThunkCall : 1;
USHORT InDebugPrint : 1;
USHORT HasFiberData : 1;
USHORT SkipThreadAttach : 1;
USHORT WerInShipAssertCode : 1;
USHORT RanProcessInit : 1;
USHORT ClonedThread : 1;
USHORT SuppressDebugMsg : 1;
USHORT DisableUserStackWalk : 1;
USHORT RtlExceptionAttached : 1;
USHORT InitialThread : 1;
USHORT SessionAware : 1;
USHORT SpareSameTebBits : 4;
};
};
PVOID TxnScopeEnterCallback;
PVOID TxnScopeExitCallback;
PVOID TxnScopeContext;
ULONG LockCount;
ULONG SpareUlong0;
PVOID ResourceRetValue;
PVOID ReservedForWdf;
} TEB, * PTEB;
struct LDR_UNKSTRUCT
{
PWSTR pInitNameMaybe;
__declspec(align(16)) PWSTR Buffer;
int Flags;
PWSTR pDllName;
char Pad1[84];
BOOLEAN IsInitedMaybe;
char Pad2[3];
};
struct LDR_UNKSTRUCT2
{
PUNICODE_STRING Name;
UINT64 Status;
};
struct LDR_UNKSTRUCT3
{
ULONG Flags;
UNICODE_STRING String;
};
typedef struct _LDRP_LOAD_CONTEXT
{
UNICODE_STRING BaseDllName;
LDR_UNKSTRUCT* UnkStruct;
HANDLE SectionHandle;
DWORD Flags;
NTSTATUS* pStatus;
LDR_DATA_TABLE_ENTRY* Entry;
_LIST_ENTRY WorkQueueListEntry;
LDR_DATA_TABLE_ENTRY* ReplacedEntry;
LDR_DATA_TABLE_ENTRY** pvImports;
LDR_DATA_TABLE_ENTRY** IATCheck;
PVOID pvIAT;
ULONG SizeOfIAT;
ULONG CurrentDll;
PIMAGE_IMPORT_DESCRIPTOR pImageImportDescriptor;
ULONG ImageImportDescriptorLen;
__declspec(align(8)) ULONG OriginalIATProtect;
PVOID GuardCFCheckFunctionPointer;
__int64 GuardFlags;
__int64 DllNameLenCompare;
__int64 UnknownFunc;
SIZE_T Size;
__int64 UnknownPtr;
HANDLE FileHandle;
PIMAGE_DOS_HEADER ImageBase;
wchar_t BaseDllNameBuffer[260];
} LDRP_LOAD_CONTEXT, *PLDRP_LOAD_CONTEXT;
struct LDRP_FILENAME_BUFFER
{
UNICODE_STRING pFileName{};
wchar_t FileName[128]{};
};
typedef struct _MEMORY_IMAGE_INFORMATION
{
PVOID ImageBase;
SIZE_T SizeOfImage;
union
{
ULONG ImageFlags;
struct
{
ULONG ImagePartialMap : 1;
ULONG ImageNotExecutable : 1;
ULONG ImageSigningLevel : 4; // REDSTONE3
ULONG Reserved : 26;
};
};
} MEMORY_IMAGE_INFORMATION, * PMEMORY_IMAGE_INFORMATION;
typedef struct _TLS_ENTRY
{
LIST_ENTRY TlsEntry;
IMAGE_TLS_DIRECTORY TlsDirectory;
PLDR_DATA_TABLE_ENTRY ModuleEntry;
SIZE_T Index;
} TLS_ENTRY, *PTLS_ENTRY;
enum SECTION_INHERIT
{
ViewShare = 1,
ViewUnmap = 2
};
/*
struct MEM_EXTENDED_PARAMETER
{
PVOID Type;
PHANDLE pHandle;
HANDLE Handle;
};
*/
typedef struct _MEMORY_WORKING_SET_EX_BLOCK
{
union
{
struct
{
ULONG_PTR Valid : 1;
ULONG_PTR ShareCount : 3;
ULONG_PTR Win32Protection : 11;
ULONG_PTR Shared : 1;
ULONG_PTR Node : 6;
ULONG_PTR Locked : 1;
ULONG_PTR LargePage : 1;
ULONG_PTR Priority : 3;
ULONG_PTR Reserved : 3;
ULONG_PTR SharedOriginal : 1;
ULONG_PTR Bad : 1;
ULONG_PTR Win32GraphicsProtection : 4; // 19H1
#ifdef _WIN64
ULONG_PTR ReservedUlong : 28;
#endif
};
struct
{
ULONG_PTR Valid : 1;
ULONG_PTR Reserved0 : 14;
ULONG_PTR Shared : 1;
ULONG_PTR Reserved1 : 5;
ULONG_PTR PageTable : 1;
ULONG_PTR Location : 2;
ULONG_PTR Priority : 3;
ULONG_PTR ModifiedList : 1;
ULONG_PTR Reserved2 : 2;
ULONG_PTR SharedOriginal : 1;
ULONG_PTR Bad : 1;
#ifdef _WIN64
ULONG_PTR ReservedUlong : 32;
#endif
} Invalid;
};
} MEMORY_WORKING_SET_EX_BLOCK, * PMEMORY_WORKING_SET_EX_BLOCK;
// private
typedef struct _MEMORY_WORKING_SET_EX_INFORMATION
{
PVOID VirtualAddress;
union
{
MEMORY_WORKING_SET_EX_BLOCK VirtualAttributes;
ULONG_PTR Long;
} u1;
} MEMORY_WORKING_SET_EX_INFORMATION, * PMEMORY_WORKING_SET_EX_INFORMATION;
typedef enum _MEMORY_INFORMATION_CLASS
{
MemoryBasicInformation, // q: MEMORY_BASIC_INFORMATION
MemoryWorkingSetInformation, // q: MEMORY_WORKING_SET_INFORMATION
MemoryMappedFilenameInformation, // q: UNICODE_STRING
MemoryRegionInformation, // q: MEMORY_REGION_INFORMATION
MemoryWorkingSetExInformation, // q: MEMORY_WORKING_SET_EX_INFORMATION // since VISTA
MemorySharedCommitInformation, // q: MEMORY_SHARED_COMMIT_INFORMATION // since WIN8
MemoryImageInformation, // q: MEMORY_IMAGE_INFORMATION
MemoryRegionInformationEx, // MEMORY_REGION_INFORMATION
MemoryPrivilegedBasicInformation, // MEMORY_BASIC_INFORMATION
MemoryEnclaveImageInformation, // MEMORY_ENCLAVE_IMAGE_INFORMATION // since REDSTONE3
MemoryBasicInformationCapped, // 10
MemoryPhysicalContiguityInformation, // MEMORY_PHYSICAL_CONTIGUITY_INFORMATION // since 20H1
MemoryBadInformation, // since WIN11
MemoryBadInformationAllProcesses, // since 22H1
MaxMemoryInfoClass
} MEMORY_INFORMATION_CLASS;
typedef enum _PROCESSINFOCLASS
{
ProcessBasicInformation, // q: PROCESS_BASIC_INFORMATION, PROCESS_EXTENDED_BASIC_INFORMATION
ProcessQuotaLimits, // qs: QUOTA_LIMITS, QUOTA_LIMITS_EX
ProcessIoCounters, // q: IO_COUNTERS
ProcessVmCounters, // q: VM_COUNTERS, VM_COUNTERS_EX, VM_COUNTERS_EX2
ProcessTimes, // q: KERNEL_USER_TIMES
ProcessBasePriority, // s: KPRIORITY
ProcessRaisePriority, // s: ULONG
ProcessDebugPort, // q: HANDLE
ProcessExceptionPort, // s: PROCESS_EXCEPTION_PORT (requires SeTcbPrivilege)
ProcessAccessToken, // s: PROCESS_ACCESS_TOKEN
ProcessLdtInformation, // qs: PROCESS_LDT_INFORMATION // 10
ProcessLdtSize, // s: PROCESS_LDT_SIZE
ProcessDefaultHardErrorMode, // qs: ULONG
ProcessIoPortHandlers, // (kernel-mode only) // PROCESS_IO_PORT_HANDLER_INFORMATION
ProcessPooledUsageAndLimits, // q: POOLED_USAGE_AND_LIMITS
ProcessWorkingSetWatch, // q: PROCESS_WS_WATCH_INFORMATION[]; s: void
ProcessUserModeIOPL, // qs: ULONG (requires SeTcbPrivilege)
ProcessEnableAlignmentFaultFixup, // s: BOOLEAN
ProcessPriorityClass, // qs: PROCESS_PRIORITY_CLASS
ProcessWx86Information, // qs: ULONG (requires SeTcbPrivilege) (VdmAllowed)
ProcessHandleCount, // q: ULONG, PROCESS_HANDLE_INFORMATION // 20
ProcessAffinityMask, // (q >WIN7)s: KAFFINITY, qs: GROUP_AFFINITY
ProcessPriorityBoost, // qs: ULONG
ProcessDeviceMap, // qs: PROCESS_DEVICEMAP_INFORMATION, PROCESS_DEVICEMAP_INFORMATION_EX
ProcessSessionInformation, // q: PROCESS_SESSION_INFORMATION
ProcessForegroundInformation, // s: PROCESS_FOREGROUND_BACKGROUND
ProcessWow64Information, // q: ULONG_PTR
ProcessImageFileName, // q: UNICODE_STRING
ProcessLUIDDeviceMapsEnabled, // q: ULONG
ProcessBreakOnTermination, // qs: ULONG
ProcessDebugObjectHandle, // q: HANDLE // 30
ProcessDebugFlags, // qs: ULONG
ProcessHandleTracing, // q: PROCESS_HANDLE_TRACING_QUERY; s: size 0 disables, otherwise enables
ProcessIoPriority, // qs: IO_PRIORITY_HINT
ProcessExecuteFlags, // qs: ULONG
ProcessTlsInformation, // PROCESS_TLS_INFORMATION // ProcessResourceManagement
ProcessCookie, // q: ULONG
ProcessImageInformation, // q: SECTION_IMAGE_INFORMATION
ProcessCycleTime, // q: PROCESS_CYCLE_TIME_INFORMATION // since VISTA
ProcessPagePriority, // qs: PAGE_PRIORITY_INFORMATION
ProcessInstrumentationCallback, // s: PVOID or PROCESS_INSTRUMENTATION_CALLBACK_INFORMATION // 40
ProcessThreadStackAllocation, // s: PROCESS_STACK_ALLOCATION_INFORMATION, PROCESS_STACK_ALLOCATION_INFORMATION_EX
ProcessWorkingSetWatchEx, // q: PROCESS_WS_WATCH_INFORMATION_EX[]
ProcessImageFileNameWin32, // q: UNICODE_STRING
ProcessImageFileMapping, // q: HANDLE (input)
ProcessAffinityUpdateMode, // qs: PROCESS_AFFINITY_UPDATE_MODE
ProcessMemoryAllocationMode, // qs: PROCESS_MEMORY_ALLOCATION_MODE
ProcessGroupInformation, // q: USHORT[]
ProcessTokenVirtualizationEnabled, // s: ULONG
ProcessConsoleHostProcess, // qs: ULONG_PTR // ProcessOwnerInformation
ProcessWindowInformation, // q: PROCESS_WINDOW_INFORMATION // 50
ProcessHandleInformation, // q: PROCESS_HANDLE_SNAPSHOT_INFORMATION // since WIN8
ProcessMitigationPolicy, // s: PROCESS_MITIGATION_POLICY_INFORMATION
ProcessDynamicFunctionTableInformation,
ProcessHandleCheckingMode, // qs: ULONG; s: 0 disables, otherwise enables
ProcessKeepAliveCount, // q: PROCESS_KEEPALIVE_COUNT_INFORMATION
ProcessRevokeFileHandles, // s: PROCESS_REVOKE_FILE_HANDLES_INFORMATION
ProcessWorkingSetControl, // s: PROCESS_WORKING_SET_CONTROL (requires SeDebugPrivilege)
ProcessHandleTable, // q: ULONG[] // since WINBLUE
ProcessCheckStackExtentsMode, // qs: ULONG // KPROCESS->CheckStackExtents (CFG)
ProcessCommandLineInformation, // q: UNICODE_STRING // 60
ProcessProtectionInformation, // q: PS_PROTECTION
ProcessMemoryExhaustion, // PROCESS_MEMORY_EXHAUSTION_INFO // since THRESHOLD
ProcessFaultInformation, // PROCESS_FAULT_INFORMATION
ProcessTelemetryIdInformation, // q: PROCESS_TELEMETRY_ID_INFORMATION
ProcessCommitReleaseInformation, // PROCESS_COMMIT_RELEASE_INFORMATION
ProcessDefaultCpuSetsInformation, // SYSTEM_CPU_SET_INFORMATION[5]
ProcessAllowedCpuSetsInformation, // SYSTEM_CPU_SET_INFORMATION[5]
ProcessSubsystemProcess,
ProcessJobMemoryInformation, // q: PROCESS_JOB_MEMORY_INFO
ProcessInPrivate, // s: void // ETW // since THRESHOLD2 // 70
ProcessRaiseUMExceptionOnInvalidHandleClose, // qs: ULONG; s: 0 disables, otherwise enables
ProcessIumChallengeResponse,
ProcessChildProcessInformation, // q: PROCESS_CHILD_PROCESS_INFORMATION
ProcessHighGraphicsPriorityInformation, // qs: BOOLEAN (requires SeTcbPrivilege)
ProcessSubsystemInformation, // q: SUBSYSTEM_INFORMATION_TYPE // since REDSTONE2
ProcessEnergyValues, // q: PROCESS_ENERGY_VALUES, PROCESS_EXTENDED_ENERGY_VALUES
ProcessPowerThrottlingState, // qs: POWER_THROTTLING_PROCESS_STATE
ProcessReserved3Information, // ProcessActivityThrottlePolicy // PROCESS_ACTIVITY_THROTTLE_POLICY
ProcessWin32kSyscallFilterInformation, // q: WIN32K_SYSCALL_FILTER
ProcessDisableSystemAllowedCpuSets, // 80
ProcessWakeInformation, // PROCESS_WAKE_INFORMATION
ProcessEnergyTrackingState, // qs: PROCESS_ENERGY_TRACKING_STATE
ProcessManageWritesToExecutableMemory, // MANAGE_WRITES_TO_EXECUTABLE_MEMORY // since REDSTONE3
ProcessCaptureTrustletLiveDump,
ProcessTelemetryCoverage,
ProcessEnclaveInformation,
ProcessEnableReadWriteVmLogging, // PROCESS_READWRITEVM_LOGGING_INFORMATION
ProcessUptimeInformation, // q: PROCESS_UPTIME_INFORMATION
ProcessImageSection, // q: HANDLE
ProcessDebugAuthInformation, // since REDSTONE4 // 90
ProcessSystemResourceManagement, // PROCESS_SYSTEM_RESOURCE_MANAGEMENT
ProcessSequenceNumber, // q: ULONGLONG
ProcessLoaderDetour, // since REDSTONE5
ProcessSecurityDomainInformation, // PROCESS_SECURITY_DOMAIN_INFORMATION
ProcessCombineSecurityDomainsInformation, // PROCESS_COMBINE_SECURITY_DOMAINS_INFORMATION
ProcessEnableLogging, // PROCESS_LOGGING_INFORMATION
ProcessLeapSecondInformation, // PROCESS_LEAP_SECOND_INFORMATION
ProcessFiberShadowStackAllocation, // PROCESS_FIBER_SHADOW_STACK_ALLOCATION_INFORMATION // since 19H1
ProcessFreeFiberShadowStackAllocation, // PROCESS_FREE_FIBER_SHADOW_STACK_ALLOCATION_INFORMATION
ProcessAltSystemCallInformation, // since 20H1 // 100
ProcessDynamicEHContinuationTargets, // PROCESS_DYNAMIC_EH_CONTINUATION_TARGETS_INFORMATION
ProcessDynamicEnforcedCetCompatibleRanges, // PROCESS_DYNAMIC_ENFORCED_ADDRESS_RANGE_INFORMATION // since 20H2
ProcessCreateStateChange, // since WIN11
ProcessApplyStateChange,
ProcessEnableOptionalXStateFeatures,
ProcessAltPrefetchParam, // since 22H1
ProcessAssignCpuPartitions,
ProcessPriorityClassEx, // s: PROCESS_PRIORITY_CLASS_EX
ProcessMembershipInformation, // PROCESS_MEMBERSHIP_INFORMATION
ProcessEffectiveIoPriority, // q: IO_PRIORITY_HINT
ProcessEffectivePagePriority, // q: ULONG
MaxProcessInfoClass
} PROCESSINFOCLASS;
typedef struct _file_info
{
ULONG type;
char info;
} file_info;
typedef struct _ASSEMBLY_STORAGE_MAP
{
ULONG Flags;
ULONG AssemblyCount;
PVOID AssemblyArray;
} ASSEMBLY_STORAGE_MAP;
typedef struct _ASSEMBLY_STORAGE_MAP_ENTRY
{
ULONG Flags;
UNICODE_STRING DosPath;
HANDLE Handle;
} ASSEMBLY_STORAGE_MAP_ENTRY;
typedef struct _ACTIVATION_CONTEXT
{
LONG RefCount;
ULONG Flags;
LIST_ENTRY Links;
PVOID ActivationContextData;
PVOID NotificationRoutine;
PVOID NotificationContext;
ULONG SentNotifications[8];
ULONG DisabledNotifications[8];
ASSEMBLY_STORAGE_MAP* StorageMap;
ASSEMBLY_STORAGE_MAP_ENTRY* InlineStorageMapEntires;
ULONG StackTraceIndex;
PVOID StackTraces[4][4];
file_info config;
file_info appdir;
char pad[256];
} ACTIVATION_CONTEXT;
#define SEC_NO_FLAGS 0x000
/* Tells the OS to allocate space for this section when loading.
This is clear for a section containing debug information
only. */
#define SEC_ALLOC 0x001
/* Tells the OS to load the section from the file when loading.
This is clear for a .bss section. */
#define SEC_LOAD 0x002
/* The section contains data still to be relocated, so there is
some relocation information too. */
#define SEC_RELOC 0x004
#if 0 /* Obsolete ? */
#define SEC_BALIGN 0x008
#endif
/* A signal to the OS that the section contains read only
data. */
#define SEC_READONLY 0x010
/* The section contains code only. */
#define SEC_CODE 0x020
/* The section contains data only. */
#define SEC_DATA 0x040
/* The section will reside in ROM. */
#define SEC_ROM 0x080
/* The section contains constructor information. This section
type is used by the linker to create lists of constructors and
destructors used by g++. When a back end sees a symbol
which should be used in a constructor list, it creates a new
section for the type of name (e.g., __CTOR_LIST__), attaches
the symbol to it, and builds a relocation. To build the lists
of constructors, all the linker has to do is catenate all the
sections called __CTOR_LIST__ and relocate the data
contained within - exactly the operations it would peform on
standard data. */
#define SEC_CONSTRUCTOR 0x100
/* The section is a constuctor, and should be placed at the
end of the text, data, or bss section(?). */
#define SEC_CONSTRUCTOR_TEXT 0x1100
#define SEC_CONSTRUCTOR_DATA 0x2100
#define SEC_CONSTRUCTOR_BSS 0x3100
/* The section has contents - a data section could be
SEC_ALLOC | SEC_HAS_CONTENTS; a debug section could be
SEC_HAS_CONTENTS */
#define SEC_HAS_CONTENTS 0x200
/* An instruction to the linker to not output the section
even if it has information which would normally be written. */
#define SEC_NEVER_LOAD 0x400
/* The section is a COFF shared library section. This flag is
only for the linker. If this type of section appears in
the input file, the linker must copy it to the output file
without changing the vma or size. FIXME: Although this
was originally intended to be general, it really is COFF
specific (and the flag was renamed to indicate this). It
might be cleaner to have some more general mechanism to
allow the back end to control what the linker does with
sections. */
#define SEC_COFF_SHARED_LIBRARY 0x800
/* The section contains common symbols (symbols may be defined
multiple times, the value of a symbol is the amount of
space it requires, and the largest symbol value is the one
used). Most targets have exactly one of these (which we
translate to bfd_com_section_ptr), but ECOFF has two. */
#define SEC_IS_COMMON 0x8000
/* The section contains only debugging information. For
example, this is set for ELF .debug and .stab sections.
strip tests this flag to see if a section can be
discarded. */
#define SEC_DEBUGGING 0x10000
/* The contents of this section are held in memory pointed to
by the contents field. This is checked by
bfd_get_section_contents, and the data is retrieved from
memory if appropriate. */
#define SEC_IN_MEMORY 0x20000
/* The contents of this section are to be excluded by the
linker for executable and shared objects unless those
objects are to be further relocated. */
#define SEC_EXCLUDE 0x40000
/* The contents of this section are to be sorted by the
based on the address specified in the associated symbol
table. */
#define SEC_SORT_ENTRIES 0x80000
/* When linking, duplicate sections of the same name should be
discarded, rather than being combined into a single section as
is usually done. This is similar to how common symbols are
handled. See SEC_LINK_DUPLICATES below. */
#define SEC_LINK_ONCE 0x100000
/* If SEC_LINK_ONCE is set, this bitfield describes how the linker
should handle duplicate sections. */
#define SEC_LINK_DUPLICATES 0x600000
/* This value for SEC_LINK_DUPLICATES means that duplicate
sections with the same name should simply be discarded. */
#define SEC_LINK_DUPLICATES_DISCARD 0x0
/* This value for SEC_LINK_DUPLICATES means that the linker
should warn if there are any duplicate sections, although
it should still only link one copy. */
#define SEC_LINK_DUPLICATES_ONE_ONLY 0x200000
/* This value for SEC_LINK_DUPLICATES means that the linker
should warn if any duplicate sections are a different size. */
#define SEC_LINK_DUPLICATES_SAME_SIZE 0x400000
/* This value for SEC_LINK_DUPLICATES means that the linker
should warn if any duplicate sections contain different
contents. */
#define SEC_LINK_DUPLICATES_SAME_CONTENTS 0x600000
/* This section was created by the linker as part of dynamic
relocation or other arcane processing. It is skipped when
going through the first-pass output, trusting that someone
else up the line will take care of it later. */
#define SEC_LINKER_CREATED 0x800000
================================================
FILE: Src/Includes.h
================================================
#pragma once
#include <Windows.h>
#include <iostream>
#include <cassert>
#include <Psapi.h>
================================================
FILE: Src/Loader/Loader.cpp
================================================
#include "Loader.h"
using namespace WID::Loader;
LOADLIBRARY::LOADLIBRARY(TCHAR* DllPath, DWORD Flags, LOADTYPE LoadType)
{
assert(DllPath);
assert(GetFileAttributes(DllPath) != INVALID_FILE_ATTRIBUTES);
if (!bInitialized)
Init();
memcpy(CreationInfo.DllPath, DllPath, MAX_PATH * sizeof(TCHAR));
CreationInfo.Flags = Flags;
CreationInfo.LoadType = LoadType;
DllHandle = NULL;
NTSTATUS Status = STATUS_SUCCESS;
if (Status = Load(), NT_SUCCESS(Status))
{
WID_DBG(TEXT("[WID] >> (Path: %s), (Flags: %lu) load successful.\n"), DllPath, Flags);
WID_DBG(TEXT("[WID] >> Base address: %p.\n"), DllHandle);
}
else
{
WID_DBG(TEXT("[WID] >> (Path: %s), (Flags: %lu) load failed, err: 0x%X.\n"), DllPath, Flags, Status);
}
}
LOADLIBRARY::~LOADLIBRARY()
{
NTSTATUS Status = STATUS_SUCCESS;
if (Status = Unload(), NT_SUCCESS(Status))
{
WID_DBG(TEXT("[WID] >> (Path: %s), (Flags: %lu) unload successful.\n"), CreationInfo.DllPath, CreationInfo.Flags);
}
else
{
WID_DBG(TEXT("[WID] >> (Path: %s), (Flags: %lu) unload failed, err: 0x%X.\n"), CreationInfo.DllPath, CreationInfo.Flags, Status);
}
}
NTSTATUS LOADLIBRARY::Load()
{
if (!CreationInfo.DllPath)
return STATUS_INVALID_PARAMETER;
switch (CreationInfo.LoadType)
{
case LOADTYPE::DEFAULT:
//case LOADTYPE::HIDDEN:
DllHandle = fLoadLibrary(CreationInfo.DllPath);
if (!DllHandle || DllHandle == INVALID_HANDLE_VALUE)
break;
return STATUS_SUCCESS;
case LOADTYPE::HIDDEN:
WID_DBG(TEXT("[WID] >> Hidden loading isn't available currently.\n"));
default:
return STATUS_INVALID_PARAMETER;
}
return STATUS_UNSUCCESSFUL;
}
HMODULE __fastcall LOADLIBRARY::fLoadLibrary(PTCHAR lpLibFileName) // CHECKED.
{
#ifndef _UNICODE
return fLoadLibraryA(lpLibFileName);
#else
return fLoadLibraryW(lpLibFileName);
#endif
}
HMODULE __fastcall LOADLIBRARY::fLoadLibraryA(LPCSTR lpLibFileName) // CHECKED.
{
// If no path was given.
if (!lpLibFileName)
//return LoadLibraryExA(lpLibFileName, 0, 0);
return NULL;
// If path isn't 'twain_32.dll'
// This is where our LoadLibrary calls mostly end up.
if (_stricmp(lpLibFileName, "twain_32.dll"))
return fLoadLibraryExA(lpLibFileName, 0, 0);
// If path is 'twain_32.dll'
// Windows probably uses this to make itself a shortcut, while we are using it the code won't reach here.
PCHAR Heap = (PCHAR)RtlAllocateHeap(NtCurrentPeb()->ProcessHeap, *KernelBaseGlobalData, MAX_PATH);
if (!Heap)
return fLoadLibraryExA(lpLibFileName, 0, 0);
HMODULE Module;
// Heap receives the Windows path (def: C:\Windows)
// The BufferSize check made against GetWindowsDirectoryA is to see if it actually received. If it's bigger than BufferSize
// then GetWindowsDirectoryA returned the size needed (in summary it fails)
// If this check doesn't fail '\twain_32.dll' is appended to the Windows path (def: C:\Windows\twain_32.dll)
// Then this final module is loaded into the program.
// If it can't load, it tries to load it directly and returns from there.
if (GetWindowsDirectoryA(Heap, 0xF7) - 1 > 0xF5 ||
(strncat_s(Heap, MAX_PATH, "\\twain_32.dll", strlen("\\twain_32.dll")), (Module = fLoadLibraryA(Heap)) == 0))
{
RtlFreeHeap(NtCurrentPeb()->ProcessHeap, 0, Heap);
return fLoadLibraryExA(lpLibFileName, 0, 0);
}
RtlFreeHeap(NtCurrentPeb()->ProcessHeap, 0, Heap);
return Module;
}
HMODULE __fastcall LOADLIBRARY::fLoadLibraryW(LPCWSTR lpLibFileName) // CHECKED.
{
return fLoadLibraryExW(lpLibFileName, 0, 0);
}
HMODULE __fastcall LOADLIBRARY::fLoadLibraryExA(LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags) // CHECKED.
{
UNICODE_STRING Unicode;
if (!Basep8BitStringToDynamicUnicodeString(&Unicode, lpLibFileName))
return NULL;
HMODULE Module = fLoadLibraryExW(Unicode.Buffer, hFile, dwFlags);
RtlFreeUnicodeString(&Unicode);
return Module;
}
HMODULE __fastcall LOADLIBRARY::fLoadLibraryExW(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags) // CHECKED.
{
NTSTATUS Status;
DWORD ConvertedFlags;
HMODULE BaseOfLoadedDll;
DWORD DatafileFlags = dwFlags & LLEXW_ASDATAFILE;
// If no DllName was given OR hFile was given (msdn states that hFile must be 0) OR dwFlags is set to an unknown value OR *both* the Datafile flags are set (they cannot be used together).
if (!lpLibFileName || hFile || ((dwFlags & 0xFFFF0000) != 0) || (DatafileFlags == LLEXW_ASDATAFILE))
{
BaseSetLastNTError(STATUS_INVALID_PARAMETER);
return NULL;
}
UNICODE_STRING DllName;
Status = RtlInitUnicodeStringEx(&DllName, lpLibFileName);
if (!NT_SUCCESS(Status))
{
BaseSetLastNTError(Status);
return NULL;
}
USHORT DllNameLen = DllName.Length;
if (!DllName.Length)
{
BaseSetLastNTError(STATUS_INVALID_PARAMETER);
return NULL;
}
// If the DllName given had empty (space) chars as their last chars, this do-while loop excludes them and sets the excluded length.
do
{
DWORD WchAmount = DllNameLen / 2;
if (DllName.Buffer[WchAmount - 1] != ' ' /* 0x20 is space char */)
break;
DllNameLen -= 2;
DllName.Length = DllNameLen;
} while (DllNameLen != 2);
// In case the above do-while loop misbehaves.
if (DllNameLen == 0)
{
BaseSetLastNTError(STATUS_INVALID_PARAMETER);
return NULL;
}
BaseOfLoadedDll = 0;
// If the dll is not getting loaded as a datafile.
if ((dwFlags & LLEXW_ISDATAFILE) == 0)
{
// Converts the actual flags into it's own flag format. Most flags are discarded (only used if loaded as datafile).
// Only flags that can go through are DONT_RESOLVE_DLL_REFERENCES, LOAD_PACKAGED_LIBRARY, LOAD_LIBRARY_REQUIRE_SIGNED_TARGET and LOAD_LIBRARY_OS_INTEGRITY_CONTINUITY
ConvertedFlags = 0;
if ((dwFlags & DONT_RESOLVE_DLL_REFERENCES) != 0)
ConvertedFlags |= CNVTD_DONT_RESOLVE_DLL_REFERENCES;
if ((dwFlags & LOAD_PACKAGED_LIBRARY) != 0)
ConvertedFlags |= LOAD_PACKAGED_LIBRARY;
if ((dwFlags & LOAD_LIBRARY_REQUIRE_SIGNED_TARGET) != 0)
ConvertedFlags |= CNVTD_LOAD_LIBRARY_REQUIRE_SIGNED_TARGET;
if ((dwFlags & LOAD_LIBRARY_OS_INTEGRITY_CONTINUITY) != 0)
ConvertedFlags |= CNVTD_LOAD_LIBRARY_OS_INTEGRITY_CONTINUITY;
// Evaluates dwFlags to get meaningful flags, includes DONT_RESOLVE_DLL_REFERENCES finally.
// But it doesn't matter because the first param LdrLoadDll takes actually a (PWCHAR PathToFile), so I have no idea why that's done.
Status = fLdrLoadDll((PWCHAR)((dwFlags & LLEXW_7F08) | 1), &ConvertedFlags, &DllName, (PVOID*)&BaseOfLoadedDll);
if (NT_SUCCESS(Status))
return BaseOfLoadedDll;
BaseSetLastNTError(Status);
return NULL;
}
PWSTR Path;
PWSTR Unknown;
// Gets the Dll path.
Status = LdrGetDllPath(DllName.Buffer, (dwFlags & LLEXW_7F08), &Path, &Unknown);
if (!NT_SUCCESS(Status))
{
BaseSetLastNTError(Status);
return NULL;
}
// First step into loading a module as datafile.
Status = fBasepLoadLibraryAsDataFileInternal(&DllName, Path, Unknown, dwFlags, &BaseOfLoadedDll);
// If the
gitextract_m362muyh/ ├── .gitignore ├── LICENSE ├── README.md ├── Src/ │ ├── Functions/ │ │ ├── KERNEL32.cpp │ │ ├── KERNEL32.h │ │ ├── NT.cpp │ │ ├── NT.h │ │ ├── Syscalls.asm │ │ └── Undocumented.h │ ├── Includes.h │ ├── Loader/ │ │ ├── Loader.cpp │ │ └── Loader.h │ ├── Main.cpp │ ├── WID.cpp │ └── WID.h ├── WID_LoadLibrary.sln ├── WID_LoadLibrary.vcxproj └── WID_LoadLibrary.vcxproj.filters
SYMBOL INDEX (233 symbols across 9 files)
FILE: Src/Functions/KERNEL32.h
type NTSTATUS (line 16) | typedef NTSTATUS(__fastcall* tBasepLoadLibraryAsDataFileInternal)(PUNICO...
FILE: Src/Functions/NT.cpp
function PEB (line 52) | PEB* NtCurrentPeb()
function VOID (line 57) | VOID __fastcall NtdllpFreeStringRoutine(PWCH Buffer) // CHECKED.
function NTSTATUS (line 62) | NTSTATUS __fastcall LdrpFastpthReloadedDll(PUNICODE_STRING FullPath, ULO...
function NTSTATUS (line 127) | NTSTATUS __fastcall LdrpIncrementModuleLoadCount(LDR_DATA_TABLE_ENTRY* L...
function VOID (line 156) | VOID __fastcall RtlFreeUnicodeString(PUNICODE_STRING UnicodeString) // C...
function VOID (line 169) | VOID __fastcall LdrpFreeUnicodeString(PUNICODE_STRING String)
function ULONG (line 183) | ULONG __fastcall RtlGetCurrentServiceSessionId(VOID) // CHECKED ?
function USHORT (line 192) | USHORT __fastcall LdrpGetBaseNameFromFullName(PUNICODE_STRING BaseName, ...
function PWCHAR (line 217) | PWCHAR __fastcall RtlGetNtSystemRoot()
function BOOLEAN (line 225) | BOOLEAN __fastcall LdrpHpatAllocationOptOut(PUNICODE_STRING FullDllName)
function NTSTATUS (line 236) | NTSTATUS __fastcall LdrpCorValidateImage(PIMAGE_DOS_HEADER DosHeader)
function NTSTATUS (line 248) | NTSTATUS __fastcall LdrpCorFixupImage(PIMAGE_DOS_HEADER DosHeader)
function NTSTATUS (line 306) | NTSTATUS __fastcall LdrpFindLoadedDllByNameLockHeld(PUNICODE_STRING Base...
function BOOLEAN (line 374) | BOOLEAN __fastcall LdrpIsILOnlyImage(PIMAGE_DOS_HEADER DllBase)
function VOID (line 387) | VOID __fastcall LdrpAddNodeServiceTag(LDR_DDAG_NODE* DdagNode, UINT_PTR ...
function PIMAGE_LOAD_CONFIG_DIRECTORY (line 422) | PIMAGE_LOAD_CONFIG_DIRECTORY LdrImageDirectoryEntryToLoadConfig(PIMAGE_D...
function BOOLEAN (line 443) | BOOLEAN __fastcall LdrpShouldModuleImportBeRedirected(LDR_DATA_TABLE_ENT...
function PIMAGE_IMPORT_DESCRIPTOR (line 458) | PIMAGE_IMPORT_DESCRIPTOR __fastcall LdrpGetImportDescriptorForSnap(LDRP_...
function NTSTATUS (line 483) | NTSTATUS __fastcall LdrpMapCleanModuleView(LDRP_LOAD_CONTEXT* LoadContext)
function NTSTATUS (line 524) | NTSTATUS __fastcall LdrpFreeReplacedModule(LDR_DATA_TABLE_ENTRY* LdrData...
function VOID (line 533) | VOID __fastcall LdrpHandlePendingModuleReplaced(LDRP_LOAD_CONTEXT* LoadC...
function PIMAGE_SECTION_HEADER (line 546) | PIMAGE_SECTION_HEADER __fastcall RtlSectionTableFromVirtualAddress(PIMAG...
function PIMAGE_SECTION_HEADER (line 567) | PIMAGE_SECTION_HEADER __fastcall RtlAddressInSectionTable(PIMAGE_NT_HEAD...
function BOOLEAN (line 577) | BOOLEAN __fastcall LdrpValidateEntrySection(LDR_DATA_TABLE_ENTRY* DllEntry)
function BOOL (line 585) | BOOL __fastcall LdrpIsExecutableRelocatedImage(PIMAGE_DOS_HEADER DllBase)
function BOOL (line 609) | BOOL __fastcall ImageTlsCallbackCaller(HINSTANCE hInstDll, DWORD fdwReas...
function NTSTATUS (line 616) | NTSTATUS __fastcall WID::Loader::LOADLIBRARY::LdrpThreadTokenSetMainThre...
function NTSTATUS (line 630) | NTSTATUS __fastcall WID::Loader::LOADLIBRARY::LdrpThreadTokenUnsetMainTh...
function NTSTATUS (line 660) | NTSTATUS __fastcall WID::Loader::LOADLIBRARY::LdrpFreeReplacedModule(LDR...
function NTSTATUS (line 671) | NTSTATUS __fastcall WID::Loader::LOADLIBRARY::LdrpResolveDllName(LDRP_LO...
function NTSTATUS (line 762) | NTSTATUS __fastcall WID::Loader::LOADLIBRARY::LdrpFindDllActivationConte...
FILE: Src/Functions/NT.h
type NTSTATUS (line 85) | typedef NTSTATUS(__fastcall** tLdrpManifestProberRoutine)(PIMAGE_DOS_HEA...
type BOOLEAN (line 87) | typedef BOOLEAN(__fastcall** tLdrpRedirectionCalloutFunc)(PWCHAR Buffer);
type NTSTATUS (line 130) | typedef NTSTATUS(__fastcall* tNtOpenThreadToken)(IN HANDLE ThreadHandle,...
type NTSTATUS (line 133) | typedef NTSTATUS(__fastcall* tNtClose)(HANDLE Handle);
type PVOID (line 136) | typedef PVOID(__fastcall* tRtlAllocateHeap)(IN PVOID HeapHandle, IN OPTI...
type BOOLEAN (line 139) | typedef BOOLEAN(__fastcall* tRtlFreeHeap)(IN PVOID HeapHandle, IN OPTION...
type NTSTATUS (line 142) | typedef NTSTATUS(__fastcall* tLdrGetDllPath)(PWCH DllName, DWORD dwFlags...
type VOID (line 145) | typedef VOID(__fastcall* tRtlReleasePath)(IN PWSTR);
type NTSTATUS (line 148) | typedef NTSTATUS(__fastcall* tRtlInitUnicodeStringEx)(PUNICODE_STRING ta...
type NTSTATUS (line 151) | typedef NTSTATUS(__fastcall* tRtlEnterCriticalSection)(PRTL_CRITICAL_SEC...
type NTSTATUS (line 154) | typedef NTSTATUS(__fastcall* tRtlLeaveCriticalSection)(PRTL_CRITICAL_SEC...
type NTSTATUS (line 157) | typedef NTSTATUS(__fastcall* tZwSetEvent)(HANDLE EventHandle, PLONG Prev...
type NTSTATUS (line 160) | typedef NTSTATUS(__fastcall* tNtOpenFile)(PHANDLE FileHandle, ACCESS_MAS...
type NTSTATUS (line 163) | typedef NTSTATUS(__fastcall* tLdrAppxHandleIntegrityFailure)(NTSTATUS St...
type NTSTATUS (line 166) | typedef NTSTATUS(__fastcall* tNtRaiseHardError)(NTSTATUS Status, ULONG N...
type NTSTATUS (line 169) | typedef NTSTATUS(__fastcall* tRtlImageNtHeaderEx)(ULONG Flags, PVOID Bas...
type VOID (line 172) | typedef VOID(__fastcall* tRtlAcquireSRWLockExclusive)(PRTL_SRWLOCK SRWLo...
type NTSTATUS (line 175) | typedef NTSTATUS(__fastcall* tRtlReleaseSRWLockExclusive)(PRTL_SRWLOCK S...
type NTSTATUS (line 178) | typedef NTSTATUS(__fastcall* tRtlEqualUnicodeString)(PUNICODE_STRING Str...
type NTSTATUS (line 181) | typedef NTSTATUS(__fastcall* tRtlAcquirePrivilege)(ULONG* Privilege,ULON...
type VOID (line 184) | typedef VOID(__fastcall* tRtlReleasePrivilege)(PVOID ReturnedState);
type NTSTATUS (line 187) | typedef NTSTATUS(__fastcall* tRtlCompareUnicodeStrings)(PWCH String1, UI...
type PIMAGE_NT_HEADERS (line 190) | typedef PIMAGE_NT_HEADERS(__fastcall* tRtlImageNtHeader)(PIMAGE_DOS_HEAD...
type UINT_PTR (line 193) | typedef UINT_PTR(__fastcall* tRtlReleaseActivationContext)(ACTIVATION_CO...
type NTSTATUS (line 196) | typedef NTSTATUS(__fastcall* tRtlCharToInteger)(const PCHAR String, ULON...
type NTSTATUS (line 199) | typedef NTSTATUS(__fastcall* tRtlActivateActivationContextUnsafeFast)(RT...
type VOID (line 202) | typedef VOID(__fastcall* tRtlDeactivateActivationContextUnsafeFast)(RTL_...
type NTSTATUS (line 205) | typedef NTSTATUS(__fastcall* tRtlAcquireSRWLockShared)(PRTL_SRWLOCK SrwL...
type NTSTATUS (line 208) | typedef NTSTATUS(__fastcall* tRtlReleaseSRWLockShared)(PRTL_SRWLOCK SrwL...
type NTSTATUS (line 213) | typedef NTSTATUS(__fastcall* tLdrpLogInternal)(PCHAR, ULONG, PCHAR, ULON...
type NTSTATUS (line 217) | typedef NTSTATUS(__fastcall* tLdrpInitializeDllPath)(PWSTR DllName, PWST...
type NTSTATUS (line 221) | typedef NTSTATUS(__fastcall* tLdrpDereferenceModule)(LDR_DATA_TABLE_ENTR...
type NTSTATUS (line 225) | typedef NTSTATUS(__fastcall* tLdrpLogDllState)(UINT_PTR, PUNICODE_STRING...
type NTSTATUS (line 229) | typedef NTSTATUS(__fastcall* tLdrpPreprocessDllName)(PUNICODE_STRING Dll...
type NTSTATUS (line 233) | typedef NTSTATUS(__fastcall* tLdrpFindLoadedDllByName)(PUNICODE_STRING F...
type TEB (line 237) | typedef TEB* (__fastcall* tLdrpDrainWorkQueue)(DRAIN_TASK DrainTask);
type NTSTATUS (line 241) | typedef NTSTATUS(__fastcall* tLdrpFindLoadedDllByHandle)(unsigned __int6...
type NTSTATUS (line 245) | typedef NTSTATUS(__fastcall* tLdrpDropLastInProgressCount)();
type NTSTATUS (line 249) | typedef NTSTATUS(__fastcall* tLdrpQueryCurrentPatch)(ULONG Checksum, ULO...
type NTSTATUS (line 253) | typedef NTSTATUS(__fastcall* tLdrpUndoPatchImage)(PLDR_DATA_TABLE_ENTRY ...
type VOID (line 257) | typedef VOID(__fastcall* tLdrpDetectDetour)();
type NTSTATUS (line 261) | typedef NTSTATUS(__fastcall* tLdrpFindOrPrepareLoadingModule)(PUNICODE_S...
type VOID (line 265) | typedef VOID(__fastcall* tLdrpFreeLoadContext)(PLDRP_LOAD_CONTEXT LoadCo...
type PVOID (line 269) | typedef PVOID* (__fastcall* tLdrpCondenseGraph)(LDR_DDAG_NODE* DdagNode);
type NTSTATUS (line 273) | typedef NTSTATUS(__fastcall* tLdrpBuildForwarderLink)(PLDR_DATA_TABLE_EN...
type NTSTATUS (line 277) | typedef NTSTATUS(__fastcall* tLdrpPinModule)(PLDR_DATA_TABLE_ENTRY LdrEn...
type NTSTATUS (line 281) | typedef NTSTATUS(__fastcall* tLdrpApplyPatchImage)(PLDR_DATA_TABLE_ENTRY...
type NTSTATUS (line 285) | typedef NTSTATUS(__fastcall* tLdrpFreeLoadContextOfNode)(PLDR_DDAG_NODE ...
type NTSTATUS (line 289) | typedef NTSTATUS(__fastcall* tLdrpDecrementModuleLoadCountEx)(PLDR_DATA_...
type PEB (line 293) | typedef PEB*(__fastcall* tLdrpLogError)(NTSTATUS Status, ULONG, ULONG, P...
type WCHAR (line 297) | typedef WCHAR*(__fastcall* tLdrpLogDeprecatedDllEtwEvent)(PLDRP_LOAD_CON...
type VOID (line 301) | typedef VOID(__fastcall* tLdrpLogLoadFailureEtwEvent)(PVOID Unknown, PVO...
type NTSTATUS (line 305) | typedef NTSTATUS(__fastcall* tLdrpReportError)(PVOID Report, ULONG Unkno...
type NTSTATUS (line 309) | typedef NTSTATUS(__fastcall* tLdrpResolveDllName)(PLDRP_LOAD_CONTEXT Fil...
type NTSTATUS (line 313) | typedef NTSTATUS(__fastcall* tLdrpAppCompatRedirect)(PLDRP_LOAD_CONTEXT ...
type ULONG (line 317) | typedef ULONG(__fastcall* tLdrpHashUnicodeString)(PUNICODE_STRING BaseDl...
type NTSTATUS (line 321) | typedef NTSTATUS(__fastcall* tLdrpFindExistingModule)(PUNICODE_STRING Ba...
type NTSTATUS (line 325) | typedef NTSTATUS(__fastcall* tLdrpLoadContextReplaceModule)(PLDRP_LOAD_C...
type NTSTATUS (line 329) | typedef NTSTATUS(__fastcall* tLdrpSearchPath)(LDRP_LOAD_CONTEXT* LoadCon...
type BOOLEAN (line 333) | typedef BOOLEAN(__fastcall* tLdrpIsSecurityEtwLoggingEnabled)();
type VOID (line 337) | typedef VOID(__fastcall* tLdrpLogEtwDllSearchResults)(ULONG Flags, LDRP_...
type BOOLEAN (line 341) | typedef BOOLEAN(__fastcall* tLdrpCheckForRetryLoading)(PLDRP_LOAD_CONTEX...
type NTSTATUS (line 345) | typedef NTSTATUS(__fastcall* tLdrpLogEtwEvent)(ULONG a1, ULONGLONG a2, U...
type BOOLEAN (line 349) | typedef BOOLEAN(__fastcall* tLdrpCheckComponentOnDemandEtwEvent)(LDRP_LO...
type NTSTATUS (line 353) | typedef NTSTATUS(__fastcall* tLdrpValidateIntegrityContinuity)(PLDRP_LOA...
type NTSTATUS (line 357) | typedef NTSTATUS(__fastcall* tLdrpSetModuleSigningLevel)(HANDLE FileHand...
type NTSTATUS (line 361) | typedef NTSTATUS(__fastcall* tLdrpCodeAuthzCheckDllAllowed)(LDRP_FILENAM...
type NTSTATUS (line 365) | typedef NTSTATUS(__fastcall* tLdrpGetFullPath)(PLDRP_LOAD_CONTEXT LoadCo...
type NTSTATUS (line 369) | typedef NTSTATUS(__fastcall* tLdrpAllocateUnicodeString)(PUNICODE_STRING...
type NTSTATUS (line 373) | typedef NTSTATUS(__fastcall* tLdrpAppendUnicodeStringToFilenameBuffer)(P...
type NTSTATUS (line 377) | typedef NTSTATUS(__fastcall* tLdrpGetNtPathFromDosPath)(PUNICODE_STRING ...
type NTSTATUS (line 381) | typedef NTSTATUS(__fastcall* tLdrpFindLoadedDllByMappingLockHeld)(PIMAGE...
type VOID (line 385) | typedef VOID(__fastcall* tLdrpInsertDataTableEntry)(PLDR_DATA_TABLE_ENTR...
type NTSTATUS (line 389) | typedef NTSTATUS(__fastcall* tLdrpInsertModuleToIndexLockHeld)(PLDR_DATA...
type NTSTATUS (line 393) | typedef NTSTATUS(__fastcall* tLdrpLogEtwHotPatchStatus)(PUNICODE_STRING ...
type PEB (line 397) | typedef PEB*(__fastcall* tLdrpLogNewDllLoad)(LDR_DATA_TABLE_ENTRY* LdrEn...
type NTSTATUS (line 401) | typedef NTSTATUS(__fastcall* tLdrpProcessMachineMismatch)(PLDRP_LOAD_CON...
type NTSTATUS (line 405) | typedef NTSTATUS(__fastcall* tRtlQueryImageFileKeyOption)(HANDLE hKey, P...
type NTSTATUS (line 409) | typedef NTSTATUS(__fastcall* tRtlpImageDirectoryEntryToDataEx)(PIMAGE_DO...
type PVOID (line 413) | typedef PVOID(__fastcall* tLdrpLogDllRelocationEtwEvent)(PUNICODE_STRING...
type NTSTATUS (line 417) | typedef NTSTATUS(__fastcall* tLdrpNotifyLoadOfGraph)(LDR_DDAG_NODE* Ddag...
type NTSTATUS (line 421) | typedef NTSTATUS(__fastcall* tLdrpDynamicShimModule)(LDR_DDAG_NODE* Ddag...
type NTSTATUS (line 425) | typedef NTSTATUS(__fastcall* tLdrpAcquireLoaderLock)();
type NTSTATUS (line 429) | typedef NTSTATUS(__fastcall* tLdrpReleaseLoaderLock)(ULONG64 Unused, ULO...
type BOOLEAN (line 433) | typedef BOOLEAN(__fastcall* tLdrpCheckPagesForTampering)(PIMAGE_DATA_DIR...
type NTSTATUS (line 437) | typedef NTSTATUS(__fastcall* tLdrpLoadDependentModuleA)(PUNICODE_STRING ...
type NTSTATUS (line 441) | typedef NTSTATUS(__fastcall* tLdrpLoadDependentModuleW)(PUNICODE_STRING ...
type NTSTATUS (line 445) | typedef NTSTATUS(__fastcall* tLdrpQueueWork)(PLDRP_LOAD_CONTEXT LoadCont...
type NTSTATUS (line 449) | typedef NTSTATUS(__fastcall* tLdrpHandleTlsData)(LDR_DATA_TABLE_ENTRY* L...
type BOOLEAN (line 453) | typedef BOOLEAN(__fastcall* tLdrControlFlowGuardEnforcedWithExportSuppre...
type __int64 (line 457) | typedef __int64(__fastcall* tLdrpUnsuppressAddressTakenIat)(PIMAGE_DOS_H...
type BOOL (line 461) | typedef BOOL(__fastcall* tLdrControlFlowGuardEnforced)();
type PIMAGE_RUNTIME_FUNCTION_ENTRY (line 465) | typedef PIMAGE_RUNTIME_FUNCTION_ENTRY(__fastcall* tRtlpxLookupFunctionTa...
type PCHAR (line 469) | typedef PCHAR(__fastcall* tLdrpCheckRedirection)(LDR_DATA_TABLE_ENTRY* D...
type BOOL (line 473) | typedef BOOL(__fastcall* tCompatCachepLookupCdb)(PWCHAR Buffer, LONG Unk...
type UINT_PTR (line 477) | typedef UINT_PTR(__fastcall* tLdrpGenRandom)();
type BOOL (line 481) | typedef BOOL(__fastcall* tLdrInitSecurityCookie)(PIMAGE_DOS_HEADER DllBa...
type NTSTATUS (line 485) | typedef NTSTATUS(__fastcall* tLdrpCfgProcessLoadConfig)(LDR_DATA_TABLE_E...
type NTSTATUS (line 489) | typedef NTSTATUS(__fastcall* tRtlInsertInvertedFunctionTable)(PIMAGE_DOS...
type LDR_DDAG_NODE (line 493) | typedef LDR_DDAG_NODE*(__fastcall* tLdrpSignalModuleMapped)(LDR_DATA_TAB...
type NTSTATUS (line 497) | typedef NTSTATUS(__fastcall* tAVrfDllLoadNotification)(LDR_DATA_TABLE_EN...
type NTSTATUS (line 501) | typedef NTSTATUS(__fastcall* tLdrpSendDllNotifications)(LDR_DATA_TABLE_E...
type NTSTATUS (line 505) | typedef NTSTATUS(__fastcall* tLdrpCallTlsInitializers)(ULONG One, LDR_DA...
FILE: Src/Functions/Undocumented.h
type LSA_UNICODE_STRING (line 7) | typedef struct _LSA_UNICODE_STRING {
type STRING (line 13) | typedef struct _STRING {
type CURDIR (line 22) | typedef struct _CURDIR
type RTL_DRIVE_LETTER_CURDIR (line 31) | typedef struct _RTL_DRIVE_LETTER_CURDIR
type RTL_USER_PROCESS_PARAMETERS (line 42) | typedef struct _RTL_USER_PROCESS_PARAMETERS
type PEB_LDR_DATA (line 85) | typedef struct _PEB_LDR_DATA {
type RTL_BALANCED_NODE (line 100) | typedef struct _RTL_BALANCED_NODE
type LDR_SERVICE_TAG_RECORD (line 123) | typedef struct _LDR_SERVICE_TAG_RECORD
type LDRP_CSLIST (line 130) | typedef struct _LDRP_CSLIST
type LDR_DDAG_STATE (line 136) | typedef enum _LDR_DDAG_STATE
type LDR_DDAG_NODE (line 156) | typedef struct _LDR_DDAG_NODE
type LDR_DEPENDENCY_RECORD (line 179) | typedef struct _LDR_DEPENDENCY_RECORD
type LDR_DLL_LOAD_REASON (line 188) | typedef enum _LDR_DLL_LOAD_REASON
type LDR_HOT_PATCH_STATE (line 203) | typedef enum _LDR_HOT_PATCH_STATE
type LDR_DATA_TABLE_ENTRY (line 247) | typedef struct _LDR_DATA_TABLE_ENTRY
type KSYSTEM_TIME (line 326) | typedef struct _KSYSTEM_TIME
type NT_PRODUCT_TYPE (line 333) | typedef enum _NT_PRODUCT_TYPE
type ALTERNATIVE_ARCHITECTURE_TYPE (line 340) | typedef enum _ALTERNATIVE_ARCHITECTURE_TYPE
type KUSER_SHARED_DATA (line 347) | typedef struct _KUSER_SHARED_DATA {
type DRAIN_TASK (line 473) | enum DRAIN_TASK
type PEB (line 479) | typedef struct _PEB {
type FUNCTION_TABLE_DATA (line 590) | struct FUNCTION_TABLE_DATA
type OBJECT_ATTRIBUTES (line 598) | typedef struct _OBJECT_ATTRIBUTES {
type HARDERROR_RESPONSE_OPTION (line 607) | enum HARDERROR_RESPONSE_OPTION
type HARDERROR_RESPONSE (line 618) | enum HARDERROR_RESPONSE
type IO_STATUS_BLOCK (line 631) | typedef struct _IO_STATUS_BLOCK {
type CLIENT_ID (line 639) | typedef struct _CLIENT_ID {
type _RTL_ACTIVATION_CONTEXT_STACK_FRAME (line 644) | struct _RTL_ACTIVATION_CONTEXT_STACK_FRAME
type _ACTIVATION_CONTEXT (line 645) | struct _ACTIVATION_CONTEXT
type _TEB_ACTIVE_FRAME (line 646) | struct _TEB_ACTIVE_FRAME
type _TEB_ACTIVE_FRAME_CONTEXT (line 647) | struct _TEB_ACTIVE_FRAME_CONTEXT
type RTL_ACTIVATION_CONTEXT_STACK_FRAME (line 649) | typedef struct _RTL_ACTIVATION_CONTEXT_STACK_FRAME {
type ACTIVATION_CONTEXT_STACK (line 655) | typedef struct _ACTIVATION_CONTEXT_STACK
type RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_BASIC (line 664) | typedef struct _RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_BASIC
type RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED (line 671) | typedef struct _RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTE...
type GDI_TEB_BATCH (line 684) | typedef struct _GDI_TEB_BATCH
type TEB_ACTIVE_FRAME_CONTEXT (line 691) | typedef struct _TEB_ACTIVE_FRAME_CONTEXT
type TEB_ACTIVE_FRAME (line 697) | typedef struct _TEB_ACTIVE_FRAME
type PROCESSOR_NUMBER (line 705) | typedef struct _PROCESSOR_NUMBER {
type TEB (line 712) | typedef struct _TEB
type LDR_UNKSTRUCT (line 858) | struct LDR_UNKSTRUCT
type LDR_UNKSTRUCT2 (line 869) | struct LDR_UNKSTRUCT2
type LDR_UNKSTRUCT3 (line 875) | struct LDR_UNKSTRUCT3
type LDRP_LOAD_CONTEXT (line 881) | typedef struct _LDRP_LOAD_CONTEXT
type LDRP_FILENAME_BUFFER (line 910) | struct LDRP_FILENAME_BUFFER
function wchar_t (line 913) | wchar_t FileName[128]{}
type MEMORY_IMAGE_INFORMATION (line 916) | typedef struct _MEMORY_IMAGE_INFORMATION
type TLS_ENTRY (line 933) | typedef struct _TLS_ENTRY
type SECTION_INHERIT (line 941) | enum SECTION_INHERIT
type MEMORY_WORKING_SET_EX_BLOCK (line 956) | typedef struct _MEMORY_WORKING_SET_EX_BLOCK
type MEMORY_WORKING_SET_EX_INFORMATION (line 999) | typedef struct _MEMORY_WORKING_SET_EX_INFORMATION
type MEMORY_INFORMATION_CLASS (line 1009) | typedef enum _MEMORY_INFORMATION_CLASS
type PROCESSINFOCLASS (line 1028) | typedef enum _PROCESSINFOCLASS
type file_info (line 1145) | typedef struct _file_info
type ASSEMBLY_STORAGE_MAP (line 1151) | typedef struct _ASSEMBLY_STORAGE_MAP
type ASSEMBLY_STORAGE_MAP_ENTRY (line 1158) | typedef struct _ASSEMBLY_STORAGE_MAP_ENTRY
type ACTIVATION_CONTEXT (line 1165) | typedef struct _ACTIVATION_CONTEXT
FILE: Src/Loader/Loader.cpp
function NTSTATUS (line 44) | NTSTATUS LOADLIBRARY::Load()
function HMODULE (line 68) | HMODULE __fastcall LOADLIBRARY::fLoadLibrary(PTCHAR lpLibFileName) // CH...
function HMODULE (line 77) | HMODULE __fastcall LOADLIBRARY::fLoadLibraryA(LPCSTR lpLibFileName) // C...
function HMODULE (line 115) | HMODULE __fastcall LOADLIBRARY::fLoadLibraryW(LPCWSTR lpLibFileName) // ...
function HMODULE (line 120) | HMODULE __fastcall LOADLIBRARY::fLoadLibraryExA(LPCSTR lpLibFileName, HA...
function HMODULE (line 131) | HMODULE __fastcall LOADLIBRARY::fLoadLibraryExW(LPCWSTR lpLibFileName, H...
function NTSTATUS (line 233) | NTSTATUS __fastcall LOADLIBRARY::fLdrLoadDll(PWSTR DllPath, PULONG pFlag...
function NTSTATUS (line 311) | NTSTATUS __fastcall LOADLIBRARY::fLdrpLoadDll(PUNICODE_STRING DllName, L...
function NTSTATUS (line 353) | NTSTATUS __fastcall LOADLIBRARY::fLdrpLoadDllInternal(PUNICODE_STRING Fu...
function NTSTATUS (line 582) | NTSTATUS __fastcall LOADLIBRARY::fLdrpProcessWork(PLDRP_LOAD_CONTEXT Loa...
function NTSTATUS (line 660) | NTSTATUS __fastcall LOADLIBRARY::fLdrpSnapModule(PLDRP_LOAD_CONTEXT Load...
function NTSTATUS (line 1389) | NTSTATUS __fastcall LOADLIBRARY::fLdrpDoPostSnapWork(LDRP_LOAD_CONTEXT* ...
function NTSTATUS (line 1426) | NTSTATUS __fastcall LOADLIBRARY::fLdrpMapDllRetry(PLDRP_LOAD_CONTEXT Loa...
function NTSTATUS (line 1433) | NTSTATUS __fastcall LOADLIBRARY::fLdrpMapDllFullPath(PLDRP_LOAD_CONTEXT ...
function NTSTATUS (line 1489) | NTSTATUS __fastcall LOADLIBRARY::fLdrpMapDllSearchPath(PLDRP_LOAD_CONTEX...
function NTSTATUS (line 1622) | NTSTATUS __fastcall LOADLIBRARY::fLdrpMapDllNtFileName(PLDRP_LOAD_CONTEX...
function NTSTATUS (line 1750) | NTSTATUS __fastcall LOADLIBRARY::fLdrpMapDllWithSectionHandle(PLDRP_LOAD...
function NTSTATUS (line 1871) | NTSTATUS __fastcall LOADLIBRARY::fLdrpMinimalMapModule(PLDRP_LOAD_CONTEX...
function NTSTATUS (line 1969) | NTSTATUS __fastcall LOADLIBRARY::fLdrpMapViewOfSection(HANDLE SectionHan...
function NTSTATUS (line 1982) | NTSTATUS __fastcall LOADLIBRARY::fLdrpCompleteMapModule(PLDRP_LOAD_CONTE...
function NTSTATUS (line 2074) | NTSTATUS __fastcall LOADLIBRARY::fLdrpRelocateImage(PIMAGE_DOS_HEADER Dl...
function NTSTATUS (line 2108) | NTSTATUS __fastcall LOADLIBRARY::fLdrpProtectAndRelocateImage(PIMAGE_DOS...
function NTSTATUS (line 2155) | NTSTATUS __fastcall LOADLIBRARY::fLdrpSetProtection(PIMAGE_DOS_HEADER Dl...
function NTSTATUS (line 2204) | NTSTATUS __fastcall LOADLIBRARY::fLdrRelocateImageWithBias(PIMAGE_DOS_HE...
function PIMAGE_NT_HEADERS (line 2258) | PIMAGE_NT_HEADERS __fastcall LOADLIBRARY::fLdrProcessRelocationBlockLong...
function NTSTATUS (line 2265) | NTSTATUS __fastcall LOADLIBRARY::fLdrpProcessMappedModule(PLDR_DATA_TABL...
function NTSTATUS (line 2327) | NTSTATUS __fastcall LOADLIBRARY::fLdrpCorProcessImports(PLDR_DATA_TABLE_...
function NTSTATUS (line 2342) | NTSTATUS __fastcall LOADLIBRARY::fLdrpMapAndSnapDependency(PLDRP_LOAD_CO...
function NTSTATUS (line 2545) | NTSTATUS __fastcall LOADLIBRARY::fLdrpPrepareImportAddressTableForSnap(L...
function NTSTATUS (line 2639) | NTSTATUS __fastcall LOADLIBRARY::fLdrpPrepareModuleForExecution(PLDR_DAT...
function NTSTATUS (line 2700) | NTSTATUS __fastcall LOADLIBRARY::fLdrpInitializeGraphRecurse(LDR_DDAG_NO...
function NTSTATUS (line 2776) | NTSTATUS __fastcall LOADLIBRARY::fLdrpInitializeNode(LDR_DDAG_NODE* Ddag...
function BOOL (line 2872) | BOOL __fastcall LOADLIBRARY::fLdrpCallTlsInitializers(DWORD fdwReason, L...
function BOOLEAN (line 2903) | BOOLEAN __fastcall LOADLIBRARY::fLdrpCallInitRoutine(BOOL(__fastcall* Dl...
function NTSTATUS (line 2959) | NTSTATUS __fastcall LOADLIBRARY::fBasepLoadLibraryAsDataFileInternal(PUN...
function NTSTATUS (line 2965) | NTSTATUS LOADLIBRARY::Unload()
FILE: Src/Loader/Loader.h
function namespace (line 69) | namespace WID
FILE: Src/Main.cpp
function main (line 5) | int main()
FILE: Src/WID.cpp
function NTSTATUS (line 8) | NTSTATUS WID::Init()
function PVOID (line 200) | PVOID WID::Helper::SigScan(PCHAR StartAddress, SIZE_T Len, PCHAR Pattern...
FILE: Src/WID.h
function namespace (line 21) | namespace WID
Condensed preview — 18 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (362K chars).
[
{
"path": ".gitignore",
"chars": 340,
"preview": "################################################################################\n# Bu .gitignore dosyası Microsoft(R) V"
},
{
"path": "LICENSE",
"chars": 1066,
"preview": "MIT License\n\nCopyright (c) 2023 Paskalian\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\n"
},
{
"path": "README.md",
"chars": 67995,
"preview": "\n\n<br>\n\n# LEGAL NOTICE\n<ins><b>I do not take responsibility for any misuse of thes"
},
{
"path": "Src/Functions/KERNEL32.cpp",
"chars": 297,
"preview": "#include \"KERNEL32.h\"\n\nULONG* KernelBaseGlobalData = nullptr;\n\ntBasep8BitStringToDynamicUnicodeString Basep8BitStringToD"
},
{
"path": "Src/Functions/KERNEL32.h",
"chars": 815,
"preview": "#pragma once\n\n#include \"..\\Includes.h\"\n#include \"Undocumented.h\"\n\nextern ULONG* KernelBaseGlobalData;\n\ntypedef BOOLEAN(W"
},
{
"path": "Src/Functions/NT.cpp",
"chars": 41307,
"preview": "#include \"NT.h\"\n\n// Implemented.\n// Variables\nDWORD* LdrpPolicyBits = nullptr;\nHANDLE*"
},
{
"path": "Src/Functions/NT.h",
"chars": 34480,
"preview": "#pragma once\n\n#include \"..\\Includes.h\"\n#include \"..\\WID.h\"\n#include \"Undocumented.h\"\n\n\n#define NT_SUCCESS(x) ((x)>=0)\n#d"
},
{
"path": "Src/Functions/Syscalls.asm",
"chars": 1702,
"preview": ".code\nZwSystemDebugControl proc\n \n\tmov r10, rcx\n\tmov eax, 1CDh\n\ttest byte ptr [7FFE0308h], 1 ; KUSER_SHARED_DATA.SystemC"
},
{
"path": "Src/Functions/Undocumented.h",
"chars": 43656,
"preview": "#pragma once\n\n#include \"..\\Includes.h\"\n\ntypedef void* PPS_POST_PROCESS_INIT_ROUTINE;\n\ntypedef struct _LSA_UNICODE_STRING"
},
{
"path": "Src/Includes.h",
"chars": 92,
"preview": "#pragma once\n\n#include <Windows.h>\n#include <iostream>\n#include <cassert>\n#include <Psapi.h>"
},
{
"path": "Src/Loader/Loader.cpp",
"chars": 99464,
"preview": "#include \"Loader.h\"\n\nusing namespace WID::Loader;\nLOADLIBRARY::LOADLIBRARY(TCHAR* DllPath, DWORD Flags, LOADTYPE LoadTyp"
},
{
"path": "Src/Loader/Loader.h",
"chars": 7612,
"preview": "#pragma once\n\n#include \"..\\WID.h\"\n\n#define LLEXW_ISDATAFILE\t(LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_IMAGE_RESOURCE |"
},
{
"path": "Src/Main.cpp",
"chars": 156,
"preview": "#include \"WID.h\"\n\n#pragma warning(disable : 6031)\n\nint main()\n{\n\t{\n\t\tWID::Loader::LOADLIBRARY Test(TEXT(\"PATH_TO_DLL.dll"
},
{
"path": "Src/WID.cpp",
"chars": 30221,
"preview": "#include \"WID.h\"\n\nBOOLEAN\t\tWID::bInitialized\t\t\t= FALSE;\nMODULEINFO\tWID::Kernel32ModuleInfo\t\t= {};\nMODULEINFO\tWID::Kernel"
},
{
"path": "Src/WID.h",
"chars": 647,
"preview": "#pragma once\n\n#include \"Includes.h\"\n\n#include \"Functions/KERNEL32.h\"\n#include \"Functions/NT.h\"\n#include \"Functions/Undoc"
},
{
"path": "WID_LoadLibrary.sln",
"chars": 1417,
"preview": "\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio Version 17\nVisualStudioVersion = 17.4.3321"
},
{
"path": "WID_LoadLibrary.vcxproj",
"chars": 6147,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msb"
},
{
"path": "WID_LoadLibrary.vcxproj.filters",
"chars": 2068,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuil"
}
]
About this extraction
This page contains the full source code of the paskalian/WID_LoadLibrary GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 18 files (331.5 KB), approximately 97.0k tokens, and a symbol index with 233 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.