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;
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;
}
{
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 과정 끝
}
{
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 을 하기 위한 기초작업은 다 된겁니다.
'컴퓨터 이야기 > Reverse Engineering' 카테고리의 다른 글
DLL Injection 을 이용한 Win32 API Hooking (1) (0) | 2010.09.07 |
---|---|
Reverse Engineering 카테고리 열었어요. (0) | 2010.07.18 |