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 注入器的主要内容,如果未能解决你的问题,请参考以下文章