최근 수정 시각 : 2025-01-28 14:27:49

후킹


1. 개요2. 방식

1. 개요

Hooking

API의 호출 흐름을 중간에 가로채는 것을 말한다.

Kernel32.dll의 TerminateProcess API를 예시로 들면 정상적인 호출 흐름일 경우 Kernel32.dll의 TerminateProcess -> ntdll.dll의 NtTerminateProcess를 거쳐 시스템 콜을 실행하지만 TerminateProcess API를 후킹할 경우에는 Kernel32.dll의 TerminateProcess -> 후킹 함수 순서로 바뀌게 된다. 이후 후킹 함수에서 일정 처리 후 원래의 API를 호출한다.

주로 다른 프로세스의 API 호출을 가로채는 것이 목적이므로 후킹 DLL 파일을 대상 프로세스에 로드시키는 프로세스 인젝션도 함께 사용한다.

2. 방식

후킹 방식으로는 IAT, EAT, Code 이렇게 세 가지 방식이 존재한다. 어떤 방식을 이용해서 후킹하느냐에 따라 난이도가 달라진다.
  • IAT (Import Address Table) 수정 - 프로세스는 외부 라이브러리의 API를 호출할 때 IAT라는 테이블을 참조하여 호출하게 되는데 IAT를 수정하여 타켓 함수의 주소를 후킹 함수의 주소로 바꾸는 방법이다. 후킹 방식 중에서 쉬운 방법이나 IAT에 없는 API는 후킹할 수 없다는 단점이 있다. (주로 동적으로 라이브러리를 로드하여 사용할 경우라면 그렇다.)
  • EAT (Export Address Table) 수정 - IAT과 다르게 API의 EAT라는 테이블을 수정하는 방식이다.
  • Code Patch - 직접 API의 코드를 패치하여 후킹 함수로 이동하도록 수정한다. 이 방식은 가장 강력한 방식이지만 코드 자체를 수정하므로 어셈블리어에 어느 정도 알고 있어야 하기에 난이도가 높고 CPU에 따라 잘 작동하지 않을 수 있다.[1]

만약 후킹 함수에서 원래 함수를 호출하려면 후킹 전 원래 함수의 주소를 구해야 한다. 단 Code Patch의 경우 패치 전 코드를 미리 저장해놓았다가 원래 함수를 호출해야할 상황이 되면 이를 이용하여 일시적으로 수정한 코드를 원래 코드로 되돌리고(언후킹) 원래 함수를 호출한 다음 다시 후킹하는 방식을 사용해야 한다.
[1] 예를 들어 32비트에서 후킹하는 방식을 64비트에서 그대로 사용하면 API 호출 시 오류가 발생하여 프로그램이 그대로 꺼진다.