아시다시피, C#은 .NET Framework 플랫폼의 동반 언어이며, 자체 라이브러리와 컴파일러 제공으로 전역 훅을 구현하는 것은 불가능합니다. 하지만 실제로는 DllImport 속성을 사용해 Unmanaged 코드 라이브러리의 메서드를 참조하는 C#에서 비관리 코드 호출이 참으로 유지됩니다. 훅 함수는 user32.dll에 존재하며, 함수 프로토타입은 다음과 같습니다:
HHOOK WINAPI SetWindowsHookEx(
__in idHook,
__in 훅프로크 lpfn,
__in hinstance hMod,
__in DWORD dwThreadId);
운영체제(Windows)에서 특정 유형의 메시지 가로채기 처리 방식을 등록하는 데 사용할 수 있습니다. 예를 들어, 전역 키보드 메시지를 차단하는 훅을 등록하여 모든 키보드 누름 및 리프트 이벤트를 인지하고 처리할 수 있습니다(메시지를 드롭하는 프론트엔드 훅이 있을 가능성도 배제하지 않습니다).
이 함수는 C#에서 다음과 같이 선언하여 참조할 수 있습니다:
[DllImport("user32.dll")] public static extern int SetWindowsHookEx( 훅타입 id훅, HookProc lpfn, IntPtr hInstance, int threadId );
위의 HookType과 HookProc는 제 커스텀 타입인데, 이는 중요하지 않습니다(실행 시 메모리 주소를 전달하기 때문입니다). 하지만 특정 사양은 충족해야 합니다.
함수의 매개변수는 위에서 아래로 다음과 같습니다:
idHook 타입으로, 여기서 형태 열거로 표현됩니다 훅이 작동할 때 LPFN 콜백 함수 hInstance 모듈 핸들(보통 훅 콜백 함수가 위치한 애플리케이션 인스턴스의 모듈 핸들) threadId설치된 훅 서브루틴과 연관된 스레드의 식별자
훅에는 여러 종류가 있습니다:
우리는 보통 키보드 메시지 차단에 13, 마우스 메시지 차단에 14를 사용합니다.
콜백 함수의 선언 C#에서 delegate를 사용해야 하며, 선언은 다음과 같습니다: 공공 대의원 int HookProc(int nCode, int wParam, IntPtr lParam);
탑다운 매개변수는 nCode 훅 체인에서 반환된 매개변수를 의미하며, 0은 이전 메시지 훅에 의한 이 메시지가 폐기됨을, 0이 아닌 경우는 이 메시지가 계속 유효함을 의미합니다
wParam 메시지 매개변수
lParam 메시지 매개변수
wParam과 lParam은 서로 다른 메시지 유형의 다른 유형이지만, wParam의 유형은 대략 다음 열거로 표현할 수 있다는 점을 언급할 가치가 있습니다:
lParam은 일반적으로 메시지 유형에 따라 달라지는 구조로 캡슐화되며, 다음 두 가지 구조가 마우스와 키보드 메시지의 lParam 구조입니다:
위 정보를 이해하면 C#의 훅 함수 구현에 대한 기본적인 이해를 갖게 되고, 몇 가지 질문에 주목해 보세요:
1. 훅은 많은 자원을 차지하며, 사용하지 않을 때는 제때 취소해야 하며, 이를 위해 UnhookWindowsHookEx 함수를 사용해야 합니다
2. 예의상 훅은 현재 훅만의 처리 결과를 반환하지 말아야 합니다(훅이 먼저 설정되고 그 후에 효력을 발휘하므로 훅 체인의 정상적인 전달을 위해 CallNextHookEx를 사용해 다음 훅을 호출하세요).
3. 훅 함수 매개변수의 hInstance는 현재 훅의 콜백 함수가 있는 곳에만 위치하며, 올바른 주소가 제공되어야 합니다
4. 위임자가 사용되기 때문에, 대리자의 메모리 주소(메서드 참조)가 가백되지 않도록 해야 하며, 그렇지 않으면 훅이 실행될 때 예외가 발생합니다
제가 작성한 샘플 프로그램을 다운로드할 수 있지만, 제 프로그램에는 다음 주요 요점들이 필요합니다:
1. 훅 구현을 차단하고, 키보드와 마우스의 메시지 가로채기 및 처리만 열었어요(사용 방법은 C#의 WinForm 마우스와 키보드 이벤트와 동일합니다). 다른 이벤트도 열 수 있습니다
2. 훅을 싱글턴 모드로 설계했으니 취소할 수 있어
3. 운영체제에 침입이 발생할 경우, 안티바이러스 소프트웨어는 위험하다고 보고될 수 있습니다
4. 코드가 엉망이니 그냥 만족하세요......
마지막으로, 프로그래밍 기술과 언어의 차이는 컴파일러와 사용자가 다르다는 점입니다. C를 사용하는 사람이 자바를 사용하는 사람보다 우월하다고 할 수 없고, 기술이 반드시 포인터, 행렬, 자료구조에 반영되는 것은 아니지만, 컴퓨터 원리, 컴파일 원리, 운영체제 원리 등을 이해하는 사람들만 더 중요합니다. 물론, 모두가 자신만의 좋아하는 언어와 일반적인 프로그래밍 방법이 있다는 점은 좋은 일입니다.
|