IAT hooking

IAT (Import Address Table)는 프로그램이 실행될 때 필요한 함수의 메모리 주소를 저장하는 테이블이며, IAT 후킹은 IAT에 저장된 메모리 주소를 조작하여 정상 API 대신 사용자가 지정한 함수가 호출되도록 흐름을 조작하는 기법입니다.

아래와 같이 Windows 함수를 통해 메시지 박스를 띄우는 C 코드를 컴파일하는 상황을 보겠습니다.

#include <windows.h>

int main() {
    return MessageBoxW(NULL, L"Hello World", L"PENTEST WIKI", 0);
}

Windows에서 메시지 박스를 띄우기 위해서는 Windows API인 MessageBoxW가 필요하지만 컴파일러의 입장에서 MessageBoxW 함수가 어떤 dll 파일에 정의되어 있는지 알 수 없습니다.

때문에 링커가 Windows SDK에 저장된 user32.lib로부터 MessageBoxW 함수는 User32.dll에 저장되어 있다는 정보를 확인 후, User32.dll의 필요성을 PE파일에 기록합니다.

링커가 PE 파일에 기록하는 라이브러리는 PE 파일의 Import Directory에 저장됩니다.

Import Directory

이후 프로그램이 실행될 때 로더는 프로세스에서 MessageBoxW 함수를 호출할 수 있도록 해당 함수의 실제 메모리 주소를 IAT에 채워넣게 되고, 결과적으로 프로그램은 IAT에 저장된 주소를 참고하여 함수를 실행합니다.

Import Address Table

x User32!MessageBoxW 를 통해 MessageBoxW의 실제 VA를 확인하면 00007ffb09b1c760 로 나오는 반면, 메인 함수를 어셈블리로 덤프하면 MessageBoxW를 호출하는 주소가 00007ff686e30150 로 확인됩니다.

이렇게 메인 함수 내의 호출 주소와 실제 VA가 다른 이유는 메인 함수 내에서는 호출 함수의 주소 값이 포인터로 저장되기 때문이며, PE 구조를 덤프하여 확인할 수 있습니다.

PE 구조를 덤프하면 이미지 베이스 주소는 00007ff686e10000 이며 IAT는 그로부터 20000떨어진 주소에서 시작하여 3F0만큼 공간을 사용합니다.

따라서 해당 PE 파일에서 IAT의 실제 사용 주소 범위는 00007ff686e30000 ~ 00007ff686e303F0 입니다.

해당 범위(IAT) 전체를 덤프하여 확인하면 MessageBoxW 함수의 포인터 주소와 실제 주소가 확인됩니다.

Last updated