Created
March 26, 2014 15:29
-
-
Save TheCjw/9786028 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
typedef struct _LdrpVectorHandlerList { | |
struct _LdrpVectorHandlerList *Prev; | |
struct _LdrpVectorHandlerList *Next; | |
DWORD Depth; | |
PVECTORED_EXCEPTION_HANDLER VectoredHandler; | |
} VECTORED_HANDLER_LIST, *PVECTORED_HANDLER_LIST; | |
VECTORED_HANDLER_LIST LdrpVectorHandlerList[2]; | |
BOOLEAN RtlpCallVectoredHandlers(PEXCEPTION_RECORD ExceptionRecord, PCONTEXT ContextRecord, BOOL flag) { | |
BOOLEAN ret; | |
DWORD hret; | |
PVECTORED_HANDLER_LIST freeList, head, next; | |
PTEB teb = _TEB; // fs:18h | |
PPEB peb = teb->ProcessEnvironmentBlock; // teb:30h | |
ret = 0; | |
head = &LdrpVectorHandlerList[flag]; | |
/* there are two possible bit flags with CrossProcessFlags that it checks here | |
flag = 0 corresponds to ProcessUsingVEH | |
flag = 1 corresponds to ProcessUsingVCH | |
*/ | |
if (peb->CrossProcessFlags & (1 << (flag + 2)) { | |
freeList = NULL; | |
/* get a slim reader/writer lock on the vectorhandlerlist */ | |
RtlAcquireSRWLockExclusive(head); | |
next = head->Next; | |
while (next != head) { | |
next->Depth++; | |
RtlReleaseSRWLockExclusive(head); | |
handler = RtlDecodePointer(next->VectoredHandler); | |
hret = handler(ExceptionRecord); | |
RtlAcquireSRWLockExclusive(head); | |
next->Depth--; | |
if (next->Depth == 0) { | |
next->Next->Prev = next->Prev; | |
next->Prev->Next = next->Next; | |
if (next->Prev == next->Next) { | |
/* this is actuall an atomic bit reset (lock btr) instruction | |
* basically they are clearing either the ProcessUsingVEH or ProcessUsingVCH flags | |
* when the list becomes empty */ | |
peb->CrossProcessFlags &= ~(1 << (flag + 2)); | |
} | |
next->Prev = freeList; | |
freeList = next; | |
} | |
next = next->Prev; | |
if (hret == EXCEPTION_CONTINUE_EXECUTION) { | |
ret = 1; | |
break; | |
} | |
} | |
RtlReleaseSRWLockExclusive(head); | |
while (freeList) { | |
LPVOID p = freeList; | |
freeList = freeList->Prev; | |
RtlFreeHeap(peb->ProcessHeap, 0, p); | |
} | |
} | |
return ret; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment