Мне интересно, что делает гиппопотам, чтобы перехватить exit
например, вызвать функцию, как показано в приведенном ниже коде:
MockRepository mocks;
mocks.ExpectCallFunc(exit).With(2).Throw(std::exception());
Код, который делает перехват, находится в hippomocks.h
, Он изменяет флаги защиты памяти, чтобы разрешить запись по адресу предоставленного указателя функции, а затем записывает инструкцию перехода вместо начальных байтов функции. Когда ловушка больше не нужна, исходные байты восстанавливаются. Это тот же подход, который используется, например, Microsoft обходит библиотека.
Он преобразует переданную функцию (в данном случае простой указатель на функцию) в char *, просит ОС получить разрешение на запись в нее (используя mprotect в Unices и VirtualProtect в Windows), а затем изменяет первые 5-14 байтов. быть безусловной инструкцией перехода. Он помещает адрес сгенерированной (с использованием шаблонов) функции с идентичной подписью на место, эффективно перекрывая функцию.
Если вы хотите, вы можете использовать код HippoMocks напрямую, создав объект класса Replace в стеке с правильными аргументами. Вы также можете скопировать код (в новейшем файле hippomocks.h на GitHub поддерживаются 32/64 бит x86, ARM и thumb). Это около линии 200, так что относительно высоко. Вам также нужно скопировать класс horrible_cast и класс Unprotect; первая позволяет ему приводить указатель на функцию-член к любому другому типу (что невозможно с reinterpret_cast), а вторая упаковывает специфичные для ОС вызовы unprotect (и reprotect).
При очистке кода для C ++ 11 я также извлек именно это подмножество, поэтому теперь вы можете использовать файл detail / replace.h, чтобы получить только код, который это делает. Для прямой ссылки, посмотрите на https://github.com/dascandy/hippomocks/blob/cpp11/HippoMocks/detail/replace.h .