DLL注入CreateRemoteThread无法在某些客户端上运行(.NET)

时间:2016-04-20 17:20:16

标签: c# .net dll code-injection

我在.NET中创建了一个启动器,它启动单人游戏并将DLL注入其中。 它适用于我自己的机器和其他几台机器,但在某些人的计算机上,它似乎神秘地失败了。我不知道原因可能是什么,并且无法直接调试它,因为它可以为我工作。也许你们中的一些人遇到了同样的问题,或者知道可能出现的问题。

这是启动程序的注入代码(.NET Framework 4.5.2,目标平台:任何CPU [更喜欢32位]):

    static void StartProcess()
    {
        ProcessStartInfo psi = new ProcessStartInfo();
        psi.UseShellExecute = false;
        psi.WorkingDirectory = Path.GetFullPath("..");
        psi.EnvironmentVariables.Add("GUCProject", projectName);
        psi.FileName = Path.GetFullPath("..\\Gothic2.exe");
        Process process = Process.Start(psi);

        string dllPath = Path.GetFullPath("UntoldChapters\\" + projectName + "\\NetInject.dll");

        //dll injection
        if (LoadLibary(process, dllPath) == IntPtr.Zero)
        {
            throw new Exception(Marshal.GetLastWin32Error().ToString());
        }
    }

    [Flags]
    public enum AllocationType
    {
        Commit = 0x1000,
        Reserve = 0x2000,
        Decommit = 0x4000,
        Release = 0x8000,
        Reset = 0x80000,
        Physical = 0x400000,
        TopDown = 0x100000,
        WriteWatch = 0x200000,
        LargePages = 0x20000000
    }

    [Flags]
    public enum MemoryProtection : uint
    {
        Execute = 0x10,
        ExecuteRead = 0x20,
        ExecuteReadWrite = 0x40,
        ExecuteWriteCopy = 0x80,
        NoAccess = 0x01,
        ReadOnly = 0x02,
        ReadWrite = 0x04,
        WriteCopy = 0x08,
        GuardModifierflag = 0x100,
        NoCacheModifierflag = 0x200,
        WriteCombineModifierflag = 0x400
    }

    [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
    public static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, AllocationType flAllocationType, MemoryProtection flProtect);

    [DllImport("kernel32.dll", SetLastError = true)]
    public static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, UInt32 nSize, out UInt32 lpNumberOfBytesWritten);

    [DllImport("kernel32", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)]
    public static extern IntPtr GetProcAddress(IntPtr hModule, string procName);

    [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
    public static extern IntPtr GetModuleHandle(string lpModuleName);

    [DllImport("kernel32.dll", SetLastError = true)]
    public static extern IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, out uint lpThreadId);

    public static IntPtr LoadLibary(Process process, String dll)
    {
        if (process == null || String.IsNullOrWhiteSpace(dll))
            return IntPtr.Zero;

        byte[] dllb = Encoding.ASCII.GetBytes(dll);
        if (dllb == null || dllb.Length == 0)
            return IntPtr.Zero;

        //Alloc
        uint len = (uint)dllb.Length + 1;
        IntPtr dllbPtr = VirtualAllocEx(process.Handle, IntPtr.Zero, len, AllocationType.Reserve | AllocationType.Commit, MemoryProtection.ReadWrite);
        if (dllbPtr == IntPtr.Zero)
        {
            throw new Exception(Marshal.GetLastWin32Error().ToString());
        }

        //Write dll name
        uint tmp = 0;
        bool b = WriteProcessMemory(process.Handle, dllbPtr, dllb, (uint)dllb.Length, out tmp);
        if (!b)
        {
            throw new Exception(Marshal.GetLastWin32Error().ToString());
        }

        IntPtr moduleHandle = GetModuleHandle("kernel32.dll");
        if (moduleHandle == IntPtr.Zero)
        {
            throw new Exception(Marshal.GetLastWin32Error().ToString());
        }

        IntPtr loadlib = GetProcAddress(moduleHandle, "LoadLibraryA");
        if (loadlib == IntPtr.Zero)
        {
            throw new Exception(Marshal.GetLastWin32Error().ToString());
        }

        return CreateRemoteThread(process.Handle, IntPtr.Zero, 0, loadlib, dllbPtr, 0, out tmp);
    }

没有显示错误消息/异常抛出给它不起作用的人,所有的指针,句柄和路径似乎都很好,但注入的' NetInject.dll&#39的DLLMain ;不被称为。

(目标平台Windows 8.1,工具集VS2015(v140),多字节字符集,无CLR支持)

int WINAPI DllMain(HINSTANCE hInst, DWORD reason, LPVOID reserved)
{
    // this is just the testing code for the people for which it doesn't work. It doesn't even get till here.
    MessageBoxW(NULL, L"Injected!", L"Error!", MB_ICONWARNING | MB_OK | MB_DEFBUTTON2);
    return true;
}
  • 启动器始终以管理权限启动。
  • 操作系统似乎不是问题,因为它的工作和一些失败 拥有相同操作系统的人。 (使用Win8.1 64位,Win7 Professional 64位,Win7企业版64位,Win7家庭高级版64位) (不适用于Win7 Professional 64Bit,Win 10 64Bit)
  • 在关闭反病毒软件的情况下,它也没有为他们工作(无论如何,我和其中一个有问题的测试人员有相同的反病毒软件。)
  • 在发布模式下编译。

提前谢谢。

1 个答案:

答案 0 :(得分:0)

Dynamic-Link Library Best Practices (Windows)。在"一般最佳实践"它说"你永远不应该" ..."调用User32.dll或Gdi32.dll中的函数"来自DllMain。 MessageBox在User32.dll中。即使您使用MessageBox作为测试,您也需要确保遵守通用最佳实践。

是的,我知道通用最佳实践非常有限。当我第一次找到它时,我对此感到惊讶。