Предисловие
Пишу дополнение к другой программе в виде длл. DllMain запускает функции, которые нужны для сбора данных и внедрения хуков в функции самой программы. Важно, что сбор информации осуществляется только один раз при запуске, а потом всю работу делают хуки, то есть после внедрения хуков функции, которые внедряли хуки и собирали данные больше не нужны и желательно от них избавиться в целях безопасности.
Способ удаления функций, который я нашёл
1. В конце каждой функции, подлежащей удалению, объявляются биты, которые потом можно будет найти:
#define fn_limit _asm{\
_emit 0x9c\
_emit 0x9c\
_emit 0x9c\
_emit 0x9c\
_emit 0x9c}
void DoSomething
{
/// do something
fn_limit;
}
2. В хуке или в функции, которая вызывала DoSomething, начиная от указателя функции начинается поиск последовательности битов из конца функции, что даёт информацию о размере функции и возможность удалить функцию из памяти с помощью
memset(DoSomething, 0, calculated_size);
И здесь возникает первый вопрос: можно и нужно ли после этого вызывать delete, чтобы передать очищенную память в пользование ОС?
Мой теоритический способ (ещё не проверял, но интересно мнение опытных кодеров)
Что будет, если создать что-то вроде продвинутого singleton, который будет динамически выделять память для класса при запуске, а после выполнения функций можно будет вызвать функцию, которая просто сотрёт класс и отпустит память?
class MainClass
{
MainClass* Get()
{
if (main_class == nullptr)
main_class = new(std::nothrow) MainClass;
return main_class;
}
void Destroy()
{
DWORD old;
VirtualProtect(main_class, sizeof(MainClass), PAGE_EXECUTE_READWRITE, &old);
memset(main_class, 0, sizeof(MainClass));
VirtualProtect(main_class, sizeof(MainClass), old, &old);
delete main_class;
main_class = nullptr;
}
void DoSomething();
private:
MainClass* main_class{ nullptr };
}
void main()
{
MainClass* mc = MainClass::Get();
if (mc)
mc->DoSomething();
MainClass::Destroy();
}