Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Windows hook with Python

I am trying to get a hook into windows and use Python to record keystrokes. For this, I'm using a LowLevelKeyboard Callback procedure.

def run():
    
    global KeyBdHook
    global messages
    
    KeyBdHook = HHook()
    messages = []
        
    start = time.time()

    #Record keystrokes for 2 seconds.
    while time.time() < (start + 2):
        KeyBdHook.hook = SetWindowsHookEx(13, KeyboardProc,
                                          GetModuleHandle(0), 0)
        if KeyBdHook.hook == 0:
            print 'ERROR: '+str(ctypes.windll.kernel32.GetLastError())
        UnhookWindowsHookEx(KeyBdHook.hook)
        
    print messages
            
def KeyboardProc(nCode, wParam, lParam):
    """http://msdn.microsoft.com/en-us/library/ms644985(v=vs.85).aspx"""
      

    if nCode < 0:
        return ctypes.windll.user32.GetNextHookEx(KeyBdHook.hook,
                                              nCode, wParam, lParam)
    else:
        ctypes.windll.kernel32.RtlMoveMemory(ctypes.addressof(KeyBdHook.kStruct),
                                             ctypes.c_void_p(lParam),
                                             ctypes.sizeof(lParam))
        
        messages.append(KeyBdHook.kStruct)
        return ctypes.windll.user32.GetNextHookEx(KeyBdHook.hook,
                                          nCode, wParam, lParam)
    
    
def SetWindowsHookEx(idHook, lpFn, hMod, dwThreadId):
    WinFunc = ctypes.WINFUNCTYPE(c_ulong, c_ulong, c_ulong, c_ulong)
    return ctypes.windll.user32.SetWindowsHookExA(idHook, WinFunc(lpFn), hMod, dwThreadId)

def GetModuleHandle(lpModuleName):
    return ctypes.windll.kernel32.GetModuleHandleA(lpModuleName)

def UnhookWindowsHookEx(hHook):
    return ctypes.windll.user32.UnhookWindowsHookEx(hHook)
    
class HHook():        
    def __init__(self):
        self.hook = HHOOK
        self.kStruct = KBLLHOOKSTRUCT()
        
class KBLLHOOKSTRUCT(Structure):
    """http://msdn.microsoft.com/en-us/library/ms644967(v=vs.85).aspx"""
    
    _fields_ = [("vkCode", c_ulong),
                ("scanCode", c_ulong),
                ("flags", c_ulong),
                ("time", c_ulong),
                ("dwExtraInfo", POINTER(c_ulong))]

The problem with this is it never enters the KeyboardProc function. I'm thinking that I might have to cast it as a C-type function using ctypes.WINFUNCTYPE or ctypes.CFUNCTYPE, but I can't figure it out. Windows doesn't seem to be throwing an error on SetWindowsEx either.

I'm assuming it's not handling the KeyboardProc parameter being passed into SetWindowsEx. Any ideas on how to cast this so Windows can input data into it? Thanks.

like image 493
mmoore Avatar asked Feb 16 '11 21:02

mmoore


People also ask

Can Python use Windows API?

Interpreted languages like Python can also be used for API hooking and have some advantages over compiled languages. In this article, we explore when and why it's best to choose Python for hooking Windows APIs and explain how to use this language for setting hooks based on easy-to-follow examples.

What Windows API hooking?

API hooking is a technique by which we can instrument and modify the behavior and flow of API calls. API hooking can be done using various methods on Windows. Techniques include memory break point and . DEP and JMP instruction insertion.


1 Answers

To resurrect an old question, ThiefMaster's belief that a dll is required is not accurate. As a counter-example, I have put up a pure Python hotkey module that implements what the OP asks for. This is the Github repo.

Also, for more features, I recommend pyHook or pyhk..

Additionally, for more features, consider pywinauto, which includes a hotkey module, and much more.

like image 128
IronManMark20 Avatar answered Oct 06 '22 00:10

IronManMark20