Подтвердить что ты не робот

С++ Запрос MSVCP110D.dll, даже если статические ссылки

Я создал метод инъекции dll на моей машине на С++, который отлично работает, когда я пытаюсь вставить определенную DLL в игру. Однако, когда я запускаю программу на моем компьютере-друге (где распространяются распространяемые компоненты Visual Studio, я не предупреждаю, что мне нужен MSVCR и т.д. (Распространяемые).
Поэтому я собрал в режиме выпуска следующий параметр в Visual Studio 2012: Библиотека времени выполнения: многопотоковая /MT . Теперь, когда я запускаю его на своего друга Я предупреждаю, что мне нужна только библиотека MSVCP110D.dll (странно, запрашивая отладочную версию) (нет антивируса, и UAC отключен). Я скопировал запрошенную библиотеку вручную в пути выпуска и все еще не работаю.

В чем проблема?

Это код инъекции, который я сделал:

    #include <Windows.h>
    #include <iostream>
    #include <stdio.h>
    #include <string>
    #include <TlHelp32.h>

class process
{
private:
     HWND hProcWnd       ;
     DWORD id            ;
     LPCWSTR lpWindowName ;

     struct PPARAM 
     {
        DWORD pId   ;
        HWND  pHwnd ;
     };
public:
process(string lpProcessName)
{
    HANDLE process_list = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
    PROCESSENTRY32  lcProcess;
    PPARAM pParam;

    pParam.pHwnd     = nullptr;
    lcProcess.dwSize = sizeof(PROCESSENTRY32);
    do {
        char ch[260];
        char DefChar = ' ';
        WideCharToMultiByte(CP_ACP,0,lcProcess.szExeFile,-1,ch,260,&DefChar, NULL);
        string ss(ch);

        if(ss == lpProcessName)
        {
            id = lcProcess.th32ProcessID;
            pParam.pId = id;
            EnumWindows(enumCallback , (LPARAM)&pParam);
            break;
        }
    }while(Process32Next(process_list,&lcProcess));     

    hProcWnd = pParam.pHwnd;
}

static BOOL CALLBACK enumCallback(HWND hWnd , LPARAM lParam)
 {
     DWORD    _tId = 0;
     PPARAM  &pData = *(PPARAM*)lParam;
     GetWindowThreadProcessId(hWnd , &_tId);

     if(_tId != pData.pId)
     {
        return 1;
     }

     pData.pHwnd = hWnd;
     return 0;
 }
int inject(string lpLibraryPath)
{
    if(hProcWnd == nullptr)
    {
        printf(ERROR_HWND_INEXISTENT);
        return 0;
    }

    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)
    {
        printf("\nCouldn't write data to process : %s , error code : %s\n" , lpLibraryPath.c_str() , GetLastError());
        return 0;
    }

    CreateRemoteThread(hProc, 0, 0, (LPTHREAD_START_ROUTINE)LoadLibraryAddr, paramAddr, 0, 0);
    CloseHandle(hProc);
    return 1;   
}
};

Вот основная функция - здесь я вызываю метод

int main()
{
  string pName;
  string dllPath = "c:\\C++ Dll to inject.dll";

  cout<<"Enter the process to inject the dll into: ";
  getline(cin , pName);

  app::process prc(pName);

  if(prc.inject(dllPath))
  {
        printf("Succesfully injected into process !\n\n\n");
  }
return 0;
}

Я нашел несколько ссылок на stackoverflow, но они не помогли. как msvcp110.dll, как мне обойти это? или Отсутствует "MSVCP110D.dll" на вашем компьютере ". вопрос

4b9b3361

Ответ 1

странно, запрашивая отладочную версию

Сообщает вам, что вы сделали неправильно, вы случайно скопировали сборку Debug из DLL вместо сборки Release. Поскольку вы только изменили настройку для сборки Release, она все равно требует msvcp110d.dll. В целом разумно изменить такую ​​настройку для всех конфигураций и всех платформ. Это утомительно, поэтому его часто пропускают.

Я скопировал запрошенную библиотеку вручную в пути выпуска и все еще не работаю

Правильно, это не сработает, поскольку вы ввели DLL. Другой процесс. Поэтому, когда он загружен, каталог установки для игры ищет файл, а не каталог, в котором установлена ​​ваша утилита.

Ответ 2

Вашему другу нужен Visual-C++ Redistributables, чтобы правильно запустить инжектор и загрузить DLL. Однако

После Injection, dll пытается LoadLibrary (если GetModuleHandle не удается) DLL CRT. Их очень много!

У вас есть несколько вариантов:

  • Включите необходимые DLL внутри вашего Инжектора (Resource, Bytecode и т.д.) и напишите их в каталог , где игра запущена с

  • Загрузите библиотеки DLL с сервера в Интернете и поместите их в каталог , где игра запускается из

  • Статическая привязка CRT (к инъецированной DLL) также работает, но вы также должны быть уверены, что получаете все зависимости!

Причина, по которой вам нужно иметь нужные DLL в папке, в которой запускается игра, заключается в том, что вызов LoadLibrary будет явно указан из самого Game.exe, и он будет искать только DLL в этом каталог.

Вы можете присоединить отладчик Runtime-debugger, такой как WinDbg, к инъецированной DLL, установить точку останова в точке входа DLL (где бы она ни была). Затем проверьте, какие вызовы LoadLibrary/GetModuleHandle выполняются при загрузке вашей DLL, это даст вам подсказку о том, какие DLL необходимы!

Проблема здесь в том, что у вашего друга нет установленного Visual-C++ Redistributables, многие из файлов CRT также имеют свои собственные зависимости! У вашего инжектора должен быть Win-Installer, который, в свою очередь, устанавливает распространяемый MSI с веб-сайта Microsoft, метод, который адаптировали многие современные игры (при установке).

Ответ 3

Попробуйте выполнить настройки вашего проекта

  • Библиотека времени выполнения C/С++: многопотоковая /MT - как вы уже знаете.

  • Генерация кода C/С++ → Основные проверки времени выполнения → "По умолчанию", если что-либо еще в ваших настройках.

  • Linker- > Manifest File- > Generate Manifest "No"

  • Инструмент манифеста- > Ввод и вывод → Вставить манифест → "НЕТ".

    1. Восстановите свое приложение в режиме выпуска и проверьте.

также использовать и проверять с помощью виджета Dependency, чтобы найти, какая DLL связывается с вашей DLL-библиотекой EXE.