C#Dll注入器,VB.Net Dll注入器 太好了!我以前做过DLL注入器,但是我有Windows 7,我用C和C++做的,效果很好!但是现在当我在Windows8中尝试相同的代码时,它似乎没有以正确的方式注入DLL:)由于DLL不工作

C#Dll注入器,VB.Net Dll注入器 太好了!我以前做过DLL注入器,但是我有Windows 7,我用C和C++做的,效果很好!但是现在当我在Windows8中尝试相同的代码时,它似乎没有以正确的方式注入DLL:)由于DLL不工作,c#,vb.net,dll-injection,C#,Vb.net,Dll Injection,(我正在尝试的代码是公共代码会发生什么? 如果远程进程崩溃,则可能不应使用GetProcAddress,因为远程API地址可能不同。例如,当注入进程使用EAT挂钩而远程进程没有挂钩时,它可能不同,因此在您从中获得的地址上没有任何有意义的内容localGetProcAddress。即使使用EAT钩住两个进程,它也会有所不同,因为钩子实现会导致更随机或完全随机的位置。 我有过类似的情况,在Windows8下发生了崩溃,但在早期版本中没有 一种解决方案是读取远程进程的EAT表并从中获取地址 相关代码如

(我正在尝试的代码是公共代码会发生什么?
如果远程进程崩溃,则可能不应使用
GetProcAddress
,因为远程API地址可能不同。例如,当注入进程使用EAT挂钩而远程进程没有挂钩时,它可能不同,因此在您从中获得的地址上没有任何有意义的内容local
GetProcAddress
。即使使用EAT钩住两个进程,它也会有所不同,因为钩子实现会导致更随机或完全随机的位置。
我有过类似的情况,在Windows8下发生了崩溃,但在早期版本中没有

一种解决方案是读取远程进程的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://stackoverflow.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://stackoverflow.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);   



    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用系统诊断;
使用System.Runtime.InteropServices;
使用系统组件模型;
运用系统反思;
使用System.IO;
使用系统线程;
使用Microsoft.Win32.SafeHandles;
使用System.Runtime.CompilerServices;
使用系统安全;
名称空间注入
{
公共静态类远程\u EAT\u读取器
{
公共静态IntPtr?GetProcessModuleHandle(intProcessID,string moduleName)
{
IntPtr snapshot=IntPtr.Zero;
尝试
{
//http://pastebin.com/BzD1jdmH
snapshot=CreateToolhelp32Snapshot(SnapshotFlags.Module | SnapshotFlags.Module32,processID);
MODULEENTRY32 mod=new MODULEENTRY32(){dwSize=MODULEENTRY32.SizeOf};
如果(!Module32First(快照,参考模块))
返回null;
string searchString=moduleName.ToLowerInvariant();
做
{
if(mod.szModule.ToLowerInvariant()==搜索字符串)
返回mod.modBaseAddr;
}
while(Module32Next(快照,ref mod));
返回IntPtr.Zero;
}
最后
{
如果(快照!=IntPtr.Zero)
CloseHandle(快照);
}
}
公共静态IntPtr?GetProcessProcAddress(IntPtr hProcess,int processID,string moduleName,string procName)
{
IntPtr?moduleHandle=GetProcessModuleHandle(processID,moduleName);
if(!moduleHandle.HasValue)
返回null;
//代码改编自http://alter.org.ua/en/docs/nt_kernel/procaddr/index3.php
UIntPtr hmodCaller=新的UIntPtr(未选中((ulong)moduleHandle.Value.ToInt64());
//http://stackoverflow.com/questions/769537/hook-loadlibrary-call-from-managed-code
//解析dos报头
uintpttr dos_header_ptr=hmodCaller;
如果(dos_头_ptr==uintpttr.Zero)
返回null;
图像_DOS_头DOS_头;
if(!ReadProcessMemory(hProcess,dos_header,out dos_header,IMAGE_dos_header.SizeOf,IntPtr.Zero))
返回null;
if(dos_header.e_magic!=图像dos_签名)
返回null;//不是dos程序
图像\数据\目录[]数据目录;
如果(IntPtr.Size==4)
{
//解析nt头
uintpttr nt_header_ptr=新的uintpttr((uint)dos_header.e_lfanew+hmodCaller.ToUInt32());
如果(nt_头_ptr==uintpttr.Zero)
返回null;
图像头32个图像头;
if(!ReadProcessMemory(hProcess,nt_header,out nt_header,IMAGE_nt_HEADERS32.SizeOf,IntPtr.Zero))
返回null;
if(nt\u header.Signature!=图像\u nt\u签名)
返回null;//不是windows程序
//http://newgre.net/ncodehook
//if(nHeaders.FileHeader.Characteristics&IMAGE\u FILE\u DLL)
//抛出std::runtime_error(“设置映像基址时出错:不是可执行文件的映像基址”);
//可选标题(几乎不是可选的)
IMAGE_OPTIONAL_HEADER32 OPTIONAL_header=nt_header.OptionalHeader32;
if(可选的\u header.Magic!=图像\u NT\u可选的\u HDR32\u Magic)
返回null;//没有可选的头
DataDirectory=可选_header.DataDirectory;
}
else//if(IntPtr.Size==4)
{
//解析nt头
uintpttr nt_header_ptr=新的uintpttr((uint)dos_header.e_lfanew+hmodCaller.ToUInt64());
如果(nt_头_ptr==uintpttr.Zero)
返回null;
图像头64个图像头;
if(!ReadProcessMemory(hProcess,nt_header,out nt_header,IMAGE_nt_HEADERS64.SizeOf,IntPtr.Zero))
返回null;
if(nt\u header.Signature!=图像\u nt\u签名)
返回null;//不是windows程序
//http://newgre.net/ncodehook
//if(nHeaders.FileHeader.Characteristics&IMAGE\u FILE\u DLL)
//抛出std::runtime_error(“设置映像基址时出错:不是可执行文件的映像基址”);
//可选标题(几乎不是可选的)
IMAGE_OPTIONAL_HEADER64 OPTIONAL_header=nt_header.OptionalHeader64;
if(可选的\u header.Magic!=图像\u NT\u可选的\u HDR64\u Magic)
返回null;//没有可选的头
DataDirectory=可选_header.DataD
CloseHandle Lib "kernel32" Alias "CloseHandleA"
CloseHandle Lib "kernel32" Alias "CloseHandle"
[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);
        }
    }
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://stackoverflow.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://stackoverflow.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);   



    }
}