我想钩住一个函数,这个函数通常被多个线程调用,中间没有任何空闲时间。我想知道有什么最安全的方法来钩住这个函数,防止其他线程(不属于我自己)在我钩住函数的时候不执行代码。
我最初的想法是暂停其他线程,但这在我的情况下并不理想。我决定使用原子操作。这是我想出的一些伪代码来测试我的想法。
#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
并返回?有没有更好的方法?
谢谢,我想钩住一个通常被多个线程调用的函数,中间没有任何空闲时间。
这取决于很多因素,有很多可能的解决方案。
请注意,解决方案2、3和4会暂停线程,所以在你的情况下可能无法接受。
另外,请注意,你分离了线程,但函数是你代码的一部分。在你的代码退出后,这些线程会继续运行吗?那些分离出来的线程就会调用删除的代码。