C\#키보드 체크(Hook)차단 기 를 깊이 분석 하고 키보드 활동 에 대한 상세 한 설명 을 차단 합 니 다.

갈고리(Hook)는 윈도 메시지 처리 메커니즘 의 플랫폼 입 니 다.프로그램 은 위 에 지정 한 창의 어떤 정 보 를 감시 하기 위해 하위 정 보 를 설정 할 수 있 고 감시 하 는 창 은 다른 프로 세 스 가 만 들 수 있 습 니 다.메시지 가 도착 하면 대상 창 에서 함 수 를 처리 하기 전에 처리 합 니 다.갈고리 체 제 는 응용 프로그램 이 window 메시지 나 특정 사건 을 캡 처 할 수 있 도록 합 니 다.갈 고 리 는 실제로 메 시 지 를 처리 하 는 프로그램 으로 시스템 호출 을 통 해 시스템 에 걸 어 놓는다.특정한 메시지 가 나 올 때마다 목적 창 에 도착 하지 않 기 전에 갈고리 프로그램 은 이 메 시 지 를 먼저 캡 처 하고 갈고리 함수 가 먼저 제어 권 을 얻 습 니 다.이때 갈고리 함 수 는 이 메 시 지 를 가공 처리(변경)할 수도 있 고 처리 하지 않 고 계속 전달 할 수도 있 으 며 메시지 의 전달 을 강제 적 으로 끝 낼 수도 있다.운영 체제 1.갈고리 링크 와 갈고리 거리:모든 Hook 은 이와 관련 된 지침 목록 을 가지 고 있 으 며 갈고리 링크 라 고 부 르 며 시스템 에서 유지 합 니 다.이 목록 의 지침 은 지정 한 프로그램 이 정의 하 는 Hook 서브 프로 세 스에 서 호출 된 리 셋 함수,즉 이 갈고리 의 각 처리 서브 프로 세 스 를 가리 키 고 있 습 니 다.지정 한 Hook 형식 과 연 결 된 메시지 가 발생 하면 시스템 은 이 메 시 지 를 Hook 서브 프로 세 스 로 전달 합 니 다.일부 Hook 서브 코스 는 메시지 만 감시 하거나 메 시 지 를 수정 하거나 메시지 의 전진 을 중단 하여 다음 Hook 서브 코스 나 목적 창 에 전달 되 지 않도록 할 수 있 습 니 다.최근 에 설 치 된 갈 고 리 는 체인 의 시작 에 놓 여 있 고 가장 먼저 설 치 된 갈 고 리 는 마지막 에 놓 여 있다.즉,나중에 가입 한 것 이 먼저 통제 권 을 얻 는 것 이다.윈도 우즈 는 갈고리 의 마 운 트 해제 순 서 를 반드시 설치 순서 와 상반 시 켜 야 한다 고 요구 하지 않 는 다.갈고리 가 마 운 트 해제 될 때마다 윈도 는 사용 하 는 메모 리 를 방출 하고 전체 훅 링크 를 업데이트 합 니 다.프로그램 이 갈 고 리 를 설 치 했 지만 갈 고 리 를 마 운 트 해제 하기 전에 끝나 면 시스템 은 자동 으로 갈 고 리 를 마 운 트 해제 하 는 작업 을 할 것 이다.갈고리 프로 세 스 는 프로그램 이 정의 하 는 리 셋 함수(CALLBACK Function)로 특정한 종류의 구성원 함수 로 정의 할 수 없고 일반적인 C 함수 로 만 정의 할 수 있 습 니 다.감시 시스템 이나 특정한 유형의 사건 으로 이 사건 들 은 특정한 스 레 드 와 관련 될 수도 있 고 시스템 의 모든 스 레 드 사건 일 수도 있다.갈고리 거 리 는 다음 과 같은 문법 에 따라 야 합 니 다.

LRESULT CALLBACKHookProc
(
int nCode,
      WPARAM wParam,
      LPARAM lParam
);
Hook Proc 는 응용 프로그램 이 정의 한 이름 입 니 다.nCode 인 자 는 Hook 코드 이 고 Hook 서브 프로 세 스 는 이 인 자 를 사용 하여 작업 을 확인 합 니 다.이 매개 변수의 값 은 Hook 형식 에 의존 하고 모든 Hook 코드 특징 문자 집합 이 있 습 니 다.wParam 과 lParam 매개 변 수 는 Hook 코드 에 의존 하지만 전형 적 인 값 은 메 시 지 를 보 내 거나 받 는 정 보 를 포함 합 니 다.2.갈고리 의 설치 와 방출:API 함수 SetWindowsHookEx()를 사용 하여 프로그램 이 정의 하 는 갈고리 거 리 를 갈고리 링크 에 설치 합 니 다.SetWindowsHookEx 함 수 는 항상 Hook 체인 의 시작 부분 에 Hook 서브 코스 를 설치 합 니 다.지정 한 유형의 훅 이 감시 하 는 사건 이 발생 하면 시스템 은 이 훅 과 연 결 된 훅 체인 의 시작 부분 인 훅 서브 프로 세 스 를 호출 합 니 다.모든 훅 체인 의 훅 거리 가 이 사건 을 다음 훅 거리 로 전달 할 지 여 부 를 결정 합 니 다.Hook 서브 프로 세 스 가 이 벤트 를 다음 Hook 서브 프로 세 스 로 전달 하려 면 CallNextHook Ex 함 수 를 호출 해 야 합 니 다.

HHOOKSetWindowsHookEx(
int idHook,      // ,
HOOKPROC lpfn,   // 。 dwThreadId 0
      // ,
      // lpfn DLL 。
      // ,lpfn 。
      // , 。
HINSTANCE hMod, // 。 lpfn
DLL。
      // dwThreadId ,
      // ,hMod NULL。
      // 。
DWORD dwThreadId // 。
      // 0, , 。
            );
함수 가 성공 하면 갈고리 의 핸들 을 되 돌려 주 고 NULL 로 돌아 가 는 데 실 패 했 습 니 다.이상 에서 말 한 갈고리 거 리 는 스 레 드 와 관련 된 것 은 갈고리 링크 에서 이 스 레 드 에 보 낸 메 시 지 를 동시에 갈고리 거리 에 보 내 고 갈고리 거리 에 의 해 먼저 처리 되 는 것 을 말한다.갈고리 과정 에서 제어 권 을 가 진 갈고리 함 수 를 호출 하여 메시지 에 대한 처 리 를 마 친 후 이 메 시 지 를 계속 전달 하려 면 다른 SDK 의 API 함수 인 CallNextHookEx 를 호출 하여 갈고리 링크 가 가리 키 는 다음 갈고리 과정 을 실행 해 야 합 니 다.이 함수 가 성공 할 때 갈고리 체인 의 다음 갈고리 과정의 반환 값 을 되 돌려 줍 니 다.반환 값 의 유형 은 갈고리 의 유형 에 의존 합 니 다.이 함수 의 원형 은 다음 과 같 습 니 다.

LRESULTCallNextHookEx
   (
    HHOOK hhk;
    int nCode;
    WPARAM wParam;
    LPARAM lParam;
    );
hhk 는 현재 갈고리 의 핸들 로 SetWindowsHookEx()함수 에서 되 돌 아 옵 니 다.NCode 는 갈고리 과정 에 전달 되 는 이벤트 코드 입 니 다.wParam 과 lParam 은 각각 갈고리 거리 에 전 달 된 wParam 값 으로 그 구체 적 인 의 미 는 갈고리 유형 과 관계 가 있다.갈고리 함수 도 TRUE 로 직접 돌아 가 이 메 시 지 를 버 리 고 이 메시지 의 전달 을 막 을 수 있다.그렇지 않 으 면 갈고리 가 설 치 된 다른 프로그램 은 갈고리 의 통 지 를 받 지 못 하고 부정 확 한 결과 가 나 올 수도 있다.갈 고 리 는 사용 이 끝 난 후에 UnHook Windows Hook Ex()로 마 운 트 를 해제 해 야 합 니 다.그렇지 않 으 면 문제 가 발생 할 수 있 습 니 다.갈 고 리 를 놓 는 것 은 간단 합 니 다.UnHook WindowsHookEx()는 하나의 인자 만 있 습 니 다.함수 원형 은 다음 과 같 습 니 다.

UnHookWindowsHookEx
(
HHOOK hhk;
);
함수 가 TRUE 를 성공 적 으로 되 돌려 주 었 습 니 다.그렇지 않 으 면 FALSE 로 돌아 갑 니 다.3.일부 운영 체제:Win 16 환경 에서 DLL 의 전체 데 이 터 는 모든 프로 세 스 를 불 러 오 는 데 똑 같 습 니 다.Win 32 환경 에서 상황 이 바 뀌 었 습 니 다.DLL 함수 의 코드 가 만 든 모든 대상(변수 포함)은 스 레 드 나 프로 세 스 를 호출 합 니 다.프로 세 스 가 DLL 을 불 러 올 때 운영 체 제 는 DLL 주 소 를 프로 세 스 의 개인 공간,즉 프로 세 스 의 가상 주소 공간 에 자동 으로 표시 하고 이 DLL 의 전체 데 이 터 를 프로 세 스 공간 으로 복사 합 니 다.즉,모든 프로 세 스 가 가지 고 있 는 같은 DLL 의 전역 데 이 터 는 이름 이 같 지만 그 값 이 반드시 같 지 않 고 서로 간섭 하지 않 는 다 는 것 이다.따라서 Win 32 환경 에서 여러 프로 세 스에 서 데 이 터 를 공유 하려 면 필요 한 설정 을 해 야 합 니 다.같은 Dll 에 접근 하 는 각 프로 세 스 간 공유 메모 리 는 메모리 맵 파일 기술 을 통 해 이 루어 집 니 다.공유 해 야 할 데 이 터 를 분리 해서 하나의 독립 된 데이터 단락 에 놓 고 이 단락 의 속성 을 공유 로 설정 할 수도 있다.이 변수 에 초기 값 을 부여 해 야 합 니 다.그렇지 않 으 면 컴 파일 러 는 초기 값 이 부여 되 지 않 은 변 수 를 초기 화 되 지 않 은 데이터 세그먼트 에 두 어야 합 니 다.\#pragma data_seg 예비 처리 명령 은 공유 데이터 세그먼트 를 설정 하 는 데 사 용 됩 니 다.예 를 들 어

#pragmadata_seg("SharedDataName")
HHOOK hHook=NULL;
#pragma data_seg()
은\#pragma dataseg("SharedDataName")과\#pragma dataseg()사이 의 모든 변 수 는 이 Dll 의 모든 프로 세 스에 접근 하여 보고 공유 합 니 다.명령 어\#pragmacont(linker,"/section:shared DataName,rws")를 추가 하면 이 데이터 섹 션 의 데 이 터 는 모든 DLL 인 스 턴 스 간 에 공유 할 수 있 습 니 다.모든 프로 세 스 의 주소 공간 에 있 는 것 이 아니 라 이 데이터 에 대한 작업 은 같은 인 스 턴 스 를 대상 으로 합 니 다.프로 세 스 가 동적 라 이브 러 리 의 함 수 를 암시 적 또는 명시 적 으로 호출 할 때 시스템 은 이 동적 라 이브 러 리 를 이 프로 세 스 의 가상 주소 공간 에 표시 해 야 합 니 다(이하'주소 공간'이 라 고 약칭).이 는 DLL 을 프로 세 스 의 일부분 으로 만 들 고 이 프로 세 스 의 스 택 을 사용 합 니 다.4.시스템 갈고리 와 스 레 드 갈고리:SetWindowsHookEx()함수 의 마지막 매개 변 수 는 이 갈고리 가 시스템 갈고리 인지 스 레 드 갈고리 인지 결정 합 니 다.스 레 드 체크 는 지정 한 스 레 드 의 이벤트 정 보 를 감시 하 는 데 사 용 됩 니 다.스 레 드 체크 는 일반적으로 현재 스 레 드 나 현재 스 레 드 가 파생 된 스 레 드 에 있 습 니 다.시스템 체크 감시 시스템 의 모든 스 레 드 이벤트 메시지 입 니 다.시스템 체크 는 시스템 의 모든 프로그램 에 영향 을 줄 수 있 기 때문에 체크 함 수 는 독립 된 동적 링크 라 이브 러 리(DLL)에 두 어야 합 니 다.시스템 은 자동 으로'갈고리 리 셋 함수'를 포함 하 는 DLL 을 갈고리 함수 의 영향 을 받 는 모든 프로 세 스 의 주소 공간 에 비 추고 이 DLL 을 프로 세 스 에 주입 합 니 다.몇 가지 설명:(1)같은 이벤트(예 를 들 어 마우스 메시지)에 스 레 드 체크 를 설치 하고 시스템 체크 를 설치 하면 시스템 은 자동 으로 스 레 드 체크 를 호출 한 다음 에 시스템 체크 를 호출 합 니 다.(2)같은 이벤트 메시지 에 여러 개의 체크 처리 과정 을 설치 할 수 있 는데 이런 체크 처리 과정 은 체크 체인 을 형성한다.현재 체크 처리 가 끝 난 후 체크 정 보 를 다음 체크 함수 에 전달 해 야 합 니 다.(3)체크,특히 시스템 체크 는 메시지 처리 시간 을 소모 하여 시스템 성능 을 떨 어 뜨 린 다.필요 할 때 만 체크 를 설치 합 니 다.사용 이 끝 난 후에 C\#키보드 체크(Hook)차단 기 를 제거 하고 키보드 활동 소스 코드 를 차단 해 야 합 니 다.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Reflection;
using System.Diagnostics;
using Microsoft.Win32;
namespace Vjsdn.Tech.KeyboardHook
{
   public partial class frmKeyboardHook : Form
   {
      //
      private KeyboardHookLib _keyboardHook = null;

      public frmKeyboardHook()
      {
         InitializeComponent();
      }

      private void button1_Click(object sender, EventArgs e)
      {
         //
         _keyboardHook = new KeyboardHookLib();
         _keyboardHook.InstallHook(this.OnKeyPress);
      }

      private void button2_Click(object sender, EventArgs e)
      {
         //
         if (_keyboardHook != null) _keyboardHook.UninstallHook();
      }

      /// <summary>
      /// .
      /// </summary>
      /// <param name="hookStruct"> Hook </param>
      /// <param name="handle"> </param>
      public void OnKeyPress(KeyboardHookLib.HookStruct hookStruct, out bool handle)
      {
         handle = false; //

         if (hookStruct.vkCode == 91) // win( )
         {
            handle = true;
         }

         if (hookStruct.vkCode == 92)// win
         {
            handle = true;
         }

         // Ctrl+Esc
         if (hookStruct.vkCode == (int)Keys.Escape && (int)Control.ModifierKeys == (int)Keys.Control)
         {
            handle = true;
         }

         // alt+f4
         if (hookStruct.vkCode == (int)Keys.F4 && (int)Control.ModifierKeys == (int)Keys.Alt)
         {
            handle = true;
         }

         // alt+tab
         if (hookStruct.vkCode == (int)Keys.Tab && (int)Control.ModifierKeys == (int)Keys.Alt)
         {
            handle = true;
         }

         // F1
         if (hookStruct.vkCode == (int)Keys.F1)
         {
            handle = true;
         }

         // Ctrl+Alt+Delete
         if ((int)Control.ModifierKeys == (int)Keys.Control + (int)Keys.Alt + (int)Keys.Delete)
         {
            handle = true;
         }

         // A~Z
         if (hookStruct.vkCode >= (int)Keys.A && hookStruct.vkCode <= (int)Keys.Z)
         {
            // B
            if (hookStruct.vkCode == (int)Keys.B)
            hookStruct.vkCode = (int)Keys.None; // 0

            handle = true;
         }

         Keys key = (Keys)hookStruct.vkCode;
         label1.Text = " :" + (key == Keys.None ? "" : key.ToString());

      }
   }
}
Keyboard Hook Lib.cs 키보드 관리 류

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Reflection;
using System.Diagnostics;
using Microsoft.Win32;
using System.Windows.Forms;
namespace Vjsdn.Tech.KeyboardHook
{
   /// <summary>
   /// Hook , by www.vjsdn.com
   /// </summary>
   public class KeyboardHookLib
   {
      private const int WH_KEYBOARD_LL = 13; //

      // , .
      private delegate int HookHandle(int nCode, int wParam, IntPtr lParam);

      //
      public delegate void ProcessKeyHandle(HookStruct param, out bool handle);

      // SetWindowsHookEx
      private static int _hHookValue = 0;

      //
      private HookHandle _KeyBoardHookProcedure;

      //Hook
      [StructLayout(LayoutKind.Sequential)]
      public class HookStruct
      {
         public int vkCode;
         public int scanCode;
         public int flags;
         public int time;
         public int dwExtraInfo;
      }

      //
      [DllImport("user32.dll")]
      private static extern int SetWindowsHookEx(int idHook, HookHandle lpfn, IntPtr hInstance, int threadId);

      //
      [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
      private static extern bool UnhookWindowsHookEx(int idHook);

      //
      [DllImport("user32.dll")]
      private static extern int CallNextHookEx(int idHook, int nCode, int wParam, IntPtr lParam);

      // ID
      [DllImport("kernel32.dll")]
      private static extern int GetCurrentThreadId();

      //Gets the main module for the associated process.
      [DllImport("kernel32.dll")]
      private static extern IntPtr GetModuleHandle(string name);

      private IntPtr _hookWindowPtr = IntPtr.Zero;

      //
      public KeyboardHookLib() { }

      //
      private static ProcessKeyHandle _clientMethod = null;

      /// <summary>
      ///
      /// </summary>
      /// <param name="hookProcess"> </param>
      public void InstallHook(ProcessKeyHandle clientMethod)
      {
         _clientMethod = clientMethod;

         //
         if (_hHookValue == 0)
         {
            _KeyBoardHookProcedure = new HookHandle(OnHookProc);

            _hookWindowPtr = GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName);

            _hHookValue = SetWindowsHookEx(
            WH_KEYBOARD_LL,
            _KeyBoardHookProcedure,
            _hookWindowPtr,
            0);

            // .
            if (_hHookValue == 0) UninstallHook();
         }
      }

      //
      public void UninstallHook()
      {
         if (_hHookValue != 0)
         {
            bool ret = UnhookWindowsHookEx(_hHookValue);
            if (ret) _hHookValue = 0;
         }
      }

      // , _clientMethod 。
      private static int OnHookProc(int nCode, int wParam, IntPtr lParam)
      {
         if (nCode >= 0)
         {
            //
            HookStruct hookStruct = (HookStruct)Marshal.PtrToStructure(lParam, typeof(HookStruct));

            if (_clientMethod != null)
            {
               bool handle = false;
               // 。
               _clientMethod(hookStruct, out handle);
               if (handle) return 1; //1: ,return
            }
         }
         return CallNextHookEx(_hHookValue, nCode, wParam, lParam);
      }

   }
}

좋은 웹페이지 즐겨찾기