先贴出二进制下载地址: http://download.csdn.net/detail/xyzzf/7322277
第一部分: 键盘映射DLL API实现:
#include <Windows.h> #include <process.h> #include <type_traits> typedef WPARAM key_type; typedef WPARAM value_type; typedef struct _k2rt_tree_node { key_type key; // virtual key code: mapping-key value_type value; // virtual key code: mapping-value struct _k2rt_tree_node* child; struct _k2rt_tree_node* next; } k2rt_tree_node, *k2rt_tree_node_pointer, k2rt_tree, *k2rt_tree_pointer; // shared data segment #pragma data_seg(".shared") __declspec(dllexport) HHOOK udg_hhook = nullptr; __declspec(dllexport) HHOOK udg_hhook_launch = nullptr; __declspec(dllexport) HMODULE udg_target_hmod = nullptr; __declspec(dllexport) HANDLE udg_target_process = nullptr; __declspec(dllexport) DWORD udg_target_tid = 0; __declspec(dllexport) HWND udg_target_hwnd = nullptr; __declspec(dllexport) k2rt_tree_pointer udg_mapper_list = nullptr; __declspec(dllexport) bool udg_start_war_require = false; #pragma data_seg() #pragma comment(linker,"/section:.shared,RWS") /* ** @useful macro utils */ #define _WriteMemory(_Paddr,_Pval) ::WriteProcessMemory(udg_target_process, _Paddr, _Pval, sizeof(*_Pval), nullptr) #define _ReadMemory(_Paddr,_Pval) ::ReadProcessMemory(udg_target_process, _Paddr, _Pval, sizeof(*_Pval), nullptr) #define _IsNotNullptr(ptr) ( (ptr) != nullptr ) #define LIST_PUSHBACK(_List,_Newkey,_Newval,_CreateFunc,_GetNextFunc,_SetNextFunc) do { decltype(_List) next = nullptr; decltype(_List) next_visitor = _List; while( _IsNotNullptr(next_visitor) && _IsNotNullptr(next = _GetNextFunc(next_visitor)) ) { next_visitor = next; } _SetNextFunc(next_visitor, _CreateFunc(_Newkey, _Newval) ); } while(false) /* ** vtree(the same line nodes have same key,graph view: ** ROOT -------- Only a placeholder node ** | ** | ** child(1) ---> child(1).next(1) ... child(1).next(n) ** | ** | ** child(2) ---> child(2).next(1) ... child(2).next(n) ** . ** . ** . ** child(n) ---> child(n).next(1) ... child(n).next(n) ** */ #define VTREE_PUSHBACK(_List,_Newkey,_Newval,_CreateFunc,_GetChildFunc,_SetChildFunc,_GetNextFunc,_SetNextFunc,_GetKeyFunc) do { decltype(_List) child = nullptr; decltype(_List) child_visitor = _List; std::remove_const<decltype(_Newkey)>::type tempkey = -1; while( ( child_visitor != nullptr ) && ( _Newkey != ( tempkey = _GetKeyFunc(child_visitor) ) ) && ( ( child = _GetChildFunc(child_visitor) ) != nullptr ) ) { child_visitor = child; } if(_Newkey == tempkey) { LIST_PUSHBACK(child_visitor, _Newkey, _Newval, _CreateFunc, _GetNextFunc, _SetNextFunc); } else { _SetChildFunc(child_visitor, _CreateFunc(_Newkey, _Newval) ); } } while(false) /** @declaration ** user interfaces ( used by external ) */ extern "C" __declspec(dllexport) void k2ud_mapper_initialize(HANDLE hProcess, DWORD tid, HWND hwnd); extern "C" __declspec(dllexport) void k2ud_mapper_finalize(void); extern "C" __declspec(dllexport) bool k2ud_mapper_enable_mapping(void); extern "C" __declspec(dllexport) bool k2ud_mapper_disable_mapping(void); /* * params: key: new short-key * value: original short-key */ extern "C" __declspec(dllexport) unsigned int k2ud_mapper_insert_mapping(const key_type key, const value_type value); extern "C" __declspec(dllexport) void k2ud_mapper_erase_mapping(const key_type key); extern "C" __declspec(dllexport) void k2ud_mapper_clear_mapping(void); extern "C" __declspec(dllexport) bool k2ud_launch_war3_quickly(void); /** @declaration ** runtime interface( used at internal ) */ static k2rt_tree_node_pointer k2rt_tree_node_create(const key_type key, const value_type value); static void k2rt_tree_node_free(k2rt_tree_node_pointer); static void k2rt_tree_list_free(k2rt_tree_node_pointer); static key_type k2rt_tree_node_get_key(k2rt_tree_node_pointer); static value_type k2rt_tree_node_get_value(k2rt_tree_node_pointer); static k2rt_tree_node_pointer k2rt_tree_node_get_child(k2rt_tree_node_pointer); static k2rt_tree_node_pointer k2rt_tree_node_get_next(k2rt_tree_node_pointer); static void k2rt_tree_node_set_key(k2rt_tree_node_pointer, const key_type key); static void k2rt_tree_node_set_value(k2rt_tree_node_pointer, const value_type value); static void k2rt_tree_node_set_child(k2rt_tree_node_pointer, k2rt_tree_node_pointer child); static void k2rt_tree_node_set_next(k2rt_tree_node_pointer, k2rt_tree_node_pointer next); static LRESULT WINAPI k2rt_GetMsgProc(int code, WPARAM wParam, LPARAM lParam); static LRESULT WINAPI k2rt_KeyboardProc(int code, WPARAM wParam, LPARAM lParam); /** @implementation ** user interfaces ( used by external ) */ extern "C" __declspec(dllexport) void k2ud_mapper_initialize(HANDLE process, DWORD tid, HWND hwnd) { udg_target_process = process; udg_target_tid = tid; udg_target_hwnd = hwnd; udg_mapper_list = k2rt_tree_node_create(-1, -1); // Just a reserved node } extern "C" __declspec(dllexport) void k2ud_mapper_finalize(void) { // destory the vtree at remoate process k2rt_tree_node_pointer ptr = udg_mapper_list; k2rt_tree_node_pointer freeing = nullptr; while(ptr != nullptr) { freeing = ptr; ptr = k2rt_tree_node_get_child(ptr); k2rt_tree_list_free(freeing); } udg_mapper_list = nullptr; udg_target_hwnd = nullptr; udg_target_tid = 0; udg_target_process = nullptr; } extern "C" __declspec(dllexport) bool k2ud_mapper_enable_mapping(void) { if(0 == udg_target_tid) { ::MessageBox(nullptr, TEXT("The target thread id is unspecified,please call k2ud_mapper_initialize function!"), TEXT("error from key_mapper2.dll::k2ud_mapper_enable_mapping"), MB_OK | MB_ICONEXCLAMATION); return false; } if(nullptr == udg_hhook) { udg_hhook = ::SetWindowsHookEx(WH_KEYBOARD, k2rt_KeyboardProc, udg_target_hmod, udg_target_tid); } return udg_hhook != nullptr; } extern "C" __declspec(dllexport) bool k2ud_mapper_disable_mapping(void) { if(udg_hhook != nullptr) { if(::UnhookWindowsHookEx(udg_hhook)) { udg_hhook = nullptr; return true; } DWORD ec = GetLastError(); if(ec == ERROR_INVALID_HANDLE) { udg_hhook = nullptr; return true; } } return false; } extern "C" __declspec(dllexport) unsigned int k2ud_mapper_insert_mapping(const key_type key, const value_type value) { if(key == value) return 0; VTREE_PUSHBACK(udg_mapper_list, key, value, k2rt_tree_node_create, k2rt_tree_node_get_child, k2rt_tree_node_set_child, k2rt_tree_node_get_next, k2rt_tree_node_set_next, k2rt_tree_node_get_key); return 1; } extern "C" __declspec(dllexport) void k2ud_mapper_erase_mapping(const key_type key) { key_type tempkey = 0; k2rt_tree_pointer child_visitor = udg_mapper_list; k2rt_tree_node_pointer parent_visitor = child_visitor; k2rt_tree_node_pointer child = nullptr; // search while( (tempkey = k2rt_tree_node_get_key(child_visitor) ) != key && ( child = k2rt_tree_node_get_child(child_visitor) ) != nullptr ) { parent_visitor = child_visitor; child_visitor = child; } // if found, remove it if(key == tempkey) { k2rt_tree_node_set_child(parent_visitor, k2rt_tree_node_get_child(child_visitor) ); k2rt_tree_list_free(child_visitor); } } extern "C" __declspec(dllexport) void k2ud_mapper_clear_mapping(void) { k2rt_tree_node_pointer ptr = k2rt_tree_node_get_child(udg_mapper_list); k2rt_tree_node_pointer freeing = nullptr; while(ptr != nullptr) { freeing = ptr; ptr = k2rt_tree_node_get_child(ptr); k2rt_tree_list_free(freeing); } k2rt_tree_node_set_child(udg_mapper_list, nullptr); } /** @implementation ** runtime interfaces ( used by external ) */ static k2rt_tree_node_pointer k2rt_tree_node_create(const key_type key, const value_type value) { if(nullptr == udg_target_process) { ::MessageBox(nullptr, TEXT("The target process is unspecified, please call k2ud_mapper_initialize function!"), TEXT("error from key_mapper2.dll::k2rt_tree_node_create"), MB_OK | MB_ICONEXCLAMATION); return nullptr; } static unsigned int zero = 0; k2rt_tree_node_pointer _Pnode = (k2rt_tree_node_pointer)::VirtualAllocEx(udg_target_process, nullptr, sizeof(k2rt_tree_node), MEM_COMMIT, PAGE_READWRITE); _WriteMemory(&_Pnode->key, &key); _WriteMemory(&_Pnode->value, &value); _WriteMemory(&_Pnode->child, &zero); _WriteMemory(&_Pnode->next, &zero); return _Pnode; } static void k2rt_tree_node_free(k2rt_tree_node_pointer _Pnode) { ::VirtualFreeEx(udg_target_process, _Pnode, 0, MEM_RELEASE); } static void k2rt_tree_list_free(k2rt_tree_node_pointer _Phead) { k2rt_tree_node_pointer ptr = _Phead; k2rt_tree_node_pointer freeing = nullptr; while(ptr != nullptr) { freeing = ptr; ptr = k2rt_tree_node_get_next(ptr); k2rt_tree_node_free(freeing); } } static key_type k2rt_tree_node_get_key(k2rt_tree_node_pointer _Pnode) { key_type key = 0; _ReadMemory(&_Pnode->key, &key); return key; } static key_type k2rt_tree_node_get_value(k2rt_tree_node_pointer _Pnode) { value_type value = 0; _ReadMemory(&_Pnode->value, &value); return value; } static k2rt_tree_node_pointer k2rt_tree_node_get_child(k2rt_tree_node_pointer _Pnode) { k2rt_tree_node_pointer child = nullptr; _ReadMemory(&_Pnode->child, &child); return child; } static k2rt_tree_node_pointer k2rt_tree_node_get_next(k2rt_tree_node_pointer _Pnode) { k2rt_tree_node_pointer next = nullptr; _ReadMemory(&_Pnode->next, &next); return next; } static void k2rt_tree_node_set_key(k2rt_tree_node_pointer _Pnode, const key_type key) // unused currentlly { _WriteMemory(&_Pnode->key, &key); } static void k2rt_tree_node_set_value(k2rt_tree_node_pointer _Pnode, const value_type value) { _WriteMemory(&_Pnode->value, &value); } static void k2rt_tree_node_set_child(k2rt_tree_node_pointer _Pnode, k2rt_tree_node_pointer child) { _WriteMemory(&_Pnode->child, &child); } static void k2rt_tree_node_set_next(k2rt_tree_node_pointer _Pnode, k2rt_tree_node_pointer next) { _WriteMemory(&_Pnode->next, &next); } typedef union { LPARAM value; struct { unsigned int repeat_count:16; // The value is the number of times the keystroke is repeated as a result of the user's holding down the key. unsigned int scan_code:8; // The value depends on the OEM. unsigned int is_extended_key:1; // extended key: F1~F12 or NUMPAD unsigned int reserved:4; unsigned int context_code:1; // 1: the ALT key is down, 0:otherwise unsigned int previous_key_state:1; // 0: up, 1: down unsigned int transition_state:1; // 0:being pressed, 1: being released } detail; } keybd_detail; static bool k2rt_keybd_post_message(key_type orig_vkey, int message) { k2rt_tree_node_pointer visit_child = udg_mapper_list->child; k2rt_tree_node_pointer visit_next = nullptr; while(visit_child != nullptr) { if(orig_vkey == visit_child->key) { visit_next = visit_child; do { ::PostMessage(udg_target_hwnd, message, visit_next->value, visit_next->key); visit_next = visit_next->next; } while(visit_next != nullptr); return true; } visit_child = visit_child->child; } return false; } static bool k2rt_keybd_imitate_event(key_type orig_vkey, int type = KEYEVENTF_KEYUP) { k2rt_tree_node_pointer visit_child = udg_mapper_list->child; k2rt_tree_node_pointer visit_next = nullptr; while(visit_child != nullptr) { if(orig_vkey == visit_child->key) { visit_next = visit_child; do { keybd_event(visit_next->value, MapVirtualKey(visit_next->value, 0), type, 0); //keybd_event(visit_next->value, MapVirtualKey(visit_next->value, 0), type, 0); visit_next = visit_next->next; } while(visit_next != nullptr); //orig_vkey = visit_child->value; return true; } visit_child = visit_child->child; } return false; } ////////////////////////////////////////////////////////////////////////////// //The hook Procedures ///////////////////////////////////////////////////////////////////////////// static bool k2rt_keybd_send_key(key_type key) { keybd_event(key, MapVirtualKey(key, 0), 0, 0); keybd_event(key, MapVirtualKey(key, 0), KEYEVENTF_KEYUP, 0); return true; } extern "C" __declspec(dllexport) bool k2ud_launch_war3_quickly(void) { udg_start_war_require = true; udg_hhook_launch = ::SetWindowsHookEx(WH_GETMESSAGE, k2rt_GetMsgProc, udg_target_hmod, udg_target_tid); return udg_hhook_launch != nullptr; } static unsigned __stdcall launch_war3_quickly_task(void*) { k2rt_keybd_send_key('L'); Sleep(1000); k2rt_keybd_send_key('C'); Sleep(1000); k2rt_keybd_send_key('C'); Sleep(1000); k2rt_keybd_send_key('C'); Sleep(1000); k2rt_keybd_send_key('C'); Sleep(1000); k2rt_keybd_send_key('C'); Sleep(1000); k2rt_keybd_send_key('C'); Sleep(1000); k2rt_keybd_send_key('C'); Sleep(1000); k2rt_keybd_send_key('C'); return 0; } static LRESULT WINAPI k2rt_GetMsgProc(int code, WPARAM wParam, LPARAM lParam) { if( code < 0 ) { return 0; } tagMSG* pmsg = (tagMSG*)lParam; if(HC_ACTION == code) { if(udg_start_war_require) { udg_start_war_require = false; UnhookWindowsHookEx(udg_hhook_launch); udg_hhook_launch = nullptr; // start a async task to quickly create a war3 GAME uintptr_t handle = _beginthreadex(nullptr, 0, launch_war3_quickly_task, nullptr, 0, nullptr); } } return CallNextHookEx(udg_hhook, code, wParam, lParam); } static LRESULT WINAPI k2rt_KeyboardProc(int code, WPARAM wParam, LPARAM lParam) { if( code < 0 ) { return 0; } keybd_detail& parser = *reinterpret_cast<keybd_detail*>(&lParam); if(HC_ACTION == code) { switch(parser.detail.transition_state) { case 0: if(k2rt_keybd_imitate_event(wParam, 0)) return TRUE; // catch the target key break; case 1: if(k2rt_keybd_imitate_event(wParam, KEYEVENTF_KEYUP)) return TRUE; // catch the target key break; default:; } } return CallNextHookEx(udg_hhook, code, wParam, lParam); } static LRESULT WINAPI k2rt_LowLevelKeyboardProc(int code, WPARAM wParam, LPARAM lParam) { if( code < 0 ) { return 0; } KBDLLHOOKSTRUCT* detail = (KBDLLHOOKSTRUCT*)lParam; if(HC_ACTION == code) { switch(wParam) { case WM_KEYDOWN: //if(k2rt_keybd_imitate_event(detail->vkCode, 0)) return TRUE; break; case WM_KEYUP: //if(k2rt_keybd_imitate_event(detail->vkCode, KEYEVENTF_EXTENDEDKEY)) return TRUE; break; default:; } } return CallNextHookEx(udg_hhook, code, wParam, lParam); } static LRESULT WINAPI k2rt_MouseProc(int nCode, WPARAM wParam, LPARAM lParam) { if( nCode < 0 ) { return 0; } MOUSEHOOKSTRUCT* detail = (MOUSEHOOKSTRUCT*)lParam; if(HC_ACTION == nCode) { switch(wParam) { case WM_MOUSEACTIVATE: case WM_MOUSEHWHEEL: case WM_MOUSEWHEEL: case WM_MOUSEHOVER: case WM_MOUSEMOVE: case WM_MOUSELEAVE: case WM_LBUTTONDBLCLK: case WM_LBUTTONDOWN: case WM_LBUTTONUP: case WM_MBUTTONDBLCLK: case WM_MBUTTONDOWN: case WM_MBUTTONUP: case WM_RBUTTONDBLCLK: case WM_RBUTTONDOWN: case WM_RBUTTONUP: default:; } } return CallNextHookEx(udg_hhook, nCode, wParam, lParam); } static LRESULT WINAPI k2rt_LowLevelMouseProc(int nCode, WPARAM wParam, LPARAM lParam) { if( nCode < 0 ) { return 0; } MSLLHOOKSTRUCT* detail = (MSLLHOOKSTRUCT*)lParam; if(HC_ACTION == nCode) { switch(wParam) { case WM_MOUSEACTIVATE: case WM_MOUSEHWHEEL: case WM_MOUSEWHEEL: case WM_MOUSEHOVER: case WM_MOUSEMOVE: case WM_MOUSELEAVE: case WM_LBUTTONDBLCLK: case WM_LBUTTONDOWN: case WM_LBUTTONUP: case WM_MBUTTONDBLCLK: case WM_MBUTTONDOWN: case WM_MBUTTONUP: case WM_RBUTTONDBLCLK: case WM_RBUTTONDOWN: case WM_RBUTTONUP: break; default:; } } return CallNextHookEx(udg_hhook, nCode, wParam, lParam); } static LRESULT WINAPI k2rt_ShellProc(int nCode, WPARAM wParam, LPARAM lParam) { if( nCode < 0 ) { return 0; } MSLLHOOKSTRUCT* detail = (MSLLHOOKSTRUCT*)lParam; switch(nCode) { case HSHELL_ACCESSIBILITYSTATE: break; case HSHELL_ACTIVATESHELLWINDOW: break; case HSHELL_APPCOMMAND: break; case HSHELL_GETMINRECT: break; case HSHELL_LANGUAGE: break; case HSHELL_REDRAW: break; case HSHELL_TASKMAN: break; case HSHELL_WINDOWACTIVATED: break; case HSHELL_WINDOWCREATED: break; case HSHELL_WINDOWDESTROYED: break; case HSHELL_WINDOWREPLACED: break; default:; } return CallNextHookEx(udg_hhook, nCode, wParam, lParam); } static LRESULT WINAPI k2rt_CallWndProc(int code, WPARAM wParam, LPARAM lParam) { if( code < 0 ) { return 0; } bool is_sent_by_current_thread = wParam; CWPSTRUCT* detail = (CWPSTRUCT*)lParam; return CallNextHookEx(udg_hhook, code, wParam, lParam); } static LRESULT WINAPI k2rt_CallWndRetProc(int code, WPARAM wParam, LPARAM lParam) { if( code < 0 ) { return 0; } bool is_sent_by_current_thread = wParam; CWPRETSTRUCT* detail = (CWPRETSTRUCT*)lParam; return CallNextHookEx(udg_hhook, code, wParam, lParam); } static LRESULT WINAPI k2rt_DebugProc(int code, WPARAM wParam, LPARAM lParam) { if( code < 0 ) { return 0; } DEBUGHOOKINFO* detail = (DEBUGHOOKINFO*)lParam; switch(wParam) { case WH_KEYBOARD: case WH_KEYBOARD_LL: case WH_GETMESSAGE: break; default:; } return CallNextHookEx(udg_hhook, code, wParam, lParam); } /** @implementation ** the entry of DLL ( used by internal ) */ BOOL WINAPI DllMain(HMODULE hModule, DWORD dwReason, LPVOID lpReserved) { DWORD thread_id = 0; switch(dwReason) { case DLL_PROCESS_ATTACH: udg_target_hmod = hModule; thread_id = GetCurrentThreadId(); break; case DLL_THREAD_ATTACH: thread_id = GetCurrentThreadId(); break; case DLL_THREAD_DETACH: thread_id = GetCurrentThreadId(); break; case DLL_PROCESS_DETACH: thread_id = GetCurrentThreadId(); break; } return TRUE; }
原文:http://blog.csdn.net/xseekerj/article/details/27114101