Closed stenlan closed 1 year ago
Through some debugging and looking at the actual memory I have found out that during the one call I make inside the dll it's actually detoured and the memory has been changed, but then the bytes just change back for no apparent reason? I never call unhook or anything. What is going on? I feel like I'm missing something extremely obvious but I have absolutely 0 idea what that could be.
If the bytes actually change then it's possible there's another thread that's working as a watchdog for hooks and restoring them. You can try to set a hardware write breakpoint on the bytes after the hook is written to break when they get restored. That should tell you at least which chunk of code is doing the restoring.
Polyhook2 does support extremely fast re-hookimg to combat this. Once you find the logic doing the restore you can either nop it out, or call reHook super fast in a loop constantly
@stevemk14ebr
That's not the case, this is an extremely simple test application I have written myself. This must be a bug somewhere (maybe my code) but I can't see why. At least it doesn't seem like desired behavior. Here's the code for the application I'm injecting into:
#include <windows.h>
#include <winhttp.h>
#include <iostream>
#include <chrono>
#include <thread>
#pragma comment(lib, "winhttp.lib")
int main()
{
while (true) {
WINHTTP_CURRENT_USER_IE_PROXY_CONFIG ProxySettings;
SecureZeroMemory(&ProxySettings, sizeof(WINHTTP_CURRENT_USER_IE_PROXY_CONFIG));
bool res = WinHttpGetIEProxyConfigForCurrentUser(&ProxySettings);
std::printf("%d", res);
std::printf("Proxy: ");
if (res && ProxySettings.lpszProxy)
{
std::wprintf((wchar_t*) ProxySettings.lpszProxy);
GlobalFree(ProxySettings.lpszProxy);
}
std::printf("\n");
if (ProxySettings.lpszProxyBypass)
GlobalFree(ProxySettings.lpszProxyBypass);
if (ProxySettings.lpszAutoConfigUrl)
GlobalFree(ProxySettings.lpszAutoConfigUrl);
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
}
}
If you want I could send both binaries somewhere. I feel like I'm going crazy here.
Yea if you can send a debug build lf both binaries and their PDBs it shouldn't be too hard for me to figure out what's happening. Share whatever your injector you're using too so I can reproduce exactly. Just a zip archive will work
Edit: I see a potential issue, move the x86detour to a global. It calls unhook in the class destructor
Edit: I see a potential issue, move the x86detour to a global. It calls unhook in the class destructor
That does the trick, thanks! Thank you so much for this library! How should I have known this was the case? Is it expected that I look through the source code or is this some common sense that I am missing?
Edit: I see a potential issue, move the x86detour to a global. It calls unhook in the class destructor
That does the trick, thanks! Thank you so much for this library! How should I have known this was the case? Is it expected that I look through the source code or is this some common sense that I am missing?
I have some docs written that do explain this, but honestly it's quite a long read and totally understandable you missed it. The next best choice would be to look into the libraries code and see how its constructors and destructors work since in C++ RAII patterns like this are common. In this case the idea is the x86Detour
owns the 'concept' of the hook, so when the class is destroyed so too should be the hook it owns, therefore it should restore things to what they were before it was constructed. That could be guessed by being an experienced c++ dev. In either case, this is just a documentation problem on my part.
I have some docs written that do explain this, but honestly it's quite a long read and totally understandable you missed it. The next best choice would be to look into the libraries code and see how its constructors and destructors work since in C++ RAII patterns like this are common. In this case the idea is the
x86Detour
owns the 'concept' of the hook, so when the class is destroyed so too should be the hook it owns, therefore it should restore things to what they were before it was constructed. That could be guessed by being an experienced c++ dev. In either case, this is just a documentation problem on my part.
Thank you! Sorry for the bother. If you have the time: what is a good way to dynamically create the hooks and not have them be destructed in this case? Let's say I first need to run code before I know the address of the function I want to hook? Because it seems I cannot just put PLH::x86Detour detour;
somewhere then later on assign to it, it tells me that the assignment operator is a deleted function. As you might have guessed I am not an experienced c++ developer. I do appreciate all the help!
To delay construction you should use a pointer type. Since we're in c++ you should use a unique_ptr since the detour represents a unique object owning the concept of a single hook. Something like this:
std::unique_ptr<PLH::x86Detour> myDetour;
void main() {
myDetours = std::make_unique<PLH::x86Detour>(...detours ctor args...)
myDetours->hook();
}
Thank you so much! That's all! <3
I have this really strange issue. Here is my DLL code:
I then inject this DLL into a process that prints the proxy settings in a loop. The bizarre thing is that only the one call I make inside the DLL is actually detoured, the call that the process makes is not at all detoured. I have also tried a direct reference to the function instead of
GetProcAddress
but it isn't working. Even the printf example isn't working. I have turned off all optimizations but that does not help either. Am I going insane? How are multiple copies of the same function from a dll loaded in memory?