https://github.com/kevrgithub/autohotke ... ectDll.ahk
I tested it with the script in the link above, but it does not work.
Is there a simple way to do dll injection with ahk?
how to dll Inject Topic is solved
-
- Posts: 147
- Joined: 05 Nov 2016, 22:42
Re: how to dll Inject
Is dll injection an 'OK' thing to do?
Like, if I were to say on Stack Overflow, you can change the font size and control colours in legacy programs using dll injection, would there be a problem?
Or similarly if I said you can retrieve the file path and set the three (yes, three) colours in MS Paint (Windows XP) by searching/editing the address space, would there be a problem?
'These are totally hypothetical things that may or may not be possible.'
Like, if I were to say on Stack Overflow, you can change the font size and control colours in legacy programs using dll injection, would there be a problem?
Or similarly if I said you can retrieve the file path and set the three (yes, three) colours in MS Paint (Windows XP) by searching/editing the address space, would there be a problem?
'These are totally hypothetical things that may or may not be possible.'
Last edited by jeeswg on 17 Aug 2017, 15:24, edited 1 time in total.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
- FanaticGuru
- Posts: 1908
- Joined: 30 Sep 2013, 22:25
Re: how to dll Inject
I am not sure what you mean by is it ok or a problem. Some programs it works fine, some it don't.jeeswg wrote:Is dll injection an OK thing to do?
Some programs like online games that monitor for tampering especially don't like it.
FG
Hotkey Help - Help Dialog for Currently Running AHK Scripts
AHK Startup - Consolidate Multiply AHK Scripts with one Tray Icon
Hotstring Manager - Create and Manage Hotstrings
[Class] WinHook - Create Window Shell Hooks and Window Event Hooks
AHK Startup - Consolidate Multiply AHK Scripts with one Tray Icon
Hotstring Manager - Create and Manage Hotstrings
[Class] WinHook - Create Window Shell Hooks and Window Event Hooks
-
- Posts: 147
- Joined: 05 Nov 2016, 22:42
Re: how to dll Inject
HotKeyIt wrote:Try InjectAhkDll()
#include _Struct.ahk
#include sizeof.ahk
InjectAhkDll(PID,dll="AutoHotkey.dll",script=0){
static PROCESS_ALL_ACCESS:=0x1F0FFF,MEM_COMMIT := 0x1000,MEM_RELEASE:=0x8000,PAGE_EXECUTE_READWRITE:=64
,hKernel32:=DllCall("LoadLibrary","Str","kernel32.dll","PTR"),LoadLibraryA:=DllCall("GetProcAddress","PTR",hKernel32,"AStr","LoadLibraryA","PTR")
,base:={__Call:"InjectAhkDll",__Delete:"InjectAhkDll"},FreeLibrary:=DllCall("GetProcAddress","PTR",hKernel32,"AStr","FreeLibrary","PTR")
static TH32CS_SNAPMODULE:=0x00000008,INVALID_HANDLE_VALUE:=-1
,MAX_PATH:=260,MAX_MODULE_NAME32:=255,ModuleName:="",init:=VarSetCapacity(ModuleName,MAX_PATH*(A_IsUnicode?2:1))
,_MODULEENTRY32:="
(
DWORD dwSize;
DWORD th32ModuleID;
.
.
.
Process,wait, notepad.exe
winget,pid,pid,ahk_exe notepad.exe
rThread:=InjectAhkDll(PID,A_ScriptDir "\AutoHotkeyMini.dll","#Persistent`nMsgBox % A_WorkingDir")
Sleep 500
rThread.Exec("MsgBox % A_AhkPath")
The program terminates with a crash.
Compiled from x64 to x86 bin.
Re: how to dll Inject Topic is solved
Try this AHK_H version:
Code: Select all
Process,Exist, notepad.exe
If !PID:=ErrorLevel
Run notepad.exe,,,PID
rThread:=InjectAhkDll(PID,"C:\Scratch\Program Files\AutoHotkey\AutoHotkey 1\Win32w\AutoHotkeyMini.dll")
rThread.Exec("MsgBox % A_WorkingDir")
InjectAhkDll(PID,dll="AutoHotkey.dll",script=0){
static PROCESS_ALL_ACCESS:=0x1F0FFF,MEM_COMMIT := 0x1000,MEM_RELEASE:=0x8000,PAGE_EXECUTE_READWRITE:=64
,hKernel32:=DllCall("LoadLibrary","Str","kernel32.dll","PTR"),LoadLibraryA:=DllCall("GetProcAddress","PTR",hKernel32,"AStr","LoadLibraryA","PTR")
,base:={__Call:"InjectAhkDll",__Delete:"InjectAhkDll"},FreeLibrary:=DllCall("GetProcAddress","PTR",hKernel32,"AStr","FreeLibrary","PTR")
static TH32CS_SNAPMODULE:=0x00000008,INVALID_HANDLE_VALUE:=-1
,MAX_PATH:=260,MAX_MODULE_NAME32:=255,ModuleName:="",init:=VarSetCapacity(ModuleName,MAX_PATH*(A_IsUnicode?2:1))
,_MODULEENTRY32:="
(
DWORD dwSize;
DWORD th32ModuleID;
DWORD th32ProcessID;
DWORD GlblcntUsage;
DWORD ProccntUsage;
BYTE *modBaseAddr;
DWORD modBaseSize;
HMODULE hModule;
TCHAR szModule[" MAX_MODULE_NAME32 + 1 "];
TCHAR szExePath[" MAX_PATH "];
)"
If IsObject(PID){
If (dll!="Exec" && script)
return DllCall("MessageBox","PTR",0,"Str","Only Exec method can be used here!","STR","Error","UInt",0)
hProc := DllCall("OpenProcess", "UInt", PROCESS_ALL_ACCESS, "Int",0, "UInt", PID.PID,"PTR")
If !hProc
return DllCall("MessageBox","PTR",0,"Str","Could not open process for PID: " PID.PID,"STR","Error","UInt",0)
if (!script) ; Free Library in remote process (object is being deleted)
{
; Terminate the thread in ahkdll
hThread := DllCall("CreateRemoteThread", "PTR", hProc, "PTR", 0, "PTR", 0, "PTR", PID.ahkTerminate, "PTR", 0, "UInt", 0, "PTR", 0,"PTR")
DllCall("WaitForSingleObject", "PTR", hThread, "UInt", 0xFFFFFFFF)
,DllCall("CloseHandle", "PTR", hThread)
; Free library in remote process
hThread := DllCall("CreateRemoteThread", "PTR", hProc, "UInt", 0, "UInt", 0, "PTR", FreeLibrary, "PTR", PID.hModule, "UInt", 0, "UInt", 0,"PTR")
DllCall("WaitForSingleObject", "PTR", hThread, "UInt", 0xFFFFFFFF)
,DllCall("CloseHandle", "PTR", hThread),DllCall("CloseHandle", "PTR", hProc)
return
}
nScriptLength := VarSetCapacity(nScript, (StrLen(script)+1)*(A_IsUnicode?2:1), 0)
,StrPut(script,&nScript)
; Reserve memory in remote process where our script will be saved
If !pBufferRemote := DllCall("VirtualAllocEx", "Ptr", hProc, "Ptr", 0, "PTR", nScriptLength, "UInt", MEM_COMMIT, "UInt", PAGE_EXECUTE_READWRITE, "Ptr")
return DllCall("MessageBox","PTR",0,"Str","Could not reseve memory for process.","STR","Error","UInt",0)
,DllCall("CloseHandle", "PTR", hProc)
; Write script to remote process memory
DllCall("WriteProcessMemory", "Ptr", hProc, "Ptr", pBufferRemote, "Ptr", &nScript, "PTR", nScriptLength, "Ptr", 0)
; Start execution of code
hThread := DllCall("CreateRemoteThread", "PTR", hProc, "PTR", 0, "PTR", 0, "PTR", PID.ahkExec, "PTR", pBufferRemote, "UInt", 0, "PTR", 0,"PTR")
If !hThread
{
DllCall("VirtualFreeEx","PTR",hProc,"PTR",pBufferRemote,"PTR",nScriptLength,MEM_RELEASE)
,DllCall("CloseHandle", "PTR", hProc)
return DllCall("MessageBox","PTR",0,"Str","Could not execute script in remote process.","STR","Error","UInt",0)
}
; Wait for thread to finish
DllCall("WaitForSingleObject", "PTR", hThread, "UInt", 0xFFFFFFFF)
; Get Exit code returned by ahkExec (1 = script could be executed / 0 = script could not be executed)
DllCall("GetExitCodeThread", "PTR", hThread, "UIntP", lpExitCode)
If !lpExitCode
return DllCall("MessageBox","PTR",0,"Str","Could not execute script in remote process.","STR","Error","UInt",0)
DllCall("CloseHandle", "PTR", hThread)
,DllCall("VirtualFreeEx","PTR",hProc,"PTR",pBufferRemote,"PTR",nScriptLength,MEM_RELEASE)
,DllCall("CloseHandle", "PTR", hProc)
return
} else if !hDll:=DllCall("LoadLibrary","Str",dll,"PTR")
return DllCall("MessageBox","PTR",0,"Str","Could not find " dll " library.","STR","Error","UInt",0),DllCall("CloseHandle", "PTR", hProc)
else {
hProc := DllCall("OpenProcess","UInt", PROCESS_ALL_ACCESS, "Int",0,"UInt", DllCall("GetCurrentProcessId"),"PTR")
DllCall("GetModuleFileName","PTR",hDll,"PTR",&ModuleName,"UInt",MAX_PATH)
DllCall("CloseHandle","PTR",hProc)
}
; Open Process to PID
hProc := DllCall("OpenProcess", "UInt", PROCESS_ALL_ACCESS, "Int",0, "UInt", PID,"PTR")
If !hProc
return DllCall("MessageBox","PTR",0,"Str","Could not open process for PID: " PID,"STR","Error","UInt",0)
; Reserve some memory and write dll path (ANSI)
nDirLength := VarSetCapacity(nDir, StrLen(dll)+1, 0)
,StrPut(dll,&nDir,"CP0")
; Reserve memory in remote process
If !pBufferRemote := DllCall("VirtualAllocEx", "Ptr", hProc, "Ptr", 0, "PTR", nDirLength, "UInt", MEM_COMMIT, "UInt", PAGE_EXECUTE_READWRITE, "Ptr")
return DllCall("MessageBox","PTR",0,"Str","Could not reseve memory for process.","STR","Error","UInt",0),DllCall("CloseHandle", "PTR", hProc)
; Write dll path to remote process memory
DllCall("WriteProcessMemory", "Ptr", hProc, "Ptr", pBufferRemote, "Ptr", &nDir, "PTR", nDirLength, "Ptr", 0)
; Start new thread loading our dll
hThread:=DllCall("CreateRemoteThread","PTR",hProc,"PTR",0,"PTR",0,"PTR",LoadLibraryA,"PTR",pBufferRemote,"UInt",0,"PTR",0,"PTR")
If !hThread {
DllCall("VirtualFreeEx","PTR",hProc,"PTR",pBufferRemote,"PTR",nDirLength,"Uint",MEM_RELEASE)
,DllCall("CloseHandle", "PTR", hProc)
return DllCall("MessageBox","PTR",0,"Str","Could not load " dll " in remote process.","STR","Error","UInt",0)
}
; Wait for thread to finish
DllCall("WaitForSingleObject", "PTR", hThread, "UInt", 0xFFFFFFFF)
; Get Exit code returned by thread (HMODULE for our dll)
DllCall("GetExitCodeThread", "PTR", hThread, "UInt*", hModule)
; Close Thread
DllCall("CloseHandle", "PTR", hThread)
If (A_PtrSize=8){ ; use different method to retrieve base address because GetExitCodeThread returns DWORD only
hModule:=0,me32 := Struct(_MODULEENTRY32)
; Take a snapshot of all modules in the specified process.
hModuleSnap := DllCall("CreateToolhelp32Snapshot","UInt", TH32CS_SNAPMODULE,"UInt", PID, "PTR" )
if( hModuleSnap != INVALID_HANDLE_VALUE ){
; reset hModule and set the size of the structure before using it.
me32.dwSize := sizeof(_MODULEENTRY32)
; Retrieve information about the first module,
; and exit if unsuccessful
if( !DllCall("Module32First" (A_IsUnicode?"W":""),"PTR", hModuleSnap,"PTR", me32[] ) ) {
; Free memory used for passing dll path to remote thread
DllCall("VirtualFreeEx","PTR",hProc,"PTR",pBufferRemote,"PTR",nDirLength,MEM_RELEASE)
,DllCall("CloseHandle","PTR", hModuleSnap ) ; Must clean up the snapshot object!
return false
}
; Now walk the module list of the process,and display information about each module
while(A_Index=1 || DllCall("Module32Next" (A_IsUnicode?"W":""),"PTR",hModuleSnap,"PTR", me32[] ) )
If (StrGet(me32.szExePath[""])=dll){
hModule := me32.modBaseAddr["",""]
break
}
DllCall("CloseHandle","PTR",hModuleSnap) ; clean up
}
}
hDll:=DllCall("LoadLibrary","Str",dll,"PTR")
; Calculate pointer to ahkdll and ahkExec functions
ahktextdll:=hModule+DllCall("GetProcAddress","PTR",hDll,"AStr","ahktextdll","PTR")-hDll
ahkExec:=hModule+DllCall("GetProcAddress","PTR",hDll,"AStr","ahkExec","PTR")-hDll
ahkTerminate:=hModule+DllCall("GetProcAddress","PTR",hDll,"AStr","ahkTerminate","PTR")-hDll
If script {
nScriptLength := VarSetCapacity(nScript, (StrLen(script)+1)*(A_IsUnicode?2:1), 0)
,StrPut(script,&nScript)
; Reserve memory in remote process where our script will be saved
If !pBufferScript := DllCall("VirtualAllocEx", "Ptr", hProc, "Ptr", 0, "PTR", nScriptLength, "UInt", MEM_COMMIT, "UInt", PAGE_EXECUTE_READWRITE, "Ptr")
return DllCall("MessageBox","PTR",0,"Str","Could not reseve memory for process.","STR","Error","UInt",0)
,DllCall("CloseHandle", "PTR", hProc)
; Write script to remote process memory
DllCall("WriteProcessMemory", "Ptr", hProc, "Ptr", pBufferScript, "Ptr", &nScript, "PTR", nScriptLength, "Ptr", 0)
} else pBufferScript:=0
; Run ahkdll function in remote thread
hThread := DllCall("CreateRemoteThread","PTR",hProc,"PTR",0,"PTR",0,"PTR",ahktextdll,"PTR",pBufferScript,"PTR",0,"UInt",0,"PTR")
If !hThread { ; could not start ahkdll in remote process
; Free memory used for passing dll path to remote thread
DllCall("VirtualFreeEx","PTR",hProc,"PTR",pBufferRemote,"PTR",nDirLength,MEM_RELEASE)
DllCall("CloseHandle", "PTR", hProc)
return DllCall("MessageBox","PTR",0,"Str","Could not start ahkdll in remote process","STR","Error","UInt",0)
}
DllCall("WaitForSingleObject", "PTR", hThread, "UInt", 0xFFFFFFFF)
DllCall("GetExitCodeThread", "PTR", hThread, "UIntP", lpExitCode)
; Release memory and handles
DllCall("VirtualFreeEx","PTR",hProc,"PTR",pBufferRemote,"PTR",nDirLength,MEM_RELEASE)
DllCall("CloseHandle", "PTR", hThread)
DllCall("CloseHandle", "PTR", hProc)
If !lpExitCode ; thread could not be created.
return DllCall("MessageBox","PTR",0,"Str","Could not create a thread in remote process","STR","Error","UInt",0)
return {PID:PID,hModule:hModule,ahkExec:ahkExec,ahkTerminate:ahkTerminate,base:base}
}
-
- Posts: 147
- Joined: 05 Nov 2016, 22:42
Re: how to dll Inject
HotKeyIt wrote:Try this AHK_H version:Code: Select all
Process,Exist, notepad.exe If !PID:=ErrorLevel Run notepad.exe,,,PID rThread:=InjectAhkDll(PID,"C:\Scratch\Program Files\AutoHotkey\AutoHotkey 1\Win32w\AutoHotkeyMini.dll") rThread.Exec("MsgBox % A_WorkingDir") InjectAhkDll(PID,dll="AutoHotkey.dll",script=0){ static PROCESS_ALL_ACCESS:=0x1F0FFF,MEM_COMMIT := 0x1000,MEM_RELEASE:=0x8000,PAGE_EXECUTE_READWRITE:=64 ,hKernel32:=DllCall("LoadLibrary","Str","kernel32.dll","PTR"),LoadLibraryA:=DllCall("GetProcAddress","PTR",hKernel32,"AStr","LoadLibraryA","PTR") ,base:={__Call:"InjectAhkDll",__Delete:"InjectAhkDll"},FreeLibrary:=DllCall("GetProcAddress","PTR",hKernel32,"AStr","FreeLibrary","PTR") static TH32CS_SNAPMODULE:=0x00000008,INVALID_HANDLE_VALUE:=-1 ,MAX_PATH:=260,MAX_MODULE_NAME32:=255,ModuleName:="",init:=VarSetCapacity(ModuleName,MAX_PATH*(A_IsUnicode?2:1)) ,_MODULEENTRY32:=" ( DWORD dwSize; DWORD th32ModuleID; DWORD th32ProcessID; DWORD GlblcntUsage; DWORD ProccntUsage; BYTE *modBaseAddr; DWORD modBaseSize; HMODULE hModule; TCHAR szModule[" MAX_MODULE_NAME32 + 1 "]; TCHAR szExePath[" MAX_PATH "]; )" If IsObject(PID){ If (dll!="Exec" && script) return DllCall("MessageBox","PTR",0,"Str","Only Exec method can be used here!","STR","Error","UInt",0) hProc := DllCall("OpenProcess", "UInt", PROCESS_ALL_ACCESS, "Int",0, "UInt", PID.PID,"PTR") If !hProc return DllCall("MessageBox","PTR",0,"Str","Could not open process for PID: " PID.PID,"STR","Error","UInt",0) if (!script) ; Free Library in remote process (object is being deleted) { ; Terminate the thread in ahkdll hThread := DllCall("CreateRemoteThread", "PTR", hProc, "PTR", 0, "PTR", 0, "PTR", PID.ahkTerminate, "PTR", 0, "UInt", 0, "PTR", 0,"PTR") DllCall("WaitForSingleObject", "PTR", hThread, "UInt", 0xFFFFFFFF) ,DllCall("CloseHandle", "PTR", hThread) ; Free library in remote process hThread := DllCall("CreateRemoteThread", "PTR", hProc, "UInt", 0, "UInt", 0, "PTR", FreeLibrary, "PTR", PID.hModule, "UInt", 0, "UInt", 0,"PTR") DllCall("WaitForSingleObject", "PTR", hThread, "UInt", 0xFFFFFFFF) ,DllCall("CloseHandle", "PTR", hThread),DllCall("CloseHandle", "PTR", hProc) return } nScriptLength := VarSetCapacity(nScript, (StrLen(script)+1)*(A_IsUnicode?2:1), 0) ,StrPut(script,&nScript) ; Reserve memory in remote process where our script will be saved If !pBufferRemote := DllCall("VirtualAllocEx", "Ptr", hProc, "Ptr", 0, "PTR", nScriptLength, "UInt", MEM_COMMIT, "UInt", PAGE_EXECUTE_READWRITE, "Ptr") return DllCall("MessageBox","PTR",0,"Str","Could not reseve memory for process.","STR","Error","UInt",0) ,DllCall("CloseHandle", "PTR", hProc) ; Write script to remote process memory DllCall("WriteProcessMemory", "Ptr", hProc, "Ptr", pBufferRemote, "Ptr", &nScript, "PTR", nScriptLength, "Ptr", 0) ; Start execution of code hThread := DllCall("CreateRemoteThread", "PTR", hProc, "PTR", 0, "PTR", 0, "PTR", PID.ahkExec, "PTR", pBufferRemote, "UInt", 0, "PTR", 0,"PTR") If !hThread { DllCall("VirtualFreeEx","PTR",hProc,"PTR",pBufferRemote,"PTR",nScriptLength,MEM_RELEASE) ,DllCall("CloseHandle", "PTR", hProc) return DllCall("MessageBox","PTR",0,"Str","Could not execute script in remote process.","STR","Error","UInt",0) } ; Wait for thread to finish DllCall("WaitForSingleObject", "PTR", hThread, "UInt", 0xFFFFFFFF) ; Get Exit code returned by ahkExec (1 = script could be executed / 0 = script could not be executed) DllCall("GetExitCodeThread", "PTR", hThread, "UIntP", lpExitCode) If !lpExitCode return DllCall("MessageBox","PTR",0,"Str","Could not execute script in remote process.","STR","Error","UInt",0) DllCall("CloseHandle", "PTR", hThread) ,DllCall("VirtualFreeEx","PTR",hProc,"PTR",pBufferRemote,"PTR",nScriptLength,MEM_RELEASE) ,DllCall("CloseHandle", "PTR", hProc) return } else if !hDll:=DllCall("LoadLibrary","Str",dll,"PTR") return DllCall("MessageBox","PTR",0,"Str","Could not find " dll " library.","STR","Error","UInt",0),DllCall("CloseHandle", "PTR", hProc) else { hProc := DllCall("OpenProcess","UInt", PROCESS_ALL_ACCESS, "Int",0,"UInt", DllCall("GetCurrentProcessId"),"PTR") DllCall("GetModuleFileName","PTR",hDll,"PTR",&ModuleName,"UInt",MAX_PATH) DllCall("CloseHandle","PTR",hProc) } ; Open Process to PID hProc := DllCall("OpenProcess", "UInt", PROCESS_ALL_ACCESS, "Int",0, "UInt", PID,"PTR") If !hProc return DllCall("MessageBox","PTR",0,"Str","Could not open process for PID: " PID,"STR","Error","UInt",0) ; Reserve some memory and write dll path (ANSI) nDirLength := VarSetCapacity(nDir, StrLen(dll)+1, 0) ,StrPut(dll,&nDir,"CP0") ; Reserve memory in remote process If !pBufferRemote := DllCall("VirtualAllocEx", "Ptr", hProc, "Ptr", 0, "PTR", nDirLength, "UInt", MEM_COMMIT, "UInt", PAGE_EXECUTE_READWRITE, "Ptr") return DllCall("MessageBox","PTR",0,"Str","Could not reseve memory for process.","STR","Error","UInt",0),DllCall("CloseHandle", "PTR", hProc) ; Write dll path to remote process memory DllCall("WriteProcessMemory", "Ptr", hProc, "Ptr", pBufferRemote, "Ptr", &nDir, "PTR", nDirLength, "Ptr", 0) ; Start new thread loading our dll hThread:=DllCall("CreateRemoteThread","PTR",hProc,"PTR",0,"PTR",0,"PTR",LoadLibraryA,"PTR",pBufferRemote,"UInt",0,"PTR",0,"PTR") If !hThread { DllCall("VirtualFreeEx","PTR",hProc,"PTR",pBufferRemote,"PTR",nDirLength,"Uint",MEM_RELEASE) ,DllCall("CloseHandle", "PTR", hProc) return DllCall("MessageBox","PTR",0,"Str","Could not load " dll " in remote process.","STR","Error","UInt",0) } ; Wait for thread to finish DllCall("WaitForSingleObject", "PTR", hThread, "UInt", 0xFFFFFFFF) ; Get Exit code returned by thread (HMODULE for our dll) DllCall("GetExitCodeThread", "PTR", hThread, "UInt*", hModule) ; Close Thread DllCall("CloseHandle", "PTR", hThread) If (A_PtrSize=8){ ; use different method to retrieve base address because GetExitCodeThread returns DWORD only hModule:=0,me32 := Struct(_MODULEENTRY32) ; Take a snapshot of all modules in the specified process. hModuleSnap := DllCall("CreateToolhelp32Snapshot","UInt", TH32CS_SNAPMODULE,"UInt", PID, "PTR" ) if( hModuleSnap != INVALID_HANDLE_VALUE ){ ; reset hModule and set the size of the structure before using it. me32.dwSize := sizeof(_MODULEENTRY32) ; Retrieve information about the first module, ; and exit if unsuccessful if( !DllCall("Module32First" (A_IsUnicode?"W":""),"PTR", hModuleSnap,"PTR", me32[] ) ) { ; Free memory used for passing dll path to remote thread DllCall("VirtualFreeEx","PTR",hProc,"PTR",pBufferRemote,"PTR",nDirLength,MEM_RELEASE) ,DllCall("CloseHandle","PTR", hModuleSnap ) ; Must clean up the snapshot object! return false } ; Now walk the module list of the process,and display information about each module while(A_Index=1 || DllCall("Module32Next" (A_IsUnicode?"W":""),"PTR",hModuleSnap,"PTR", me32[] ) ) If (StrGet(me32.szExePath[""])=dll){ hModule := me32.modBaseAddr["",""] break } DllCall("CloseHandle","PTR",hModuleSnap) ; clean up } } hDll:=DllCall("LoadLibrary","Str",dll,"PTR") ; Calculate pointer to ahkdll and ahkExec functions ahktextdll:=hModule+DllCall("GetProcAddress","PTR",hDll,"AStr","ahktextdll","PTR")-hDll ahkExec:=hModule+DllCall("GetProcAddress","PTR",hDll,"AStr","ahkExec","PTR")-hDll ahkTerminate:=hModule+DllCall("GetProcAddress","PTR",hDll,"AStr","ahkTerminate","PTR")-hDll If script { nScriptLength := VarSetCapacity(nScript, (StrLen(script)+1)*(A_IsUnicode?2:1), 0) ,StrPut(script,&nScript) ; Reserve memory in remote process where our script will be saved If !pBufferScript := DllCall("VirtualAllocEx", "Ptr", hProc, "Ptr", 0, "PTR", nScriptLength, "UInt", MEM_COMMIT, "UInt", PAGE_EXECUTE_READWRITE, "Ptr") return DllCall("MessageBox","PTR",0,"Str","Could not reseve memory for process.","STR","Error","UInt",0) ,DllCall("CloseHandle", "PTR", hProc) ; Write script to remote process memory DllCall("WriteProcessMemory", "Ptr", hProc, "Ptr", pBufferScript, "Ptr", &nScript, "PTR", nScriptLength, "Ptr", 0) } else pBufferScript:=0 ; Run ahkdll function in remote thread hThread := DllCall("CreateRemoteThread","PTR",hProc,"PTR",0,"PTR",0,"PTR",ahktextdll,"PTR",pBufferScript,"PTR",0,"UInt",0,"PTR") If !hThread { ; could not start ahkdll in remote process ; Free memory used for passing dll path to remote thread DllCall("VirtualFreeEx","PTR",hProc,"PTR",pBufferRemote,"PTR",nDirLength,MEM_RELEASE) DllCall("CloseHandle", "PTR", hProc) return DllCall("MessageBox","PTR",0,"Str","Could not start ahkdll in remote process","STR","Error","UInt",0) } DllCall("WaitForSingleObject", "PTR", hThread, "UInt", 0xFFFFFFFF) DllCall("GetExitCodeThread", "PTR", hThread, "UIntP", lpExitCode) ; Release memory and handles DllCall("VirtualFreeEx","PTR",hProc,"PTR",pBufferRemote,"PTR",nDirLength,MEM_RELEASE) DllCall("CloseHandle", "PTR", hThread) DllCall("CloseHandle", "PTR", hProc) If !lpExitCode ; thread could not be created. return DllCall("MessageBox","PTR",0,"Str","Could not create a thread in remote process","STR","Error","UInt",0) return {PID:PID,hModule:hModule,ahkExec:ahkExec,ahkTerminate:ahkTerminate,base:base} }
It works really well. Thank you.
Re: how to dll Inject
Is it possible to use ComObjCreate and InjectAhkDll() in AutoHotkey_L v1.1?
I'm getting the error message:
I'm getting the error message:
An outgoing call cannot be made since the application is dispatching an input-synchronous call.
Code: Select all
;requires: AutoHotkeyMini.dll (either x64 or x32), _Struct.ahk, sizeof.ahk, InjectAhkDll function
;[AutoHotkeyMini.dll]
;GitHub - HotKeyIt/ahkdll-v1-release: AutoHotkey_H v1 release
;https://github.com/HotKeyIt/ahkdll-v1-release
;[_Struct.ahk, sizeof.ahk]
;GitHub - HotKeyIt/_Struct: class to enable easy access to structures
;https://github.com/HotKeyIt/_Struct
;[InjectAhkDll function]
;[SOLVED]get other process's working dir - Page 3 - Ask for Help - AutoHotkey Community
;https://autohotkey.com/board/topic/85304-solvedget-other-processs-working-dir/page-3#entry544650
;note: AHK, Notepad, and the dll, should all be x64 or x32
vPathDll := "C:\Program Files\AutoHotkey\AutoHotkeyMini.dll"
WinGet, vPID, PID, ahk_class Notepad
vScript = ;continuation section
(%
MsgBox, % "hello"
WinGet, hWnd, ID, ahk_class CabinetWClass
for oWin in ComObjCreate("Shell.Application").Windows
if (oWin.HWND = hWnd)
break
oWindows := ComObjCreate("Shell.Application").Windows
Loop, % oWindows.Count()
if (oWindows.Item[A_Index-1].HWND = hWnd)
{
oWin := oWindows.Item[A_Index-1]
break
}
)
;rThread := InjectAhkDll(vPID, vPathDll, "#Persistent")
rThread := InjectAhkDll(vPID, vPathDll)
rThread.Exec(vScript)
return
Code: Select all
;[SOLVED]get other process's working dir - Page 3 - Ask for Help - AutoHotkey Community
;https://autohotkey.com/board/topic/85304-solvedget-other-processs-working-dir/page-3#entry544650
#Include <_Struct>
InjectAhkDll(PID,dll="AutoHotkey.dll",script=0){
static PROCESS_ALL_ACCESS:=0x1F0FFF,MEM_COMMIT := 0x1000,MEM_RELEASE:=0x8000,PAGE_EXECUTE_READWRITE:=64
,hKernel32:=DllCall("LoadLibrary","Str","kernel32.dll","PTR"),LoadLibraryA:=DllCall("GetProcAddress","PTR",hKernel32,"AStr","LoadLibraryA","PTR")
,base:={__Call:"InjectAhkDll",__Delete:"InjectAhkDll"},FreeLibrary:=DllCall("GetProcAddress","PTR",hKernel32,"AStr","FreeLibrary","PTR")
static TH32CS_SNAPMODULE:=0x00000008,INVALID_HANDLE_VALUE:=-1
,MAX_PATH:=260,MAX_MODULE_NAME32:=255,ModuleName:="",init:=VarSetCapacity(ModuleName,MAX_PATH*(A_IsUnicode?2:1))
,_MODULEENTRY32:="
(
DWORD dwSize;
DWORD th32ModuleID;
DWORD th32ProcessID;
DWORD GlblcntUsage;
DWORD ProccntUsage;
BYTE *modBaseAddr;
DWORD modBaseSize;
HMODULE hModule;
TCHAR szModule[" MAX_MODULE_NAME32 + 1 "];
TCHAR szExePath[" MAX_PATH "];
)"
If IsObject(PID){
If (dll!="Exec" && script)
return DllCall("MessageBox","PTR",0,"Str","Only Exec method can be used here!","STR","Error","UInt",0)
hProc := DllCall("OpenProcess", "UInt", PROCESS_ALL_ACCESS, "Int",0, "UInt", PID.PID,"PTR")
If !hProc
return DllCall("MessageBox","PTR",0,"Str","Could not open process for PID: " PID.PID,"STR","Error","UInt",0)
if (!script) ; Free Library in remote process (object is being deleted)
{
; Terminate the thread in ahkdll
hThread := DllCall("CreateRemoteThread", "PTR", hProc, "PTR", 0, "PTR", 0, "PTR", PID.ahkTerminate, "PTR", 0, "UInt", 0, "PTR", 0,"PTR")
DllCall("WaitForSingleObject", "PTR", hThread, "UInt", 0xFFFFFFFF)
,DllCall("CloseHandle", "PTR", hThread)
; Free library in remote process
hThread := DllCall("CreateRemoteThread", "PTR", hProc, "UInt", 0, "UInt", 0, "PTR", FreeLibrary, "PTR", PID.hModule, "UInt", 0, "UInt", 0,"PTR")
DllCall("WaitForSingleObject", "PTR", hThread, "UInt", 0xFFFFFFFF)
,DllCall("CloseHandle", "PTR", hThread),DllCall("CloseHandle", "PTR", hProc)
return
}
nScriptLength := VarSetCapacity(nScript, (StrLen(script)+1)*(A_IsUnicode?2:1), 0)
,StrPut(script,&nScript)
; Reserve memory in remote process where our script will be saved
If !pBufferRemote := DllCall("VirtualAllocEx", "Ptr", hProc, "Ptr", 0, "PTR", nScriptLength, "UInt", MEM_COMMIT, "UInt", PAGE_EXECUTE_READWRITE, "Ptr")
return DllCall("MessageBox","PTR",0,"Str","Could not reseve memory for process.","STR","Error","UInt",0)
,DllCall("CloseHandle", "PTR", hProc)
; Write script to remote process memory
DllCall("WriteProcessMemory", "Ptr", hProc, "Ptr", pBufferRemote, "Ptr", &nScript, "PTR", nScriptLength, "Ptr", 0)
; Start execution of code
hThread := DllCall("CreateRemoteThread", "PTR", hProc, "PTR", 0, "PTR", 0, "PTR", PID.ahkExec, "PTR", pBufferRemote, "UInt", 0, "PTR", 0,"PTR")
If !hThread
{
DllCall("VirtualFreeEx","PTR",hProc,"PTR",pBufferRemote,"PTR",nScriptLength,MEM_RELEASE)
,DllCall("CloseHandle", "PTR", hProc)
return DllCall("MessageBox","PTR",0,"Str","Could not execute script in remote process.","STR","Error","UInt",0)
}
; Wait for thread to finish
DllCall("WaitForSingleObject", "PTR", hThread, "UInt", 0xFFFFFFFF)
; Get Exit code returned by ahkExec (1 = script could be executed / 0 = script could not be executed)
DllCall("GetExitCodeThread", "PTR", hThread, "UIntP", lpExitCode)
If !lpExitCode
return DllCall("MessageBox","PTR",0,"Str","Could not execute script in remote process.","STR","Error","UInt",0)
DllCall("CloseHandle", "PTR", hThread)
,DllCall("VirtualFreeEx","PTR",hProc,"PTR",pBufferRemote,"PTR",nScriptLength,MEM_RELEASE)
,DllCall("CloseHandle", "PTR", hProc)
return
} else if !hDll:=DllCall("LoadLibrary","Str",dll,"PTR")
return DllCall("MessageBox","PTR",0,"Str","Could not find " dll " library.","STR","Error","UInt",0),DllCall("CloseHandle", "PTR", hProc)
else {
hProc := DllCall("OpenProcess","UInt", PROCESS_ALL_ACCESS, "Int",0,"UInt", DllCall("GetCurrentProcessId"),"PTR")
DllCall("GetModuleFileName","PTR",hDll,"PTR",&ModuleName,"UInt",MAX_PATH)
DllCall("CloseHandle","PTR",hProc)
}
; Open Process to PID
hProc := DllCall("OpenProcess", "UInt", PROCESS_ALL_ACCESS, "Int",0, "UInt", PID,"PTR")
If !hProc
return DllCall("MessageBox","PTR",0,"Str","Could not open process for PID: " PID,"STR","Error","UInt",0)
; Reserve some memory and write dll path (ANSI)
nDirLength := VarSetCapacity(nDir, StrLen(dll)+1, 0)
,StrPut(dll,&nDir,"CP0")
; Reserve memory in remote process
If !pBufferRemote := DllCall("VirtualAllocEx", "Ptr", hProc, "Ptr", 0, "PTR", nDirLength, "UInt", MEM_COMMIT, "UInt", PAGE_EXECUTE_READWRITE, "Ptr")
return DllCall("MessageBox","PTR",0,"Str","Could not reseve memory for process.","STR","Error","UInt",0),DllCall("CloseHandle", "PTR", hProc)
; Write dll path to remote process memory
DllCall("WriteProcessMemory", "Ptr", hProc, "Ptr", pBufferRemote, "Ptr", &nDir, "PTR", nDirLength, "Ptr", 0)
; Start new thread loading our dll
hThread:=DllCall("CreateRemoteThread","PTR",hProc,"PTR",0,"PTR",0,"PTR",LoadLibraryA,"PTR",pBufferRemote,"UInt",0,"PTR",0,"PTR")
If !hThread {
DllCall("VirtualFreeEx","PTR",hProc,"PTR",pBufferRemote,"PTR",nDirLength,"Uint",MEM_RELEASE)
,DllCall("CloseHandle", "PTR", hProc)
return DllCall("MessageBox","PTR",0,"Str","Could not load " dll " in remote process.","STR","Error","UInt",0)
}
; Wait for thread to finish
DllCall("WaitForSingleObject", "PTR", hThread, "UInt", 0xFFFFFFFF)
; Get Exit code returned by thread (HMODULE for our dll)
DllCall("GetExitCodeThread", "PTR", hThread, "UInt*", hModule)
; Close Thread
DllCall("CloseHandle", "PTR", hThread)
If (A_PtrSize=8){ ; use different method to retrieve base address because GetExitCodeThread returns DWORD only
hModule:=0,me32 := new _Struct(_MODULEENTRY32)
; Take a snapshot of all modules in the specified process.
hModuleSnap := DllCall("CreateToolhelp32Snapshot","UInt", TH32CS_SNAPMODULE,"UInt", PID, "PTR" )
if( hModuleSnap != INVALID_HANDLE_VALUE ){
; reset hModule and set the size of the structure before using it.
me32.dwSize := sizeof(_MODULEENTRY32)
; Retrieve information about the first module,
; and exit if unsuccessful
if( !DllCall("Module32First" (A_IsUnicode?"W":""),"PTR", hModuleSnap,"PTR", me32[] ) ) {
; Free memory used for passing dll path to remote thread
DllCall("VirtualFreeEx","PTR",hProc,"PTR",pBufferRemote,"PTR",nDirLength,MEM_RELEASE)
,DllCall("CloseHandle","PTR", hModuleSnap ) ; Must clean up the snapshot object!
return false
}
; Now walk the module list of the process,and display information about each module
while(A_Index=1 || DllCall("Module32Next" (A_IsUnicode?"W":""),"PTR",hModuleSnap,"PTR", me32[] ) )
If (StrGet(me32.szExePath[""])=dll){
hModule := me32.modBaseAddr["",""]
break
}
DllCall("CloseHandle","PTR",hModuleSnap) ; clean up
}
}
hDll:=DllCall("LoadLibrary","Str",dll,"PTR")
; Calculate pointer to ahkdll and ahkExec functions
ahktextdll:=hModule+DllCall("GetProcAddress","PTR",hDll,"AStr","ahktextdll","PTR")-hDll
ahkExec:=hModule+DllCall("GetProcAddress","PTR",hDll,"AStr","ahkExec","PTR")-hDll
ahkTerminate:=hModule+DllCall("GetProcAddress","PTR",hDll,"AStr","ahkTerminate","PTR")-hDll
If script {
nScriptLength := VarSetCapacity(nScript, (StrLen(script)+1)*(A_IsUnicode?2:1), 0)
,StrPut(script,&nScript)
; Reserve memory in remote process where our script will be saved
If !pBufferScript := DllCall("VirtualAllocEx", "Ptr", hProc, "Ptr", 0, "PTR", nScriptLength, "UInt", MEM_COMMIT, "UInt", PAGE_EXECUTE_READWRITE, "Ptr")
return DllCall("MessageBox","PTR",0,"Str","Could not reseve memory for process.","STR","Error","UInt",0)
,DllCall("CloseHandle", "PTR", hProc)
; Write script to remote process memory
DllCall("WriteProcessMemory", "Ptr", hProc, "Ptr", pBufferScript, "Ptr", &nScript, "PTR", nScriptLength, "Ptr", 0)
} else pBufferScript:=0
; Run ahkdll function in remote thread
hThread := DllCall("CreateRemoteThread","PTR",hProc,"PTR",0,"PTR",0,"PTR",ahktextdll,"PTR",pBufferScript,"PTR",0,"UInt",0,"PTR")
If !hThread { ; could not start ahkdll in remote process
; Free memory used for passing dll path to remote thread
DllCall("VirtualFreeEx","PTR",hProc,"PTR",pBufferRemote,"PTR",nDirLength,MEM_RELEASE)
DllCall("CloseHandle", "PTR", hProc)
return DllCall("MessageBox","PTR",0,"Str","Could not start ahkdll in remote process","STR","Error","UInt",0)
}
DllCall("WaitForSingleObject", "PTR", hThread, "UInt", 0xFFFFFFFF)
DllCall("GetExitCodeThread", "PTR", hThread, "UIntP", lpExitCode)
; Release memory and handles
DllCall("VirtualFreeEx","PTR",hProc,"PTR",pBufferRemote,"PTR",nDirLength,MEM_RELEASE)
DllCall("CloseHandle", "PTR", hThread)
DllCall("CloseHandle", "PTR", hProc)
If !lpExitCode ; thread could not be created.
return DllCall("MessageBox","PTR",0,"Str","Could not create a thread in remote process","STR","Error","UInt",0)
return {PID:PID,hModule:hModule,ahkExec:ahkExec,ahkTerminate:ahkTerminate,base:base}
}
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
Re: how to dll Inject
Exec works via SendMessage and while this is being processed you cannot use COM calls.
Re: how to dll Inject
Thank you HotKeyIt, but this potentially scuppers a lot of things I might want to do with dll injection, is there any workaround?
3 potential uses for dll inject and COM:
[major: drag-and-drop a file to a program when WM_DROPFILES doesn't work]
[COM] Help with the IDropSource and IDropTarget interfaces - Page 3 - AutoHotkey Community
https://autohotkey.com/boards/viewtopic ... 60#p164860
[middle: Common Item Dialog get folder/file]
get full paths of selected files on Desktop and Common File Dialogs - AutoHotkey Community
https://autohotkey.com/boards/viewtopic ... 77#p145577
[minor: Explorer get column widths in Windows 7]
Explorer column interaction (get/set: which appear, width, ascending/descending order) - AutoHotkey Community
https://autohotkey.com/boards/viewtopic ... 61#p154461
3 potential uses for dll inject and COM:
[major: drag-and-drop a file to a program when WM_DROPFILES doesn't work]
[COM] Help with the IDropSource and IDropTarget interfaces - Page 3 - AutoHotkey Community
https://autohotkey.com/boards/viewtopic ... 60#p164860
[middle: Common Item Dialog get folder/file]
get full paths of selected files on Desktop and Common File Dialogs - AutoHotkey Community
https://autohotkey.com/boards/viewtopic ... 77#p145577
[minor: Explorer get column widths in Windows 7]
Explorer column interaction (get/set: which appear, width, ascending/descending order) - AutoHotkey Community
https://autohotkey.com/boards/viewtopic ... 61#p154461
Last edited by jeeswg on 19 Aug 2017, 08:44, edited 5 times in total.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
Re: how to dll Inject
You have to include the script upfront when calling InjectAhkDll and control it using .Exec("SetTimer, ...").
Re: how to dll Inject
@HotKeyIt: Many thanks, I had thought that SetTimer might be a way, but I don't really understand InjectAhkDll. Btw when I ran the script, I used SetTimer with '-1', but it appeared to run the subroutine twice simultaneously (I got two MsgBoxes).
Btw also, what is the best way to cleanly withdraw, i.e. 'uninject'. I've been experimenting with .Terminate and ExitApp but I'm still getting crashes regularly. Is there any documentation or advice for this function somewhere? Cheers.
Btw also, what is the best way to cleanly withdraw, i.e. 'uninject'. I've been experimenting with .Terminate and ExitApp but I'm still getting crashes regularly. Is there any documentation or advice for this function somewhere? Cheers.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
Re: how to dll Inject
Did you include the script with Return in first line when calling InjectAhkDll? .Exec() deletes the script after it ran so you can't use it to create script and SetTimer!
Re: how to dll Inject
Haha cheers, I didn't understand what you meant at first, but I worked it out after, helped by your comment, when I checked over the code. My code works now, I get one MsgBox, now that I added 'return' to the top of my vScriptFunc variable.
Re. crashing. If I do q it works, and then I can do w as many times as I like, but if I do e to try and close the thread, and then q to inject again, it crashes.
Re. crashing. If I do q it works, and then I can do w as many times as I like, but if I do e to try and close the thread, and then q to inject again, it crashes.
Code: Select all
;==================================================
#SingleInstance force
ListLines, Off
#KeyHistory 0
Menu, Tray, Click, 1
#NoEnv
AutoTrim, Off
#UseHook
SplitPath, A_ScriptName,,,, vScriptNameNoExt
Menu, Tray, Tip, % vScriptNameNoExt
#Persistent
;==================================================
;if !A_IsAdmin
; Run, % "*RunAs " (A_IsCompiled ? "" : A_AhkPath " ") """" A_ScriptFullPath """"
vAhkIs64 := (A_PtrSize=8)
;vDir := "C:\Program Files\AutoHotkey"
vDir := A_ScriptDir
;note: I copied and renamed the dlls adding '64' and '32'
if vAhkIs64
vPathDll := vDir "\AutoHotkeyMini64.dll"
else
vPathDll := vDir "\AutoHotkeyMini32.dll"
if (vAhkIs64 || !A_Is64bitOS)
vPathNP := "C:\Windows\System32\notepad.exe"
else
vPathNP := "C:\Windows\SysWOW64\notepad.exe"
;==================================================
if !vAhkIs64
{
MsgBox, % "the script must be run with AutoHotkeyU64.exe to inject into a 64-bit process"
ExitApp
}
q::
WinGet, vPID, PID, A
if !JEE_ProcessIs64Bit(vPID)
{
MsgBox, % "the window must be 64-bit"
return
}
vScriptFunc = ;continuation section
(%
return
CountOpenFolders: ;this also counts IE tabs
oWindows := ComObjCreate("Shell.Application").Windows
MsgBox, % oWindows.Count()
return
)
;inject dll, set #Persistent and add some functions/subroutines
rThread := InjectAhkDll(vPID, vPathDll, "#Persistent`n" vScriptFunc)
w::
vScript = ;continuation section
(%
SetTimer, CountOpenFolders, -1
)
rThread.Exec(vScript)
return
;==================================================
e::
rThread.Terminate()
return
;==================================================
JEE_ProcessIs64Bit(vPID)
{
if !A_Is64bitOS
return 0
hProc := DllCall("kernel32\OpenProcess", UInt,0x400, Int,0, UInt,vPID, Ptr)
DllCall("kernel32\IsWow64Process", Ptr,hProc, IntP,vIsWow64Process)
DllCall("kernel32\CloseHandle", Ptr,hProc)
return !vIsWow64Process
}
;==================================================
#Include, <_Struct>
#Include, InjectAhkDll.ahk
;==================================================
Last edited by jeeswg on 17 Feb 2019, 17:44, edited 1 time in total.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
Re: how to dll Inject
Did you rThread:="" before injecting again?
Re: how to dll Inject
You're quite right HotKeyIt.
This seems to be invalid:
rThread.Terminate()
I replaced it with this and it's all working:
rThread := ""
All the details for the function are here it turns out:
[SOLVED]get other process's working dir - Page 3 - Ask for Help - AutoHotkey Community
https://autohotkey.com/board/topic/8530 ... ntry544650
A small amount of documentation, but all that's needed.
==================================================
One thing that someone mentioned to me, was that some dll injection techniques require you to latch onto a specific thread, rather than simply to latch onto a process.
Now, I don't actually need to do that, as I have workarounds, however, I'd just like to mention it in case you have any useful links, or anything to say on how to achieve that. Cheers.
[EDIT:] At some point soon I will post some example code for setting the font colour/background colour/font in Notepad, and a prototype window message spy.
This seems to be invalid:
rThread.Terminate()
I replaced it with this and it's all working:
rThread := ""
All the details for the function are here it turns out:
[SOLVED]get other process's working dir - Page 3 - Ask for Help - AutoHotkey Community
https://autohotkey.com/board/topic/8530 ... ntry544650
A small amount of documentation, but all that's needed.
==================================================
One thing that someone mentioned to me, was that some dll injection techniques require you to latch onto a specific thread, rather than simply to latch onto a process.
Now, I don't actually need to do that, as I have workarounds, however, I'd just like to mention it in case you have any useful links, or anything to say on how to achieve that. Cheers.
[EDIT:] At some point soon I will post some example code for setting the font colour/background colour/font in Notepad, and a prototype window message spy.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
Re: how to dll Inject
Here CreateRemoteThread is used so a new thread is created in process, not sure how to latch onto a specific thread and when / why it might be required.
Re: how to dll Inject
qwerty12 provided an example of latching onto a specific thread here, using Tiny C Compiler:
[Common Item Dialog get folder/file]
get full paths of selected files on Desktop and Common File Dialogs - AutoHotkey Community
https://autohotkey.com/boards/viewtopic ... 77#p145577
And mentioned another potential use of it here:
[Explorer get column widths in Windows 7]
Explorer column interaction (get/set: which appear, width, ascending/descending order) - AutoHotkey Community
https://autohotkey.com/boards/viewtopic ... 61#p154461
These two links also appear earlier on this page. Both problems have workarounds, however, maybe one day the approach could be very useful. Cheers.
[Common Item Dialog get folder/file]
get full paths of selected files on Desktop and Common File Dialogs - AutoHotkey Community
https://autohotkey.com/boards/viewtopic ... 77#p145577
And mentioned another potential use of it here:
[Explorer get column widths in Windows 7]
Explorer column interaction (get/set: which appear, width, ascending/descending order) - AutoHotkey Community
https://autohotkey.com/boards/viewtopic ... 61#p154461
These two links also appear earlier on this page. Both problems have workarounds, however, maybe one day the approach could be very useful. Cheers.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
Re: how to dll Inject
I have a prototype window spy, but it seems to crash the program it latched onto when I: reload the script, end the remote thread, or try to close the program.
WARNING: use with caution, *expect* it to crash the program. This will crash your program.
WARNING: use with caution, *expect* it to crash the program. This will crash your program.
Code: Select all
;prototype window message spy
;currently checks for WM_COMMAND and WM_SYSCOMMAND messages
;this can be changed by editing MyWndProc
#SingleInstance force
ListLines, Off
#KeyHistory 0
Menu, Tray, Click, 1
#NoEnv
AutoTrim, Off
#UseHook
SplitPath, A_ScriptName,,,, vScriptNameNoExt
Menu, Tray, Tip, % vScriptNameNoExt
#Persistent
;==================================================
OnMessage(0x5555, "MsgMonitor")
OnExit("ExitFunc")
return
;==================================================
q::
vAhkIs64 := (A_PtrSize=8)
;vDir := "C:\Program Files\AutoHotkey"
vDir := A_ScriptDir
if vAhkIs64
vPathDll := vDir "\AutoHotkeyMini64.dll"
else
vPathDll := vDir "\AutoHotkeyMini32.dll"
;==================================================
DetectHiddenWindows, On
WinGet, hWnd, ID, A
;ControlGet, hWnd, Hwnd,, Edit1, % "ahk_id " hWnd
WinGet, vPID, PID, % "ahk_id " hWnd
if !(vAhkIs64 = JEE_ProcessIs64Bit(vPID))
{
MsgBox, % "not latched on: AHK and external process must have the same bitness"
return
}
;==================================================
vScriptFunc = ;continuation section
(% `
#Persistent
DetectHiddenWindows, On
hWnd := hWndX1
pWndProc := RegisterCallback("MyWndProc", "")
;GWL_WNDPROC := -4
vSfx := (A_PtrSize=8) ? "Ptr" : ""
pWndProcOld := DllCall("SetWindowLong" vSfx, Ptr,hWnd, Int,-4, Ptr,pWndProc, Ptr)
vToolTipIsOn := 1
MyWndProc(hWnd, uMsg, wParam, lParam)
{
global pWndProcOld, vToolTipIsOn
;WM_COMMAND := 0x111 ;WM_SYSCOMMAND := 0x112
if vToolTipIsOn
if (uMsg >= 0x111) && (uMsg <= 0x112)
if !(wParam = 0xF100) ;61696
if !(wParam = 0x100000F) ;16777231
if !(wParam = 0x200000F) ;33554447
if !(wParam = 0x300000F) ;50331663
if !(wParam = 0x400000F) ;67108879
PostMessage, 0x5555, % uMsg, % wParam,, % "ahk_id " hWndX2 ;didn't work
return DllCall("CallWindowProc", Ptr,pWndProcOld, Ptr,hWnd, UInt,uMsg, UPtr,wParam, Ptr,lParam, Ptr)
}
)
vScriptFunc := StrReplace(vScriptFunc, "hWndX1", hWnd)
vScriptFunc := StrReplace(vScriptFunc, "hWndX2", A_ScriptHwnd)
rThread := InjectAhkDll(vPID, vPathDll, vScriptFunc)
return
;==================================================
e::
rThread := ""
return
;==================================================
MsgMonitor(wParam, lParam, uMsg, hWnd)
{
ToolTip, % wParam " " lParam "`r`n" Format("0x{:X} 0x{:X}", wParam, lParam)
}
;==================================================
ExitFunc()
{
global
ToolTip
rThread := ""
}
;==================================================
JEE_ProcessIs64Bit(vPID)
{
if !A_Is64bitOS
return 0
hProc := DllCall("kernel32\OpenProcess", UInt,0x400, Int,0, UInt,vPID, Ptr)
DllCall("kernel32\IsWow64Process", Ptr,hProc, IntP,vIsWow64Process)
DllCall("kernel32\CloseHandle", Ptr,hProc)
return !vIsWow64Process
}
;==================================================
#Include, <_Struct>
#Include, InjectAhkDll.ahk
;==================================================
Last edited by jeeswg on 17 Feb 2019, 17:45, edited 1 time in total.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
Re: how to dll Inject
Here are some examples for interacting with Notepad, which is the last dll injection script I intend to post, unless I can ever get this working:
[COM] Help with the IDropSource and IDropTarget interfaces - Page 3 - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=5&t=8700&p=165994#p165994
I'm still having problems relating to dll injection and programs crashing, if anyone can help me with that.
The main aim here is to programmatically set the background colour and font for Notepad's Edit control.
Note: The default system colour for Edit controls can be changed (e.g. on Windows 7) by going to Control Panel\Appearance and Personalization\Personalization and changing the colour for 'Window'. Or you can get/set that colour programmatically by using GetSysColor/SetSysColors (note: 'Color' v. 'Colors').
This script changes the colour for an individual existing Edit control.
Note in terms of scripts for setting the colour of an Edit control, there are a tonne of links if you search for 'edit control set colour' or 'Control_Colors', here are some of them:
[COM] Help with the IDropSource and IDropTarget interfaces - Page 3 - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=5&t=8700&p=165994#p165994
I'm still having problems relating to dll injection and programs crashing, if anyone can help me with that.
The main aim here is to programmatically set the background colour and font for Notepad's Edit control.
Note: The default system colour for Edit controls can be changed (e.g. on Windows 7) by going to Control Panel\Appearance and Personalization\Personalization and changing the colour for 'Window'. Or you can get/set that colour programmatically by using GetSysColor/SetSysColors (note: 'Color' v. 'Colors').
This script changes the colour for an individual existing Edit control.
Code: Select all
q:: ;get/set Edit control background colour
;[list of RGB values]
;Progress/SplashImage
;https://autohotkey.com/docs/commands/Progress.htm#Object_Colors
;COLOR_WINDOW := 5
vColBGR := DllCall("user32\GetSysColor", Int,5, UInt)
MsgBox, % Format("0x{:06X}", vColBGR)
;COLOR_WINDOW := 5
DllCall("user32\SetSysColors", Int,1, IntP,5, UIntP,0xefcdab) ;BGR
Sleep 2000
DllCall("user32\SetSysColors", Int,1, IntP,5, UIntP,0x0000ff) ;BGR ;red
Sleep 2000
DllCall("user32\SetSysColors", Int,1, IntP,5, UIntP,0x00ffff) ;BGR ;yellow
Sleep 2000
DllCall("user32\SetSysColors", Int,1, IntP,5, UIntP,0x00ff00) ;BGR ;lime
Sleep 2000
DllCall("user32\SetSysColors", Int,1, IntP,5, UIntP,0xff0000) ;BGR ;blue
Sleep 2000
DllCall("user32\SetSysColors", Int,1, IntP,5, UIntP,0xc0c0c0) ;BGR ;silver
Sleep 2000
DllCall("user32\SetSysColors", Int,1, IntP,5, UIntP,0xffffff) ;BGR ;white
MsgBox, % "done"
return
Code: Select all
;script to interact with Notepad via dll injection
;warning: this script is likely to crash your Notepad window,
;currently it appears that if Notepad is closed first, that's fine,
;but if the script is closed/reloaded first, it crashes Notepad
#SingleInstance force
ListLines, Off
#KeyHistory 0
Menu, Tray, Click, 1
#NoEnv
AutoTrim, Off
#UseHook
SplitPath, A_ScriptName,,,, vScriptNameNoExt
Menu, Tray, Tip, % vScriptNameNoExt
#Persistent
;==================================================
vAhkIs64 := (A_PtrSize=8)
;vDir := "C:\Program Files\AutoHotkey"
vDir := A_ScriptDir
if vAhkIs64
vPathDll := vDir "\AutoHotkeyMini64.dll"
else
vPathDll := vDir "\AutoHotkeyMini32.dll"
if (vAhkIs64 || !A_Is64bitOS)
vPathNP := "C:\Windows\System32\notepad.exe"
else
vPathNP := "C:\Windows\SysWOW64\notepad.exe"
;==================================================
;find Notepad window
DetectHiddenWindows, On
WinGet, vWinList, List, ahk_class Notepad
vOutput := ""
WinGet, hWnd, ID, % "ahk_class Notepad ahk_exe " vPathNP
if !hWnd
{
Run, % vPathNP
WinWait, % "ahk_class Notepad ahk_exe " vPathNP
WinGet, hWnd, ID, % "ahk_class Notepad ahk_exe " vPathNP
}
WinGet, vPID, PID, % "ahk_id " hWnd
WinActivate, % "ahk_id " hWnd
MsgBox, % vPID
;==================================================
vScriptFunc = ;continuation section
(
CtlSetColors(hWnd, uMsg, wParam, lParam = 0)
{
global vColText, vColBk, hBrush, pWndProcOld
Critical
;WM_CTLCOLOREDIT := 0x133 ;WM_CTLCOLORSTATIC := 0x138
if (uMsg >= 0x132) && (uMsg <= 0x138)
{
DllCall("SetTextColor", Ptr,wParam, UInt,vColText, UInt)
DllCall("SetBkColor", Ptr,wParam, UInt,vColBk, UInt)
return DllCall("CreateSolidBrush", UInt,vColBk, Ptr)
}
return DllCall("CallWindowProcA", Ptr,pWndProcOld, Ptr,hWnd, UInt,uMsg, UPtr,wParam, Ptr,lParam, Ptr)
}
)
;inject dll, set #Persistent and add some functions
rThread := InjectAhkDll(vPID, vPathDll, "#Persistent`n" vScriptFunc)
;==================================================
vScript = ;continuation section
(% `
DetectHiddenWindows, On
vPID := DllCall("kernel32\GetCurrentProcessId", UInt)
WinGet, vPName, ProcessName, % "ahk_pid " vPID
vOutput := "process name: " vPName "`r`n"
vOutput .= "working dir: " A_WorkingDir "`r`n"
vOutput .= "path: " A_AhkPath
MsgBox, % vOutput
)
rThread.Exec(vScript)
;==================================================
vScript = ;continuation section
(
Add(vNum1, vNum2)
{
return vNum1 + vNum2
}
)
rThread.Exec(vScript)
;==================================================
vScript = ;continuation section
(%
MsgBox, % "Add(1, 1) = " Add(1, 1)
)
rThread.Exec(vScript)
;==================================================
vFontName := "Arial", vFontSize := 48, vFontIsBold := 0
vFontHeight := -DllCall("kernel32\MulDiv", Int,vFontSize, Int,A_ScreenDPI, Int,72)
vFontWeight := vFontIsBold ? 700 : 400
ControlGet, hCtl, Hwnd,, Edit1, % "ahk_id " hWnd
vScript = ;continuation section
(
hFont := DllCall("CreateFont", Int,%vFontHeight%, Int,0, Int,0, Int,0
, Int,%vFontWeight%, UInt,0, UInt,0, UInt,0
, UInt,0, UInt,3, UInt,2, UInt,1
, UInt,34, Str,"%vFontName%", Ptr)
PostMessage, 0x30, `% hFont, 1, Edit1, ahk_id %hWnd% ;WM_SETFONT := 0x30
)
rThread.Exec(vScript)
;==================================================
vSfx := (A_PtrSize=8) ? "Ptr" : ""
vScript = ;continuation section
(
hCtl := %hCtl%
hWnd := %hWnd%
vColText := 0xFF0000 ;BGR
vColBk := 0xEFCDAB ;BGR
pWndProcNew := RegisterCallback("CtlSetColors", "", 4)
pWndProcOld := DllCall("SetWindowLong%vSfx%", Ptr,hWnd, Int,-4, Ptr,pWndProcNew, Ptr) ;GWL_WNDPROC := -4
WinSet, Redraw,, ahk_id %hWnd%
)
rThread.Exec(vScript)
;Sleep 5000
;rThread := "" ;this line crashes the script
return
;==================================================
JEE_ProcessIs64Bit(vPID)
{
if !A_Is64bitOS
return 0
hProc := DllCall("kernel32\OpenProcess", UInt,0x400, Int,0, UInt,vPID, Ptr)
DllCall("kernel32\IsWow64Process", Ptr,hProc, IntP,vIsWow64Process)
DllCall("kernel32\CloseHandle", Ptr,hProc)
return !vIsWow64Process
}
;==================================================
#Include, <_Struct>
#Include, InjectAhkDll.ahk
;==================================================
Spoiler
Last edited by jeeswg on 17 Feb 2019, 17:45, edited 2 times in total.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
Who is online
Users browsing this forum: No registered users and 10 guests