Here an implementation of AddVectoredExceptionHandler as it was reverse engineered.
PVOID RtlAddVectoredExceptionHandler(ULONG FirstHandler, PVECTORED_EXCEPTION_HANDLER VectoredHandler, int Unknown) { PPEB pPeb = GetPEB(); VECTORED_HANDLER_ENTRY *pVecNewEntry = (VECTORED_HANDLER_ENTRY *)HeapAlloc((HANDLE)pPeb->ProcessHeap, 0, sizeof(VECTORED_HANDLER_ENTRY)); if(pVecNewEntry == nullptr) { return nullptr; } pVecNewEntry->dwAlwaysOne = 1; PVOID pEncodedHandler = EncodePointer(VectoredHandler); VECTORED_HANDLER_LIST *pVecHandlerBase = (VECTORED_HANDLER_LIST *)(VectorHandlerListBase); AcquireSRWLockExclusive(&pVecHandlerBase->srwLock); pVecNewEntry->pVectoredHandler = (PVECTORED_EXCEPTION_HANDLER)pEncodedHandler; //If the list is empty then set the CrossProcessFlags fields if(pVecHandlerBase->pFirstHandler == (VECTORED_HANDLER_ENTRY *)&pVecHandlerBase->pFirstHandler) { InterlockedBitTestAndSet((LONG *)&pPeb->CrossProcessFlags, 2); } if(FirstHandler) { //Insert new node at the head of the VEH list pVecNewEntry->pNext = pVecHandlerBase->pFirstHandler; pVecNewEntry->pPrev = (VECTORED_HANDLER_ENTRY *)&pVecHandlerBase->pFirstHandler; pVecHandlerBase->pFirstHandler->pPrev = pVecNewEntry; pVecHandlerBase->pFirstHandler = pVecNewEntry; } else { //Insert new node at the end of the VEH list pVecNewEntry->pNext = (VECTORED_HANDLER_ENTRY *)&pVecHandlerBase->pFirstHandler; pVecNewEntry->pPrev = pVecHandlerBase->pLastHandler; pVecHandlerBase->pLastHandler->pNext = pVecNewEntry; pVecHandlerBase->pLastHandler = pVecNewEntry; } ReleaseSRWLockExclusive(&pVecHandlerBase->srwLock); return (PVOID)pVecNewEntry; } |
You can download the full Visual Studio 2013 project here. Follow on Twitter for more updates.