Получение недопустимой процедуры перехвата Ошибка после введения DLL в windows перехват - PullRequest
0 голосов
/ 17 февраля 2020

Я пытаюсь подключиться к windows глобально, вводя dll. Мой код работает с 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

1 Ответ

0 голосов
/ 17 февраля 2020

В Python 3.7 результат sys.getdefaultencoding() равен 'utf-8'. Этот ответ от @jfs отметил, что

sys.getdefaultencoding() всегда запускает 'ascii' во всех системах Python 2, если вы его не переписываете.

Возможно, именно поэтому вы ошиблись.

  1. используйте b'' вместо r'' или просто используйте функцию широкого байта.
  2. GetProcAddress не имеет Широкобайтовая версия. Просто используйте также GetProcAddress(handle, b'meconnect').
  3. tHook в DLL не определено, и это приведет к неопределенному поведению в следующей ловушке.
  4. Вам лучше поместить сообщение l oop до UnhookWindowsHookEx и вместо sleep метода.

Вы можете вызвать SetWindowsHookEx в DLL. Вот образец. 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(r'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()
...