C ++ Dll инъекция — Hello world dll работает только тогда, когда внедрен в тот же .exe, который внедряет его

На прошлой неделе я работал над тем, чтобы мое простое приложение для инъекций успешно внедрило dll в другие процессы. Пока, однако, это работало только когда я ввожу dll в сам инжектор. Когда я пытаюсь внедрить в другое приложение, моя функция сообщает об успехе (поток успешно создан, память выделена и записана в цель), но мой dllMain, похоже, не вызывается. Кроме того, код ошибки 0 (ERROR_SUCCESS) определяется как GetLastError(),

При указании targetProcessId как GetCurrentProcess(), диалоговое окно показывает, и RemoteThread успешно выполнен.

Однако, когда я пытаюсь установить targetProcessId для работающего экземпляра calc.exe, ничего не происходит. В другом месте я читал, что вызов MessageBox из DllMain — плохая идея, поскольку его модуль еще не загружен, поэтому я также попытался создать бесконечный цикл в моем DllMain и проверить, увеличилось ли число потоков в calc.exe на 1. Это осталось без изменений.

Это мой первый вопрос о StackOverflow, и я постарался провести как можно больше исследований по этой теме до публикации, но после многих часов мне не повезло. Я, очевидно, новичок в DLL инъекции (я недавно закончил читать книгу Ритчера, Windows через C / C ++). Любая помощь с благодарностью.

Весь мой код компилируется из Visual Studio 2010 для платформы x64.

Вот соответствующий код ниже из моего приложения Injector:

BOOL WINAPI Inject(DWORD processID, PCWSTR sourceDLL)
{
BOOL success = false;
HANDLE targetProcess = NULL, createdThread = NULL;
PWSTR pszLibFileRemote = NULL;
__try
{
std::cout << "Process ID: "<< processID << std::endl;
targetProcess = OpenProcess(
PROCESS_QUERY_INFORMATION | PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION  | PROCESS_VM_WRITE,
FALSE, processID);
if (targetProcess == NULL)
{
std::cout << "ERROR: " << GetLastError();
MessageBox(NULL, L"Unable to open process.", L"Error", MB_OK);
__leave;
}

int cch = 1 + lstrlenW(sourceDLL); //Calculate the number of bytes required for the DLL's path
int cb = cch * sizeof(wchar_t);

pszLibFileRemote = (PWSTR)VirtualAllocEx(targetProcess, NULL, cb, MEM_COMMIT, PAGE_READWRITE);
if (pszLibFileRemote == NULL)
{
MessageBox(NULL, L"Could not allocate dll pathname in target process.", L"Error", MB_OK);
__leave;
}

if (!WriteProcessMemory(targetProcess, pszLibFileRemote, (PVOID) sourceDLL, cb, NULL))
{
MessageBox(NULL, L"Could not write dll pathname in target process.", L"Error", MB_OK);
__leave;
}

PTHREAD_START_ROUTINE pfnThreadRtn = (PTHREAD_START_ROUTINE) GetProcAddress(GetModuleHandle(_T("Kernel32")), "LoadLibraryW");

if (pfnThreadRtn == NULL)
{
MessageBox(NULL, L"Error finding LoadLibraryW address.", L"Error", MB_OK);
__leave;
}

createdThread = CreateRemoteThread(targetProcess, NULL, 0, pfnThreadRtn, pszLibFileRemote, 0, NULL);
if (createdThread == NULL)
{
__leave;
}

WaitForSingleObject(createdThread, INFINITE);
success = true;

}
__finally { // Now, we can clean everything up
// Free the remote memory that contained the DLL's pathname
if (pszLibFileRemote != NULL)
VirtualFreeEx(targetProcess, pszLibFileRemote, 0, MEM_RELEASE);
if (createdThread != NULL)
CloseHandle(createdThread);
if (targetProcess != NULL)
CloseHandle(targetProcess);
}

return success;
}
int _tmain(int argc, _TCHAR* argv[])
{
PCWSTR srcDll = L"test.dll"; //dll in the same directory as the injector.exe, its code is specified below.
DWORD processID = "768"; //Hard coded process ID of a running calc.exe. When I change this line to GetCurrentProcessId() the messagebox from my dll shows.
if (Inject(processID, srcDll))
{
std::cout << "Injection successful" << std::endl;
Eject(processID, srcDll); //This detaches the dll by calling freelibrary from a remote thread. This function was omitted from this response to keep things relavent.
}
system("PAUSE");
return 0;
}

А вот код для моего простого helloworld test.dll:

#include "stdafx.h"#include <Windows.h>
#include <tchar.h>
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD  ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
MessageBox(NULL, L"HULLO.", L"DLL", MB_OK);
break;
case DLL_THREAD_ATTACH:
MessageBox(NULL, L"HULLO.", L"DLL", MB_OK);
break;
case DLL_THREAD_DETACH:
MessageBox(NULL, L"HULLO.", L"DLL", MB_OK);
break;
case DLL_PROCESS_DETACH:
MessageBox(NULL, L"HULLO.", L"DLL", MB_OK);
break;
}
return TRUE;
}

Решено: каталог внедренной dll должен быть указан либо относительно целевого процесса, либо как полный путь, чтобы целевой процесс мог его найти. (У меня было это в директории моего Инжектора, которая вызывала проблему загрузки — calc не знал, где это было.)

3

Решение

PCWSTR srcDll = L"test.dll"; //dll in the same directory as the injector.exe

Так как вы выполняете LoadLibraryW() в целевой программе, а не в инжекторе, он не знает, что такое «тот же каталог, что и инжектор» — он просто ищет его в стандартных каталогах, документированных на MSDN.

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

4

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector