Внедрение DLL продолжает сбой из-за несовместимых ошибок - PullRequest
2 голосов
/ 11 октября 2019

Я пытаюсь написать 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. Я пытался запустить программу от имени администратора, но она все равно не работала.

Я понятия не имею, в чем проблема.

1 Ответ

1 голос
/ 11 октября 2019

Согласно ответу Нины, я неправильно его компилировал. Спасибо, Нина!

Является ли ваш инжектор / dll той же архитектурой, что и процесс, который вы вводите? Например, если вы внедряете в 64-битный процесс, ваш dll и ваш инжектор должны быть скомпилированы как x64. Аналогично, если это x86 или WOW64, он должен быть скомпилирован соответствующим образом.

...