Я пытаюсь перехватить функцию, которая обычно вызывается несколькими потоками без простоя между ними. Мне было интересно, какой самый безопасный способ подключить функцию, не позволяя другим потокам (которыми я не владею) не выполнять код, пока я подключаю функцию.
Моя первоначальная идея заключалась в том, чтобы приостановить другие потоки, но это не идеально в моей ситуации. Решил использовать atomi c operations. Это какой-то псевдокод, который я придумал, чтобы проверить свою идею:
#include <thread>
#include <cstdio>
#include <Windows.h>
void hook()
{
puts("Function hooked");
}
void func()
{
puts("Actual function");
}
void __declspec(noreturn) thread()
{
while (true)
func(); //Hammer the function
}
int main()
{
DWORD old;
VirtualProtect(func, 0x5, PAGE_EXECUTE_READWRITE, &old); //change memory protections so we can write
//create the threads and release the handle (we don't own them)
std::thread t{thread};
t.detach();
std::thread s{thread};
s.detach();
std::thread z{thread};
z.detach();
//sleep 1 second to allow `threads t, s, z` to run
Sleep(1000);
//Hook the function
_InterlockedExchange8(reinterpret_cast<char*>(func), 0xe9);
const auto diff = static_cast<ULONG>(reinterpret_cast<ULONG>(hook) - reinterpret_cast<ULONG>(func)) - 5;
_InterlockedExchange(reinterpret_cast<unsigned long*>(reinterpret_cast<PUCHAR>(func) + 1), diff);
//Halt the current thread until program is terminated
WaitForSingleObject(GetCurrentProcess(), INFINITE);
}
Это работает, но безопасно ли это? Или это работает только из-за времени, необходимого для вызова puts
и вернуться? Есть ли лучший способ сделать это?
Спасибо.