DLL Injection 을 이용한 Win32 API Hooking (2)

컴퓨터 이야기/Reverse Engineering 2010. 9. 7. 02:22

이전 글과 이어서 이번엔 그냥 단순히

다른 프로세스에 DLL 파일을 집어넣는 작업을 해보겠습니다.

DLL 파일은 아무 DLL 파일이든지 상관없으니까


#include <windows.h>
#define MB_OUT MB_OK
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
 HANDLE hThread = NULL;
 switch( fdwReason )
 {
  case DLL_PROCESS_ATTACH :
   MessageBoxA(0, "dll 진입", "dll 진입", MB_OUT);
   break;
 }
 return TRUE;
}
 

DLL 프로젝트로 다음과 같은 코드를 넣고 컴파일을 합니다. 여기서 나온 파일을 dllproject.dll 라고 치고
c:\dllproject.dll 로 옮깁니다.

이제 이 dll 파일을 넣을 타겟 프로그램을 설정하여야 하는데. 이걸로 합니다.

DLL Injection 의 개요는 다음과 같습니다.
#1 타겟프로그램의 적당한 곳에 메모리를 할당한 후 dll 경로를 저장합니다. ("c:\\dllproject.dll" 라는 문자열)
#2 메모리에 맵핑되어있는 kernel32.dll 의 LoadLibraryA 함수의 주소를 구합니다.
#3 타겟 프로그램에 스레드를 생성시켜 LoadLibraryA 함수의 인자로 dll 경로가 전달되게 합니다.
--<1> 스레드를 생성시킬 때 스레드 함수 주소로 #2 에서 구한 LoadLibraryA 의 주소를 넣습니다.
--<2> 인자로 타겟프로그램안에 저장되어있는 "c:\\dllproject.dll" 라는 문자열을 인자로 넘깁니다.

코드로 보면 확실해집니다.

#include <cstdio>
#include <windows.h>
#include <tlhelp32.h>
#include <tchar.h>

// DLL Inject : 다른 프로세스의 주소 공간에 특정 DLL을 넣는다.
void DllInject(DWORD pid, char* path); // processid 와 dll 경로를 받음
 
int main()
{

 HWND hNotepad = FindWindow("ThunderRT6FormDC", 0); // "ThunderRT6FormDC" 인 클래스를 찾아서 ~
 DWORD pid;
 GetWindowThreadProcessId(hNotepad, &pid); // hWnd 로 부터 processid 얻음.
 DllInject(pid, "C:\\dllproject.dll");
 return 0;
}


void DllInject(DWORD pid, char* path)
{
//#1 과정 진행
hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0, pid);
 void* dllpath = VirtualAllocEx(hProcess, 0, // 원하는 주소(0은 알아서 해달라)
  _tcslen(path)+1, // 크기
  MEM_RESERVE | MEM_COMMIT, // 예약과 동시 확정
  PAGE_READWRITE);
 // 이제 DLL의 경로를 담을 문자열 복사
 // WriteProcessMemory()는 다른 프로세스 주소 공간에 무언가를 쓸 수 있다.
 // 타겟의 주소공간에 메모리를 할당하고, DLL의 경로를 복사해준다.
 // VirtualAlloc은 가상 메모리를 할당하는 API이지만, Ex가 붙으면 다른 프로세스의 주소공간을 할당할 수 있다.
 DWORD len;
 WriteProcessMemory(hProcess, dllpath, path, _tcslen(path)+1, &len);
//#1 과정 끝

//#2 과정 진행
 HMODULE hDll = GetModuleHandle("kernel32.dll"); // kernel32.dll 모듈의 핸들값을 GetModuleHandle로 구한다.
 PTHREAD_START_ROUTINE loadlibthread = (PTHREAD_START_ROUTINE)GetProcAddress(hDll, "LoadLibraryA");
//#2 과정 끝

//#3 과정 진행
 // 타겟에 새로운 스레드를 만든다.
 // CreateRemoteThread는 다른 프로세스에 스레드를 생성시킨다.
 HANDLE hThread = CreateRemoteThread(hProcess, // 타겟 핸들
  0, 0, 
  loadlibthread, dllpath, // 함수, 인자
  0, 0);
 CloseHandle(hThread);
 CloseHandle(hProcess);
//#3 과정 끝
}


네 c:\dllproject.dll 위치시키고 프로그램을 실행시켰더니 예상대로 이렇게 뜹니다.





그리고 Process Explorer 로 확인해본 결과 메모리에 이제 dllproject.dll 가 떠있군요.

이로써 Win32 API Hooking 을 하기 위한 기초작업은 다 된겁니다.
: