Я пытаюсь написать DLL-инжектор в приложении C # WPF. Я написал DLL Injector ранее в Windows Forms, однако я хотел написать новую программу с нуля. Я много раз писал DLL Injectors на многих других языках (используя традиционный метод VirtualAllocEx
/ WriteProcessMemory
/ CreateRemoteThread
), однако столкнулся с некоторыми специфическими проблемами. Мой DLL Injector сказал, что это успешно, но моя программа тестирования не показала никаких изменений. Я провел некоторое тестирование с Marshal.GetLastWin32Error()
и получил ERROR_FILE_NOT_FOUND в результате для VirtualAllocEx
, WriteProcessMemory
и CreateRemoteThread
. Затем я создал Injector в C ++, чтобы проверить, была ли проблема в C #. Когда я тестировал C ++ DLL Injector, каждый метод выдавал ошибку ERROR_NO_MORE_FILES . Наконец, я скачал свой старый DLL Injector и обнаружил, что он больше не работает.
Я понятия не имею, в чем проблема вообще.
C # Код инжектора:
IntPtr handle = OpenProcess(ProcessAccessFlags.All, false, SelectedProcess.Id);
Console.WriteLine("OpenProcess: " + new Win32Exception(Marshal.GetLastWin32Error()).Message); // This does not fail.
foreach (string files in DLLFiles.Items) // Get the files from the ListView control
{
// Allocate memory
IntPtr address = VirtualAllocEx(handle, IntPtr.Zero, (uint)(files.Length + 1), AllocationType.Commit, MemoryProtection.ExecuteReadWrite);
Console.WriteLine("VirtualAllocEx: " + new Win32Exception(Marshal.GetLastWin32Error()).Message);
// Write in memory
if (address != IntPtr.Zero)
{
bool success = WriteProcessMemory(handle, address, Encoding.ASCII.GetBytes(files), files.Length + 1, out IntPtr lpNumberOfBytesWritten);
Console.WriteLine("WriteProcessMemory: " + new Win32Exception(Marshal.GetLastWin32Error()).Message);
if (success)
{
IntPtr module = LoadLibrary("kernel32.dll"); // Get the module
Console.WriteLine("LoadLibrary: " + new Win32Exception(Marshal.GetLastWin32Error()).Message);
IntPtr LoadLib = GetProcAddress(module, "LoadLibraryA"); // Get the address of the function
Console.WriteLine("GetProcAddress: " + new Win32Exception(Marshal.GetLastWin32Error()).Message);
// Create a remote thread in the target process
IntPtr thread_handle = CreateRemoteThread(handle, IntPtr.Zero, 0, LoadLib, address, 0, out IntPtr lpThreadId);
Console.WriteLine("CreateRemoteThread: " + new Win32Exception(Marshal.GetLastWin32Error()).Message);
if (thread_handle == IntPtr.Zero)
{
Console.Write("[");
Console.ForegroundColor = ConsoleColor.Red;
Console.Write(files);
Console.ResetColor();
Console.WriteLine("] Injection Failed: " + new Win32Exception(Marshal.GetLastWin32Error()).Message);
}
else
{
Console.Write("[");
Console.ForegroundColor = ConsoleColor.Cyan;
Console.Write(files);
Console.ResetColor();
Console.WriteLine("] Injected Successfully.");
}
}
}
}
После запуска консоль сообщила, что инъекция прошла успешно, но вывод ошибок все равно продолжал отображаться:
Системе не удалось найти указанный файл.
Код инжектора C ++:
#include <windows.h>
#include <iostream>
#include <string>
int main() {
DWORD pid = 25860; // Hardcoded for testing purposes.
std::string str;
HANDLE handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid); // Get the process handle
std::cout << handle << std::endl;
std::cout << "Error: " << GetLastError() << std::endl;
LPVOID addr = VirtualAllocEx(handle, NULL, sizeof("C:\\Users\\BenHerebefore\\source\\repos\\InjectionTest\\InjectionTest\\InjectionTest.dll") + 1, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
std::cout << addr << std::endl;
std::cout << "Error: " << GetLastError() << std::endl;
BOOL success = WriteProcessMemory(handle, addr, "C:\\Users\\BenHerebefore\\source\\repos\\InjectionTest\\InjectionTest\\InjectionTest.dll", sizeof("C:\\Users\\BenHerebefore\\source\\repos\\InjectionTest\\InjectionTest\\InjectionTest.dll") + 1, NULL);
std::cout << success << std::endl;
std::cout << "Error: " << GetLastError() << std::endl;
HMODULE module = LoadLibrary("kernel32");
std::cout << module << std::endl;
std::cout << "Error: " << GetLastError() << std::endl;
FARPROC proc = GetProcAddress(module, "LoadLibraryA");
std::cout << proc << std::endl;
std::cout << "Error: " << GetLastError() << std::endl;
HANDLE test = CreateRemoteThread(handle, NULL, 0, (LPTHREAD_START_ROUTINE)GetProcAddress(LoadLibrary("kernel32"), "LoadLibrary"), addr, 0, NULL);
std::cout << test << std::endl;
std::cout << "Error: " << GetLastError() << std::endl;
std::getline(std::cin, str);
}
Инжектор C ++ отображает Error: 18
после каждой строки. Результат для CreateRemoteThread
возвращает 0
, а сообщение - Error: 5
. Я пытался запустить программу от имени администратора, но она все равно не работала.
Я понятия не имею, в чем проблема.