프로세스에 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 의 정의를 보시겠습니다.
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) 부탁드려요~
'study' 카테고리의 다른 글
| API Hooking - '스텔스' 프로세스 (2) (32) | 2009/12/16 |
|---|---|
| API Hooking – '스텔스' 프로세스 (1) (18) | 2009/12/13 |
| API Hooking - 계산기, 한글을 배우다. (4) (10) | 2009/11/27 |
| API Hooking – 계산기, 한글을 배우다. (3) (35) | 2009/11/20 |
| API Hooking - 계산기, 한글을 배우다. (2) (14) | 2009/11/13 |
| API Hooking - 계산기, 한글을 배우다. (1) (30) | 2009/11/10 |
| API Hooking - 메모장 WriteFile() 후킹 (3) (26) | 2009/11/04 |
| API Hooking - 메모장 WriteFile() 후킹 (2) (3) | 2009/11/03 |
| API Hooking - 메모장 WriteFile() 후킹 (1) (22) | 2009/10/08 |
| API Hooking - Tech Map (10) | 2009/09/29 |
| API Hooking - 리버싱의 '꽃' (22) | 2009/09/22 |
