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
相关推荐
如竟没有火炬几秒前
至少有K个重复字符的最长子串
开发语言·数据结构·python·算法·leetcode·动态规划
三品吉他手会点灯17 分钟前
C语言学习笔记 - 32.嵌入式C语言学习阶段对初学编程者的建议
c语言·开发语言·笔记·学习
l1t17 分钟前
DeepSeek总结的一种带宽高效的压缩基数排序FractalSortCPU
开发语言·python
沐知全栈开发20 分钟前
jEasyUI 树形网格动态加载详解
开发语言
Java源头21 分钟前
PHP 身份证二要素检测
开发语言·php
折哥的程序人生 · 物流技术专研25 分钟前
《Java 100 天进阶之路》第21篇:Java Object类
java·开发语言·后端·面试·哈希算法
谙弆悕博士29 分钟前
快速学C语言——第17章:多文件编程与头文件规范
c语言·开发语言·算法·学习方法·头文件·多文件编程
熊猫_豆豆34 分钟前
仿真模拟两颗卫星的自主交会对接过程(Python版)
开发语言·python
三品吉他手会点灯37 分钟前
C语言学习笔记 - 31.数据类型 - 基本输入输出函数printf与scanf
c语言·开发语言·笔记·学习
sycmancia39 分钟前
Qt中的事件处理(二)
开发语言·qt