我正在尝试通过注入dll全局插入Windows。我的代码可与python2.7一起使用,但在使用Python3.7且已提及的错误时可悲地失败了。这是示例代码:
user32.SetWindowsHookExA.errcheck = errcheck_bool
user32.SetWindowsHookExA.restype = HHOOK
user32.SetWindowsHookExA.argtypes = (c_int, # _In_ idHook
HOOKPROC, # _In_ lpfn
HINSTANCE, # _In_ hMod
DWORD) # _In_ dwThreadId
user32.CallNextHookEx.restype = LRESULT
user32.CallNextHookEx.argtypes = (HHOOK, # _In_opt_ hhk
c_int, # _In_ nCode
WPARAM, # _In_ wParam
LPARAM) # _In_ lParam
user32.GetMessageW.argtypes = (LPMSG, # _Out_ lpMsg
HWND, # _In_opt_ hWnd
UINT, # _In_ wMsgFilterMin
UINT) # _In_ wMsgFilterMax
user32.TranslateMessage.argtypes = (LPMSG,)
user32.DispatchMessageW.argtypes = (LPMSG,)
GetModuleHandle = ctypes.windll.kernel32.GetModuleHandleA
GetModuleHandle.restype = POINTER(c_void_p)
LoadLibrary = ctypes.windll.kernel32.LoadLibraryA
LoadLibrary.restype = HINSTANCE
GetProcAddress = ctypes.windll.kernel32.GetProcAddress
GetProcAddress.restype = HOOKPROC
user32.GetWindowThreadProcessId.restype = DWORD
def pointer_msg_loop():
lib = LoadLibrary(r'C:\Users\Braun\Documents\BA_Thesis\ba-oliver-braun-logging-tool-code\MessagesDll\x64\Release\Dll.dll')
handle = GetModuleHandle(r'C:\Users\Braun\Documents\BA_Thesis\ba-oliver-braun-logging-tool-code\MessagesDll\x64\Release\Dll.dll')
print(lib)
print(handle)
procedure = GetProcAddress(handle, "meconnect".encode())
print(procedure)
print('correct value procedure')
tHook = user32.SetWindowsHookExA(WH_GETMESSAGE, procedure, lib, 0)
time.sleep(30)
user32.UnhookWindowsHookEx(tHook)
print(tHook)
msg = MSG()
while True:
bRet = user32.GetMessageW(byref(msg), None, 0, 0)
if not bRet:
break
if bRet == -1:
raise WinError(get_last_error())
user32.TranslateMessage(byref(msg))
user32.DispatchMessageW(byref(msg))
if __name__ == '__main__':
import time
import datetime
import threading
control_key_pressed = False
startTime = datetime.datetime.now()
tmouse = threading.Thread(target=mouse_msg_loop)
tkeyboard = threading.Thread(target=keyboard_msg_loop)
ttouch = threading.Thread(target=pointer_msg_loop)
tmouse.start()
tkeyboard.start()
ttouch.start()
while True:
try:
time.sleep(1)
except KeyboardInterrupt:
user32.PostThreadMessageW(tmouse.ident, WM_QUIT, 0, 0)
break
DLL:
// dllmain.cpp : Defines the entry point for the DLL application.
#include "pch.h"
#pragma data_seg("Shared")
#pragma data_seg()
#pragma comment(linker,"/section:Shared,rws")
#include <windows.h>
#include <stdio.h>
#include <string.h>
HHOOK tHook;
extern "C" __declspec(dllexport) LRESULT meconnect(int code, WPARAM wParam, LPARAM lParam) {
BOOL EnableMouseInPointer = TRUE;
if (code == HC_ACTION) {
LPMSG data = (LPMSG)lParam;
if (data->message == WM_POINTERDOWN) {
MessageBoxA(NULL, "eee", NULL, 0);
}
}
return(CallNextHookEx(tHook, code, wParam, lParam));
}
[一些有趣的观察:将LoadLibraryA更改为LoadLibraryW时,甚至python2.7也会失败。这似乎真的很明显,我怀疑是因为两个版本都强制使用不同的字符串类型?但是,是的,我可以做些什么才能使其在Python3.7中起作用
在Python 3.7中,sys.getdefaultencoding()
的结果为'utf-8'
。 @jfs的This answer表示
sys.getdefaultencoding()
始终在以下系统的所有系统上运行'ascii'Python 2,除非您重写它。
这可能是您弄错了的原因。
b''
代替r''
,或仅使用宽字节功能。GetProcAddress
没有宽字节版本。只需使用GetProcAddress(handle, b'meconnect')
。tHook
,它将在下一个挂钩中导致未定义的行为。UnhookWindowsHookEx
之前,而不是sleep
方法。您可以在DLL中调用SetWindowsHookEx
。这是示例。DLL:
// dllmain.cpp : Defines the entry point for the DLL application.
#include "pch.h"
#include <windows.h>
#include <stdio.h>
#include <string.h>
HHOOK tHook;
HMODULE hinstDLL;
LRESULT CALLBACK meconnect(int code, WPARAM wParam, LPARAM lParam) {
BOOL EnableMouseInPointer = TRUE;
if (code == HC_ACTION) {
LPMSG data = (LPMSG)lParam;
if (data->message == WM_POINTERDOWN) {
MessageBoxA(NULL, "eee", NULL, 0);
}
}
return(CallNextHookEx(tHook, code, wParam, lParam));
}
extern "C" __declspec(dllexport) BOOL SetHook()
{
tHook = SetWindowsHookEx(WH_GETMESSAGE, meconnect, hinstDLL, 0);
if (tHook == NULL)
return FALSE;
else
return TRUE;
}
extern "C" __declspec(dllexport) BOOL UnHook()
{
return UnhookWindowsHookEx(tHook);
}
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
hinstDLL = hModule;
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
python:
import threading
import ctypes
from ctypes import wintypes
from ctypes import *
import win32api
import win32gui
def pointer_msg_loop():
lib = cdll.LoadLibrary(b'PATH\DLL.dll')
print(lib)
res = lib.SetHook()
print(res)
win32gui.PumpMessages()
res = lib.UnHook()
if __name__ == '__main__':
ttouch = threading.Thread(target=pointer_msg_loop)
ttouch.start()
ttouch.join()