C# 远程注入Dll

注入代码

csharp 复制代码
#region 工具
public class Util
{
    #region 函数
    /// <summary>
    /// 获取进程id
    /// </summary>
    /// <param name="name"></param>
    /// <returns></returns>
    public static int GetProcessId(string name)
    {
        var ps = Process.GetProcesses();
        foreach (var p in ps)
        {
            if(p.ProcessName.Equals(name, StringComparison.OrdinalIgnoreCase))
            {
                return p.Id;
            }
        }
        return 0;
    }

    /// <summary>
    /// 进程是否包含模块
    /// </summary>
    /// <param name="name"></param>
    /// <param name="pid"></param>
    /// <returns></returns>
    public static bool HasMoudle(string name, int pid)
    {
        var ps = Process.GetProcesses();
        foreach (var p in ps)
        {
            if(p.Id != pid)
            {
                continue;
            }
            foreach (ProcessModule module in p.Modules)
            {
                if(module.FileName.Equals(name, StringComparison.OrdinalIgnoreCase))
                {
                    return true;
                }
            }
        }
        return false;
    }

    /// <summary>
    /// dll注入
    /// </summary>
    /// <param name="dll_path"></param>
    /// <param name="pid"></param>
    /// <returns></returns>
    public static bool InjectDll(string dll_path, int pid)
    {
        bool bRet = false;
        IntPtr hProcess = IntPtr.Zero;
        IntPtr hRemoteThread = IntPtr.Zero;
        try
        {
            // 入参检查
            dll_path = Path.GetFullPath(dll_path);
            if (!File.Exists(dll_path) || pid <= 0)
            {
                return false;
            }

            // 无需重复注入
            if(HasMoudle(dll_path, pid))
            {
                return true;
            }

            hProcess = Win32.OpenProcess(Win32.ProcessAccessFlags.PROCESS_ALL_ACCESS, false, pid);
            if (hProcess == IntPtr.Zero)
            {
                return false;
            }

            // 把dll路径写到目标进程
            IntPtr pRemotePath = Win32.VirtualAllocEx(hProcess, IntPtr.Zero, 
                ((dll_path.Length + 1) * Marshal.SizeOf(typeof(char))), 
                (int)Win32.MemoryAccessFlags.MEM_COMMIT, 
                (int)Win32.MemoryAccessFlags.PAGE_READWRITE);
            if (pRemotePath == IntPtr.Zero)
            {
                return false;
            }

            var dllBytes = Encoding.Default.GetBytes(dll_path);
            if (!Win32.WriteProcessMemory(hProcess, pRemotePath, dllBytes, dllBytes.Length, out int bytesWritten))
            {
                return false;
            }

            // 获取目标dll加载函数
            IntPtr loadLibraryAddr = Win32.GetProcAddress(Win32.GetModuleHandle("kernel32.dll"), "LoadLibraryA");
            if (loadLibraryAddr == IntPtr.Zero)
            {
                return false;
            }

            // 创建远程线程,在目标进程中调用 LoadLibraryA 加载 DLL
            // 注意,不能往64位的进程注入32位的程序
            hRemoteThread = Win32.CreateRemoteThread(hProcess, IntPtr.Zero, 0, loadLibraryAddr, pRemotePath, 0, IntPtr.Zero);
            if (hRemoteThread == IntPtr.Zero)
            {
                return false;
            }

            // 等待远程线程执行完毕
            Win32.WaitForSingleObject(hRemoteThread, Win32.INFINITE);
            bRet = true;
        }
        catch
        {

        }
        finally
        {
            Win32.CloseHandle(hRemoteThread);
            Win32.CloseHandle(hProcess);
        }
        return bRet;
    }
    #endregion
}
#endregion

#region WIN32
public class Win32
{
    #region 对象定义
    public const uint INFINITE = 0xFFFFFFFF;

    // 内存访问标志
    [Flags]
    public enum MemoryAccessFlags : uint
    {
        MEM_COMMIT = 0x00001000,
        MEM_RESERVE = 0x00002000,
        PAGE_READWRITE = 4
    }

    // 进程访问权限标志位
    [Flags]
    public enum ProcessAccessFlags : uint
    {
         PROCESS_CREATE_THREAD = 0x0002,
         PROCESS_QUERY_INFORMATION = 0x0400,
         PROCESS_VM_OPERATION = 0x0008,
         PROCESS_VM_WRITE = 0x0020,
         PROCESS_VM_READ = 0x0010,
         PROCESS_ALL_ACCESS = 0x001F0FFF,
    }
    #endregion

    #region 函数

    [DllImport("Advapi32.dll")]
    public static extern bool OpenProcessToken(IntPtr hHandle, UInt32 nDesiredAccess, ref IntPtr TokenHandle);
    //[DllImport("Advapi32.dll")]
    //public static extern bool LookupPrivilegeValueA(string lpSystemName, string lpName, ref LUID LUID);

    [DllImport("kernel32.dll", SetLastError = true)]
    public static extern UInt32 WaitForSingleObject(IntPtr hHandle, UInt32 dwMilliseconds);
    [DllImport("kernel32.dll")]
    public static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName);
    [DllImport("kernel32.dll")]
    public static extern IntPtr GetModuleHandle(string lpModuleName);
    [DllImport("kernel32.dll", SetLastError = true)]
    public static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, int dwSize, int flAllocationType, int flProtect);
    [System.Runtime.InteropServices.DllImport("kernel32.dll", SetLastError = true)]
    public static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, int dwSize, out int lpNumberOfBytesRead);
    [DllImport("kernel32.dll")]
    public static extern IntPtr OpenProcess(ProcessAccessFlags dwDesiredAccess, bool bInheritHandle, int dwProcessId);
    [DllImport("kernel32.dll")]
    public static extern bool CloseHandle(IntPtr hObject);
    [DllImport("kernel32.dll")]
    public static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, int nSize, out int lpNumberOfBytesWritten);
    [DllImport("kernel32.dll", SetLastError = true)]
    public static extern IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId);
    #endregion
}
#endregion
相关推荐
----云烟----35 分钟前
QT中QString类的各种使用
开发语言·qt
lsx20240640 分钟前
SQL SELECT 语句:基础与进阶应用
开发语言
开心工作室_kaic1 小时前
ssm161基于web的资源共享平台的共享与开发+jsp(论文+源码)_kaic
java·开发语言·前端
向宇it1 小时前
【unity小技巧】unity 什么是反射?反射的作用?反射的使用场景?反射的缺点?常用的反射操作?反射常见示例
开发语言·游戏·unity·c#·游戏引擎
武子康1 小时前
Java-06 深入浅出 MyBatis - 一对一模型 SqlMapConfig 与 Mapper 详细讲解测试
java·开发语言·数据仓库·sql·mybatis·springboot·springcloud
九鼎科技-Leo2 小时前
什么是 WPF 中的依赖属性?有什么作用?
windows·c#·.net·wpf
转世成为计算机大神2 小时前
易考八股文之Java中的设计模式?
java·开发语言·设计模式
宅小海2 小时前
scala String
大数据·开发语言·scala
qq_327342732 小时前
Java实现离线身份证号码OCR识别
java·开发语言
锅包肉的九珍2 小时前
Scala的Array数组
开发语言·后端·scala