C# Dll 注入器、VB.Net Dll 注入器

Posted

技术标签:

【中文标题】C# Dll 注入器、VB.Net Dll 注入器【英文标题】:C# Dll injector, VB.Net Dll injector 【发布时间】:2014-07-07 07:41:46 【问题描述】:

我之前让 dll 注入器变得简单,但我有 Windows 7,我用 C# 和 C++ 制作它,效果很好!但是现在当我在 Windows 8 中尝试相同的代码时,它似乎没有以正确的方式注入 DLL! :) 因为 DLL 不工作...

(我正在尝试的代码是公共代码

VB.Net 代码:

Private TargetProcessHandle As Integer
Private pfnStartAddr As Integer
Private pszLibFileRemote As String
Private TargetBufferSize As Integer

Public Const PROCESS_VM_READ = &H10
Public Const TH32CS_SNAPPROCESS = &H2
Public Const MEM_COMMIT = 4096
Public Const PAGE_READWRITE = 4


Public Const PROCESS_CREATE_THREAD = (&H2)
Public Const PROCESS_VM_OPERATION = (&H8)
Public Const PROCESS_VM_WRITE = (&H20)
Dim DLLFileName As String
Public Declare Function ReadProcessMemory Lib "kernel32" ( _
ByVal hProcess As Integer, _
ByVal lpBaseAddress As Integer, _
ByVal lpBuffer As String, _
ByVal nSize As Integer, _
ByRef lpNumberOfBytesWritten As Integer) As Integer

Public Declare Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA" ( _
ByVal lpLibFileName As String) As Integer

Public Declare Function VirtualAllocEx Lib "kernel32" ( _
ByVal hProcess As Integer, _
ByVal lpAddress As Integer, _
ByVal dwSize As Integer, _
ByVal flAllocationType As Integer, _
ByVal flProtect As Integer) As Integer

Public Declare Function WriteProcessMemory Lib "kernel32" ( _
ByVal hProcess As Integer, _
ByVal lpBaseAddress As Integer, _
ByVal lpBuffer As String, _
ByVal nSize As Integer, _
ByRef lpNumberOfBytesWritten As Integer) As Integer

Public Declare Function GetProcAddress Lib "kernel32" ( _
ByVal hModule As Integer, ByVal lpProcName As String) As Integer

Private Declare Function GetModuleHandle Lib "Kernel32" Alias "GetModuleHandleA" ( _
ByVal lpModuleName As String) As Integer

Public Declare Function CreateRemoteThread Lib "kernel32" ( _
ByVal hProcess As Integer, _
ByVal lpThreadAttributes As Integer, _
ByVal dwStackSize As Integer, _
ByVal lpStartAddress As Integer, _
ByVal lpParameter As Integer, _
ByVal dwCreationFlags As Integer, _
ByRef lpThreadId As Integer) As Integer

Public Declare Function OpenProcess Lib "kernel32" ( _
ByVal dwDesiredAccess As Integer, _
ByVal bInheritHandle As Integer, _
ByVal dwProcessId As Integer) As Integer

Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" ( _
ByVal lpClassName As String, _
ByVal lpWindowName As String) As Integer

Private Declare Function CloseHandle Lib "kernel32" Alias "CloseHandle" ( _
ByVal hObject As Integer) As Integer


Dim ExeName As String = IO.Path.GetFileNameWithoutExtension(Application.ExecutablePath)

Private Sub Inject()

    Try
        Timer1.Stop()
        Dim TargetProcess As Process() = Process.GetProcessesByName(TextBox1.Text)
        TargetProcessHandle = OpenProcess(PROCESS_CREATE_THREAD Or PROCESS_VM_OPERATION Or PROCESS_VM_WRITE, False, TargetProcess(0).Id)
        pszLibFileRemote = OpenFileDialog1.FileName
        pfnStartAddr = GetProcAddress(GetModuleHandle("Kernel32"), "LoadLibraryA")
        TargetBufferSize = 1 + Len(pszLibFileRemote)
        Dim Rtn As Integer
        Dim LoadLibParamAdr As Integer
        LoadLibParamAdr = VirtualAllocEx(TargetProcessHandle, 0, TargetBufferSize, MEM_COMMIT, PAGE_READWRITE)
        Rtn = WriteProcessMemory(TargetProcessHandle, LoadLibParamAdr, pszLibFileRemote, TargetBufferSize, 0)
        CreateRemoteThread(TargetProcessHandle, 0, 0, pfnStartAddr, LoadLibParamAdr, 0, 0)
        CloseHandle(TargetProcessHandle)
    Catch ex As Exception
        MessageBox.Show("EX:" + ex.ToString)
    End Try
End Sub

它给出了一个错误“System.EntryPointNotFoundException.....”但是在我改变这个之后:

CloseHandle Lib "kernel32" Alias "CloseHandleA"

到这里:

CloseHandle Lib "kernel32" Alias "CloseHandle"

它不再显示错误,但它也没有以正确的方式注入它!

对于 C#:

[DllImport("kernel32")]
    public static extern IntPtr CreateRemoteThread(
      IntPtr hProcess,
      IntPtr lpThreadAttributes,
      uint dwStackSize,
      UIntPtr lpStartAddress, // raw Pointer into remote process
      IntPtr lpParameter,
      uint dwCreationFlags,
      out IntPtr lpThreadId
    );

    [DllImport("kernel32.dll")]
    public static extern IntPtr OpenProcess(
        UInt32 dwDesiredAccess,
        Int32 bInheritHandle,
        Int32 dwProcessId
        );

    [DllImport("kernel32.dll")]
    public static extern Int32 CloseHandle(
    IntPtr hObject
    );

    [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
    static extern bool VirtualFreeEx(
        IntPtr hProcess, 
        IntPtr lpAddress,
        UIntPtr dwSize, 
        uint dwFreeType
        );

    [DllImport("kernel32.dll", CharSet = CharSet.Ansi, ExactSpelling = true)]
    public static extern UIntPtr GetProcAddress(
        IntPtr hModule, 
        string procName
        );

    [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
    static extern IntPtr VirtualAllocEx(
        IntPtr hProcess, 
        IntPtr lpAddress,
        uint dwSize, 
        uint flAllocationType, 
        uint flProtect
        );

    [DllImport("kernel32.dll")]
    static extern bool WriteProcessMemory(
        IntPtr hProcess,
        IntPtr lpBaseAddress,
        string lpBuffer,
        UIntPtr nSize,
        out IntPtr lpNumberOfBytesWritten
    );

    [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
    public static extern IntPtr GetModuleHandle(
        string lpModuleName
        );

    [DllImport("kernel32", SetLastError = true, ExactSpelling = true)]
    internal static extern Int32 WaitForSingleObject(
        IntPtr handle, 
        Int32 milliseconds
        );

    public Int32 GetProcessId(String proc)
    
        Process[] ProcList;
        ProcList = Process.GetProcessesByName(proc);
        return ProcList[0].Id;
    

    public void InjectDLL(IntPtr hProcess, String strDLLName)
    
        IntPtr bytesout;

        // Length of string containing the DLL file name +1 byte padding
        Int32 LenWrite = strDLLName.Length + 1;
        // Allocate memory within the virtual address space of the target process
        IntPtr AllocMem = (IntPtr)VirtualAllocEx(hProcess, (IntPtr)null, (uint)LenWrite, 0x1000, 0x40); //allocation pour WriteProcessMemory

        // Write DLL file name to allocated memory in target process
        WriteProcessMemory(hProcess, AllocMem, strDLLName, (UIntPtr)LenWrite, out bytesout);
        // Function pointer "Injector"
        UIntPtr Injector = (UIntPtr)GetProcAddress( GetModuleHandle("kernel32.dll"), "LoadLibraryA");

        if (Injector == null)
        
            MessageBox.Show(" Injector Error! \n ");
            // return failed
            return;
        

        // Create thread in target process, and store handle in hThread
        IntPtr hThread = (IntPtr)CreateRemoteThread(hProcess, (IntPtr)null, 0, Injector, AllocMem, 0, out bytesout);
        // Make sure thread handle is valid
        if ( hThread == null )
        
            //incorrect thread handle ... return failed
            MessageBox.Show(" hThread [ 1 ] Error! \n ");
            return;
        
        // Time-out is 10 seconds...
        int Result = WaitForSingleObject(hThread, 10 * 1000);
        // Check whether thread timed out...
        if (Result == 0x00000080L || Result == 0x00000102L || Result == 0xFFFFFFFF)
        
            /* Thread timed out... */
            MessageBox.Show(" hThread [ 2 ] Error! \n ");
            // Make sure thread handle is valid before closing... prevents crashes.
            if (hThread != null)
            
                //Close thread in target process
                CloseHandle(hThread);
            
            return;
        
        // Sleep thread for 1 second
        Thread.Sleep(1000);
        // Clear up allocated space ( Allocmem )
        VirtualFreeEx(hProcess, AllocMem, (UIntPtr)0, 0x8000);
        // Make sure thread handle is valid before closing... prevents crashes.
        if (hThread != null)
        
            //Close thread in target process
            CloseHandle(hThread);
        
        // return succeeded
        return;
    

    private void button1_Click(object sender, EventArgs e)
    
        String strDLLName = "C:\\test.dll"; 
        String strProcessName = "notepad"; 

        Int32 ProcID = GetProcessId(strProcessName);
        if (ProcID >= 0)
        
            IntPtr hProcess = (IntPtr)OpenProcess(0x1F0FFF, 1,ProcID);
            if (hProcess == null)
            
                MessageBox.Show("OpenProcess() Failed!");
                return;
            
            else
                InjectDLL(hProcess, strDLLName);
        
    

它不会给我错误,但它也不会以正确的方式注入!

非常感谢! :)

【问题讨论】:

“没有以正确的方式注入”是什么意思? dll 不工作! :D 而且它不是来自 DLL .. 因为我尝试了注入器并且它有效!另外,如果有工作源代码公开.. 如果你告诉我这将是很好的! “不起作用”告诉我们没有任何用处。两个代码摘录的错误检查都很差。但两者看起来都基本健全。我的猜测是dll和目标之间不匹配。或者它可能是一个 32 位注入器和一个 64 位目标。您没有提供足够的信息。您应该进行一些调试并报告更多详细信息。 这就是我所知道的,它可能是 64 位目标。为了调试,我之前调试过,但我在想一些可能出错的事情 你需要做一些错误检查。我无法调试您的程序。我不知道你在注入什么。阅读文档,添加错误检查。 【参考方案1】:

会发生什么? 如果远程进程崩溃,那么您可能不应该使用GetProcAddress,因为远程 API 地址可能不同。例如,当注入进程使用 EAT 挂钩而远程进程没有被挂钩时,它可能会有所不同,因此它在您从本地 GetProcAddress 获得的地址上没有任何意义。即使两个进程都使用 EAT 挂钩挂钩,它也会有所不同,因为挂钩实现会导致更多随机或完全随机的位置。 我遇到过类似的情况,在 Windows 8 下发生了崩溃,但在早期版本中没有。

一种解决方案是读取远程进程的 EAT 表并从那里获取地址。

相关代码如下

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.ComponentModel;
using System.Reflection;
using System.IO;
using System.Threading;
using Microsoft.Win32.SafeHandles;
using System.Runtime.CompilerServices;
using System.Security;

namespace Injection

    public static class Remote_EAT_Reader
    

        public static IntPtr? GetProcessModuleHandle(int processID, string moduleName) 
        
            IntPtr snapshot = IntPtr.Zero;

            try
            
                //http://pastebin.com/BzD1jdmH
                snapshot = CreateToolhelp32Snapshot(SnapshotFlags.Module | SnapshotFlags.Module32, processID);

                MODULEENTRY32 mod = new MODULEENTRY32()  dwSize = MODULEENTRY32.SizeOf ;

                if (!Module32First(snapshot, ref mod))
                    return null;


                string searchString = moduleName.ToLowerInvariant();

                do
                
                    if (mod.szModule.ToLowerInvariant() == searchString)
                        return mod.modBaseAddr;
                
                while (Module32Next(snapshot, ref mod));

                return IntPtr.Zero;
            
            finally
            
                if (snapshot != IntPtr.Zero)
                    CloseHandle(snapshot);
            
        


        public static IntPtr? GetProcessProcAddress(IntPtr hProcess, int processID, string moduleName, string procName)   
        
            IntPtr? moduleHandle = GetProcessModuleHandle(processID, moduleName);

            if (!moduleHandle.HasValue)
                return null;



            //code adapted from http://alter.org.ua/en/docs/nt_kernel/procaddr/index3.php


            UIntPtr hmodCaller = new UIntPtr(unchecked((ulong)moduleHandle.Value.ToInt64()));


            //http://***.com/questions/769537/hook-loadlibrary-call-from-managed-code

            //parse dos header
            UIntPtr dos_header_ptr = hmodCaller;
            if (dos_header_ptr == UIntPtr.Zero)
                return null;

            IMAGE_DOS_HEADER dos_header;
            if (!ReadProcessMemory(hProcess, dos_header_ptr, out dos_header, IMAGE_DOS_HEADER.SizeOf, IntPtr.Zero))
                return null;

            if (dos_header.e_magic != IMAGE_DOS_SIGNATURE)
                return null; //not a dos program



            IMAGE_DATA_DIRECTORY[] DataDirectory;
            if (IntPtr.Size == 4)
            
                //parse nt header
                UIntPtr nt_header_ptr = new UIntPtr((uint)dos_header.e_lfanew + hmodCaller.ToUInt32());
                if (nt_header_ptr == UIntPtr.Zero)
                    return null;

                IMAGE_NT_HEADERS32 nt_header;
                if (!ReadProcessMemory(hProcess, nt_header_ptr, out nt_header, IMAGE_NT_HEADERS32.SizeOf, IntPtr.Zero))
                    return null;

                if (nt_header.Signature != IMAGE_NT_SIGNATURE)
                    return null; //not a windows program


                //http://newgre.net/ncodehook
                //if (ntHeaders.FileHeader.Characteristics & IMAGE_FILE_DLL)
                //  throw std::runtime_error("Error while setting image base address: not the image base of an executable");


                //optional header (pretty much not optional)
                IMAGE_OPTIONAL_HEADER32 optional_header = nt_header.OptionalHeader32;
                if (optional_header.Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC)     
                    return null; //no optional header


                DataDirectory = optional_header.DataDirectory;
            
            else    //if (IntPtr.Size == 4)
            
                //parse nt header
                UIntPtr nt_header_ptr = new UIntPtr((uint)dos_header.e_lfanew + hmodCaller.ToUInt64());
                if (nt_header_ptr == UIntPtr.Zero)
                    return null;

                IMAGE_NT_HEADERS64 nt_header;
                if (!ReadProcessMemory(hProcess, nt_header_ptr, out nt_header, IMAGE_NT_HEADERS64.SizeOf, IntPtr.Zero))
                    return null;

                if (nt_header.Signature != IMAGE_NT_SIGNATURE)
                    return null; //not a windows program


                //http://newgre.net/ncodehook
                //if (ntHeaders.FileHeader.Characteristics & IMAGE_FILE_DLL)
                //  throw std::runtime_error("Error while setting image base address: not the image base of an executable");


                //optional header (pretty much not optional)
                IMAGE_OPTIONAL_HEADER64 optional_header = nt_header.OptionalHeader64;
                if (optional_header.Magic != IMAGE_NT_OPTIONAL_HDR64_MAGIC)     
                    return null; //no optional header


                DataDirectory = optional_header.DataDirectory;

                //if (IntPtr.Size == 4)



            //http://***.com/questions/3430718/thunk-table-in-import-address-table and http://forums.codeguru.com/showthread.php?512610-RESOLVED-api-hooking and especially http://svn.coderepos.org/share/lang/objective-cplusplus/i3/trunk/tmp/dwmedit/ApiHook.cc
            DirectoryEntries entryIndex = DirectoryEntries.IMAGE_DIRECTORY_ENTRY_EXPORT;   

            uint size = DataDirectory[(int)entryIndex].Size;

            if (size == 0)
                return null; //no import table

            uint virtualAddress = DataDirectory[(int)entryIndex].VirtualAddress;

            //http://newgre.net/ncodehook
            if (virtualAddress == 0)
                return null; //no import directory


            UIntPtr pExports_ptr = new UIntPtr((ulong)virtualAddress + hmodCaller.ToUInt64());
            if (pExports_ptr == UIntPtr.Zero)
                return null;

            IMAGE_EXPORT_DIRECTORY pExports;
            if (!ReadProcessMemory(hProcess, pExports_ptr,
                out pExports, IMAGE_EXPORT_DIRECTORY.SizeOf, IntPtr.Zero))
            
                return null;
            


            UIntPtr functions_ptr = new UIntPtr(hmodCaller.ToUInt64() + (ulong)pExports.AddressOfFunctions);
            UIntPtr ordinals_ptr = new UIntPtr(hmodCaller.ToUInt64() + (ulong)pExports.AddressOfNameOrdinals);
            UIntPtr names_ptr = new UIntPtr(hmodCaller.ToUInt64() + (ulong)pExports.AddressOfNames);

            uint max_name = pExports.NumberOfNames;
            uint max_func = pExports.NumberOfFunctions;

            uint max_ordinal = max_name;   



            uint[] functions = new uint[max_func];
            if (!ReadProcessMemory(hProcess, functions_ptr, functions, (int)max_func * sizeof(uint), IntPtr.Zero))
            
                return null;
            

            ushort[] ordinals = new ushort[max_ordinal];
            if (!ReadProcessMemory(hProcess, ordinals_ptr, ordinals, (int)max_ordinal * sizeof(ushort), IntPtr.Zero))
            
                return null;
            

            uint[] names = new uint[max_name];
            if (!ReadProcessMemory(hProcess, names_ptr, names, (int)max_name * sizeof(uint), IntPtr.Zero))
            
                return null;
            



            for (uint i = 0; i < max_ordinal; i++)    
            
                uint ord = ordinals[i];
                if (i >= max_name || ord >= max_func)
                
                    return null;
                

                if (functions[ord] < virtualAddress || functions[ord] >= virtualAddress + size)
                
                    UIntPtr name_ptr = new UIntPtr(hmodCaller.ToUInt64() + (ulong)names[i]);

                    if (name_ptr != UIntPtr.Zero)
                    
                        byte[] name_buf = new byte[procName.Length + 1];    //NB! +1 for terminating zero
                        if (!ReadProcessMemory(hProcess, name_ptr, name_buf, name_buf.Length, IntPtr.Zero))
                        
                            continue;
                        

                        if (name_buf[name_buf.Length - 1] == 0)     //check for partial name that does not end with terminating zero
                        
                            string name = Encoding.ASCII.GetString(name_buf, 0, name_buf.Length - 1);   //NB! buf length - 1

                            if (name == procName)
                            
                                var pFunctionAddress1 = new UIntPtr(hmodCaller.ToUInt64() + (ulong)functions[ord]);

                                return new IntPtr(unchecked((long)pFunctionAddress1.ToUInt64()));
                            
                        
                       //if (name_ptr != UIntPtr.Zero)
                   //if (functions[ord] < virtualAddress || functions[ord] >= virtualAddress + size)
               //for (uint i = 0; i < pExports.AddressOfNames; i++)

            return null;

           //static IntPtr? GetProcessProcAddress(int procID, string moduleName, string procName)

        #region PE Structs

        private const uint IMAGE_DOS_SIGNATURE = 0x5A4D;      // MZ
        private const uint IMAGE_OS2_SIGNATURE = 0x454E;      // NE
        private const uint IMAGE_OS2_SIGNATURE_LE = 0x454C;      // LE
        private const uint IMAGE_VXD_SIGNATURE = 0x454C;      // LE
        private const uint IMAGE_NT_SIGNATURE = 0x00004550;  // PE00

        private const uint IMAGE_NT_OPTIONAL_HDR32_MAGIC = 0x10b;
        private const uint IMAGE_NT_OPTIONAL_HDR64_MAGIC = 0x20b;

        private enum DirectoryEntries
        
            IMAGE_DIRECTORY_ENTRY_EXPORT = 0,   // Export Directory
            IMAGE_DIRECTORY_ENTRY_IMPORT = 1,   // Import Directory
            IMAGE_DIRECTORY_ENTRY_RESOURCE = 2,   // Resource Directory
            IMAGE_DIRECTORY_ENTRY_EXCEPTION = 3,   // Exception Directory
            IMAGE_DIRECTORY_ENTRY_SECURITY = 4,   // Security Directory
            IMAGE_DIRECTORY_ENTRY_BASERELOC = 5,   // Base Relocation Table
            IMAGE_DIRECTORY_ENTRY_DEBUG = 6,   // Debug Directory
            //      IMAGE_DIRECTORY_ENTRY_COPYRIGHT       7,   // (X86 usage)
            IMAGE_DIRECTORY_ENTRY_ARCHITECTURE = 7,   // Architecture Specific Data
            IMAGE_DIRECTORY_ENTRY_GLOBALPTR = 8,   // RVA of GP
            IMAGE_DIRECTORY_ENTRY_TLS = 9,   // TLS Directory
            IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG = 10,   // Load Configuration Directory
            IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT = 11,   // Bound Import Directory in headers
            IMAGE_DIRECTORY_ENTRY_IAT = 12,   // Import Address Table
            IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT = 13,   // Delay Load Import Descriptors
            IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR = 14,   // COM Runtime descriptor

           //private enum DirectoryEntries



        //code taken from http://www.sergeyakopov.com/2010/11/reading-pe-format-using-data-marshaling-in-net

        [StructLayout(LayoutKind.Sequential)]
        public struct IMAGE_DOS_HEADER
        
            public static int SizeOf = Marshal.SizeOf(typeof(IMAGE_DOS_HEADER));

            public UInt16 e_magic;
            public UInt16 e_cblp;
            public UInt16 e_cp;
            public UInt16 e_crlc;
            public UInt16 e_cparhdr;
            public UInt16 e_minalloc;
            public UInt16 e_maxalloc;
            public UInt16 e_ss;
            public UInt16 e_sp;
            public UInt16 e_csum;
            public UInt16 e_ip;
            public UInt16 e_cs;
            public UInt16 e_lfarlc;
            public UInt16 e_ovno;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
            public UInt16[] e_res1;
            public UInt16 e_oemid;
            public UInt16 e_oeminfo;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
            public UInt16[] e_res2;
            public UInt32 e_lfanew;
        

        [StructLayout(LayoutKind.Sequential)]
        public struct IMAGE_NT_HEADERS32
        
            public static int SizeOf = Marshal.SizeOf(typeof(IMAGE_NT_HEADERS32));

            public UInt32 Signature;
            public IMAGE_FILE_HEADER FileHeader;
            public IMAGE_OPTIONAL_HEADER32 OptionalHeader32;
        

        [StructLayout(LayoutKind.Sequential)]
        public struct IMAGE_NT_HEADERS64
        
            public static int SizeOf = Marshal.SizeOf(typeof(IMAGE_NT_HEADERS64));

            public UInt32 Signature;
            public IMAGE_FILE_HEADER FileHeader;
            public IMAGE_OPTIONAL_HEADER64 OptionalHeader64;
        

        [StructLayout(LayoutKind.Sequential)]
        public struct IMAGE_FILE_HEADER
        
            public UInt16 Machine;
            public UInt16 NumberOfSections;
            public UInt32 TimeDateStamp;
            public UInt32 PointerToSymbolTable;
            public UInt32 NumberOfSymbols;
            public UInt16 SizeOfOptionalHeader;
            public UInt16 Characteristics;
        

        [StructLayout(LayoutKind.Sequential)]
        public struct IMAGE_OPTIONAL_HEADER32
        
            public UInt16 Magic;
            public Byte MajorLinkerVersion;
            public Byte MinorLinkerVersion;
            public UInt32 SizeOfCode;
            public UInt32 SizeOfInitializedData;
            public UInt32 SizeOfUninitializedData;
            public UInt32 AddressOfEntryPoint;
            public UInt32 BaseOfCode;
            public UInt32 BaseOfData;
            public UInt32 ImageBase;
            public UInt32 SectionAlignment;
            public UInt32 FileAlignment;
            public UInt16 MajorOperatingSystemVersion;
            public UInt16 MinorOperatingSystemVersion;
            public UInt16 MajorImageVersion;
            public UInt16 MinorImageVersion;
            public UInt16 MajorSubsystemVersion;
            public UInt16 MinorSubsystemVersion;
            public UInt32 Win32VersionValue;
            public UInt32 SizeOfImage;
            public UInt32 SizeOfHeaders;
            public UInt32 CheckSum;
            public UInt16 Subsystem;
            public UInt16 DllCharacteristics;
            public UInt32 SizeOfStackReserve;
            public UInt32 SizeOfStackCommit;
            public UInt32 SizeOfHeapReserve;
            public UInt32 SizeOfHeapCommit;
            public UInt32 LoaderFlags;
            public UInt32 NumberOfRvaAndSizes;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
            public IMAGE_DATA_DIRECTORY[] DataDirectory;
        

        [StructLayout(LayoutKind.Sequential)]
        public struct IMAGE_OPTIONAL_HEADER64
        
            public UInt16 Magic;
            public Byte MajorLinkerVersion;
            public Byte MinorLinkerVersion;
            public UInt32 SizeOfCode;
            public UInt32 SizeOfInitializedData;
            public UInt32 SizeOfUninitializedData;
            public UInt32 AddressOfEntryPoint;
            public UInt32 BaseOfCode;
            public UInt64 ImageBase;
            public UInt32 SectionAlignment;
            public UInt32 FileAlignment;
            public UInt16 MajorOperatingSystemVersion;
            public UInt16 MinorOperatingSystemVersion;
            public UInt16 MajorImageVersion;
            public UInt16 MinorImageVersion;
            public UInt16 MajorSubsystemVersion;
            public UInt16 MinorSubsystemVersion;
            public UInt32 Win32VersionValue;
            public UInt32 SizeOfImage;
            public UInt32 SizeOfHeaders;
            public UInt32 CheckSum;
            public UInt16 Subsystem;
            public UInt16 DllCharacteristics;
            public UInt64 SizeOfStackReserve;
            public UInt64 SizeOfStackCommit;
            public UInt64 SizeOfHeapReserve;
            public UInt64 SizeOfHeapCommit;
            public UInt32 LoaderFlags;
            public UInt32 NumberOfRvaAndSizes;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
            public IMAGE_DATA_DIRECTORY[] DataDirectory;
        

        [StructLayout(LayoutKind.Sequential)]
        public struct IMAGE_DATA_DIRECTORY
        
            public UInt32 VirtualAddress;
            public UInt32 Size;
        


        [StructLayout(LayoutKind.Sequential)]
        public struct ImgDelayDescr
        
            public static uint SizeOf = (uint)Marshal.SizeOf(typeof(ImgDelayDescr));

            public uint grAttrs;        // attributes
            public uint rvaDLLName;     // RVA to dll name
            public uint rvaHmod;        // RVA of module handle
            public uint rvaIAT;         // RVA of the IAT
            public uint rvaINT;         // RVA of the INT
            public uint rvaBoundIAT;    // RVA of the optional bound IAT
            public uint rvaUnloadIAT;   // RVA of optional copy of original IAT
            public uint dwTimeStamp;    // 0 if not bound,
            // O.W. date/time stamp of DLL bound to (Old BIND)
         //ImgDelayDescr, * PImgDelayDescr;


        //http://www.gamedev.net/topic/409936-advanced-c-native-dll-image-import-reading/
        [StructLayout(LayoutKind.Explicit)]
        public struct IMAGE_IMPORT_DESCRIPTOR
        
            public static uint SizeOf = (uint)Marshal.SizeOf(typeof(IMAGE_IMPORT_DESCRIPTOR));

            #region union
            /// <summary>
            /// CSharp doesnt really support unions, but they can be emulated by a field offset 0
            /// </summary>
            [FieldOffset(0)]
            public uint Characteristics;            // 0 for terminating null import descriptor
            [FieldOffset(0)]
            public uint OriginalFirstThunk;         // RVA to original unbound IAT (PIMAGE_THUNK_DATA)
            #endregion

            [FieldOffset(4)]
            public uint TimeDateStamp;
            [FieldOffset(8)]
            public uint ForwarderChain;
            [FieldOffset(12)]
            public uint Name;
            [FieldOffset(16)]
            public uint FirstThunk;
        

        //http://pinvoke.net/default.aspx/Structures/IMAGE_EXPORT_DIRECTORY.html
        [StructLayout(LayoutKind.Sequential)]
        public struct IMAGE_EXPORT_DIRECTORY
        
            public static uint SizeOf = (uint)Marshal.SizeOf(typeof(IMAGE_EXPORT_DIRECTORY));

            public UInt32 Characteristics;
            public UInt32 TimeDateStamp;
            public UInt16 MajorVersion;
            public UInt16 MinorVersion;
            public UInt32 Name;
            public UInt32 Base;
            public UInt32 NumberOfFunctions;
            public UInt32 NumberOfNames;
            public UInt32 AddressOfFunctions;     // RVA from base of image
            public UInt32 AddressOfNames;     // RVA from base of image
            public UInt32 AddressOfNameOrdinals;  // RVA from base of image
        


        [StructLayout(LayoutKind.Sequential)]
        public struct IMAGE_THUNK_DATA        
        
            public static uint SizeOf = (uint)Marshal.SizeOf(typeof(IMAGE_THUNK_DATA));

            public IntPtr ForwarderString;      // PBYTE 
            public IntPtr Function;             // PDWORD
            public IntPtr Ordinal;
            public IntPtr AddressOfData;        // PIMAGE_IMPORT_BY_NAME
        



        #endregion



        [DllImport("kernel32.dll", SetLastError = true)]
        static public extern bool CloseHandle(IntPtr hHandle);

        [DllImport("kernel32.dll")]
        static extern bool Module32First(IntPtr hSnapshot, ref MODULEENTRY32 lpme);

        [DllImport("kernel32.dll")]
        static extern bool Module32Next(IntPtr hSnapshot, ref MODULEENTRY32 lpme);

        [DllImport("kernel32.dll", SetLastError = true)]
        static public extern IntPtr CreateToolhelp32Snapshot(SnapshotFlags dwFlags, int th32ProcessID);

        public const short INVALID_HANDLE_VALUE = -1;

        [Flags]
        public enum SnapshotFlags : uint
        
            HeapList = 0x00000001,
            Process = 0x00000002,
            Thread = 0x00000004,
            Module = 0x00000008,
            Module32 = 0x00000010,
            Inherit = 0x80000000,
            All = 0x0000001F
        

        public struct MODULEENTRY32
        
            public static uint SizeOf = (uint)Marshal.SizeOf(typeof(MODULEENTRY32));

            //http://pastebin.com/BzD1jdmH
            private const int MAX_PATH = 255;
            internal uint dwSize;    
            internal uint th32ModuleID;
            internal uint th32ProcessID;
            internal uint GlblcntUsage;
            internal uint ProccntUsage;
            internal IntPtr modBaseAddr;
            internal uint modBaseSize;
            internal IntPtr hModule;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_PATH + 1)]
            internal string szModule;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_PATH + 5)]
            internal string szExePath;
        



        [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
        private static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr baseAddress, [Out] byte[] buffer, int size, out IntPtr numBytesRead);  

        [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
        private static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr baseAddress, [Out] byte[] buffer, int size, IntPtr numBytesRead);

        [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
        private static extern bool ReadProcessMemory(IntPtr hProcess, UIntPtr baseAddress, [Out] byte[] buffer, int size, IntPtr numBytesRead);

        [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
        private static extern bool ReadProcessMemory(IntPtr hProcess, UIntPtr baseAddress, [Out] uint[] buffer, int size, IntPtr numBytesRead);

        [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
        private static extern bool ReadProcessMemory(IntPtr hProcess, UIntPtr baseAddress, [Out] ushort[] buffer, int size, IntPtr numBytesRead);

        [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
        private static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr baseAddress, out IntPtr buffer, int size, IntPtr numBytesRead);

        [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
        private static extern bool ReadProcessMemory(IntPtr hProcess, UIntPtr baseAddress, out IMAGE_DOS_HEADER buffer, int size, IntPtr numBytesRead);

        [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
        private static extern bool ReadProcessMemory(IntPtr hProcess, UIntPtr baseAddress, out IMAGE_NT_HEADERS32 buffer, int size, IntPtr numBytesRead);

        [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
        private static extern bool ReadProcessMemory(IntPtr hProcess, UIntPtr baseAddress, out IMAGE_NT_HEADERS64 buffer, int size, IntPtr numBytesRead);

        [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
        private static extern bool ReadProcessMemory(IntPtr hProcess, UIntPtr baseAddress, out ImgDelayDescr buffer, uint size, IntPtr numBytesRead);

        [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
        private static extern bool ReadProcessMemory(IntPtr hProcess, UIntPtr baseAddress, out IMAGE_THUNK_DATA buffer, uint size, IntPtr numBytesRead);   

        [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
        private static extern bool ReadProcessMemory(IntPtr hProcess, UIntPtr baseAddress, out IMAGE_IMPORT_DESCRIPTOR buffer, uint size, IntPtr numBytesRead);   

        [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
        private static extern bool ReadProcessMemory(IntPtr hProcess, UIntPtr baseAddress, out IMAGE_EXPORT_DIRECTORY buffer, uint size, IntPtr numBytesRead);   



    

【讨论】:

那么,我应该使用这个 EAT 阅读器而不是 GetProcAddress 来获取地址吗? :) 我会试试 . 是的。请注意,第二个参数是进程 ID。最后一个是过程名称。我的代码中的参数名称令人困惑。 另外一个版本的代码更加清理和合并了CreateRemoteThread部分代码,这里由Ultratrunks提供:gist.github.com/ultratrunks/63008d0aafe3c7aec68b(相关讨论可以在这个问题下找到***.com/questions/31594130/…)

以上是关于C# Dll 注入器、VB.Net Dll 注入器的主要内容,如果未能解决你的问题,请参考以下文章

dll注入器怎么用 看完你就知道了

dll注入器怎么用 看完你就知道了

DLL注入---任务管理器之进程保护--Python

开源dll注入器

资源分享Dll Injector(DLL注入器)

使用来自 x64 注入器的 x86 dll 注入 x86 目标