bool ExHandlerGetUnhandled(std::vector<duint> & Entries) { // Try the address for Windows Vista+ static duint addr_BasepCurrentTopLevelFilter = 0; #ifdef _WIN64 auto symbol = "BasepCurrentTopLevelFilter"; #else auto symbol = "_BasepCurrentTopLevelFilter"; #endif if(addr_BasepCurrentTopLevelFilter || valfromstring(symbol, &addr_BasepCurrentTopLevelFilter)) { // Read external pointer duint handlerValue = 0; if(!MemRead(addr_BasepCurrentTopLevelFilter, &handlerValue, sizeof(duint))) return false; // Decode with remote process cookie if(!MemDecodePointer(&handlerValue, true)) return false; Entries.push_back(handlerValue); return true; } return false; }
bool ExHandlerGetVCH(std::vector<duint> & Entries, bool UseVEH) { // VECTORED_HANDLER_LIST LdrpVectorHandlerList[2]; static duint addr_LdrpVectorHandlerList = 0; if(!addr_LdrpVectorHandlerList && !valfromstring("ntdll:LdrpVectorHandlerList", &addr_LdrpVectorHandlerList)) return false; // Increase array index when using continue handlers if(!UseVEH) addr_LdrpVectorHandlerList += (1 * sizeof(VECTORED_HANDLER_LIST)); // Read head entry VECTORED_HANDLER_LIST list; memset(&list, 0, sizeof(VECTORED_HANDLER_LIST)); if(!MemRead(addr_LdrpVectorHandlerList, &list, sizeof(VECTORED_HANDLER_LIST))) return false; // Sub-entries in list duint listCurrent = (duint)list.Next; duint listEnd = addr_LdrpVectorHandlerList; while(listCurrent && listCurrent != listEnd) { duint handler = (duint)list.VectoredHandler; MemDecodePointer(&handler); Entries.push_back(handler); // Move to next element memset(&list, 0, sizeof(VECTORED_HANDLER_LIST)); if(!MemRead(listCurrent, &list, sizeof(VECTORED_HANDLER_LIST))) break; listCurrent = (duint)list.Next; } return true; }
bool ExHandlerGetVCH(std::vector<duint> & Entries, bool GetVEH) { // VECTORED_HANDLER_LIST LdrpVectorHandlerList[2]; static duint addr_LdrpVectorHandlerList = 0; duint addrInc = sizeof(duint); //Vista+ has an extra ULONG_PTR in front of the structure #ifdef _WIN64 auto symbol = "LdrpVectorHandlerList"; #else auto symbol = "_LdrpVectorHandlerList"; #endif if(!addr_LdrpVectorHandlerList && !valfromstring(symbol, &addr_LdrpVectorHandlerList)) return false; // Increase array index when using continue handlers if(!GetVEH) addrInc += sizeof(duint) + sizeof(LIST_ENTRY); //Vista+ has an extra ULONG_PTR // Read head entry auto list_head = addr_LdrpVectorHandlerList + addrInc; 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_VISTA entry; if(!MemRead(cur_entry, &entry, sizeof(entry))) return false; auto handler = entry.VectoredHandler; if(!MemDecodePointer(&handler, true)) return false; Entries.push_back(handler); if(!MemRead(cur_entry, &cur_entry, sizeof(cur_entry))) return false; } return 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; 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); }