- SetWindowsHookEx() API를 이용한 메시지 후킹

# 바로 앞에 포스팅한 Windows 메시지 후킹 실습으로, SetWindowsHookEx() API를 이용하여 메시지 후킹 실습을 해보겠습니다.

  본 내용은 리버싱 핵심원리에 나와 있는 내용을 참고하여 했습니다.



# SetWindowsHookEx() API를 사용하여 메시지 후킹을 한다고 했는데요.

  해당 API 함수를 정리해두었습니다. 참고하실분들은 참고 하세요. [ http://yokang90.tistory.com/48 ]




# 해당 실습에 사용된 파일 HookMain.cpp / KeyHook.cpp  2개의 파일입니다. (리버싱핵심원리에서 제공되어진 소스파일입니다)

- HookMain.cpp 은 키보드 훅을 설치하는 파일 소스입니다.

- KeyHook.cpp 은 키보드 후킹을 실제로 하는 파일 소스입니다.





# 소스코드 분석


[ 그림 1 ] HookMain.cpp 소스

- HookMain.cpp 소스를 보면 후킹 행위를 하는 "KeyHook.dll" 파일을 LoadLibraryA API 함수를 이용하여 로딩하고,

  로딩이 성공한다면, 로딩된 Dll 파일의 핸들값을 hDll 변수에 저장합니다. 실패할 경우에는 에러메시지를 출력하고 종료.

- 로딩이 성공되면, GetProcAddress API 함수를 이용하여 "KeyHook.dll" 모듈에서 "HookStart", "HookStop" 함수의 주소를

  찾아서 HookStart, HookStop 변수에 저장하고, "KeyHook.dll" 모듈에 있는 HookStart 함수를 실행합니다.

- 사용자가 'q' 입력을 하기 전까지는 메시지 후킹이 계속 지속됩니다.



[ 그림 2 ] KeyHook.cpp 소스

- HookMain 프로그램이 실행되면, 사전에 구했던 HookStart 주소를 통해서 HookStart 함수부분이 실행됩니다.

  그 부분이 바로 50번 라인인데요. SetWindowsHookEx 함수를 이용해서 후킹할 타입(키보드), 후킹하는 프로시저 함수명, 

  그리고 후킹 프로시저가 있는 DLL의 핸들값, 마지막으로 hook을 걸고 싶은 스레드 핸들값(0이라는 값을 주어 모든 프로세스에

  영향을 미치는 글로벌 훅이 설치됩니다)을 파라미터로 키보드 훅 프로시저를 실행합니다.

- lParam은 키보드 입력에 대한 부가 정보를 32Bit로 가지고 나타내는데, 여기서 31번째 bit가 키보드를 눌렀는지,

  누르지 않았는지에 대한 상태를 0과 1의 값으로 나타냅니다.

  lParam의 31bit가 '0'이라면 키보드가 눌러진 상태이며, '1'이면 눌러진 상태가 아닌것 말합니다.

- 그래서 32번째 라인에서 lParam의 31번째 비트를 확인해서 1일 경우, 키보드 입력이 발생한 프로세스의 이름과 절대경로를

  얻어서 키보드 입력이 발생한 프로세스가 "notepad.exe" 인지 확인하여 맞다면 해당 메시지를 응용프로그램의 메시지 큐로

  보내지않고 종료하게 됩니다. (즉, 노트패드에서 사용자가 입력한 키값이 입력되지 않음을 말합니다.)

- 노트패드가 아닌 경우에는 해당 응용프로그램의 메시지큐로 전달되어 정상적으로 처리됩니다.

- KeyboardProc 함수는 키보드 입력이 생겨 이벤트가 발생하면 호출되는 프로시저입니다.




- Vmware에서 테스트 한 동영상입니다. HookMain 프로그램을 실행시키고, 키보드 입력을 하게 되면, 키보드 입력 이벤트가 발생하는 프로세스에 

  KeyHook.dll 이 인젝션되고, 키 입력 할 때 마다 해당 dll의 키보드 프로시저가 호출됩니다. KeyHook.dll에 작성되어져 있는 소스코드를 보면, 

  Notepad 에서 발생한 키보드 입력 이벤트일 경우에만 Notepad 응용 프로그램 메시지큐로 전달하지 않고, 종료하게 되어 있습니다.

  동영상을 보시면 노트패드에서만 키 입력이 되지 않는 것을 확인할 수 있습니다.

 (크롬에서는 KeyHook.dll이 인젝션되더라도, 입력이 가능한것을 확인할 수 있습니다)




# 참고 도서 : 리버싱 핵심원리



Trackbacks 0 / Comments 3

  • 2015.08.22 12:57

    비밀댓글입니다

  • 이거 조금 2015.09.12 17:12

    이거 조금 부족한 정보 같은데요.. dll 전역변수가 서로 공유가 안됩니다.

    • yO Kang 2015.11.18 14:17 신고

      답변이 늦어 죄송합니다.ㅎ 저도 참고도서를 이용해서 공부하는 학부생 입장이라, 어느 부분이 잘못되었다라고 말씀드리기가 어렵네요. 참고로 위에 나와있는 코드는 "리버싱 핵심원리" 책에 나와있는 소스코드 그대로 실습내용을 따라한 것 입니다. visual studio 버전 혹은 설정에 있는 문제로 예상됩니다. 책을 참고하시는게 가장 정확하실 것 같습니다.

Leave Comments

by yO Kang

Notices

Tags

Tistory Cumulus Flash tag cloud by L´avare requires Flash Player 9 or better.

Statistics

  • Total : 90,532
  • Today : 11
  • Yesterday : 165