Ok....so here is my problem. I want to release a library where with my dllInjection class, whenever the user instantiates an object, it will automatically perform the injection for the user. The only arguments they need to provide will be the processName, and dllName. Anyways my question is, i understand if i do it this way and i have a possibility of throwing an exception in a constructor, anything allocated manually on the heap,must be deallocated manually as well since the class's destructor will not be executed if u throw an exception in a constructor before it finishes. Well due to this, i realize i need to make processHandle & possibly memoryAddress into objects, so if they manually allocate memory, or handles, they will automatically destroy themself with their destructor when my dllInjection class throws an exception in the constructor.

sorry if the above was confusing! i hope i made it clear. Anyways would anyone happen to have any advice on HOW the design of my processHandle class and possibly memoryAddress class should be constructed! below is my injection code,injection class,and my constructor that is used to create and perform the injection object. Any advice would be greatly appreciated! -thx

class DllInjection
{
	private:
		std::wstring dllName;
		std::wstring processName;
		DWORD processID;

		HANDLE processHandle; 
        LPVOID memoryAddress;

		void isValidProcess(const std::wstring& processName);
		void isValidDll(const std::wstring& dllName);

	public:
		DllInjection(const std::wstring&,const std::wstring&);
		~DllInjection();
		void injectCode();
		void unInjectCode();
};



DllInjection::DllInjection(const std::wstring& processName,const std::wstring& dllName) 
{
	isValidDll(dllName);
	isValidProcess(processName); 

	this->dllName = dllName;                                     
	this->processName = processName;
	memoryAddress = NULL;
	injectCode();
	
	
}




void DllInjection::injectCode()
{

	if ((processHandle = OpenProcess( PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ,0,processID)) == NULL)
	throw InjectionException(GetLastError());
	if ((memoryAddress = VirtualAllocEx(processHandle,NULL,wcslen(dllName.c_str()),MEM_COMMIT,PAGE_READWRITE)) == NULL)
	throw InjectionException(GetLastError());
	if ((WriteProcessMemory(processHandle, memoryAddress, dllName.c_str(),sizeof(dllName),NULL)) == 0)
	throw InjectionException(GetLastError());
	_LoadLibraryEx procAdd = (_LoadLibraryEx)GetProcAddress(GetModuleHandle(L"kernel32.dll"), "LoadLibraryEx");
	if ((CreateRemoteThread(processHandle, NULL, 0, (LPTHREAD_START_ROUTINE)procAdd, (LPVOID)memoryAddress, 0, NULL)) == NULL)
	throw InjectionException(GetLastError());
	return;
}

I'm only going to show you how to implement the processHandle in RAII, the others are for you to do in a similar fashion. You simply wrap the processHandle in a private struct (if you don't need to reuse this struct's code somewhere else in your library). Then, you load the process in its constructor. If it throws, then it will not try to free the process handle, but if it was successfully constructed, it will get destroyed and will free its processHandle upon destruction. That can be done as follows:

class DllInjection
{
  private:
    std::wstring dllName;
    
    
    struct ProcessHandleImpl {
      HANDLE processHandle; 
      DWORD processID;
      std::wstring processName;
      ProcessHandleImpl(const std::wstring& aProcessName);
      ~ProcessHandleImpl();

      void isValidProcess(const std::wstring& aProcessName);
    };
    ProcessHandleImpl processHdl;

    LPVOID memoryAddress;

    void isValidDll(const std::wstring& dllName);

  public:
    DllInjection(const std::wstring&,const std::wstring&);
    ~DllInjection();
    void injectCode();
    void unInjectCode();
};


DllInjection::ProcessHandleImpl::ProcessHandleImpl(const std::wstring& aProcessName) : processHandle(0), processID(/* ??? */), processName(aProcessName) {
  isValidProcess(processName);

  if ((processHandle = OpenProcess( PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ,0,processID)) == NULL)
    throw InjectionException(GetLastError());
};

DllInjection::ProcessHandleImpl::~ProcessHandleImpl() {
  if(processHandle) //this check is not really necessary because processHandle is always non-NULL if the constructor succeeded.
    CloseHandle(processHandle);
};


DllInjection::DllInjection(const std::wstring& processName,const std::wstring& dllName) : processHdl(processName)
{
  isValidDll(dllName);

  this->dllName = dllName;
  memoryAddress = NULL;
  injectCode();	
}

void DllInjection::injectCode()
{
  if ((memoryAddress = VirtualAllocEx(processHdl.processHandle,NULL,wcslen(dllName.c_str()),MEM_COMMIT,PAGE_READWRITE)) == NULL)
    throw InjectionException(GetLastError());
  if ((WriteProcessMemory(processHdl.processHandle, memoryAddress, dllName.c_str(),sizeof(dllName),NULL)) == 0)
    throw InjectionException(GetLastError());
  _LoadLibraryEx procAdd = (_LoadLibraryEx)GetProcAddress(GetModuleHandle(L"kernel32.dll"), "LoadLibraryEx");
  if ((CreateRemoteThread(processHdl.processHandle, NULL, 0, (LPTHREAD_START_ROUTINE)procAdd, (LPVOID)memoryAddress, 0, NULL)) == NULL)
    throw InjectionException(GetLastError());
  return;
}

The others can be done in a similar fashion.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.