# search(Using Python to build a spy program Develop Paper)
def whatis(x, verbose = 0):
    print(x, 'is a ', end=''); x = eval(x); print(type(x), end='')
    print(', which has ' + str(dir(x)) + '\n' if verbose else '')

from ctypes import *
from ctypes.wintypes import DWORD, UINT, LPCWSTR, HWND, WPARAM, LPARAM
user32 = CDLL('user32.dll'); kernel32 = CDLL('kernel32.dll')
whatis('user32'); whatis('cast')

# WH_KEYBOARD 2, 有老外说是20,坑了我一会。Installs a hook procedure that monitors keystroke messages.
# WH_KEYBOARD_LL 13 Enables you to monitor keyboard input events about to be posted in a thread input queue.
WH_KEYBOARD_LL = 13
# LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
# lParam指向如下结构。用contents来dereference pointer.
class KBDLLHOOKSTRUCT(Structure): _fields_ = [
    ('vkCode', DWORD),
    ('scanCode', DWORD),
    ('flags', DWORD),
    ('time', DWORD),
    ('dwExtraInfo', DWORD)]
whatis('KBDLLHOOKSTRUCT')

VK_SHIFT = 16; VK_CAPITAL = 20
def LlkProc(nCode, wp, lp):
    global hhook
    # If nCode < 0, you must return the value returned by CallNextHookEx
    # Else, it is highly recommended that you call CallNextHookEx and return the value it returns.
    if nCode >= 0: 
        if wp: # If the message is sent by the current process, wp != 0
            k = cast(lp, POINTER(KBDLLHOOKSTRUCT)).contents # lp.contents.value
            def h(x): return (1*'0' + hex(x)[2:])[-2:] + 'h'
            print(h(k.vkCode), h(k.scanCode), h(k.flags), k.time, k.dwExtraInfo, user32.GetKeyState(VK_SHIFT))
    return user32.CallNextHookEx(hhook, nCode, wp, lp)

# WINFUNCTYPE(restype, *argtypes) returns a function prototype that creates functions using the stdcall calling convention.
# restype是函数的返回值,argtypes是函数的参数。
MAKE_HOOKPROC = WINFUNCTYPE(c_int, c_int, WPARAM, POINTER(DWORD)) # LPARAM didn't work
LlkProc = MAKE_HOOKPROC(LlkProc)
whatis('WINFUNCTYPE'); whatis('MAKE_HOOKPROC'); whatis('LlkProc')
dwThreadId = 0; # The hook procedure is associated with all existing threads.
hhook = user32.SetWindowsHookExW(WH_KEYBOARD_LL, LlkProc, kernel32.GetModuleHandleW(), dwThreadId)
print('hhook=', hex(hhook))
if not hhook: quit()
windll.user32.MessageBoxW(0, "按12345试试,亲。", "信息", 1)    
user32.UnhookWindowsHookEx(hhook)

# https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-messagebox
MB_YESNOCANCEL = 0x3; MB_ICONQUESTION = 0x20; IDYES = 6; IDNO = 7
prototype = WINFUNCTYPE(c_int, UINT, LPCWSTR, LPCWSTR, UINT)
# The optional paramflags parameter creates foreign function wrappers with much more functionality than the features described above.
paramflags = (1, "hwnd", 0), (1, "text", "这个程序好吧?"), (1, "caption", "调查"), (1, "flags", 0)
MessageBox = prototype(("MessageBoxW", windll.user32), paramflags)
print(MessageBox(flags=MB_YESNOCANCEL | MB_ICONQUESTION))
posted on 2021-12-09 22:33  华容道专家  阅读(666)  评论(0)    收藏  举报