If you haven’t read the previous post you can find it here. Today we will continue analyzing some functions that DriverEntry is using.
On part 1 we identified the Dispatcher function of the driver as well as two functions that were initializing some variables for the driver (fn_InitDispatchMethodArray and fn_ObtainKernelFunctions). Let’s reverse each of them, and quickly analyze what are they doing. This will help us to understand the Dispatcher functions implemented on this driver.
What we will go through?
- Some basic initialization mechanism of this Driver
- Identify what it seems to be a custom structure used to index and store all available methods.
- Identify how function addresses are being located on memory. For example, ObRegisterCallbacks. We are going to be talking about this in the following posts.
fn_InitDispatchMethodArray (0x1400015F8)
The original code for this function can be found here: decompiled and asm. And the final result here (try not to spoil yourself yet).
We are going to see now in this function that a sort of custom structure is being initialized:
We can figure this out, because if we pay attention to the assembly, we will see that they are assigning first a int value to a particular address of memory, and then moving 8 bytes further to write a pointer to a function inside of the binary. We will call this structure IOCTLFunctionArray. An array? just keep reading =) This array will play an important role while dispatching a request.
The structure would be something like this:
And in IDA Pro:
This process is repeated multiple times on this function, 25 times exactly. That’s why we call it array, they are stored 25 times the same structure (with different values, of course) inside of an array.
The value 25 is also being stored in a variable I decided to rename from dword_14000A240 to FunctionsCount:
We will see later how this variable is used on the Dispatcher, but we may be able to try to guess it. Based on this function, we can deduse that the driver has a list of all available methods that can be invoked, and providing some kind of index value, it could be possible to invoke them.
The final result would be something like this. Note that some functions have been renamed since I have started to reverse them before. We will see some interesting ones on the following posts.
fn_ObtainKernelFunctions (0x140002A18)
The following function is simple. In order to continue with the initialization, the Driver needs the address of some particular routines:
By doing this, they can make sure that those functions are available on the running version of windows and obtain a pointer to them. They just need to store them in a variable and then use it to call any of those routines by casting it to the propery function definition. You can spot this easily also on the assembly function:
There is not much difference between the original code and the final result. The code was kind of obvious for this function.
Next Steps
- Analyze Dispatch function (fn_DriverIOCTLDispatcher)
- Analyzing Registering Notify and Callback Routines (fn_InitRegistrationNotifyAndCallbackRoutines and fn_RegisterCreateProcessNotifyRoutine)