Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/282.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 是否将.Net程序集加载/注入现有.Net进程?_C#_.net_Reflection - Fatal编程技术网

C# 是否将.Net程序集加载/注入现有.Net进程?

C# 是否将.Net程序集加载/注入现有.Net进程?,c#,.net,reflection,C#,.net,Reflection,在我的情况下,我想将自定义.net程序集加载到正在运行的.net进程的域中,例如Windows Explorer,我已经尝试过的只是将程序集注入到Explorer.exe,但这似乎没有明显的原因 喷油器代码: public class CodeInjector { [DllImport("kernel32.dll", SetLastError = true)] public static extern IntPtr OpenProcess(uint dwDesiredAccess

在我的情况下,我想将自定义.net程序集加载到正在运行的.net进程的域中,例如
Windows Explorer
,我已经尝试过的只是将程序集注入到
Explorer.exe
,但这似乎没有明显的原因

喷油器代码:

public class CodeInjector
{
    [DllImport("kernel32.dll", SetLastError = true)]
    public static extern IntPtr OpenProcess(uint dwDesiredAccess, int bInheritHandle, uint dwProcessId);

    [DllImport("kernel32.dll", SetLastError = true)]
    public static extern int CloseHandle(IntPtr hObject);

    [DllImport("kernel32.dll", SetLastError = true)]
    public static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName);

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

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

    [DllImport("kernel32.dll", SetLastError = true)]
    public static extern int WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] buffer, uint size, int lpNumberOfBytesWritten);

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

    private static CodeInjector _instance;

    public static CodeInjector GetInstance
    {
        get { return _instance ?? (_instance = new CodeInjector()); }
    }

    public InjectionResult Inject(string sProcName, string sDllPath)
    {
        if (!File.Exists(sDllPath))
        {
            return InjectionResult.DllNotFound;
        }

        var procs = Process.GetProcesses();
        var procId = (from t in procs where t.ProcessName == sProcName select (uint)t.Id).FirstOrDefault();

        if (procId == 0)
        {
            return InjectionResult.ProcessNotFound;
        }

        if (!Inject(procId, sDllPath))
        {
            return InjectionResult.InjectionFailed;
        }

        return InjectionResult.InjectionSucceed;
    }

    private static bool Inject(uint pToBeInjected, string sDllPath)
    {
        var hndProc = OpenProcess((0x2 | 0x8 | 0x10 | 0x20 | 0x400), 1, pToBeInjected);

        if (hndProc == IntPtr.Zero)
        {
            return false;
        }

        var lpLlAddress = GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");

        if (lpLlAddress == IntPtr.Zero)
        {
            return false;
        }

        var lpAddress = VirtualAllocEx(hndProc, (IntPtr)null, (IntPtr)sDllPath.Length, (0x1000 | 0x2000), 0X40);

        if (lpAddress == IntPtr.Zero)
        {
            return false;
        }

        var bytes = Encoding.ASCII.GetBytes(sDllPath);

        if (WriteProcessMemory(hndProc, lpAddress, bytes, (uint)bytes.Length, 0) == 0)
        {
            return false;
        }

        if (CreateRemoteThread(hndProc, (IntPtr)null, IntPtr.Zero, lpLlAddress, lpAddress, 0, (IntPtr)null) == IntPtr.Zero)
        {
            return false;
        }

        CloseHandle(hndProc);

        return true;
    }
}

作为另一个选项,您可以使用现有库-
ManagedInjector
-。有一个工具snoopwpf可以显示任何WPF进程的详细信息,它使用进程注入来实现这一点。我不久前用过,效果很好

您需要构建它,将其添加到项目中作为参考,并按如下方式调用:

Injector.Launch(someProcess.MainWindowHandle, 
                  typeof(Loader).Assembly.Location, 
                  typeof(Loader).FullName, 
                  "Inject");
Loader
是将加载到进程中的类型的名称,
Inject
是将执行的静态方法。就我而言,我有:

public class Loader
{

    public static void Inject()
    {
          // i did CBT Hook on main window here 
          // and also displayed sample message box for debugging purposes
          MessageBox.Show("Hello from another process");
    }
}

管理注射器是用托管C++代码编写的。基本上,它将自己的非托管C++方法作为MaseAdHooCoC钩住,并在注入后启动指定的程序集并运行指定的方法。无论是托管程序还是非托管程序,它都应该可以正常工作。在我的例子中,我将其用于非托管程序

更新

我在本地测试了它,它成功地将我的消息框注入到Windows8.1x64下的资源管理器进程中。我编译了ManagedInjector64-4.0,我的示例控制台项目在平台选择中也有x64。这是我的工作代码:

class Program
{
    static void Main(string[] args)
    {
        var proc = Process.GetProcessesByName("explorer").FirstOrDefault();
        Injector.Launch(proc.MainWindowHandle, typeof(Loader).Assembly.Location, typeof(Loader).FullName, "Inject");
    }
}

public class Loader
{
    public static void Inject()
    {
        MessageBox.Show("Hello");
        Task.Run(() =>
        {
            Thread.Sleep(3000);
            MessageBox.Show("Hello again");
            Thread.Sleep(5000);
            MessageBox.Show("Hello again again");
        });
    }
}

如何验证程序集没有注入?您是否在
sDllPath
变量中发送了相同的程序集?该程序集是否与注入进程的可执行文件位于同一文件夹中?顺便说一句,资源管理器不是.Net进程,因此它内部可能没有正在运行的CLR。在这种情况下,其他方法是注入自己的C++程序集并创建新的AppDevices并在注入的过程中运行程序集。process@SergeyLitvinov是否有一种将.net程序集加载到资源管理器的好方法?我已经尝试了所有我能找到的方法,但运气不佳。我使用procexplorer查看我的程序集是否加载到目标进程中。它会不断抛出FileLoadException,即使没有调用Inject方法。。任何帮助,因为您的解决方案似乎很有趣。我在使用注入器时出错。第二个参数应该指向程序集位置,因此可能无法加载它。我已经更新了答案并添加了工作示例。很抱歉,我无法生成我一直收到的喷油器项目
错误5错误LNK2022:元数据操作失败(80131195):自定义属性不一致:(0x0c000089).
您可以安装使用它的Snoop WPF工具,然后从安装它的文件夹中获取此库。已经尝试过了,但我一直得到
未知模块中出现“System.IO.FileLoadException”类型的未处理异常。
每次我的c应用程序启动时。。。它是一款.NET3.5c#控制台应用程序