13

I created a library injection method on my machine in C++ which works very well when I try to inject a specific dll into a process. However, when I run the program on my friend's computer (where Visual Studio's redistributables are not installed), I am warned that I need MSVCR, etc ... (the redistributables).

So I compiled in the release mode with the following setting in Visual Studio 2012 : Runtime Library : Multi-threaded /MT. Now when I run it on my friend's machine I am warned that I need only the library MSVCP110D.dll ( weird, asking for the debug version) (there is no antivirus, and UAC is disabled ). I copied the requested library manually in the release path and still wont work.

This is the injection code i made :

int inject(string lpLibraryPath)
{
    HANDLE      hProc;
    LPVOID      paramAddr;
    HINSTANCE   hDll;

    hDll = LoadLibrary(L"KERNEL32");

    fpLoadLibrary LoadLibraryAddr = (fpLoadLibrary)GetProcAddress(hDll, "LoadLibraryA");

    hProc = OpenProcess(PROCESS_ALL_ACCESS, false, id);

    paramAddr = VirtualAllocEx(hProc, 0, strlen(lpLibraryPath.c_str()) + 1, MEM_COMMIT, PAGE_READWRITE);

    if(WriteProcessMemory(hProc, paramAddr, lpLibraryPath.c_str(), strlen(lpLibraryPath.c_str()) + 1, NULL) == NULL)
    {
        return 0;
    }

    CreateRemoteThread(hProc, 0, 0, (LPTHREAD_START_ROUTINE)LoadLibraryAddr, paramAddr, 0, 0);

    CloseHandle(hProc);

    return 1;   
}
};

I found some references on stackoverflow but they were of no help . like msvcp110.dll, how do I get around it? or Fixing the "MSVCP110D.dll is missing from your computer" issue

Reznicencu Bogdan
  • 902
  • 2
  • 11
  • 28
  • maybe ... the machine is protected by admin rights .. –  Jan 04 '17 at 18:58
  • 1
    Note that you are not checking whether `OpenProcess` is correctly opening the process, (maybe it fails), you use a very heavy access rights parameter `PROCESS_ALL_ACCESS`, maybe try using `PROCESS_VM_WRITE` - `if(hProc == NULL) { MessageBox(0, "Couldn't open process", "Error", MB_ICONERROR); }` try this. Getting your friend to run the program with admin rights might be a good tip too. – Vinícius Jan 04 '17 at 19:07
  • Yes i tried with admin rights ... i forgot however to check if OpenProcess fails ... I will check . Thank you for the sugestion. – Reznicencu Bogdan Jan 04 '17 at 19:15
  • 2
    @ViniyoShouta - `PROCESS_VM_WRITE` not enough here - need `PROCESS_VM_OPERATION|PROCESS_VM_WRITE|PROCESS_CREATE_THREAD` – RbMm Jan 04 '17 at 19:41
  • you compile both `exe` and `dll` with static linked CRT ? this is your `exe` or `dll` depended from `MSVCP110D.dll` ? – RbMm Jan 07 '17 at 15:20
  • @RbMm : well , i compile only the exe this way .... – Reznicencu Bogdan Jan 07 '17 at 15:24
  • 2
    but you must and dll compile also with static CRT :) – RbMm Jan 07 '17 at 15:26
  • thank you .... i completeley forgot about it .... ? I forgot i replaced the dll and thought it was already compiled the right way .. – Reznicencu Bogdan Jan 07 '17 at 15:31
  • You may find that static linking doesn't work with a MFC DLL. You end up with two copies of the MFC runtime, and there are static structures like window tables that won't be shared between them. – Mark Ransom Jan 07 '17 at 16:24
  • 1
    @MarkRansom This `MSVCP110D.dll` is not MFC, just one part of CRT. – Chris O Jan 07 '17 at 17:27
  • That doesn't matter, my point still stands. If both the DLL and Exe use MFC, you might run into problems. I was reading your last comment to say that the base problem was that you forgot to change the setting or recompile the DLL, and that part was solved. – Mark Ransom Jan 07 '17 at 17:52

3 Answers3

10

weird , asking for the debug version

Tells you what you did wrong, you accidentally copied the Debug build of the DLL instead of the Release build. Since you only changed the setting for the Release build, it still requires msvcp110d.dll. It is in general wise to change such a setting for all configurations and all platforms. Tedious, so it often gets skipped.

I copied the requested library manually in the release path and still wont work

Right, that cannot work since you injected the DLL. A different process. So when it is loaded, the install directory for the game is searched for the file, not the directory where your utility is installed.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • *"change such a setting for* all *configurations and* all *platforms. Tedious, so it often gets skipped."* - Not really tedious, since the project properties GUI offers *"All Configurations"* and *"All Platforms"* filters. The tedious part usually was settings the appropriate filters. A lot less tedious now, since the GUI *does* remember settings in between invocations. – IInspectable Jan 09 '17 at 19:13
3

Your friend needs the Visual-C++ Redistributables in order to properly run your injector, and for the DLL to be loaded. However

After Injection, the dll is trying to LoadLibrary (if GetModuleHandle fails) the CRT dlls. There are a lot of them!

You have some options:

  1. Include the required DLLs inside your Injector (Resource, Bytecode, etc) and write them to the directory where the game is run from

  2. Download the DLLs from a server on the internet and put them in the directory where the game is run from

  3. Statically linking the CRT (to the injected DLL) also works, but you have to make sure you get all dependencies too!

The reason you need to have the required DLLs in the folder where the game is run from is because the LoadLibrary call will be made explicitly from the Game.exe itself, and it will only be looking for the DLLs in that directory.

You can choose to attach a Runtime-debugger such as WinDbg to the injected DLL, set a breakpoint at the DLL entry-point (wherever it is for you). Then check what sort of LoadLibrary/GetModuleHandle calls are made when your DLL is loaded, this will give you a hint as to what DLLs are required!

The problem here is because your friend doesn't have the Visual-C++ Redistributables installed, many of the CRT files also have dependencies of their own! Your injector will have to have a Win-Installer which in turn installs the redistributables MSI from the Microsoft website, a technique which many modern games (at install time) adapted.

Droopy
  • 124
  • 8
2

Try following on your project settings

  1. C/C++ Runtime Library : Multi-threaded /MT - as you already have.

  2. C/C++ Code Generation -> Basic Run time checks -> "Default" if anything else in your settings.

  3. Linker->Manifest File-> Generate Manifest "No"

  4. Manifest tool->Input and Output -> Embed Manifest -> "NO".

    1. Rebuild your application in Release mode and check.
  5. also use and Check with Dependency walker to find which DLL is linking to your EXE "debug DLL".

RaspiRepo
  • 78
  • 2