title: Manual DLL injection
body: <p>I am trying to learn some manual dll injection, but cant seem to get the execution of the dlls code to work. I am new to Windows C++ so any tips on improving my code is appreciated. I have also only posted the relevant code.</p>
  
  <p>Injector program:</p>
  
  <pre class="lang-cpp prettyprint-override"><code>hProcess = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE, FALSE, getPID(TARGET_NAME));
  
  DWORD gotDLL = GetFullPathName(DLL_NAME, MAX_PATH, dllPath, NULL);
  
  hFile = CreateFile(dllPath, GENERIC_READ, NULL, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  
  dllFileSize = GetFileSize(hFile, NULL);
  memAddrForDLL = VirtualAllocEx(hProcess, NULL, dllFileSize, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
  
  loadedDLL = HeapAlloc(GetProcessHeap(), NULL, dllFileSize);
  
  // Load dll into allocated memory in current process
  ReadFile(hFile, loadedDLL, dllFileSize, &amp;bytesRead, NULL))
  
  // Find offset of dll entry point
  IMAGE_NT_HEADERS* pOldNtHeader = reinterpret_cast&lt;IMAGE_NT_HEADERS*&gt;(reinterpret_cast&lt;BYTE*&gt;(loadedDLL) + reinterpret_cast&lt;IMAGE_DOS_HEADER*&gt;(loadedDLL)-&gt;e_lfanew);
  IMAGE_OPTIONAL_HEADER* pOldOptHeader = &amp;pOldNtHeader-&gt;OptionalHeader;
  
  entryPointOffset = pOldOptHeader-&gt;AddressOfEntryPoint;
  
  // Load dll into allocated memory in target process
  WriteProcessMemory(hProcess, memAddrForDLL, loadedDLL, bytesRead, NULL)
  
  LPTHREAD_START_ROUTINE entryPoint = (LPTHREAD_START_ROUTINE)((unsigned __int64)memAddrForDLL + entryPointOffset);
  
  CreateRemoteThread(hProcess, NULL, NULL, (LPTHREAD_START_ROUTINE)LoadLibrary, entryPoint, NULL, NULL)
  </code></pre>
  
  <p>DLL:</p>
  
  <pre class="lang-cpp prettyprint-override"><code>DWORD WINAPI OnDllAttach(LPVOID base){
      typedef void func(void);
      func* f = (func*)0x00007FF605EC5835;
      f();
      FreeLibraryAndExitThread(static_cast&lt;HMODULE&gt;(base),1);
  }
  
  BOOL WINAPI OnDllDetach(){
      return TRUE;
  }
  
  BOOL WINAPI DllMain(_In_ HINSTANCE hinstDll,
                      _In_ DWORD fdwReason,
                      _In_opt_ LPVOID lpvReserved){
      typedef void func(void);
      func* f = (func*)0x00007FF605EC5835;
      f();
      switch(fdwReason) {
          case DLL_PROCESS_ATTACH:
              DisableThreadLibraryCalls(hinstDll);
              CreateThread(nullptr, 0, OnDllAttach, hinstDll, 0, nullptr);
              return TRUE;
          case DLL_PROCESS_DETACH:
              if(lpvReserved == nullptr)
                  return OnDllDetach();
              return TRUE;
          default:
              return TRUE;
      }
  }
  </code></pre>
  
  <p>Target program contains this function:</p>
  
  <pre class="lang-cpp prettyprint-override"><code>void printer(){
      cout &lt;&lt; "test" &lt;&lt; endl;
  }
  </code></pre>
  
  <p>My injector produces the following output</p>
  
  <pre><code>1. Attempting to attatch to process target.exe
  --- Got target.exe PID: 14640
  --- Got target.exe Handle: 0x0000000000000084
  2. Attempting to allocate memory
  --- Found dll: D:\projects\injector\hack.dll
  --- Got hack.dll Handle: 0x0000000000000088
  --- Allocated memory in target.exe at 0x0000017BEB690000
  3. Attempting to copy dll to target.exe
  --- Allocated memory at 0x00000226A060FFE0
  --- Loaded hack.dll in current process at 0x00000226A060FFE0
  --- hack.dll is a valid DLL
  --- Loaded hack.dll into target.exe at 0x0000017BEB690000
  4. Attempting to execute dll
  --- Offset from start of file to entrypoint: 0x3cf6
  --- Began execution of hack.dll in target.exe at 0x0000017BEB693CF6
  </code></pre>
  
  <p>Using Ghidra I can confirm this is the correct offset for the dll entrypoint. But when running my injector nothing happens in the target process, I've also tried using cout to print a message from the dll but I get nothing(I dont think it would even work because nothing has been relocated)</p>
  
  <p>I was using</p>
  
  <pre class="lang-cpp prettyprint-override"><code>CreateRemoteThread(hProcess, NULL, NULL, entryPoint, memAddrForDLL, NULL, NULL)
  </code></pre>
  
  <p>before as the 4th parameter is called lpStartAddress and I thought this should want the entry point but it was causing the target process to crash and every example I saw used the way I currently have it in my code.</p>
  
  <p>In my dll I am calling the function in the target process by the address.</p>
  
  <p>EDIT: I am testing this on my own console application.</p>