CreateRemoteThread() успешно, но ничего не делает
Я пытаюсь ввести DLL (найдено в dll_path[]
и это правильный путь) в целевой процесс, используя CreateRemoteThread()
, К сожалению, полностью ничего не происходит (ожидаемый результат MessageBox()
позвонить с DLL_PROCESS_ATTACH
в результате всплывающее окно). Он работает правильно при использовании с дистанционным инжектором.
Вы можете лечить каждый what()
называть как GetLastError()
а также assert(0)
, Гарантируется, что переменная PID
будет содержать правильный идентификатор процесса (я проверял это много раз). Также ни один из вызовов функций, которые вы видите в коде ниже, не работает. Забавно то, что он работал хорошо, пока я не переписал его с C на более похожий на C++ код, который вы можете увидеть ниже. Я скомпилировал код ниже и код DLL без каких-либо предупреждений. Интересно, где я ошибся? Вот мой код:
int main() {
const WCHAR dll_path[] = L"C:\\myDLL.dll";
const std::wstring process_name = L"target.exe";
const DWORD PID = get_PID(process_name);
if (!PID)
what();
HANDLE process = OpenProcess(PROCESS_ALL_ACCESS, false, PID);
if (!process)
what();
FARPROC lib = GetProcAddress(GetModuleHandle(L"kernel32.dll"), "LoadLibraryA");
if (!lib)
what();
LPVOID base = (LPVOID)VirtualAllocEx(process, 0, wcslen(dll_path), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
if (!base)
what();
BOOL good = WriteProcessMemory(process, base, dll_path, wcslen(dll_path), 0);
if (!good)
what();
HANDLE thread = CreateRemoteThread(process, 0, 0, reinterpret_cast<LPTHREAD_START_ROUTINE>(lib), base, 0, 0);
if (!thread)
what();
if (thread) {
std::cout << "Remote thread successfully created." << std::endl;
std::cout << "process ID = " << PID << std::endl;
}
#if 1
CloseHandle(thread);
CloseHandle(process);
#endif
return 0;
}
2 ответа
Как сказал @adelphus, вы используете LoadLibraryA()
когда вы должны использовать LoadLibraryW()
вместо.
Что еще более важно, вы не выделяете достаточно памяти в удаленном процессе для хранения вашей широкой строки пути DLL. VirtualAllocEx()
а также WriteProcessMemory()
оперировать байтами, а не символами. И вам нужно убедиться, что вы выделяете И копируете также нулевой терминатор строки. Так что вам нужно использовать (wcslen(dll_path) + 1) * sizeof(WCHAR)
или вы можете использовать sizeof(dll_path)
так как это статический массив.
Теперь, с этим сказал, так как процедура удаленного потока LoadLibrary()
сам код выхода потока будет возвращаемым значением LoadLibrary()
, Если CreateRemoteThread()
успешно, вы можете позвонить WaitForSingleObject()
ждать завершения потока, а затем вызвать GetExitCodeThread()
получить LoadLibrary()
возвращаемое значение. Если это 0, LoadLibrary()
не удалось, даже если сам поток завершился успешно.
int main() {
const WCHAR dll_path[] = L"C:\\myDLL.dll";
const int dll_path_size = (wcslen(dll_path) + 1) * sizeof(WCHAR); // or sizeof(dll_path);
const std::wstring process_name = L"target.exe";
const DWORD PID = get_PID(process_name);
if (!PID)
what();
HANDLE process = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, FALSE, PID);
if (!process)
what();
FARPROC lib = GetProcAddress(GetModuleHandle(L"kernel32.dll"), "LoadLibraryW");
if (!lib)
what();
LPVOID base = VirtualAllocEx(process, 0, dll_path_size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
if (!base)
what();
BOOL good = WriteProcessMemory(process, base, dll_path, dll_path_size, 0);
if (!good)
what();
HANDLE thread = CreateRemoteThread(process, 0, 0, reinterpret_cast<LPTHREAD_START_ROUTINE>(lib), base, 0, 0);
if (!thread)
what();
std::cout << "Remote thread successfully created." << std::endl;
std::cout << "process ID = " << PID << std::endl;
WaitForSingleObject(thread, INFINITE);
DWORD exitCode = 0;
GetExitCodeThread(thread, &exitCode);
if (exitCode != 0)
std::cout << "DLL loaded successfully." << std::endl;
else
std::cout << "DLL load failed." << std::endl;
#if 1
CloseHandle(thread);
CloseHandle(process);
#endif
return 0;
}
К сожалению, вы не сможете узнать, почему LoadLibrary()
не удалось, если вы не изменили логику удаленного потока, чтобы ввести целую функцию, которая вызывает LoadLibrary()
а также GetLastError()
вместе, а затем возвращает значение из GetLastError()
, Значение из GetLastError()
хранится в локальном потоке Один поток не может прочитать код ошибки другого потока (если вы не покопаетесь в чашах ОС и не прочитаете структуру TIB удаленного потока напрямую).
И, наконец, обязательно учитывайте, является ли целевой процесс 32-битным или 64-битным. Вы не можете внедрить 32-битную DLL в 64-битный процесс, и наоборот.
Ты звонишь LoadLibraryA
с указателем, который указывает на строку Widechar. Ты наверное имел ввиду LoadLibraryW
?