CDllInject::CDllInject(){
m_handle = 0;
m_ThreadId = 0;
m_ExitCode = 0;
m_pID = 0; // 데이터를 초기화한다
}
CDllInject::~CDllInject(){
DllCloseProcess(); // DLL을 닫아준다
}
HANDLE CDllInject::DllOpenProcess(DWORD pID){ // 프로세스를 연다
if (m_handle)
DllCloseProcess(); // 열려 있으면 닫는다
m_pID = pID;
m_handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pID); // 프로세스 열기
return m_handle;
}
int CDllInject::DllInject(LPSTR DllPath){
return CreateThreadEx((PROC)GetProcAddress(LoadLibrary("Kernel32.dll"), "LoadLibraryA"), (LPVOID)DllPath, strlen(DllPath));
// DLL을 삽입한다.
}
int CDllInject::DllEject(){
int ret = CreateThreadEx((PROC)GetProcAddress(LoadLibrary("Kernel32.dll"), "FreeLibrary"), (LPVOID)m_ExitCode, sizeof(DWORD), FALSE);
m_ThreadId = 0;
m_ExitCode = 0;
// DLL을 꺼내고 초기화
return ret;
}
int CDllInject::DllClear(){ // 정보를 완전히 초기화시킨다
m_ExitCode = 0;
CloseHandle(m_handle);
m_handle = 0;
m_pID = 0;
m_ThreadId = 0;
return 0;
}
int CDllInject::DllCloseProcess(){
if (m_ExitCode > 1)
DllEject(); // DLL이 삽입되어 있으면 꺼낸다
CloseHandle(m_handle); // 핸들을 닫는다
m_handle = 0;
m_ThreadId = 0; // 초기화
return TRUE;
}
int CDllInject::CreateThreadEx(PROC ThreadMain, LPVOID lpParameter, DWORD nParamSize, BOOL bPtr){
// ThreadMain: LPTHREAD_START_ROUTINE
// lpParameter: 파라메터
// nParamSize: 파라메터가 포인터일 경우 그 크기
// bPtr: 파라메터가 포인터일 때 TRUE
if (m_handle == NULL)
return 0;
LPVOID lpParam;
if (bPtr == TRUE){ // By Reference일 경우에 프로세스가 다르므로 대상 프로세스에 데이터를 써준다
lpParam = VirtualAllocEx(m_handle, NULL, nParamSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE); // 대상 프로세스에 메모리를 확보
if (WriteProcessMemory(m_handle, (LPVOID)lpParam, lpParameter, nParamSize, NULL) == FALSE) // 데이터를 쓴다
return 0;
}
else{ // By Value일 경우
lpParam = lpParameter;
}
m_ThreadId = CreateRemoteThread(m_handle, NULL, NULL, (LPTHREAD_START_ROUTINE)ThreadMain, lpParam, NULL, NULL); // 호출한다
if (!m_ThreadId) return 0;
WaitForSingleObject(m_ThreadId, INFINITE); // 완료될때까지 기다림
GetExitCodeThread(m_ThreadId, &m_ExitCode);
VirtualFreeEx(m_handle, lpParam, NULL, MEM_RELEASE); // 메모리 해제
return m_ExitCode;
}
|