| 212 | } |
| 213 | |
| 214 | std::unique_ptr<ModuleNotification> |
| 215 | Environment::onModuleLoaded(QObject* o, std::function<void(Module)> f) |
| 216 | { |
| 217 | typedef struct _UNICODE_STRING |
| 218 | { |
| 219 | USHORT Length; |
| 220 | USHORT MaximumLength; |
| 221 | PWSTR Buffer; |
| 222 | } UNICODE_STRING, *PUNICODE_STRING; |
| 223 | |
| 224 | typedef const PUNICODE_STRING PCUNICODE_STRING; |
| 225 | |
| 226 | typedef struct _LDR_DLL_LOADED_NOTIFICATION_DATA |
| 227 | { |
| 228 | ULONG Flags; // Reserved. |
| 229 | PCUNICODE_STRING FullDllName; // The full path name of the DLL module. |
| 230 | PCUNICODE_STRING BaseDllName; // The base file name of the DLL module. |
| 231 | PVOID DllBase; // A pointer to the base address for the DLL in memory. |
| 232 | ULONG SizeOfImage; // The size of the DLL image, in bytes. |
| 233 | } LDR_DLL_LOADED_NOTIFICATION_DATA, *PLDR_DLL_LOADED_NOTIFICATION_DATA; |
| 234 | |
| 235 | typedef struct _LDR_DLL_UNLOADED_NOTIFICATION_DATA |
| 236 | { |
| 237 | ULONG Flags; // Reserved. |
| 238 | PCUNICODE_STRING FullDllName; // The full path name of the DLL module. |
| 239 | PCUNICODE_STRING BaseDllName; // The base file name of the DLL module. |
| 240 | PVOID DllBase; // A pointer to the base address for the DLL in memory. |
| 241 | ULONG SizeOfImage; // The size of the DLL image, in bytes. |
| 242 | } LDR_DLL_UNLOADED_NOTIFICATION_DATA, *PLDR_DLL_UNLOADED_NOTIFICATION_DATA; |
| 243 | |
| 244 | typedef union _LDR_DLL_NOTIFICATION_DATA |
| 245 | { |
| 246 | LDR_DLL_LOADED_NOTIFICATION_DATA Loaded; |
| 247 | LDR_DLL_UNLOADED_NOTIFICATION_DATA Unloaded; |
| 248 | } LDR_DLL_NOTIFICATION_DATA, *PLDR_DLL_NOTIFICATION_DATA; |
| 249 | |
| 250 | typedef VOID CALLBACK LDR_DLL_NOTIFICATION_FUNCTION( |
| 251 | ULONG NotificationReason, const PLDR_DLL_NOTIFICATION_DATA NotificationData, |
| 252 | PVOID Context); |
| 253 | |
| 254 | typedef LDR_DLL_NOTIFICATION_FUNCTION* PLDR_DLL_NOTIFICATION_FUNCTION; |
| 255 | |
| 256 | typedef NTSTATUS NTAPI LdrRegisterDllNotificationType( |
| 257 | ULONG Flags, PLDR_DLL_NOTIFICATION_FUNCTION NotificationFunction, PVOID Context, |
| 258 | PVOID * Cookie); |
| 259 | |
| 260 | const ULONG LDR_DLL_NOTIFICATION_REASON_LOADED = 1; |
| 261 | const ULONG LDR_DLL_NOTIFICATION_REASON_UNLOADED = 2; |
| 262 | |
| 263 | // loading ntdll.dll, the function will be found with GetProcAddress() |
| 264 | LibraryPtr ntdll(LoadLibraryW(L"ntdll.dll")); |
| 265 | |
| 266 | if (!ntdll) { |
| 267 | log::error("failed to load ntdll.dll while registering for module notifications"); |
| 268 | return {}; |
| 269 | } |
| 270 | |
| 271 | auto* LdrRegisterDllNotification = reinterpret_cast<LdrRegisterDllNotificationType*>( |