Как перехватить бесплатный вызов функции, как это делают hippomocks?

Мне интересно, что делает гиппопотам, чтобы перехватить exit например, вызвать функцию, как показано в приведенном ниже коде:

   MockRepository mocks;
mocks.ExpectCallFunc(exit).With(2).Throw(std::exception());

4

Решение

Код, который делает перехват, находится в hippomocks.h, Он изменяет флаги защиты памяти, чтобы разрешить запись по адресу предоставленного указателя функции, а затем записывает инструкцию перехода вместо начальных байтов функции. Когда ловушка больше не нужна, исходные байты восстанавливаются. Это тот же подход, который используется, например, Microsoft обходит библиотека.

5

Другие решения

Он преобразует переданную функцию (в данном случае простой указатель на функцию) в 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 .

5

По вопросам рекламы [email protected]