26.08.2013 Views

366.7 KB - Evernote

366.7 KB - Evernote

366.7 KB - Evernote

SHOW MORE
SHOW LESS

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

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!