Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for ExCreateCallback objects to system callbacks list #26

Merged
merged 1 commit into from
Apr 26, 2021

Conversation

Mattiwatti
Copy link
Contributor

I recently stumbled upon an interesting change in the ExCreateCallback function that is responsible for creating executive callbacks like \Callback\ProcessorAdd. It turns out that the size of the CALLBACK_OBJECT type changed in Windows 8.1: from 40 bytes previously to 56 bytes now (going by the size that ExCreateCallback is requesting from ObCreateObject).

It doesn't take a rocket scientist to figure out what these 16 bytes are used for: there is a new LIST_ENTRY at the end of the CALLBACK_OBJECT struct that ExCreateCallback uses to insert the callback object into the ExpCallbackListHead list (also new in 8.1). And if you traverse ExpCallbackListHead, you will quickly see that there are a lot more objects in this list than what the \Callback directory shows! It seems that this change hasn't really been picked up on before, probably because CALLBACK_OBJECT is a private type that is not in any headers or PDBs.

This PR adds a typedef for the new CALLBACK_OBJECT that looks like this:

typedef struct _CALLBACK_OBJECT_V2 {
    ULONG Signature;
    KSPIN_LOCK Lock;
    LIST_ENTRY RegisteredCallbacks;
    BOOLEAN AllowMultipleCallbacks;
    LIST_ENTRY ExpCallbackList;
} CALLBACK_OBJECT_V2, *PCALLBACK_OBJECT_V2;

This type is not used in the object dump procedure for callback objects; I tried doing it that way at first but quickly realized it didn't make much sense, because the second list is a reference to a global list and the list entries are really unrelated to the object itself. So I decided to add support for enumerating callback objects to the 'callbacks extra' instead.

There is a finder routine named FindExpCallbackListHead, which finds the address of ExpCallbackListHead and is not particularly interesting. The dump routine (DumpExpCallbackListCallbacks) is a bit different from the ones that are currently in the callbacks extra. This is because it is IMO not really interesting or helpful to print the address of a CALLBACK_OBJECT (which is what is in the list). These objects are not function addresses, and they aren't even located in a kernel module. So what I have done instead is this:

  • For each callback object in ExpCallbackListHead, add a new item to the tree list that shows only the object address.
  • For each callback registration (CALLBACK_REGISTRATION) in the RegisteredCallbacks list of the object, add a new sub-item of the parent callback object. This can be 0 or many entries depending on the callback object.

If this sounds confusing, here's what it looks like:

image

Essentially you can expand each callback object to see the callback function(s) registered with it. I preferred doing this over a flat layout, because without nesting it would be impossible to tell which registered callback functions belong to which callback object.

I did need to add a new AddParentEntryToList function to support doing this cleanly, and I'm no good at GUI stuff, so I hope I didn't mess that part up.

@hfiref0x
Copy link
Owner

That's a very nice done addition, thanks.

@hfiref0x hfiref0x merged commit 3457e83 into hfiref0x:master Apr 26, 2021
@Mattiwatti Mattiwatti deleted the excallback-objects branch April 26, 2021 02:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants