❌

Normal view

There are new articles available, click to refresh the page.
Before yesterdayReverse Engineering 0x4 Fun

Windows Internals - Quantum end context switching

30 August 2014 at 21:12
Hello,
Lately I decided to start sharing the notes I gather , almost daily , while reverse engineering and studying Windows. As I focused in the last couple of days on studying context switching , I was able to decompile the most involved functions and study them alongside with noting the important stuff. The result of this whole process was a flowchart.

Before getting to the flowchart let's start by putting ourselves in the main plot :
As you might know, each thread runs for a period of time before another thread is scheduled to run, excluding the cases where the thread is preempted ,entering a wait state or terminated. This time period is called a quantum. Everytime a clock interval ends (mostly 15 ms) the system clock issues an interrupt.While dispatching the interrupt, the thread current cycle count is verified against its cycle count target (quantum target) to see if it has reached or exceeded its quantum so the context would be switched the next thread scheduled to run.
Note that a context-switch in Windows doesn't happen only when a thread has exceeded its quantum, it also happens when a thread enters a wait state or when a higher priority thread is ready to run and thus preempts the current thread.

As it will take some time to organize my detailed notes and share them here as an article (maybe for later),consider the previous explanation as a small introduction into the topic. However ,the flowchart goes through the details involved in quantum end context switching.

Please consider downloading the pdfΒ  to be able to zoom as much as you like under your PDF reader because GoogleDocs doesn't provide enough zooming functionality to read the chart.

Preview (unreadable) :


PDF full size DownloadΒ  : GoogleDocs Link

P.S :
- As always , this article is based is on : Windows 7 32-bit
- Note that details concerning the routine that does the context switching (SwapContext) aren't included in the chart and are left it for a next post.

See you again soon.

-Souhail.

OkayToCloseProcedure callback kernel hook

Hi ,

During the last few weeks I was busy exploring the internal working of Handles under Windows , by disassembling and decompiling certain kernel (ntoskrnl.exe) functions under my Windows 7 32-bit machine.In the current time I am preparing a paper to describe and explain what I learned about Handles. But today I’m here to discuss an interesting function pointer hook that I found while decompiling and exploring the ObpCloseHandleEntry function. (Source codes below).

A function pointer hook consists of overwriting a callback function pointer so when a kernel routine will call the callback function, the hook function will be called instead . The function pointer that we will be hooking in this article is the OkayToCloseProcedure callback that exists in the _OBJECT_TYPE_INITIALIZER structure which is an element of the OBJECT_TYPE struct.

Every object in Windows has an OBJECT_TYPE structure which specifies the object type name , number of opened handles to this object type ...etc OBJECT_TYPE also stores a type info structure (_OBJECT_TYPE_INITIALIZER) that has a group of callback functions (OpenProcedure ,CloseProcedure…) . All OBJECT_TYPE structures pointers are stored in the unexported ObTypeIndexTable array.

As I said earlier , the OkayToCloseProcedure is called inside ObpCloseHandleEntry function.In general this function (if the supplied handle is not protected from being closed) frees the handle table entry , decrements the object’s handle count and reference count.
Another case when the handle will not be closed is if the OkayToCloseProcedure returned 0 , in this case the ObpCloseHandleTableEntry returns STATUS_HANDLE_NOT_CLOSABLE.
I will discuss handles in more details in my future blog posts.

So how the OkayToCloseProcedure is called ?

ObpCloseHandleTableEntry function actually gets the Object (which the handle is opened to) header (_OBJECT_HEADER). A pointer to the object type structure (_OBJECT_TYPE) is then obtained by accessing the ObTypeIndexTable array using the Object Type Index from the object header (ObTypeIndexTable[ObjectHeader->TypeIndex]).

The function will access the OkayToCloseProcedure field and check if it’s NULL , if that’s true the function will proceed to other checks (check if the handle is protected from being closed). If the OkayToCloseProcedure field isn’t NULL , the function will proceed to call the callback function. If the callback function returns 0 the handle cannot be closed and ObpCloseHandleTableEntry will return STATUS_HANDLE_NOT_CLOSABLE. If it returns a value other than 0 we will proceed to the other checks as it happens when the OkayToCloseProcedure is NULL.

An additional point is that the OkayToCloseProcedure must always run within the context of the process that opened the handle in the first place (a call to KeStackAttachProcess). I don’t think that this would be a problem if ObpCloseHandleTableEntry is called as a result of calling ZwClose from usermode because we’ll be running in the context of the process that opened the handle.However, if ZwClose was called from kernel land and was supplied a kernel handle KeStackAttachProcess will attach the thread to the system process. The reason behind that is that we always want to access the right handle table (each process has a different handle table, and for the kernel we have the system handle table).

So if ObpCloseHandleTableEntry is called from another process context and is trying to close another process’s handle, the OkayToCloseProcedure must run in that process context. That’s why ObpCloseHandleTableEntry takes a pointer to the process object (owner of the handle) as a parameter.

Applying the hook :

Now after we had a quick overview of what’s happening , let’s try and apply the hook on the OBJECT_TYPE_INITIALIZER’s OkayToCloseProcedure field.
I applied the hook on the Process object type , we can obtain a pointer to the process object type by taking advantage of the exported PsProcessType , it’s actually a pointer to a pointer to the process’s object type.

Here’s a list containing the exported object types :
POBJECT_TYPE *ExEventObjectType;
POBJECT_TYPE *ExSemaphoreObjectType;
POBJECT_TYPE *IoFileObjectType;
POBJECT_TYPE *PsThreadType;
POBJECT_TYPE *SeTokenObjectType;
POBJECT_TYPE *PsProcessType;
POBJECT_TYPE *TmEnlistmentObjectType;
POBJECT_TYPE *TmResourceManagerObjectType;
POBJECT_TYPE *TmTransactionManagerObjectType;
POBJECT_TYPE *TmTransactionObjectType;


A second way to get an object’s type is by getting an existing object’s pointer and then pass it to the exported kernel function ObGetObjectType which will return a pointer to the object’s type.

A third way is to get a pointer to the ObTypeIndexTable array, it’s unexported by the kernel but there are multiple functions using it including the exported ObGetObjectType function.So the address can be extracted from the function's opcodes , but that will introduce another compatibility problem. After getting the pointer to the ObTypeIndexTable you'll have to walk through the whole table and preform a string comparison to the target's object type name ("Process","Thread" ...etc) against the Name field in each _OBJECT_TYPE structure.

In my case I hooked the Process object type , and I introduced in my code the 1st and the 2nd methods (second one commented).
My hook isn’t executing any malicious code !! it’s just telling us (using DbgPrint) that an attempt to close an open handle to a process was made.
β€œAn attempt” means that we’re not sure "yet" if the handle will be closed or not because other checks are made after a successful call to the callback.And by a successful call , I mean that the callback must return a value different than 0 that’s why the hook function is returning 1. I said earlier that the ObpCloseHandleTableEntry will proceed to check if the handle is protected from being closedΒ  (after returning from the callback) if the OkayToCloseProcedure is null or if it exists and returns 1 , that's why it’s crucial that our hook returns 1.One more thing , I’ve done a small check to see if the object type’s OkayToCloseProcedure is already NULL before hooking it (avoiding issues).

Example :
For example when closing a handle to a process opened by OpenProcess a debug message will display the handle value and the process who opened the handle.
As you can see "TestOpenProcess.exe" just closed a handle "0x1c" to a process that it opened using OpenProcess().


P.S : The hook is version specific.


Source codes :
Decompiled ObpCloseHandleTableEntry : http://pastebin.com/QL0uaCtJ
Driver Source Code :Β  http://pastebin.com/Z2zucYGZ


Your comments are welcome.

Souhail Hammou.

@Dark_Puzzle

❌
❌