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
相关推荐
_r0bin_2 小时前
前端面试准备-7
开发语言·前端·javascript·fetch·跨域·class
zhang98800002 小时前
JavaScript 核心原理深度解析-不停留于表面的VUE等的使用!
开发语言·javascript·vue.js
Fanxt_Ja3 小时前
【JVM】三色标记法原理
java·开发语言·jvm·算法
蓝婷儿3 小时前
6个月Python学习计划 Day 15 - 函数式编程、高阶函数、生成器/迭代器
开发语言·python·学习
绿荫阿广4 小时前
互联网不景气了那就玩玩嵌入式吧,用纯.NET开发并制作一个智能桌面机器人(五):使用.NET为树莓派开发Wifi配网功能
c#·.net
love530love4 小时前
【笔记】在 MSYS2(MINGW64)中正确安装 Rust
运维·开发语言·人工智能·windows·笔记·python·rust
slandarer4 小时前
MATLAB | 绘图复刻(十九)| 轻松拿捏 Nature Communications 绘图
开发语言·matlab
狐凄4 小时前
Python实例题:Python计算二元二次方程组
开发语言·python
roman_日积跬步-终至千里5 小时前
【Go语言基础【3】】变量、常量、值类型与引用类型
开发语言·算法·golang
roman_日积跬步-终至千里5 小时前
【Go语言基础】基本语法
开发语言·golang·xcode