Reputation: 583
I'm working on a way to add/remove/insert vectored exception handlers on Windows. So far I reversed AddVectoredExceptionHandler and found the structure for a single node which looks like this:
typedef struct _VECTORED_HANDLER_NODE
{
_VECTORED_HANDLER_NODE *PrevNode;
_VECTORED_HANDLER_NODE *NextNode;
BOOL IsNodeAllocated;
PVOID EncodedHandler;
}VECTORED_HANDLER_NODE, *PVECTORED_HANDLER_NODE;
I'm using hardcoded addresses to find the start of the linked list (the head) which is at ntdll!0x7DF74744
At the moment I can insert into the linked list using this code:
void InsertHandler(PVECTORED_EXCEPTION_HANDLER cb, size_t pos)
{
size_t counter = 1;
veh_node *head = reinterpret_cast<veh_node*>(WINDOWS_7_VEH_HEAD),
*first = head->NextNode,
*end = head->NextNode;
do
{
if(counter == pos)
{
break;
}
++counter;
first = first->NextNode;
} while(first != end);
// Copy the contents over
veh_node *newNode = new veh_node();
newNode->PrevNode = first->PrevNode;
newNode->NextNode = first;
newNode->EncodedHandler = EncodePointer(cb);
newNode->IsNodeAllocated = TRUE;
// Redirect the old pointers
// to include the new node
auto beforeNode = first->PrevNode;
beforeNode->NextNode = newNode;
first->PrevNode = newNode;
}
And the linked list looks like this:
This is what the linked list looks like when using AddVectoredExceptionHandler:
HEAD is the first data structure in the linked list while MEM(x) is the x'th data structure inside of the linked list. Cont denotes the decoded pointer which is the address of the callback function.
As you can see, other than the dynamic allocations causing different addresses, the output is the same. This means that I'm adding to the linked list correctly. The problem arises when I cause an exception since my handler is never called. Instead the program just raises an exception and crashes.
Any ideas?
Upvotes: 0
Views: 2607
Reputation: 583
I solved this issue a while back but only saw that this stood unanswered so I shall answer it now. The problem wasn't with the addresses or the data structures but with the fact that with every call to AddVectoredExceptionHandler Windows does a check to see if the chain of nodes contains only 1 node and if so does this:
if ( (RTL_VEH_NODE *)FirstNodeInChain->NextNode == FirstNodeInChain )// Check if only 1 handler currently exists
_interlockedbittestandset(
(volatile signed __int32 *)(*(_QWORD *)(*MK_FP(__GS__, 48i64) + 96i64) + 80i64),
arg31 + 2);
I also realized that all of this has already been reversed and a C version is located at:
https://git.reactos.org/?p=reactos.git;a=blob;f=reactos/lib/rtl/vectoreh.c
For more clarity, here's an implementation I made in C++ of an iterator that walks the vectored exception handler linked list:
https://github.com/Maktm/hadesmem/blob/master/include/memory/hadesmem/detail/vectored_handler_list.hpp https://github.com/Maktm/hadesmem/blob/master/include/memory/hadesmem/detail/vectored_handler.hpp
Upvotes: 2