366.7 KB - Evernote
366.7 KB - Evernote
366.7 KB - Evernote
Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
NTKERNELAPI VOID KeInitializeApc (<br />
IN PRKAPC Apc,<br />
IN PKTHREAD Thread,<br />
IN KAPC_ENVIRONMENT Environment,<br />
IN PKKERNEL_ROUTINE KernelRoutine,<br />
IN PKRUNDOWN_ROUTINE RundownRoutine OPTIONAL,<br />
IN PKNORMAL_ROUTINE NormalRoutine OPTIONAL,<br />
IN KPROCESSOR_MODE ApcMode,<br />
IN PVOID NormalContext<br />
);<br />
This prototype was published in [1] and is still valid for Windows Vista SP1.<br />
Calling nt!KeInitializeApc does not schedule the APC yet: it just fills the members of the _KAPC. To<br />
actually schedule the APC one more step will be required.<br />
Ke InitializeApc sets the Type field to a constant value (0x12) which identifies this structure as a<br />
_KAPC and the Size field to 0x30, i.e. the size of the structure rounded up to a multiple of 4.<br />
The Thread field is set to the corresponding function parameter and contains a pointer to the<br />
_KTHREAD for the thread the APC is intended for.<br />
The ApcListEntry is not set by nt!KeInitializeApc. Rather, it is used when the APC is actually<br />
scheduled, to chain it to a list of pending APCs for the thread.<br />
The KernelRoutine field, taken from the function input parameter, stores a pointer to the function to be<br />
called when the APC is dispatched. This is the actual code which will be executed in the context of<br />
the thread targeted by the APC. Every APC has a KernelRoutine and, depending on its type it can<br />
have a NormalRoutine as well.<br />
The function pointed by KernelRoutine is called at APC IRQL.<br />
The NormalRoutine and ApcMode function parameters determine the type of the APC.<br />
If NormalRoutine is 0, this is a special kernel mode APC.<br />
For this kind of APCs nt!KeInitializeApc sets _KAPC.ApcMode to 0, which stands for kernel mode<br />
and _KAPC.NormalContext to 0. The corresponding function parameters are ignored.<br />
If NormalRoutine is not 0 and ApcMode is set to 0, this is a regular kernel mode APC;<br />
_KAPC.ApcMode and _KACP.NormalContext are set from the function parameters.<br />
This kind of APC will still execute kernel mode code, as denoted by ApcMode = 0, but it is less<br />
privileged than a special one, which means it can be executed only under certain conditions, which<br />
will be detailed later. NormalRoutine is stored in the corresponding _KAPC member and is the<br />
address of a function which will be called when the APC is delivered.<br />
When such an APC is serviced, the KernelRoutine is called first, at APC IRQL. Afterwards, the<br />
NormalRoutine is called at PASSIVE IRQL. Both functions execute in kernel mode.<br />
As we will see in more detail later, the KernelRoutine has a chance to prevent the execution of the<br />
NormalRoutine or to change the address which will be called, before the NormalRoutine comes into<br />
play.<br />
7