'''후킹'''()은 소프트웨어 공학 용어로, 운영 체제나 응용 소프트웨어 등의 각종 컴퓨터 프로그램에서 소프트웨어 구성 요소 간에 발생하는 함수 호출, 메시지, 이벤트 등을 중간에서 바꾸거나 가로채는 명령, 방법, 기술이나 행위를 말한다. 이때 이러한 간섭된 함수 호출, 이벤트 또는 메시지를 처리하는 코드를 '''훅'''()이라고 한다. 크래킹(불법적인 해킹)을 크래킹 대상 컴퓨터의 메모리 정보, 키보드 입력 정보 등을 빼돌리기 위해서 사용되기도 한다. 예를 들어 특정한 API를 후킹하게 되면 해당 API의 리턴값을 조작하는 등의 동작을 수행할 있다. == 방법 == 일반적으로 훅은 소프트웨어가 이미 실행중일 삽입되지만, 후킹은 응용 프로그램이 실행되기도 전에 쓰일 있는 전략이다. 기술은 아래에 자세히 설명되어 있다. === 물리적 수정 === 응용 프로그램이 실행되기 전에 리버스 엔지니어링 기법으로 실행 또는 라이브러리를 물리적 수정함으로써 후킹을 있다. 이러한 기법은 일반적으로 다른 모니터로 함수 호출을 가로채거나 그것들을 완전히 다른 함수로 대체하는데 사용된다. 예를 들어, 역어셈블러를 사용하여 모듈 내에서 함수의 시작점을 찾을 있다. 다음, 다른 라이브러리 모듈을 동적으로 로드하고, 로드된 라이브러리 내에서 원하는 함수를 실행하도록 변경할 있다. 해당되는 경우, 후킹으로 얻을 있는 관련된 다른 접근 방법은 실행 파일의 임포트 테이블을 변경하는 것이다. 테이블은 추가 라이브러리 모듈을 로드하도록 수정될 있을뿐만이 아니라 함수가 응용 프로그램에 의해 호출될 외부 코드가 호출되는 것으로 바뀔 수도 있다. 후킹을 하기 위한 대체 방법은 래퍼 라이브러리를 통해 함수 호출을 차단하는 것이다. 래퍼를 만들 때, 응용 프로그램을 로드하는 라이브러리는 원본 라이브러리와 동일한 기능을 가진 자신만의 라이브러리를 만든다. 즉, 접근할 있는 모든 기능은 원본과 대체된 라이브러리 모두 동일한 것이다. 래퍼 라이브러리는 원래 라이브러리의 기능 하나를 호출하거나, 논리의 완전히 새로운 설정으로 대체되도록 설계할 있다. === 런타임 수정 === 운영체제와 소프트웨어는 훅을 삽입하는 프로세스에 충분한 권한이 부여된 경우 런타임도중 이벤트 훅을 쉽게 삽입할 있다. 예를 들어, Microsoft Windows에서는 대화 상자, 스크롤바 메뉴뿐만 아니라 다른 항목에 대한 시스템 이벤트와 응용 프로그램 이벤트를 처리하거나 수정하는 사용될 있는 훅을 삽입할 있다. 또한 훅은 키보드 마우스 이벤트를 삽입, 제거, 프로세스 또는 수정할 있다. 리눅스에서는 훅이 넷필터를 통해 커널 내의 네트워크 이벤트를 처리하기 위해 비슷한 방식으로 사용될 있는 다른 예를 제공한다. 이러한 기능이 제공되지 않은 경우, 후킹의 특별한 형태는 프로세스에 의해 만들어진 라이브러리 함수 호출을 차단하는 방법을 사용한다. 후킹은 대상 함수의 번째 몇몇 코드가 주입 코드로 이동하도록 지시를 변경하여 구현된다. 또는 공유 라이브러리의 개념을 사용하는 시스템에서는 인터럽트 벡터 테이블 또는 임포트 디스크립터 테이블이 메모리에서 수정될 있다. 기본적으로 이러한 전술은 물리적 수정과 같은 아이디어를 사용한다. 하지만 이미 실행되어 있는 상태라면 프로세스의 메모리에 있는 명령과 구조를 변경한다. == 예제 코드 == === C# 키보드 이벤트 후킹 === 다음 예제는 닷넷 프레임워크를 사용하여 마이크로소프트 윈도우에서 키보드 이벤트를 후킹하는 것이다. using namespace Hooks public class KeyHook /* Member variables */ protected static int Hook; protected static Delegate; protected static readonly object Lock new object(); protected static bool IsRegistered false; /* DLL imports */ private static extern int idHook, lpfn, int hmod, int dwThreadId); private static extern int hHook, int nCode, int wParam, KBDLLHOOKSTRUCT lParam); private static extern int hHook); /* Types constants */ protected delegate int nCode, int wParam, ref KBDLLHOOKSTRUCT lParam); private const int HC_ACTION 0; private const int WM_KEYDOWN 0x0100; private const int WM_KEYUP 0x0101; private const int WH_KEYBOARD_LL 13; public struct KBDLLHOOKSTRUCT public int vkCode; public int scanCode; public int flags; public int time; public int dwExtraInfo; /* Methods */ static private int nCode, int wParam, ref KBDLLHOOKSTRUCT lParam) if (nCode == HC_ACTION) if (wParam == WM_KEYDOWN) Down: lParam.vkCode); else if (wParam == WM_KEYUP) Up: lParam.vkCode); return nCode, wParam, lParam); public static bool RegisterHook() lock (Lock) if (IsRegistered) return true; Delegate Hook WH_KEYBOARD_LL, Delegate, ).ToInt32(), ); if (Hook != 0) return IsRegistered true; Delegate null; return false; public static bool lock (Lock) return IsRegistered != 0); === DirectDraw 후킹 === 다음은 윈도에서 함수 호출을 후킹한 예이다. 이것은 APIHijack(에이피아이 하이잭)이라는 후킹 라이브러리를 활용한 것이고, 소스는 DLL(동적 링크 라이브러리)로 컴파일되었다. 호출할 추가적인 응용 프로그램도 필요하다. #include #include #include #include "testdll.h" #include char temp256; HINSTANCE hDLL; // type defs typedef HRESULT (WINAPI GUID FAR *lpGUID, LPVOID *lplpDD, REFIID iid, IUnknown FAR *pUnkOuter ); // function prototypes HRESULT WINAPI GUID FAR lpGuid, LPVOID *lplpDD, REFIID iid,IUnknown FAR *pUnkOuter ); // hook structure enum }; SDLLHook D3DHook "DDRAW.DLL", false, NULL, }, NULL, NULL }; // Hook function. HRESULT WINAPI FAR* lpGuid, LPVOID *lplpDD, REFIID iid,IUnknown FAR *pUnkOuter OldFn return OldFn( lpGuid, lplpDD, iid, pUnkOuter ); // CBT Hook-style injection. BOOL APIENTRY DllMain( HINSTANCE hModule, DWORD fdwReason, LPVOID lpReserved if fdwReason == // When hDLL hModule; // Only hook the APIs if this is the fsim proess. temp, sizeof(temp)); "fsim.exe" == 0) HookAPICalls( &D3DHook ); return TRUE; // This segment must be defined as SHARED in the .DEF #pragma data_seg // Shared instance for all processes. HHOOK hHook NULL; #pragma data_seg () TESTDLL_API LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam) return CallNextHookEx( hHook, nCode, wParam, lParam); TESTDLL_API void InstallHook() hHook HookProc, hDLL, 0); TESTDLL_API void RemoveHook() hHook ); === JMP 명령어를 이용한 API/함수 후킹(가로채기) === 다음 소스 코드는 오픈 소스인 Chrom(크롬) 라이브러리를 사용하는 API/함수 후킹의 예시이다. 이는 새로운 함수에 대한 JMP 명령으로 대상 함수의 처음 6바이트를 덮어써서 훅한다. 코드는 DLL로 컴파일 후, 코드 인젝션의 방법을 사용하여 대상 프로세스에 로드된다. 예제 코드는 "nspr4.dll"의 "PR_Write" 함수와 "c:/log.txt"에 기록된 모든 HTTP/HTTPS 요청을 훅한다. /* Firefox_hook (C) Raja Jamwal 2011 Distributed under GNU GPL License Firefox_hook is example code for Chrom Library, Firefox_hook log every HTTP/HTTPS requests that firefox makes Chrom, is API/Funtion library for windows systems Copyright (C) 2011 Raja Jamwal This file is part of Chrom. */ #include "stdafx.h" #include "chrom.h" Hook Firefox; // Hook firefox DWORD PR_Write_H (DWORD *fd, void *buf,DWORD amount); // this is our typedef DWORD // defination of our original function prWrite prw NULL; // create orginal function, we later point this to orginal function // address char // logfile // this will log our data int write_log(char log, char data) ofstream fout(log, ios::app); fout === Netfilter 후킹 === 예제에서는 Netfilter(넷필터)를 사용하여 리눅스 커널에서 네트워크 트래픽을 변경할 있는 훅를 사용하는 방법을 보여준다. #include #include #include #include #include #include #include #include /* Port we want to drop packets on */ static const uint16_t port 25; /* This is the hook function itself */ static unsigned int int hooknum, struct sk_buff **pskb, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *)) struct iphdr *iph ip_hdr(*pskb); struct tcphdr *tcph, tcpbuf; if (iph->protocol != IPPROTO_TCP) return NF_ACCEPT; tcph sizeof(*tcph), &tcpbuf); if (tcph == NULL) return NF_ACCEPT; return (tcph->dest == port) NF_DROP NF_ACCEPT; /* Used to register our hook function */ static struct nf_hook_ops nfho .hook hook_func, .hooknum .pf NFPROTO_IPV4, .priority }; static __init int my_init(void) return static __exit void my_exit(void) == 각주 == == 후킹 프로그램의 목록 == AGTH == 외부 링크 == hook 번째 항목 참조 분류:제어 흐름 분류:컴퓨터 보안 분류:DLL 인젝션