/
githubmirror
/
x64dbg
Обзор
Документация
Войти
/
githubmirror
/
x64dbg
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
development
src/dbg/exhandlerinfo.cpp
209 строк
6 KB
Duncan Ogilvie
Fix compilation on Windows with clang++
12 апр 2026, 18:48
12 апр 2026, 18:48
2b3d38a
Код
Авторство
О чём код?
/** @file exhandlerinfo.cpp @brief ??? */ #include "exhandlerinfo.h" #include "memory.h" #include "thread.h" #include "value.h" #include "debugger.h" bool IsVistaOrLater() { return BridgeGetNtBuildNumber() >= 6000; } bool Is19042OrLater() { return BridgeGetNtBuildNumber() >= 19042; } 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 ExHandlerGetInfo(EX_HANDLER_TYPE Type, EX_HANDLER_INFO* Info) { std::vector<duint> handlerEntries; if(!ExHandlerGetInfo(Type, handlerEntries)) { 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 true; } #define MAX_HANDLER_DEPTH 10 bool ExHandlerGetSEH(std::vector<duint> & Entries) { #ifdef _WIN64 return false; // TODO: 64-bit #endif static duint nextSEH = 0; NT_TIB tib; if(ThreadGetTib((duint)GetTEBLocation(hActiveThread), &tib)) { EXCEPTION_REGISTRATION_RECORD sehr; duint addr_ExRegRecord = (duint)tib.ExceptionList; int MAX_DEPTH = MAX_HANDLER_DEPTH; while(addr_ExRegRecord != 0xFFFFFFFF && MAX_DEPTH) { Entries.push_back(addr_ExRegRecord); if(!MemRead(addr_ExRegRecord, &sehr, sizeof(EXCEPTION_REGISTRATION_RECORD))) break; addr_ExRegRecord = (duint)sehr.Next; MAX_DEPTH--; } } return true; } struct VEH_ENTRY_XP { duint Flink; duint Blink; duint VectoredHandler; }; 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); 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); } struct VEH_ENTRY_VISTA { duint Flink; duint Blink; duint PtrRefCount; duint VectoredHandler; // unclear when this changed duint VectoredHandler2; }; 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; // At some point Windows updated the structure if(Is19042OrLater()) handler = entry.VectoredHandler2; if(!MemDecodePointer(&handler, true)) return false; Entries.push_back(handler); if(!MemRead(cur_entry, &cur_entry, sizeof(cur_entry))) return false; } return true; } bool ExHandlerGetUnhandled(std::vector<duint> & Entries) { static duint addr_BasepCurrentTopLevelFilter = 0; auto symbol = ArchValue("_BasepCurrentTopLevelFilter", "BasepCurrentTopLevelFilter"); 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, IsVistaOrLater())) return false; Entries.push_back(handlerValue); return true; } return false; }