bool ExHandlerGetInfo(EX_HANDLER_TYPE Type, std::vector<duint> & Entries) { Entries.clear(); switch(Type) { case EX_HANDLER_SEH: return ExHandlerGetSEH(Entries); case EX_HANDLER_VEH: return ExHandlerGetVEH(Entries); case EX_HANDLER_VCH: return ExHandlerGetVCH(Entries, false); case EX_HANDLER_UNHANDLED: return ExHandlerGetUnhandled(Entries); } return false; }
bool ExHandlerGetVEH(std::vector<duint> & Entries) { // Try the address for Windows XP first (or older) // // VECTORED_EXCEPTION_NODE RtlpCalloutEntryList; static duint addr_RtlpCalloutEntryList = 0; if(addr_RtlpCalloutEntryList || valfromstring("ntdll:RtlpCalloutEntryList", &addr_RtlpCalloutEntryList)) { // Read header node VECTORED_EXCEPTION_NODE node; memset(&node, 0, sizeof(VECTORED_EXCEPTION_NODE)); if(!MemRead(addr_RtlpCalloutEntryList, &node, sizeof(VECTORED_EXCEPTION_NODE))) return false; // Move to the next link duint listCurrent = (duint)node.ListEntry.Flink; duint listEnd = addr_RtlpCalloutEntryList; while(listCurrent && listCurrent != listEnd) { duint handler = (duint)node.handler; MemDecodePointer(&handler); Entries.push_back(handler); // Move to next element memset(&node, 0, sizeof(VECTORED_EXCEPTION_NODE)); if(!MemRead(listCurrent, &node, sizeof(VECTORED_EXCEPTION_NODE))) break; listCurrent = (duint)node.ListEntry.Flink; } } // Otherwise try the Windows Vista or newer version return ExHandlerGetVCH(Entries, true); }
bool ExHandlerGetVEH(std::vector<duint> & Entries) { // Try the address for Windows XP first (or older) // // VECTORED_EXCEPTION_NODE RtlpCalloutEntryList; static duint addr_RtlpCalloutEntryList = 0; #ifdef _WIN64 auto symbol = "RtlpCalloutEntryList"; #else auto symbol = "_RtlpCalloutEntryList"; #endif if(addr_RtlpCalloutEntryList || valfromstring(symbol, &addr_RtlpCalloutEntryList)) { // Read head entry auto list_head = addr_RtlpCalloutEntryList; duint cur_entry; if(!MemRead(list_head, &cur_entry, sizeof(cur_entry))) return false; auto count = 0; while(cur_entry != list_head && count++ < MAX_HANDLER_DEPTH) { VEH_ENTRY_XP entry; if(!MemRead(cur_entry, &entry, sizeof(entry))) return false; auto handler = entry.VectoredHandler; MemDecodePointer(&handler, false); //TODO: Windows XP doesn't allow a remote process to query this value Entries.push_back(handler); if(!MemRead(cur_entry, &cur_entry, sizeof(cur_entry))) return false; } return true; } // Otherwise try the Windows Vista or newer version return ExHandlerGetVCH(Entries, true); }
bool ExHandlerGetInfo(EX_HANDLER_TYPE Type, EX_HANDLER_INFO* Info) { bool ret = false; std::vector<duint> handlerEntries; switch(Type) { case EX_HANDLER_SEH: ret = ExHandlerGetSEH(handlerEntries); break; case EX_HANDLER_VEH: ret = ExHandlerGetVEH(handlerEntries); break; case EX_HANDLER_VCH: ret = ExHandlerGetVCH(handlerEntries, false); break; case EX_HANDLER_UNHANDLED: ret = ExHandlerGetUnhandled(handlerEntries); break; } // Check if a call failed if(!ret) { Info->count = 0; Info->addresses = nullptr; return false; } // Convert vector to C-style array Info->count = (int)handlerEntries.size(); Info->addresses = (duint*)BridgeAlloc(Info->count * sizeof(duint)); memcpy(Info->addresses, handlerEntries.data(), Info->count * sizeof(duint)); return false; }