
PE 헤더를 파싱하고 가져온 함수 주소를 대상 프로세스 내부의 사용자 지정 후크로 리디렉션하여 IAT(Import Address Table) 후킹을 수행하는 C++ DLL입니다.
후킹은 사용자가 프로그램의 실행 흐름을 리다이렉트할 수 있게 해주는 기법이다. 대부분의 경우 우리는 함수 후킹을 사용한다. 우리는 함수를 우리 자신의 함수로 교체하거나 리다이렉트할 것인데, 이는 매우 유용하며 다양한 사용 사례를 가지고 있다. 후킹에는 여러 가지 방법이 있는데, 여기서는 IAT Hooking을 살펴본다. 이는 Import Address Table의 약자이다. 이는 런타임에 채워지는 큰 테이블에서 함수의 주소를 우리 자신의 주소로 교체하는 것으로 구성된다. 다른 저장소에서 이전에 언급했듯이, 이 코드의 IAT 파싱 부분을 이해하려면 PE Format에 대해 더 읽어보는 것을 권장한다.
다음은 IAT Hooking이 어떻게 작동하는지에 대한 기본 다이어그램이다. 이 예제에서는 악성 코드가 실행된 후 원래 함수가 호출된다. 이 예제에서는 단순히 원래 함수 대신 다른 함수를 호출할 것이다. 이 기법의 장점은 일반적인 detours .text 패치 후킹과 달리 함수의 본문을 수정할 필요가 없다는 것이다. 일반적인 detours .text 패치 후킹은 예를 들어 jmp를 배치하기 위해 함수 시작 부분의 명령어를 변경해야 한다.
실제로는 들리는 것보다 훨씬 간단하다. 우리는 내부적으로 진행하여 일을 더 쉽게 만들 것이다. 즉, 이 저장소는 대상 프로세스에 주입할 수 있는 DLL로 컴파일되며, 내 LoadLibraryA 또는 Manual Mapping 인젝터를 사용하여 대상 프로세스에 주입할 수 있다.
먼저 다음과 같이 대상 프로세스의 PE Headers를 파싱하여 Import Descriptor를 찾는다:
process_base + nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
그런 다음 각 임포트된 모듈을 순회하고, 이 모듈의 각 함수를 순회하며(중첩 루프의 이유), 런타임에 채워진 해당 함수의 주소를 찾을 수 있다. 이 예제에서는 Windows가 GUI의 이벤트를 처리하는 데 사용하는 TranslateMessage를 후킹할 것이다. 따라서 해당 함수의 주소를 찾으면, 우리가 이전에 정의했고 내부이기 때문에 원격 프로세스의 컨텍스트에 존재하는 우리 자신의 함수 주소로 교체한다. 해당 위치에 쓸 권한이 있는지 확인하기 위해 VirtualProtect를 사용하는 것을 잊지 말자.
VirtualProtect(&firstThunk->u1.Function, sizeof(uint64_t), PAGE_READWRITE, &old_protection);
firstThunk->u1.Function = (uint64_t)hookfunction;
보시다시피, notepad가 TranslateMessage를 호출할 때(거의 항상) 우리의 후킹 함수가 실행되어 결국 메시지 박스를 표시한다!
image