Windows Driver Kit: Kernel-Mode Driver Architecture
PsSetLoadImageNotifyRoutine
The PsSetLoadImageNotifyRoutine routine registers a driver-supplied callback that is subsequently notified whenever an image is loaded (or mapped into memory).
NTSTATUS
PsSetLoadImageNotifyRoutine(
IN PLOAD_IMAGE_NOTIFY_ROUTINE NotifyRoutine
);
Parameters
- NotifyRoutine
- Specifies the entry point of the caller-supplied load-image callback.
Return Value
PsSetLoadImageNotifyRoutine either returns STATUS_SUCCESS or it returns STATUS_INSUFFICIENT_RESOURCES if it failed the callback registration.
Comments
Highest-level system-profiling drivers can call PsSetLoadImageNotifyRoutine to set up their load-image notify routines, declared as follows:
VOID
(*PLOAD_IMAGE_NOTIFY_ROUTINE) (
IN PUNICODE_STRING FullImageName,
IN HANDLE ProcessId, // where image is mapped
IN PIMAGE_INFO ImageInfo
);
After such a driver's callback has been registered, the system calls its load-image notify routine whenever an executable image is mapped into virtual memory, whether in system space or user space, before the execution of the image begins.
A driver must remove any callbacks it registers before it unloads. You can remove the callback by calling the PsRemoveLoadImageNotifyRoutine routine.
When the load-image notify routine is called, the input FullImageName points to a buffered Unicode string identifying the executable image file. The ProcessId handle identifies the process in which the image has been mapped, but this handle is zero if the newly loading image is a driver. The buffered data at ImageInfo is formatted as follows:
typedef struct _IMAGE_INFO {
union {
ULONG Properties;
struct {
ULONG ImageAddressingMode : 8; //code addressing mode
ULONG SystemModeImage : 1; //system mode image
ULONG ImageMappedToAllPids : 1; //mapped in all processes
ULONG Reserved : 22;
};
};
PVOID ImageBase;
ULONG ImageSelector;
ULONG ImageSize;
ULONG ImageSectionNumber;
} IMAGE_INFO, *PIMAGE_INFO;
When such a profiling driver's load-image routine is called, the members of this structure contain the following information:
- ImageAddressingMode
- Always set to IMAGE_ADDRESSING_MODE_32BIT.
- SystemModeImage
- Set either to one for newly loaded kernel-mode components, such as drivers, or to zero for images that are mapped into user space.
- ImageMappedToAllPids and Reserved
- Always set to zero.
- ImageBase
- Set to the virtual base address of the image.
- ImageSelector
- Always set to zero.
- ImageSize
- Set to the virtual size, in bytes, of the image.
- ImageSectionNumber
- Always set to zero.
For Windows Vista and later, this changes to:
typedef struct _IMAGE_INFO {
union {
ULONG Properties;
struct {
ULONG ImageAddressingMode : 8; // Code addressing mode
ULONG SystemModeImage : 1; // System mode image
ULONG ImageMappedToAllPids : 1; // Image mapped into all processes
ULONG ExtendedInfoPresent : 1; // IMAGE_INFO_EX available
ULONG Reserved : 21;
};
};
PVOID ImageBase;
ULONG ImageSelector;
SIZE_T ImageSize;
ULONG ImageSectionNumber;
} IMAGE_INFO, *PIMAGE_INFO;
If present, the callee can use CONTAINING_RECORD to obtain:
typedef struct _IMAGE_INFO_EX {
SIZE_T Size;
IMAGE_INFO ImageInfo;
struct _FILE_OBJECT *FileObject;
} IMAGE_INFO_EX, *PIMAGE_INFO_EX;
Size is the size of the IMAGE_INFO_EX structure so that the driver can see how much info is provided.
This adds a pointer to the file object backing the file. The driver can take a reference to this or use it for other operations.
Requirements
IRQL: PASSIVE_LEVEL
Headers: Declared in ntddk.h. Include ntddk.h.
See Also
PsGetCurrentProcessId, PsRemoveLoadImageNotifyRoutine, PsSetCreateProcessNotifyRoutine, PsSetCreateThreadNotifyRoutine