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
相关推荐
Algorithm15768 分钟前
云原生相关的 Go 语言工程师技术路线(含博客网址导航)
开发语言·云原生·golang
shinelord明17 分钟前
【再谈设计模式】享元模式~对象共享的优化妙手
开发语言·数据结构·算法·设计模式·软件工程
呆呆小雅23 分钟前
C#关键字volatile
java·redis·c#
Monly2124 分钟前
Java(若依):修改Tomcat的版本
java·开发语言·tomcat
boligongzhu25 分钟前
DALSA工业相机SDK二次开发(图像采集及保存)C#版
开发语言·c#·dalsa
Eric.Lee202125 分钟前
moviepy将图片序列制作成视频并加载字幕 - python 实现
开发语言·python·音视频·moviepy·字幕视频合成·图像制作为视频
7yewh27 分钟前
嵌入式Linux QT+OpenCV基于人脸识别的考勤系统 项目
linux·开发语言·arm开发·驱动开发·qt·opencv·嵌入式linux
waicsdn_haha39 分钟前
Java/JDK下载、安装及环境配置超详细教程【Windows10、macOS和Linux图文详解】
java·运维·服务器·开发语言·windows·后端·jdk
_WndProc41 分钟前
C++ 日志输出
开发语言·c++·算法
web1478621072343 分钟前
C# .Net Web 路由相关配置
前端·c#·.net