티스토리 뷰
[Reversing] Detours 을 이용한 Windows API 후킹 2 (Feat. CreateRemoteThread를 이용한 DLL Injection)
ch4njun 2020. 2. 28. 01:29저번 포스팅에서는 Detours Library을 이용해서 실행되지 않은 Process에 대해서 DLL을 주입하여 Windows API Hooking하는 실습을 진행했다. 그러나, 실제 이렇게 실행되지 않은 Process에 대해서 DLL을 주입하는 경우는 생각보다 많지 않을 것 같다. 그래서 이번 포스팅에서는 실행중인 Process에 DLL을 Injection해 Hooking을 진행할 수 있는 방법에 대해 소개해보고자 한다.
[ DLL Injection ]
DLL Injection 기법에는 여러가지 기법이 있겠지만 내가 사용한 방법은 CreateRemoteThread API를 이용한 방법이다. 친구 게임보안 면접질문에서 동작방식이 나왔다고 한다..? (TMI)
Injection을 진행하는 코드는 아래와 같다.

CreateRemoteThread API를 통해 LoadLibraryA API를 실행하는 과정이다.
- OpenProcess
- VirtualAllocEx
- WriteProcessMemory
- GetModuleHandle
- GetProcAddress
- CreateRemoteThread
- WaitForSingleObject
순서대로 진행되며 세부적인 동작과정은 아래와 같다.
OpenProcess : Argument로 주어진 PID를 통해 해당 Process의 HANDLE을 획득한다.
VirtualAllocEx : 해당 Process의 메모리에서 읽고 쓸수 있는 DllName 길이 만큼의 공간을 요청하고,
그에 해당하는 주소를 반환받아 LPVOID 변수에 저장한다.
WriteProcessMemory : 해당 Process의 특정 메모리주소에 DllName을 작성한다.
특정 메모리 주소는 VirtualAllocEx에서 할당받은 주소로 사용한다.
GetModuleHandle : 해당 DLL의 Module을 획득한다.
GetProcAddress : 해당 DLL에서 LoadLibraryA 라는 이름을 가지는 API 주소를 획득한다.
CreateRemoteThraed : LoadLibraryA를 실행하는데, 인자를 아까 할당받은 메모리 주소로한다.
그 메모리 주소에는 내가 Injection하고자하는 DLL의 경로가 저장되어 있다.
WaitForSingleObject : 이 Process를 CreatRemoteThread로 생성해준 Thread가
종료될 때 까지 대기한다.
해당 Process에서 DLL Injection을 해제하는 코드는 아래와 같다.

CreateRemoteThread API를 통해 FreeLibrary API를 호출하는 것은 DLL Injection에서 LoadLibrary API를 호출하는 것과 매우매우 동일하다. 그러나, FreeLibrary에서 사용하는 첫 번째 인자 즉, 내가 Injection한 DLL의 주소를 찾는 과정이 추가된다.
CreateToolhelp32Snapshot API를 통해 찾아나가는 과정은 우선 기억하도록 하자.

main 함수에서는 간단하게 사용법에 따른 Injection/UnInjection만 구분해줬다.
그럼 한번 사용해보자 !!
우선 이전 예제에서 사용했던 crackme3.exe를 실행하고 ProcessExplorer를 확인해보자.

현재 Load된 DLL목록을 주욱 한번 살펴본 뒤 위에서 작성한 DLL Injection 코드를 실행해보자. 여기서 crackme3.exe의 PID를 확인한 후 DLL Injection 코드를 실행할 때 인자로 전달해 주어야 한다.

-i 옵션을 주어 15780을 PID로 가지는 Process에 해당 DLL을 Injection했다.
해당 실행파일을 실행하자마자 Process Explorer에 ch4njun_sleep.dll이 정상적으로 Injection 된 것을 확인할 수 있다. 정상적으로 Process에 Load되었기 때문에 자동적으로 해당 DLL의 DllMain이 수행된다.
해당 DLL파일은 이전 포스팅에서 사용했던 코드와 완전히 동일하며, Detours Library를 사용해 MessageBoxA API의 API Hooking을 진행하는 코드이다.

그러나 주의해야 할 점은 실행되지 않은 Process에 Hooking할 때와 달리 26번 라인의 DisableThreadLibraryCalls API를 반드시 호출해 주어야 한다. 이거 때문에 오지게 삽질함..ㅠ

그렇게 DLL Injection이 성공하면 자연스럽게 Hooking에도 성공되며 두 번째 MessageBox부터는 내가 원하는 Hooking 함수가 호출되는 것을 확인할 수 있다.
'Reversing > Concept' 카테고리의 다른 글
[Reversing] DLL Injection (0) | 2020.03.05 |
---|---|
[Reversing] Code Injection (0) | 2020.03.04 |
[Reversing] Detours을 이용한 Windows API 후킹 (0) | 2020.02.27 |
[Reversing] UPackPE ( Feat. 나뭇잎 ) (0) | 2020.01.14 |
[Reversing] PE 파일의 재배치 ( Feat. 나뭇잎 ) (0) | 2020.01.14 |