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
相关推荐
软件黑马王子2 小时前
C#初级教程(4)——流程控制:从基础到实践
开发语言·c#
闲猫2 小时前
go orm GORM
开发语言·后端·golang
李白同学4 小时前
【C语言】结构体内存对齐问题
c语言·开发语言
黑子哥呢?5 小时前
安装Bash completion解决tab不能补全问题
开发语言·bash
青龙小码农5 小时前
yum报错:bash: /usr/bin/yum: /usr/bin/python: 坏的解释器:没有那个文件或目录
开发语言·python·bash·liunx
大数据追光猿5 小时前
Python应用算法之贪心算法理解和实践
大数据·开发语言·人工智能·python·深度学习·算法·贪心算法
彳卸风6 小时前
Unable to parse timestamp value: “20250220135445“, expected format is
开发语言
dorabighead6 小时前
JavaScript 高级程序设计 读书笔记(第三章)
开发语言·javascript·ecmascript
风与沙的较量丶7 小时前
Java中的局部变量和成员变量在内存中的位置
java·开发语言
水煮庄周鱼鱼7 小时前
C# 入门简介
开发语言·c#