Исходник ExceptionFilter [x32/x64]

SR_team

like pancake
Автор темы
BH Team
4,809
6,487
Это обертка над AddVectoredExceptionHandler и RemoveVectoredExceptionHandler, что бы засунуть обработчик не пойманных исключений внутрь класса.

Пример использования:
C++:
class MyExceptionFilter : public ExceptionFilter {
protected:
    long filter( _EXCEPTION_POINTERS *ep ) noexcept override{
        // handle exception
        return 0; // EXCEPTION_CONTINUE_SEARCH
    }
};
Данный класс добавляет хуки на основе исключений. Такие хуки можно поставить туда, куда не впихиваются другие. Минус таких хуков - они очень медленно выполняются.
header:
#pragma once

#include "ExceptionFilter.h"
#include <map>
#include <vector>
#include <functional>

class SilentHooks : public ExceptionFilter {
#ifdef _WIN64
    static constexpr auto kMaxOpcodeLength = 20;
#else
    static constexpr auto kMaxOpcodeLength = 10;
#endif

    std::map<size_t, std::vector<std::function<void( _EXCEPTION_POINTERS * )>>> hooks_;

public:
    void addHook( size_t addr, const std::function<void( _EXCEPTION_POINTERS * )> &callback ) noexcept;
    void removeHook( size_t addr ) noexcept;

    bool reenableHook( size_t addr ) const noexcept;

    static void changerRetAddr( _EXCEPTION_POINTERS *ep, size_t addr ) noexcept;

protected:
    long filter( _EXCEPTION_POINTERS *ep ) noexcept override;
};
source:
#include "SilentHooks.h"
#include <windows.h>

void SilentHooks::addHook( size_t addr, const std::function<void( _EXCEPTION_POINTERS * )> &callback ) noexcept {
    auto newHook = hooks_.find( addr ) == hooks_.end();
    hooks_[addr].push_back( callback );
    if ( newHook ) {
        DWORD oldVP;
        VirtualProtect( (void *)addr, 1, PAGE_EXECUTE_READ | PAGE_GUARD, &oldVP );
    }
}

void SilentHooks::removeHook( size_t addr ) noexcept {
    if ( hooks_.find( addr ) == hooks_.end() ) return;
    while ( reenableHook( addr ) )
        ; // wait to hook exited
    DWORD oldVP;
    VirtualProtect( (void *)addr, 1, PAGE_EXECUTE_READ, &oldVP );
}

bool SilentHooks::reenableHook( size_t addr ) const noexcept {
    if ( hooks_.find( addr ) == hooks_.end() ) return false;
    DWORD oldVP;
    VirtualProtect( (void *)addr, 1, PAGE_EXECUTE_READ | PAGE_GUARD, &oldVP );
    return oldVP != ( PAGE_EXECUTE_READ | PAGE_GUARD );
}

void SilentHooks::changerRetAddr( _EXCEPTION_POINTERS *ep, size_t addr ) noexcept {
    ep->ContextRecord->Eip = addr;
    ep->ContextRecord->EFlags &= ~0x100;
}

long SilentHooks::filter( _EXCEPTION_POINTERS *ep ) noexcept {
    if ( ep->ExceptionRecord->ExceptionCode == STATUS_GUARD_PAGE_VIOLATION ) {
        auto it = hooks_.find( (size_t)ep->ExceptionRecord->ExceptionAddress );
        if ( it == hooks_.end() ) return 0;

        DWORD oldVP;
        VirtualProtect( ep->ExceptionRecord->ExceptionAddress, 1, PAGE_EXECUTE_READ, &oldVP );
        ep->ContextRecord->EFlags |= 0x100; // step once

        for ( auto &cb : it->second ) cb( ep ); // execute callbacks
        return -1;
    } else if ( ep->ExceptionRecord->ExceptionCode == STATUS_SINGLE_STEP ) {
        bool fromHook = false;
        for ( auto &&[addr, cb] : hooks_ ) {
            if ( addr > (size_t)ep->ExceptionRecord->ExceptionAddress ) continue;
            if ( !reenableHook( addr ) ) continue;
            fromHook = true;
            break;
        }
        if ( !fromHook ) return 0;

        ep->ContextRecord->EFlags &= ~0x100; // run code
        return -1;
    }
    return 0;
}

Требования: C++11 или выше

Код: https://gitlab.com/SR_team/ExceptionFilter
 

kin4stat

mq-team · kin4@naebalovo.team
Всефорумный модератор
2,746
4,831
Разве eip не нужно смещать чтобы дальше выполнение пошло?
reenablehook возвращает page_guard, а eip на том же месте. Рекурсии не будет?
 

SR_team

like pancake
Автор темы
BH Team
4,809
6,487
Разве eip не нужно смещать чтобы дальше выполнение пошло?
reenablehook возвращает page_guard, а eip на том же месте. Рекурсии не будет?
его не нужно смещать, потому что надо выполнить инструкцию на которую он указывает

UPD: и второй пример говно - там надо страницы сравнивать и идти пошагово до выхода из нее
 
  • Нравится
Реакции: kin4stat