我正致力于在Windows上添加/删除/插入向量异常处理程序。到目前为止,我颠倒了AddVectoredExceptionHandler并找到了单个节点的结构,如下所示:
typedef struct _VECTORED_HANDLER_NODE
{
_VECTORED_HANDLER_NODE *PrevNode;
_VECTORED_HANDLER_NODE *NextNode;
BOOL IsNodeAllocated;
PVOID EncodedHandler;
}VECTORED_HANDLER_NODE, *PVECTORED_HANDLER_NODE;
我使用硬编码地址查找ntdll!0x7DF74744
目前我可以使用以下代码插入链接列表:
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;
}
链接列表如下所示:
这是使用AddVectoredExceptionHandler时链接列表的样子:
HEAD是链表中的第一个数据结构,而MEM(x)是链表内的第x个数据结构。 Cont表示解码指针,它是回调函数的地址。
如您所见,除了导致不同地址的动态分配外,输出是相同的。这意味着我正确地添加到链接列表。因为我的处理程序从未被调用,所以当我导致异常时会出现问题。 相反,该程序只会引发异常并崩溃。
有什么想法吗?
答案 0 :(得分:1)
我暂时解决了这个问题,但只看到这个问题没有答案,所以我现在就回答。问题不在于地址或数据结构,而在于每次调用AddVectoredExceptionHandler时,Windows都会检查节点链是否只包含1个节点,如果是,则执行此操作:
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);
我也意识到所有这些都已被颠倒过来,C版本位于:
https://git.reactos.org/?p=reactos.git;a=blob;f=reactos/lib/rtl/vectoreh.c
为了更清楚,这是我在C ++中用迭代器实现的实现,它遍历向量异常处理程序链表:
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