C#注入器

    using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace injectprocedure
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
    //        LPVOID VirtualAllocEx(
    //  [in] HANDLE hProcess,
    //  [in, optional] LPVOID lpAddress,
    //  [in] SIZE_T dwSize,
    //  [in] DWORD flAllocationType,
    //  [in] DWORD flProtect
    //);
    /// 
    /// 开辟内存
    /// 
    /// 开辟内存的进程指针
    /// 开辟内存的起始地址如果 lpAddress 为 NULL,则该函数确定分配区域的位置。
    /// 开辟内存的大小
    /// 内存分配的类型
    /// 要分配的页区域的内存操作权限
    /// 开辟内存的指针
    [DllImport("Kernel32.dll")]
    public static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, int dwSize, FlAllocationType flAllocationType, FlProtect flProtect);

    //        BOOL WriteProcessMemory(
    //  [in] HANDLE hProcess,
    //  [in] LPVOID lpBaseAddress,
    //  [in] LPCVOID lpBuffer,
    //  [in] SIZE_T nSize,
    //  [out] SIZE_T* lpNumberOfBytesWritten
    //);
    //https://learn.microsoft.com/zh-cn/windows/win32/api/memoryapi/nf-memoryapi-writeprocessmemory
    /// 
    /// 写入内存
    /// 
    /// 写人内存的进程指针
    /// 写入内存的指针
    /// 写入内存的数据
    /// 写入内存的大小
    /// 指向变量的指针,该变量接收传输到指定进程的字节数。 此参数是可选的。 如果 lpNumberOfBytesWritten 为 NULL,则忽略参数。
    /// 是否写入成功
    [DllImport("Kernel32.dll")]
    public static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, string lpBuffer, int nSize, IntPtr lpNumberOfBytesWritten);


    //        HMODULE GetModuleHandleA(
    //  [in, optional] LPCSTR lpModuleName
    //);
    //https://learn.microsoft.com/zh-cn/windows/win32/api/libloaderapi/nf-libloaderapi-getmodulehandlea
    /// 
    /// 获取模块(dll)
    /// 
    /// 模块名称
    /// 该模块的指针
    [DllImport("Kernel32.dll")]
    public static extern IntPtr GetModuleHandleA(string lpModuleName);

    //        FARPROC GetProcAddress(
    //  [in] HMODULE hModule,
    //  [in] LPCSTR lpProcName
    //);
    //https://learn.microsoft.com/zh-cn/windows/win32/api/libloaderapi/nf-libloaderapi-getprocaddress
    /// 
    /// 获取模块内的函数指针
    /// 
    /// 模块指针
    /// 函数名称
    /// 该函数的指针
       [DllImport("Kernel32.dll")]
    public static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName);


    //        HANDLE CreateRemoteThread(
    //  [in] HANDLE hProcess,
    //  [in] LPSECURITY_ATTRIBUTES lpThreadAttributes,
    //  [in] SIZE_T dwStackSize,
    //  [in] LPTHREAD_START_ROUTINE lpStartAddress,
    //  [in] LPVOID lpParameter,
    //  [in] DWORD dwCreationFlags,
    //  [out] LPDWORD lpThreadId
    //);
    //https://learn.microsoft.com/zh-cn/windows/win32/api/processthreadsapi/nf-processthreadsapi-createremotethread
    /// 
    /// 创建远程线程
    /// 
    /// 创建线程的进程指针
    ///  如果 lpThreadAttributes 为 NULL,则线程将获取默认安全描述符,并且无法继承句柄。 访问控制在来自创建者主令牌的线程的默认安全描述符中列出 (ACL) 
    /// 堆栈的初始大小(以字节为单位)。
    /// 线程执行的应用程序定义函数的指针,表示远程进程中线程的起始地址。 函数必须存在于远程进程中。(创建的函数指针)
    /// 指向要传递给线程函数的变量的指针。(函数变量指针)
    /// 控制线程创建的标志。0:线程在创建后立即运行
    /// 指向接收线程标识符的变量的指针。如果此参数为 NULL,则不返回线程标识符。
    /// 如果函数成功,则返回值是新线程的句柄。
    [DllImport("Kernel32.dll")]
    public static extern IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr lpThreadAttributes, int dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, int dwCreationFlags, IntPtr lpThreadId);

    private void button1_Click(object sender, EventArgs e)
    {
        //1.遍历进程找到微信进程(CreateToolhelp32Snapshot、Processes32Next)
        Process[] processes = Process.GetProcesses();
        string processName = string.Empty;
        int ProcessPId = 0;
        //2。打开微信进程,获得微信句柄(OpenProcess)
        IntPtr processintPtr = IntPtr.Zero;
        foreach (Process process in processes)
        {
            if (process.ProcessName == "WeChat") {
                processName= process.ProcessName;
                ProcessPId = process.Id;
                processintPtr = process.Handle;
                break;
            }
        }
        if (processintPtr == IntPtr.Zero) {
            MessageBox.Show("未找到微信");
            return;
        }
        //3.打开微信进程,为dll文件路径字符串事情内存空间(VirtualAllocEx)
        string dllFilePath = @"";
        int dllFilePathLenth = dllFilePath.Length+1;
       
      IntPtr dllFilePathintPtr= VirtualAllocEx(processintPtr, IntPtr.Zero, dllFilePathLenth, FlAllocationType.MEM_COMMIT, FlProtect.PAGE_READWRITE);
        if (dllFilePathintPtr == IntPtr.Zero) {
            MessageBox.Show("字符串内存分配失败!");
            return;
        }
        //4.把dll文件路径字符串写入到申请内存中(WriteProcessMemory)
        bool isWriteOk=WriteProcessMemory(processintPtr, dllFilePathintPtr, dllFilePath, dllFilePathLenth, IntPtr.Zero);
        if (!isWriteOk) {
            MessageBox.Show("写入进程的内存失败!");
            return;
        }
        //5.从kernel32.dll中获取loadLibraryA的函数地址(GetModuleHandle、GetProcAddress)
        IntPtr moduleIntPtr = GetModuleHandleA("Kernel32.dll");

        IntPtr loadLibraryAintPtr = GetProcAddress(moduleIntPtr, "loadLibraryA");
        if (loadLibraryAintPtr == IntPtr.Zero) {
            MessageBox.Show("寻找loadLibraryA失败");
            return;
        }
        //6.在微信中启动内存中指定了文件名路径的dll(CreateRemoteThredad)
       IntPtr remoteThreadIntPtr = CreateRemoteThread(processintPtr, IntPtr.Zero, 0, loadLibraryAintPtr, dllFilePathintPtr, 0, IntPtr.Zero);
        if (IntPtr.Zero == remoteThreadIntPtr) {
            MessageBox.Show("注入失败");
            return;
        }
        MessageBox.Show("注入成功");

    }
}
//https://learn.microsoft.com/zh-cn/windows/win32/api/memoryapi/nf-memoryapi-virtualallocex
public enum FlAllocationType {
    /// 
    /// 从指定保留内存页的磁盘) 的总内存大小和分页文件 (分配内存费用
    /// 
    MEM_COMMIT = 0x00001000,
    MEM_RESERVE = 0x00002000,
    MEM_RESET = 0x00080000,
    MEM_RESET_UNDO = 0x1000000,
    MEM_LARGE_PAGES= 0x20000000,
    MEM_PHYSICAL= 0x00400000,
    MEM_TOP_DOWN= 0x00100000,

}

//https://learn.microsoft.com/zh-cn/windows/win32/Memory/memory-protection-constants
public enum FlProtect {
    PAGE_EXECUTE= 0x10,
    PAGE_EXECUTE_READ = 0x20,
    PAGE_EXECUTE_READWRITE = 0x40,
    PAGE_EXECUTE_WRITECOPY = 0x80,
    PAGE_NOACCESS=0x01,
    /// 
    /// 启用对已提交页面区域的只读或读/写访问。 如果启用了 数据执行保护 ,则尝试在提交的区域中执行代码会导致访问冲突。
    /// 
    PAGE_READWRITE = 0x04,

}
}

你可能感兴趣的:(C#,逆向)