API Hooking 기법 중에서 DLL Injection 기법을 설명 드리겠습니다.

프로세스에 Injection 된 DLL 파일은 IAT(Import Address Table)후킹(hooking)하여 프로세스에서 호출 되는 특정 API 의 기능을 변경시킵니다.

Windows 계산기(calc.exe) 프로세스에 dll 을 삽입시켜 IAT의 user32!SetWindowTextW() API 주소를 후킹합니다. SetWindowTextW() API 가 후킹당한 계산기는 계산결과를 숫자가 아닌 한글로 출력하게 됩니다.


<SetWindowTextW() 가 후킹된 계산기 프로세스>

* 본문 내용과 관련된 정보는 아래와 같습니다.

PE(Portable Executable) File Format (1)
- PE(Portable Executable) File Format (6)
DLL Injection – 다른 프로세스에 침투하기
API Hooking – 리버싱의 ‘꽃’



Tech Map



<Fig. 1>

위 그림은 API Hooking TechMap 에서 "DLL Injection 을 통한 IAT 후킹 기법"빨간색으로 보여줍니다.

이 방식의 장점은 동작 원리와 구현이 비교적 간단하다는 것입니다. (원하는 API 를 사용자 DLL 에 재정의 하고 프로세스에 Injection 시키면 됩니다.)

단점으로는 후킹을 원하는 API 가 대상 프로세스의 IAT 에 존재하지 않다면 사용할 수 없다는 것입니다. 즉, 프로그램 코드 상에서 동적으로 DLL 을 로딩해서 사용하는 API 의 경우는 이 방법으로 후킹할 수 없습니다.



대상 API 선정


작업 목표를 설정한 후 API 후킹 기법을 사용하겠다고 결정하였다면, 그 다음으로 중요한 작업은 후킹 대상 API 를 선정하는 작업입니다.

초보자 분들께서는 어쩌면 이 부분에 어려움을 겪으실 수 있겠습니다.
왜냐하면 후킹을 원하는 기능을 제공하는 API 가 뭔지 알아야 하기 때문입니다.

예를 들면 파일 생성은 kernel32!CreateFile() API, 레지스트리 생성은 advapi32!RegCreateKeyEx() API, 네트워크 접속은 ws2_32!connect() API 등에서 담당합니다.

개발/리버싱 경험이 많다면 원하는 API 를 쉽게 떠올릴 수 있지만, 그렇지 않다면 검색이 필요합니다. 공개된 API 말고 공개되지 않은 undocumented API 를 후킹해야 하는 상황도 있기 때문에 검색은 필수입니다. 검색이 잘 안될 때는 일단 경험(또는 직관)에 의존하여 선택한 후 검증 작업을 거치면 됩니다.

적절한 API 를 선택하기 전에 먼저 작업 목표를 설정합니다.
이번 포스트의 실습 목표는 "계산기의 텍스트 에디터에 표시되는 모든 숫자를 한글로 변경" 하기입니다.

PE View 등의 유틸리티를 이용해서 계산기(calc.exe)에서 import 하는 API 를 확인합니다.

<Fig. 2>

위 그림을 보시면 2개의 API 가 눈에 띕니다. 바로 SetWindowTextW(), SetDlgItemTextW() 입니다.

두 API 모두 텍스트 에디터에 글씨를 써주는 역할을 합니다. 그런데 SetDlgItemTextW() 는 내부적으로 다시 SetWindowTextW() 를 호출하기 때문에 여기서는 SetWindowTextW() 를 후킹하면 될 것이라고 일단 가정합니다.

SetWindowTextW() API 의 정의를 보시겠습니다.

BOOL SetWindowText(     
    HWND hWnd,
    LPCTSTR lpString
);

* 출처 : http://msdn.microsoft.com/en-us/library/ms633546(VS.85).aspx

이 API 는 파라미터로 윈도우 핸들(hWnd)과 문자열 포인터(lpString)를 받습니다.
우리가 딱 원하는 파라미터(lpString)가 있네요. 실제 후킹할 때는 저 문자열(lpString)을 살펴보고 숫자를 한글로 변경하면 될 것 같습니다.

*참고!
API 이름 뒤 ‘W’ 의 의미는 해당 API 의 “Wide character” 버전을 의미합니다. 이와 대응해서 같은 이름으로 끝에 ‘A’ 가 붙은 API 들이 있는데 이는 “ASCII character” 버전을 의미합니다.
예) SetWindowTextA(), SetWindowTextW()

OllyDbg 로 위 가정을 "검증" 해보겠습니다.

<Fig. 3>

위 그림과 같이 Search for - All intermodular calls 명령을 사용하여 계산기(calc.exe) 코드 내에서 호출되는 모든 SetWindowTextW() API 에 대해서 BP 를 설치한 후 실행합니다.

실행시키자마자 아래 그림과 같이 BP 에 걸립니다.

<Fig. 4>

SetWindowTextW() API 의 lpString 파라미터는 스택(ESP+4) 에 있는 7FB5C 입니다. (OllyDbg 에서는 "Text" 라고 표시해 주는군요.)

7FB5C 주소에 가면 "0. " 문자열이 wide character 형식으로 저장되어 있습니다. 이 문자열은 계산기에 있는 텍스트 창의 초기값입니다.

이 상태에서 그대로 실행해 보겠습니다.

<Fig. 5>

위 <Fig. 5> 그림과 같이 계산기(calc.exe)가 정상적으로 실행되고 텍스트 창에 <Fig. 4> 에서 보았던 "0. " 문자열이 나타납니다. (". " 은 계산기에서 자동으로 붙여주는 문자열입니다.)

좀 더 디버깅을 하기 위해서 계산기에 숫자를 입력해 보겠습니다.
숫자 7 을 입력 하였습니다. 이미 BP 가 걸려있기 때문에 <Fig. 4> 와 동일한 위치에서 멈춥니다.

<Fig. 6>

위의 그림에서는 Text 파라미터의 값이 7F978 로 <Fig. 4> 의 7FB5C 값과는 틀립니다만, 7F978 주소에 지금 입력한 “7“ 이 보입니다. (끝에 있는 “. “ 문자열은 계산기에서 자동으로 추가해주는 문자열입니다.)

테스트를 위해서 이 숫자 “7” 을 한글 “칠” 로 바꿔 보겠습니다.

한글 “칠” 에 해당하는 wide character 는 0xCE60 입니다.

이 값을 아래와 같이 7F978 주소에 덮어쓰겠습니다.

<Fig. 7>

Intel Architecture 계열은 Little Endian 표기법에 따라서 역순(60CE)으로 써줘야 한다는 걸 기억하세요.

위와 같이 SetWindowTextW() API 의 lpString(또는 Text) 파리미터 내용을 변경한 후 실행하면 아래 그림과 같이 숫자 "7" 이 한글 "칠" 로 변경됩니다.

<Fig. 8>

이것으로써 SetWindowTextW() API 에 대한 검증이 완료되었습니다.


다음 포스트에서 IAT 후킹의 동작 및 구현 원리를 알아보고, 계산기의 SetWindowText() API 의 IAT 후킹 소스 코드에 대해서 살펴보도록 하겠습니다.


API Hooking - 계산기, 한글을 배우다. (2)


+---+

ReverseCore


위 글이 도움이 되셨다면 추천(view on) 부탁드려요~ 

Trackback Address :: http://www.reversecore.com/trackback/59 관련글 쓰기

  1. 냥냥 2009/11/10 01:37 댓글주소 | 수정 | 삭제 | 댓글

    이번에도 제가 1등인가요..?! > <// ㅎㅎ
    항상 감사합니다~

  2. 늅늅 2009/11/10 09:53 댓글주소 | 수정 | 삭제 | 댓글

    2등이군요.

    이런데서 등수놀이 할 줄이여 -.-;;

    text 로만 보면 어려울 수 있는 내용을 그림과 함께 잘 설명해 주셔서 감사합니다 ^^

  3. 이승철 2009/11/10 17:38 댓글주소 | 수정 | 삭제 | 댓글

    안녕하세요!@ 이승철입니다.

    다름이 아니라 리플을 읽어 보니깐 오프라인 강의나 책을 출판 하신다고 하시는데

    혹시 어디에 사세요? 서울 사시나요? 전 부산이라서 ㅜㅜ

    출판 하게 되신다면 윤성우강사님처럼 친철한 강의 원하는데

    • ReverseCore 2009/11/10 22:39 댓글주소 | 수정 | 삭제

      이승철님, 안녕하세요.

      전 서울입니다. ^^

      출판, 강연은 아직 먼 미래의 일이구요...

      음... 저도 친절하고 싶어요 ^^

  4. safscx 2009/11/10 21:52 댓글주소 | 수정 | 삭제 | 댓글

    굿

  5. 2009/11/11 20:57 댓글주소 | 수정 | 삭제 | 댓글

    비밀댓글입니다

  6. 뿡뿡이 2009/11/12 00:25 댓글주소 | 수정 | 삭제 | 댓글

    우와...

    리버싱 공부 시작한지 이제 3일된 초보자 입니다....

    관련 자료들 찾던중...이렇게 재미있고 괜찮은 강좌가 있눈 사이트를 발견한게

    정말 행운이라고 생각합니다!!!! 아직 초보라 강좌 내용은 잘모르지만..

    그래도!! 1시간 가량 정말 잼있게 읽었습니다..ㅎㅎㅎ

    앞으로도 자주 들러볼께요!!

    좋은 강좌 많이 해주세용 ㅋㅋㅋ

  7. 부자봉스 2009/11/12 00:36 댓글주소 | 수정 | 삭제 | 댓글

    참 잘 보고 있습니다.. 지금 시작이지만 좋은 공부가 될거 같네요

  8. 부자봉스 2009/11/13 02:00 댓글주소 | 수정 | 삭제 | 댓글

    일일이 답변주시고 감사합니다

  9. 쭈욱 2010/01/20 16:51 댓글주소 | 수정 | 삭제 | 댓글

    정성껏 작성하신 글 잘 봤습니다. 감사합니다~
    앞으로도 계속 도움이 될거 같네요. 후킹은 첨이라서 얼떨떨하네요.

  10. 경서기 2010/02/19 17:29 댓글주소 | 수정 | 삭제 | 댓글

    후킹... 다른 글은 어려운 말로 나를 괴롭혔는데...
    여기 글 보고... 한번 해봐야겠다는 의욕이 생기네요 ^^
    좋은 감사합니다.

    • reversecore 2010/02/19 23:52 댓글주소 | 수정 | 삭제

      안녕하세요.

      제 글을 읽고 의욕이 생기셨다니 기쁘네요. ^^

      후킹을 공부하시다가 질문이 있으시면 올려주세요~

      감사합니다.

  11. 시간의흔적 2010/03/26 15:53 댓글주소 | 수정 | 삭제 | 댓글

    정말 글을 잘 읽고 있습니다 ^^ 넘넘 감사드리구요..
    눈으로만 보다가 실제로 해보니 궁금한 점이 생겨서 질문을 들려요..
    만약 칠. -> HEX code로 바꿀때.. 다른 툴을 쓰시는 건지 아님 OllyDbg를 쓰시는건지 ^^;;
    넘 기본적인 질문인가요?? OllyDbg를 첨써봐서 ^^
    지금 열심히 따라하고 있습니다 ㅎㅎ..

    • reversecore 2010/03/28 00:06 댓글주소 | 수정 | 삭제

      시간의흔적님, 안녕하세요.

      OllyDbg 는 아니구요.
      예전에 프로그래머로 일할때 이미 알고 있던 내용입니다.

      간단히 VC++ 에서 아래와 같이 프로그래밍하신 후 디버깅 하시면 해당 값을 알 수 있습니다.

      wchar_t wc = L"칠";

      따라 하시다가 다른 궁금한 내용 있으시면 질문 올려주세요.

      감사합니다.

    • Ezbeat 2010/04/11 14:12 댓글주소 | 수정 | 삭제

      저도 그거때문에 고생한 적이 있어요~!
      댓글 보고 바로 프로그램으로 만들어봤어요 ^^;

      http://ezbeat.tistory.com/174
      항상 디버거로 열어서 보기 귀찮으시다면.. 써주세요
      ㅜ ㅜㅋㅋ

    • reversecore 2010/04/11 23:05 댓글주소 | 수정 | 삭제

      Ezbeat님, 안녕하세요.

      답변 감사드리고요,
      좋은 프로그램 만들어 주셔서 감사합니다.

  12. 시간의흔적 2010/03/29 11:40 댓글주소 | 수정 | 삭제 | 댓글

    아 그렇군요 ^^ OllyDbg에서 안되길래.. 다른 프로그램을 쓰시는줄 알았습니다.
    감사합니다~

  13. 안정현 2010/06/28 11:59 댓글주소 | 수정 | 삭제 | 댓글

    search-무슨무슨 모듈콜 이거있자나요 ㅋ 아무것도안뜨는건 무슨현상이죵 ㅜ

    • reversecore 2010/06/29 23:00 댓글주소 | 수정 | 삭제

      음... 질문내용이 잘 이해가 안되는데요...
      OllyDbg 에서 해당 명령을 내리면 아무런 창이 안보인 다는 말씀이신가요?
      해당 윈도우가 작게 숨어있던지 다른 윈도우 밑에 깔려있는것은 아닐까요?

  14. 궁금이 2011/01/26 06:39 댓글주소 | 수정 | 삭제 | 댓글

    안녕하세요. 작년에 reversecore.com에서 크랙미 리버싱 강좌를 보다가 어셈블리가 어렵고 눈에 안들어와서 접었다가

    각종 후킹 방법들을 배우다 보니 다시 이곳에 오게되었습니다. 아직 몇개 읽어보지는 못했지만 이 곳 만큼 자료가 많고 정리 잘 된곳도 없다는 생각이 드네요. 감사드립니다..

    사실 처음에 어셈블리만 거의 나오길래 쉽게 포기했었는데 나중에보니까 제 좁은소견으로는 주로 쓰이는 후킹 기법 몇가지만 알아도 제가 원하는 바를 이룰수가 있는 것 같더라구요.(맞나요?)

    TCP/IP프로그래밍과 MS에서 출판한 Windows Internals를 보려고 하고 있습니다만 Windows Internals를 보는 것이 리버싱에 좀 도움이 될까요? 고맙습니다..

    • reversecore 2011/01/31 12:01 댓글주소 | 수정 | 삭제

      안녕하세요.

      칭찬 감사합니다.

      Windows Internals 요? 리버서에게 그만큼 좋은 책은 없을겁니다. 끝까지 읽기가 너무 힘들어서 문제이지요.

      서점에서 한번 훑어 보신 후에 너무 어렵다고 생각되시면 나중에 실력이 좋아진 후 구입하셔도 될 것 같습니다.

      제 주변에 드라이버 개발자들도 고개를 설레설레 젓는 책입니다. ^^

      감사합니다.

  15. Ch3ongDY 2011/06/27 19:32 댓글주소 | 수정 | 삭제 | 댓글

    좋은글 감사합니다.


◀ PREV : [1] : ... [32] : [33] : [34] : [35] : [36] : [37] : [38] : [39] : [40] : ... [91] : NEXT ▶