【问题标题】:DLL Injection Keeps Failing with Inconsistent ErrorsDLL 注入不断失败并出现不一致的错误
【发布时间】:2020-02-09 01:47:36
【问题描述】:

我正在尝试在 C# WPF 应用程序中编写 DLL 注入器。我之前在 Windows 窗体中编写过一个 DLL 注入器,但是我想从头开始编写一个新程序。我以前用许多其他语言多次编写过 DLL 注入器(使用传统的 VirtualAllocEx / WriteProcessMemory / CreateRemoteThread 方法),但是我遇到了一些特殊的问题。我的 DLL Injector 说它成功了,但我的测试程序显示没有任何变化。我对Marshal.GetLastWin32Error() 进行了一些测试,结果VirtualAllocExWriteProcessMemoryCreateRemoteThread 得到了ERROR_FILE_NOT_FOUND。然后我在 C++ 中创建了一个 Injector 来测试 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: 18CreateRemoteThread 的结果返回 0,消息为 Error: 5。我尝试以管理员身份运行该程序,但仍然无法正常工作。

我完全不知道问题是什么。

【问题讨论】:

  • 您可能正在注入提升的进程。尝试以管理员身份运行注射器。也使用 sizeof(string) 可能是错误的。试试 strlen,别忘了 \0
  • @Nina 如前所述,我已经尝试以管理员身份运行它。另外,我已经尝试过使用 strlen。我相信字符串通常在它们的末尾有空终止符,并且将它们添加到末尾没有任何作用。不过谢谢!
  • 您的注入器/dll 与您注入的进程的架构是否相同?例如,如果您要注入 64 位进程,则您的 dll 和注入器应编译为 x64。 Likewsie,如果它是 x86 或 WOW64,它应该相应地编译。
  • @Nina 哇!这行得通!非常感谢你做的这些。我会确保在问题中认可你。

标签: c# c++ wpf windows dll-injection


【解决方案1】:

根据尼娜的回答,我编译不正确。谢谢妮娜!

您的注入器/dll 与您注入的进程的架构是否相同?例如,如果您要注入 64 位进程,则您的 dll 和注入器应编译为 x64。 Likewsie 如果它是 x86 或 WOW64,它应该相应地编译。

【讨论】:

    猜你喜欢
    • 2019-12-11
    • 1970-01-01
    • 2020-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-27
    • 2019-09-01
    • 1970-01-01
    相关资源
    最近更新 更多