본문 바로가기
코드/c/c++

dll injection 하기 관련 코드

by WeZZ 2008. 9. 24.



 

class CDllInject{
   private:
      HANDLE m_handle;   // 대상 프로세스의 핸들
      HANDLE m_ThreadId;  // 리모트 쓰레드의 핸들
      DWORD m_ExitCode;  // 삽입한 DLL의 인스턴스
      DWORD m_pID;    // 대상 프로세스의 ID
   public:
      HANDLE DllOpenProcess(DWORD pID); // 프로세스를 연다
      int DllInject(LPSTR DllPath);     // DLL 삽입
      int DllEject();           // DLL 해제
      int DllCloseProcess();        // 프로세스를 닫는다 (DLL 해제)
      int DllClear();      // 정보 초기화 (DLL을 빼고 싶지 않을 때 사용)
      int CreateThreadEx(PROC ThreadMain, LPVOID lpParameter, DWORD nParamSize, BOOL bPtr = TRUE);
 // CreateRemoteThread 참고. 인수 bPtr는, lpParameter가 By Reference일 경우 TRUE, By Value일 경우 FALSE
      inline operator HANDLE(){
         return m_handle;
      }
 
      CDllInject();
      virtual ~CDllInject();
};



 

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;
}



 

CDllInject dll;

dll.DllOpenProcess(dwProcessId);

dll.DllInject("MyDll.dll"); //전체 풀 경로를  넣어 줘야 한다.

 





출처 : Tong - yjh811220님의 [ C, C++ ]통