-
Member
Is DLL injection useless ?
Today I translated a C# class to C++ to run functions on the main thread of a window of a game thanks to Windows API, and I thought that if you can run your own functions on the main thread this way, maybe DLL injection (which is about exploiting the address space of the targeted process) becomes useless since your functions will run in the same address space of the targeted process.
First I'll share my code, then I'll illustrate an exemple of how I think it's possible to just use game's functions with this method:
The header:
Code:
class ThreadSynchronizer {
public:
static void Init();
static void RunOnMainThread(std::function<void()> action);
static int WndProc(HWND hwnd, UINT Msg, WPARAM wparam, LPARAM lparam);
static void SendUserMessage();
private:
static WNDPROC newCallback;
static WNDPROC oldCallback;
static HWND windowHandle;
static std::vector<std::function<void()>> actionQueue;
};
The .cpp file:
Code:
WNDPROC ThreadSynchronizer::oldCallback;
WNDPROC ThreadSynchronizer::newCallback;
HWND ThreadSynchronizer::windowHandle;
std::vector<std::function<void()>> ThreadSynchronizer::actionQueue;
void ThreadSynchronizer::Init() {
windowHandle = FindWindowW(NULL, L"World of Warcraft");
newCallback = (WNDPROC)&WndProc;
oldCallback = (WNDPROC)SetWindowLongW(windowHandle, GWL_WNDPROC, (LONG)newCallback);
}
void ThreadSynchronizer::RunOnMainThread(std::function<void()> action) {
actionQueue.push_back(action);
SendUserMessage();
}
int ThreadSynchronizer::WndProc(HWND hwnd, UINT Msg, WPARAM wparam, LPARAM lparam) {
if (actionQueue.size() > 0) {
std::invoke(actionQueue.back());
actionQueue.pop_back();
}
return CallWindowProcW(oldCallback, hwnd, Msg, wparam, lparam);
}
void ThreadSynchronizer::SendUserMessage() {
SendMessageW(windowHandle, WM_USER, 0, 0);
}
And this is how I use it for instance for my SetTarget() function, which needs a GUID as parameter:
Code:
void LocalPlayer::SetTarget(unsigned long long tguid) {
typedef void __stdcall func(unsigned long long tguid);
func* function = (func*)SET_TARGET_FUN_PTR;
ThreadSynchronizer::RunOnMainThread( //Or KA-BOOM !
[function, tguid]() { function(tguid); }
);
}
Don't forget to initialise everything and you're good to go:
Code:
ThreadSynchronizer::Init();
localPlayer.SetTarget(closestUnit.Guid);
So by using this method my process which is controlling the bot doesn't even need to have a starting point written in the address space of the targeted process since I'll use my hook to do that for me.
What do you think of that ? Am I wrong ?
Last edited by Lywbringer; 09-24-2022 at 09:24 AM.
-
Active Member
A simple GetWindowLongW() check can easily reveal the address of your own "wndproc", outside the main module address space. The only reason you are not banned is BLZ now is not interested in updating its own Warden anymore, for the time being.
-
Post Thanks / Like - 1 Thanks
Lywbringer (1 members gave Thanks to zys924 for this useful post)
-
-
Contributor
Originally Posted by
Razzue
Funny you say that right after a couple new scans were added but okay...
Enlighten us . I think there are many legit modules that hook WndProc for various reasons.
-
Active Member
Yes, and those modules are easily identifiable by their hash/digital signatures, which you can't forge.
-
Originally Posted by
zys924
Yes, and those modules are easily identifiable by their hash/digital signatures, which you can't forge.
Are you saying there is a whitelist and unknown modules constitute a detection? This is news to me.
-
Contributor
Originally Posted by
zys924
Yes, and those modules are easily identifiable by their hash/digital signatures, which you can't forge.
but you could find a way to make you callback appear inside one of those modules fairly easily ( if this was a concern)