취약점분석/Reversing

[Reversing] Hooking - 6 (notepad.exe 후킹 ①)

poiri3r 2025. 7. 26. 19:58

안녕하세요. 오늘은 notepad.exe를 후킹해보도록 하겠습니다.

원래는 inline후킹으로만 후킹을 연습해보려고 했는데, 따로 방법을 정해두지 않고 목표를 설정한 뒤 그에 맞게 진행해보도록 하겠습니다.

포스팅 내용에 시행착오가 포함되어 있을 수 있습니다.

 

먼저 notepad.exe에 대한 분석을 해보겠습니다.

먼저 메모장을 키면 다음과 같습니다.

다들 많이 사용해보셨을것입니다,. 위에는 파일 저장,불러오기,이름 변경, 글씨 크기 변경하는 등의 기능을 지원합니다.

IDA를 관리자 권한으로 실행시킨 뒤 import 테이블을 보면 다음과 같습니다. 저희는 다음 dll에 포함된 함수 중 후킹할 함수를 정해서 원하는 기능을 구현해야 합니다.

 

어떤 기능을 사용할 때 어떤 함수가 사용되는지 확인하기 위해서 API moniter를 켜주었습니다.

 

일단 Kernal32.dll과 User32.dll안의 모든 함수들을 모니터해줬는데 로그가 너무 많이 찍혀서 특정 몇개만 지정해보겠습니다.

user32.dll에서 몇개만 지정을 해뒀는데

 

글자를 입력할때마다 SendMessegeA가 호출됩니다.

그러나 글자를 입력하는 것 외에도 클릭이나 파일버튼을 누르거나 하는 동작에도 모두 SendMessage가 호출되기 때문에 SendMessage는 그냥 사용자의 모든 입력을 전송하는 것 같습니다.

 

이번엔 kernel32.dll에만 모니터링을 걸어두고 이것저것 입력해봤습니다.

아까랑 마찬가지로 SendMessageW가 글자입력이나 클릭 등을 할때 찍힙니다.

알아보니까 kernel32.dll에서 SendMessageW를 내부적으로 호출하는 코드 흐름이 있어서 찍히는 거라고 합니다.

 

이번엔 GDI32.dll을 모니터링 해보겠습니다.

글자를 하나 클릭할 때마다 다음의 9개 함수가 반복적으로 호출됩니다.

글자 입력 흐름입니다.

SendMessageW가 계속 호출되고 있는데 후킹을 하려면 SendMessageW의 인자 Msg값을 같이 후킹해서 특정 msg의 값에서만 동작하도록 코드를 짜도 될 것 같습니다.

여태껏 보니까 글자 입력시에 호출되는 SendMessageW의 msg인자값에는 WM_COMMAND 만 호출이 되는것같아 검색해줬습니다.

다음은 SendMessageW의 함수 원형입니다.

LRESULT SendMessageW(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);

 

여기서 Msg == WM_COMMAND (0x0111)일 때, wParam과 lParam은 다음과 같습니다.

 

조금 이해가 되었는데 호출되는 SendMessageW에서 msg인자값이 WM_CHAR같은 호출을 찾아야되는데 모든 dll에 모니터링을 걸고 입력해도 찾을수가 없었습니다. 그래서 이것저것 검색해보니까 윈도우 10부터 도입된 앱들은 UWP라는 플랫폼이 있어서 전통적인 WM_CHAR이나 DispatchMessage 흐름을 따르지 않는다고 합니다. UWP 앱들을 후킹연습하는건 난이도가 매우매우 어렵다고 하네요 ..

 

그래서 Win32메모장을 실행해두었습니다.

경로는 C:\Windows\System32\notepad.exe 입니다.

실행후

DispatchMessageW,PeekMessageW,GetMessageW,SendMessageW에 후킹을 걸어뒀습니다. 

로그가 엄청 많이 찍혀서 구분이 좀 힘든것같습니다 ..

이전 최신형 메모장을 썼을 땐 Getcursor랑 SetCursor로그가 엄청 찍혔는데 Win32메모장에서는 모든 이벤트가 DispatchMessageW로 찍히는 것 같습니다.

보기는 좀 힘들어 졌지만, 그래도 전보단 흐름이 ㅂ이는 것 같습니다.

 

모든 함수에 모니터링을 걸어두고 메모장에 poiri3r을 입력해보았습니다.

이번엔 확실하게 poiri3r라는 문자열이 함수에서 전달되는게 보입니다.

 

SendMessageW에만 후킹을 걸고 메세지를 입력했습니다.

 

일단 목표를 잡았는데, riched20.dll에서 SendMessageW에 인자가 1532로 담겨있는 메세지를 어떻게 해석해서 어떤 동작을 수행하는지 알아봐야 할 것 같습니다.

문자 입출력을 처리하는 부분이 riched20.dll인건 확실한 것 같은데 .. 감이 잘 안잡혀서 몇시간 째 헤메고 있습니다.

문자 입출력부분이랑 저장/불러오기 부분을 후킹하고싶었는데 너무 어려워서 계속 헤메고만 있네요 ..

 

riched20.dll을 찾아 들어가서 1532를 해석하는 부분을 찾아보겠습니다.

IDA를 관리자 권한으로 실행해서 riched20.dll 을 켜주었습니다.

이것저것 보다 함수 목록에 Winproc,Message 등을 검색하면서 1532루틴을 처리하는 case문을 찾으려고 했습니다.

그러다 HandleMessage를 처리하는 함수를 찾았는데,

 

case문이 너무 많아서 case문중에서 1532를 처리하는 루틴을 찾아보면 될 것 같습니다.

챗지피티가 헛소리만 해서 계속 헤맸는데 결론적으로는 

CTextMsgFilter를 생성/설치한 뒤 HandleMessage를 통해 실제 메세지를 필터링/처리하는 역할입니다..

 

찾아보면서도 무슨말인지 하나도 모르겠고 너무 복잡한데 쉽게쉽게 갈걸 너무 복잡하게 가는건지, 원래 윈도우 프로그램을 실제로 후킹하는게 너무 어려운 작업인건지 잘 모르겠네요.

 

오늘의 포스팅은 여기까지 마치고 다음번에 이어서 작성해보도록 하겠습니다.

이런식의 머리박으면서 공부하는게 제 실력 향상에 도움이 될진 잘 모르겠다는 생각이 계속 드네요.

 

오늘 한 분석을 요약해보겠습니다.

  1. notepad.exe를 API moniter로 함수호출 확인
  2. SendMessageW와 DispatchMessageW로 메세지 전송
  3. SendMessageW의 2번째 인자 msg값에 따라 처리가 달라짐
  4. notepad의 메세지 처리는 riched20.dll에서 처리
  5. 해당 riched20.dll에서 처리하는 분기문을 확인

다음에 조금 더 고민해보고 접근 방식을 바꿔서 포스팅을 하든 해보겠습니다.

읽어주셔서 감사합니다. 다음번엔 더 힘내서 작성해보겠습니다