, setting display affinity to 0 for Authy Desktop seems to fix that problem. I'm not sure whether it's necessary to call SetWindowDisplayAffinity before every FindText call or just periodically, but the following code seems to fix it. Unfortunately it's an incomplete solution, because I only got it working with Authy Desktop, and calling it on other programs will most likely crash the program. Perhaps somebody else can figure out the cause (I suspect it's because LoadLibrary isn't called from the external thread?).
Code: Select all
hWnd := WinExist("Twilio")
OutputDebug, % GetWindowDisplayAffinity(hWnd) "`n"
SetWindowDisplayAffinity(hWnd, 0)
OutputDebug, % GetWindowDisplayAffinity(hWnd) "`n"
GetWindowDisplayAffinity(hWnd) {
DllCall("GetWindowDisplayAffinity", "int", hWnd, "int*", out)
return out
}
SetWindowDisplayAffinity(hWnd, dwAffinity:=0) {
static pGlobal, mcode:="2,x86:g+wci0QkIItQCIlUJATB+h+JVCQIi1AEiRQk/xCDxBzD,x64:TItBCEiLURBIiwFMicFI/+A=", e := {1:4, 2:1}, c := (A_PtrSize=8) ? "x64" : "x86"
, hFunc := DllCall("GetProcAddress", "ptr", DllCall("GetModuleHandle", "str", "user32.dll", "ptr"), "astr", "SetWindowDisplayAffinity", "ptr")
/*
#include <windows.h>
BOOL SetAffinity(void* args[]) {
BOOL(*func)(HWND, long long) = (BOOL(*)(HWND, long long))args[0];
return func((HWND)args[1], (long long)args[2]);
}
*/
; Load MCode into local memory
if (!pGlobal) {
if (!regexmatch(mcode, "^([0-9]+),(" c ":|.*?," c ":)([^,]+)", m))
return
if (!DllCall("crypt32\CryptStringToBinary", "str", m3, "uint", 0, "uint", e[m1], "ptr", 0, "uint*", s, "ptr", 0, "ptr", 0))
return
pGlobal := DllCall("GlobalAlloc", "uint", 0, "ptr", s, "ptr")
if (c="x64")
DllCall("VirtualProtect", "ptr", pGlobal, "ptr", s, "uint", 0x40, "uint*", op)
if (!DllCall("crypt32\CryptStringToBinary", "str", m3, "uint", 0, "uint", e[m1], "ptr", pGlobal, "uint*", s, "ptr", 0, "ptr", 0))
DllCall("GlobalFree", "ptr", pGlobal)
}
; Write MCode function pointer, window hWnd, and dwAffinity parameters into a buffer to be copied over
WinGet, pid, PID, ahk_id %hWnd%
VarSetCapacity(buffer, A_PtrSize*3)
NumPut(hFunc, buffer, 0, "ptr")
NumPut(hWnd, buffer, A_PtrSize, "ptr")
NumPut(dwAffinity, buffer, A_PtrSize*2, "ptr")
; Get process handle for process
hProc := DllCall("OpenProcess", "int", 0x000F0000 | 0x00100000 | 0xFFFF, "int", 0, "int", pid) ; PROCESS_ALL_ACCESS
; Allocate memory for the process, and then copy the parameters from buffer
remotebuffer := DllCall("VirtualAllocEx", "ptr", hProc, "ptr", 0, "int", A_PtrSize*3, "int", 0x00001000 | 0x00002000, "int", 0x04, "ptr")
DllCall("WriteProcessMemory", "ptr", hProc, "ptr", remotebuffer, "ptr", &buffer, "int", A_PtrSize*3, "int*", written)
; Write the MCode function in the process memory
pRemoteFunc := DllCall("VirtualAllocEx", "ptr", hProc, "ptr", 0, "int", s, "int", 0x00001000 | 0x00002000, "int", 0x40, "ptr")
DllCall("WriteProcessMemory", "ptr", hProc, "ptr", pRemoteFunc, "ptr", pGlobal, "int", s, "int*", written)
; Execute new thread using MCode function and allocated parameters
hThread := DllCall("CreateRemoteThread", "ptr", hProc, "uint", 0, "uint", 0, "ptr", pRemoteFunc, "ptr", remotebuffer, "uint", 0, "uint", 0, "ptr")
DllCall("WaitForSingleObject", "ptr", hThread, "UInt", 0xFFFFFFFF)
DllCall("VirtualFree", "ptr", pRemoteFunc, "int", 0, "int", 0x00008000) ; MEM_DECOMMIT
DllCall("VirtualFree", "ptr", remotebuffer, "int", 0, "int", 0x00008000)
DllCall("CloseHandle", "ptr", hThread)
DllCall("CloseHandle", "ptr", hProc)
}