Something went wrong. Try again.
Native control, inspection, UI automation and evidence capture for a running Witcher 3 process.
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128// Optional lab-only focus handling. Named Win32 imports, no engine offsets.// Window-procedure approach also used by araghon007/NoFocusLoss (Unlicense).#define WIN32_LEAN_AND_MEAN#define NOMINMAX#include <windows.h>#include <cstring>#include <atomic>
static std::atomic<HWND> gameWindow{nullptr};static WNDPROC previousProc = nullptr;static decltype(&CreateWindowExA) createWindow = nullptr;static decltype(&GetForegroundWindow) foreground = nullptr;static decltype(&SetCursorPos) cursorPos = nullptr;static decltype(&ClipCursor) clipCursor = nullptr;static decltype(&SetCapture) setCapture = nullptr;static decltype(&SetForegroundWindow) setForeground = nullptr;static decltype(&GetAsyncKeyState) asyncKey = nullptr;static HANDLE logFile = INVALID_HANDLE_VALUE;static LONG focusLosses = 0;struct ImportHook { void** slot; void* original; void* replacement; };static ImportHook hooks[8]{};static int hookCount = 0;
static void Log(const char* text) { if (logFile != INVALID_HANDLE_VALUE) { DWORD written; WriteFile(logFile,text,static_cast<DWORD>(std::strlen(text)),&written,nullptr); }}static bool Hidden() { HWND w=gameWindow.load(); return w && foreground && foreground()!=w; }
static bool HookImport(const char* dll, const char* name, WORD ordinal, void* replacement, void** original) { auto base = reinterpret_cast<unsigned char*>(GetModuleHandleW(nullptr)); auto dos = reinterpret_cast<IMAGE_DOS_HEADER*>(base); if (dos->e_magic != IMAGE_DOS_SIGNATURE) return false; auto pe = reinterpret_cast<IMAGE_NT_HEADERS64*>(base + dos->e_lfanew); if (pe->Signature != IMAGE_NT_SIGNATURE || pe->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR64_MAGIC) return false; auto directory = pe->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]; if (!directory.VirtualAddress || directory.VirtualAddress >= pe->OptionalHeader.SizeOfImage) return false; auto imports = reinterpret_cast<IMAGE_IMPORT_DESCRIPTOR*>(base + directory.VirtualAddress); for (; imports->Name; ++imports) { if (_stricmp(reinterpret_cast<char*>(base + imports->Name), dll)) continue; if (!imports->OriginalFirstThunk) return false; auto lookup = reinterpret_cast<IMAGE_THUNK_DATA64*>(base + imports->OriginalFirstThunk); auto target = reinterpret_cast<IMAGE_THUNK_DATA64*>(base + imports->FirstThunk); for (; lookup->u1.AddressOfData; ++lookup, ++target) { bool match = IMAGE_SNAP_BY_ORDINAL64(lookup->u1.Ordinal) ? ordinal && IMAGE_ORDINAL64(lookup->u1.Ordinal) == ordinal : name && !std::strcmp(reinterpret_cast<IMAGE_IMPORT_BY_NAME*>(base + lookup->u1.AddressOfData)->Name, name); if (!match) continue; DWORD protection; if (!VirtualProtect(&target->u1.Function, sizeof(void*), PAGE_READWRITE, &protection)) return false; *original = reinterpret_cast<void*>(target->u1.Function); hooks[hookCount++] = {reinterpret_cast<void**>(&target->u1.Function), *original, replacement}; InterlockedExchangePointer(reinterpret_cast<void* volatile*>(&target->u1.Function), replacement); DWORD unused; VirtualProtect(&target->u1.Function, sizeof(void*), protection, &unused); return true; } } return false;}
static LRESULT CALLBACK WindowProc(HWND window, UINT message, WPARAM wp, LPARAM lp) { // Keep the engine active without moving OS focus or exposing other apps' input. if ((message==WM_ACTIVATE && LOWORD(wp)==WA_INACTIVE) || (message==WM_ACTIVATEAPP && !wp) || message==WM_KILLFOCUS || (message==WM_IME_SETCONTEXT && !wp)) { if (InterlockedIncrement(&focusLosses)<=16) Log("suppressed focus loss\n"); if (clipCursor) clipCursor(nullptr); ReleaseCapture(); return 0; } if (message==WM_NCACTIVATE && !wp) return DefWindowProcA(window,message,wp,lp); if (Hidden() && ((message>=WM_KEYFIRST && message<=WM_KEYLAST) || (message>=WM_MOUSEFIRST && message<=WM_MOUSELAST) || message==WM_INPUT)) return DefWindowProcA(window,message,wp,lp); auto result=CallWindowProcA(previousProc,window,message,wp,lp); if (message==WM_NCDESTROY) gameWindow.store(nullptr); return result;}
static HWND WINAPI Create(DWORD ex,LPCSTR klass,LPCSTR title,DWORD style,int x,int y,int width,int height,HWND parent,HMENU menu,HINSTANCE instance,LPVOID param) { HWND window=createWindow(ex,klass,title,style,x,y,width,height,parent,menu,instance,param); if (window && !parent && title && reinterpret_cast<ULONG_PTR>(title)>65535 && !std::strcmp(title,"The Witcher 3") && !gameWindow.load()) { previousProc=reinterpret_cast<WNDPROC>(GetWindowLongPtrA(window,GWLP_WNDPROC)); gameWindow.store(window); SetLastError(0); auto old=SetWindowLongPtrA(window,GWLP_WNDPROC,reinterpret_cast<LONG_PTR>(WindowProc)); if (!old && GetLastError()) { gameWindow.store(nullptr); Log("ERROR window subclass failed\n"); } else { previousProc=reinterpret_cast<WNDPROC>(old); Log("main window subclass installed\n"); // A pinned window can launch without ever receiving OS activation. CallWindowProcA(previousProc,window,WM_ACTIVATEAPP,TRUE,0); CallWindowProcA(previousProc,window,WM_ACTIVATE,WA_ACTIVE,0); CallWindowProcA(previousProc,window,WM_SETFOCUS,0,0); } } return window;}static HWND WINAPI Foreground() { auto window=gameWindow.load(); return window ? window : foreground(); }static BOOL WINAPI CursorPos(int x,int y) { return Hidden() ? TRUE : cursorPos(x,y); }static BOOL WINAPI Clip(const RECT* rect) { return clipCursor(Hidden() ? nullptr : rect); }static HWND WINAPI Capture(HWND window) { return Hidden() ? nullptr : setCapture(window); }static BOOL WINAPI Activate(HWND window) { return Hidden() && window==gameWindow.load() ? FALSE : setForeground(window); }static SHORT WINAPI Key(int key) { return Hidden() ? 0 : asyncKey(key); }
BOOL WINAPI DllMain(HINSTANCE module,DWORD reason,LPVOID) { if (reason==DLL_PROCESS_ATTACH) { DisableThreadLibraryCalls(module); char path[MAX_PATH]{};GetModuleFileNameA(module,path,MAX_PATH); char* dot=std::strrchr(path,'.');if(dot)std::strcpy(dot,".log"); logFile=CreateFileA(path,GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,nullptr,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,nullptr); bool ok=HookImport("USER32.dll","GetForegroundWindow",0,reinterpret_cast<void*>(Foreground),reinterpret_cast<void**>(&foreground)) && HookImport("USER32.dll","SetCursorPos",0,reinterpret_cast<void*>(CursorPos),reinterpret_cast<void**>(&cursorPos)) && HookImport("USER32.dll","ClipCursor",0,reinterpret_cast<void*>(Clip),reinterpret_cast<void**>(&clipCursor)) && HookImport("USER32.dll","SetCapture",0,reinterpret_cast<void*>(Capture),reinterpret_cast<void**>(&setCapture)) && HookImport("USER32.dll","SetForegroundWindow",0,reinterpret_cast<void*>(Activate),reinterpret_cast<void**>(&setForeground)) && HookImport("USER32.dll","GetAsyncKeyState",0,reinterpret_cast<void*>(Key),reinterpret_cast<void**>(&asyncKey)) && HookImport("USER32.dll","CreateWindowExA",0,reinterpret_cast<void*>(Create),reinterpret_cast<void**>(&createWindow)); if(!ok) { for(int i=hookCount-1;i>=0;--i) { DWORD protection; if(VirtualProtect(hooks[i].slot,sizeof(void*),PAGE_READWRITE,&protection)) { *hooks[i].slot=hooks[i].original; DWORD unused;VirtualProtect(hooks[i].slot,sizeof(void*),protection,&unused); } } Log("ERROR import set incomplete; rolled back\n"); } else Log("seven named imports installed\n"); } // Never unload dynamically; uninstall requires game closed. Process teardown // owns its address space and avoids racing a live window callback. return TRUE;}