-->

DLL 인젝션을 통한 지뢰찾기 API 후킹 (Hooking) 구현

저번 포스팅에서는 지뢰찾기에서 클릭시 발생하는 이벤트핸들러 호출 부분 코드를 후킹해서 모든 지뢰가 표시되는 함수 실행이 되도록 해보았다. 이번에는 클릭 이벤트 핸들러 중간에 호출하는 win32u.dll의 NtUserSetCapture() API를 후킹해보도록 한다.

 

- 빌드 : VisualStudio 2015

- 환경 : Windows10 x64

 

 

후킹이 성공하면 아래와 같이 모든 지뢰가 표시되기 때문에 지뢰들을 피해서 게임을 진행할 수 있다 :)

 

 

타겟 API 선정

타겟 API는 win32u.dll의 NtUserSetCapture()로 정했는데, 클릭시 호출되는 클릭 이벤트핸들러를 트레이싱하다보면 마우스의 움직임을 감지하는 SetCapture함수를 호출(내부에서 NtUserSetCapture 호출)하는 것을 볼 수 있다. 이 win32u.dll의 NtUserSetCaptureAPI를 후킹해서 클릭 이벤트가 발생하면 게임 종료 직전에 모든 지뢰를 보여주는 함수 sub_1002F80가 실행되도록 해볼것이다.

 

 

 

 

참고로 클릭이벤트 함수와 지뢰를 보여주는 함수(sub_1002F80)는 이전 포스팅을 보면 알 수 있지만, 심볼을 못구해서 그냥 노가다로 찾았다.

 


DLL 인젝션을 통한 코드 후킹 (Code Hooking) 구현

 

DLL 인젝션을 통한 코드 후킹 (Code Hooking) 구현

저번 포스팅에서 CreateRemoteThread를 통해 지뢰찾기.exe에 메시지창을 띄우는 스레드를 실행시키는 DLL을 인젝션해보았다. 이번에는 DLL에 메시지창을 띄우는 스레드를 실행시키는 코드 대신에 특정 코드를 후킹..

liveyourit.tistory.com

 

 

 

API 후킹 코드 구성

참고로 sub_1002F80는 인자로 0xA를 받기 때문에 push 0xA도 같이 넣어주어야 하고 남는 바이트는 0x90(nop)으로 채워준다. 그리고 아래처럼만 코드를 변경하면 1002F80 함수 호출 후 리턴 시 call edx를 하게 되는데 구성된 인자가 맞지 않아서 세그폴트가 나기 때문에 nop으로 채워주었다. ( 총 12바이트 : [6A 0A 90 90 90 E8 56 FF 2D 8A 90 90] )

 

 

 

페이지 권한 확인

API 후킹을 하려면 코드를 패치해야 하기 때문에 해당 주소 영역에 WRITE 권한이 있어야 하는데 코드 영역이므로 당연하게도 WRITE 권한이 없다. 따라서 VirtualProtect 함수를 사용해 WRITE 권한을 주는 작업이 필요하다.

 

 

 

API 후킹을 수행하는 DLL 코드

DLLMain에서는 DLL이 로딩될 시 CreateThread로 APIHooking 스레드를 실행시킨다. APIHooking은 먼저 후킹이 필요한 12바이트에 대해 VirtualProtect를 사용해서 WRITE 권한을 추가한 후 sub_1002F80이 실행되도록 EP부터 한바이트씩 코드를 변경하게 된다. 그리고 코드를 전부 쓴 후에는 변경한 권한을 원래대로 복구한다.

 

#include "stdio.h"
#include "windows.h"

DWORD WINAPI APIHooking(LPVOID lParam)
{
	HMODULE hMod;
	LPVOID TargetAddr;
	HANDLE hThread = NULL;
	DWORD OldProtect = 0;

	// NtUserSetTimer API 주소 구하기
	hMod = GetModuleHandle(TEXT("win32u.dll"));
	TargetAddr = (LPTHREAD_START_ROUTINE)GetProcAddress(hMod, "NtUserSetCapture");

	// 12바이트 권한 PAGE_READWRITE로 변경
	VirtualProtect(TargetAddr, 12, PAGE_READWRITE, &OldProtect);

	// win32u.NtUserSetCapture API EP 코드 후킹
	*((LPBYTE)TargetAddr + 0) = 0x6A;
	*((LPBYTE)TargetAddr + 1) = 0x0A;
	*((LPBYTE)TargetAddr + 2) = 0x90;
	*((LPBYTE)TargetAddr + 3) = 0x90;
	*((LPBYTE)TargetAddr + 4) = 0x90;
	*((LPBYTE)TargetAddr + 5) = 0xE8;
	*((LPBYTE)TargetAddr + 6) = 0x56;
	*((LPBYTE)TargetAddr + 7) = 0xFF;
	*((LPBYTE)TargetAddr + 8) = 0x2D;
	*((LPBYTE)TargetAddr + 9) = 0x8A;
	*((LPBYTE)TargetAddr + 10) = 0x90;
	*((LPBYTE)TargetAddr + 11) = 0x90;

	// 페이지 권한 복원
	VirtualProtect(TargetAddr, 12, OldProtect, &OldProtect);

	return 0;
}

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
	HANDLE hThread = NULL;

	switch (fdwReason)
	{
		case DLL_PROCESS_ATTACH:
			hThread = CreateThread(NULL, 0, APIHooking, NULL, 0, NULL);
	}
	return TRUE;
}

 

 

DLL 인젝션 코드

DLL 인젝션 코드는 아래 포스팅에서 제작한 코드와 동일한 코드를 사용했다. 인젝션 관련 내용은 아래 포스팅을 참고하길 바란다.

 


CreateRemoteThread를 사용한 DLL 인젝션 구현

 

CreateRemoteThread를 사용한 DLL 인젝션 구현

간단한 32bit exe인 '지뢰찾기.exe'에 스레드 내에서 메시지창을 실행시키는 DLL을 제작해 인젝션하는 인젝터를 제작해보려 한다. 지뢰찾기.exe를 사용한 특별한 이유는 없고 32bit 프로그램이라면 어떤것이든 (아..

liveyourit.tistory.com

 

 

DLL 인젝션을 사용한 API 후킹 결과

클릭이벤트 함수 내부에서 호출되는 API를 후킹했기 때문에 첫 클릭시 모든 지뢰가 보이게 되고 그상태로 게임을 진행할 수 있게 된다.

 

 

댓글

Designed by JB FACTORY