因此,我决定出于教育目的将DLL注入记事本进程。
IntPtr hProcess = OpenProcess(ProcessAccessFlags.VirtualMemoryWrite | ProcessAccessFlags.VirtualMemoryWrite | ProcessAccessFlags.VirtualMemoryOperation, false, process.Id);
_log.Info({0}, new Win32Exception(Marshal.GetLastWin32Error()).Message);
这似乎因“拒绝访问”而失败。奇怪的是hProcess
不是IntPtr.Zero
,它看起来像一个句柄。因此,我不确定它是否真的失败了。
我尝试过的事情如下。
Process.EnterDebugMode();
0x001F0FFF
整个课程都在下面(不再位于粘贴容器上)。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Runtime.ConstrainedExecution;
using System.Runtime.InteropServices;
using System.Security;
using System.Text;
using System.Threading.Tasks;
namespace Blade.Injector
{
class Injector
{
private readonly NLog.Logger _log = NLog.LogManager.GetCurrentClassLogger();
[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, AllocationType flAllocationType, MemoryProtection flProtect);
[Flags]
public enum AllocationType
{
Commit = 0x1000,
Reserve = 0x2000,
Decommit = 0x4000,
Release = 0x8000,
Reset = 0x80000,
Physical = 0x400000,
TopDown = 0x100000,
WriteWatch = 0x200000,
LargePages = 0x20000000
}
[Flags]
public enum MemoryProtection
{
Execute = 0x10,
ExecuteRead = 0x20,
ExecuteReadWrite = 0x40,
ExecuteWriteCopy = 0x80,
NoAccess = 0x01,
ReadOnly = 0x02,
ReadWrite = 0x04,
WriteCopy = 0x08,
GuardModifierflag = 0x100,
NoCacheModifierflag = 0x200,
WriteCombineModifierflag = 0x400
}
[DllImport("kernel32.dll", SetLastError = true)]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
[SuppressUnmanagedCodeSecurity]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool CloseHandle(IntPtr hObject);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern IntPtr OpenProcess(ProcessAccessFlags processAccess, bool bInheritHandle, int processId);
[Flags]
public enum ProcessAccessFlags : uint
{
All = 0x001F0FFF,
Terminate = 0x00000001,
CreateThread = 0x00000002,
VirtualMemoryOperation = 0x00000008,
VirtualMemoryRead = 0x00000010,
VirtualMemoryWrite = 0x00000020,
DuplicateHandle = 0x00000040,
CreateProcess = 0x000000080,
SetQuota = 0x00000100,
SetInformation = 0x00000200,
QueryInformation = 0x00000400,
QueryLimitedInformation = 0x00001000,
Synchronize = 0x00100000
}
private const string DllFile = @"C:\Poison.dll";
public void List()
{
var processes = Process.GetProcesses().Where(p => !string.IsNullOrEmpty(p.MainWindowTitle)).ToList();
foreach (var process in processes)
{
_log.Info("{0} -> {1}", process.MainWindowTitle, process.Id);
}
}
public bool Inject(int pid)
{
Process.EnterDebugMode();
Process process = Process.GetProcessById(pid);
foreach (ProcessModule module in process.Modules)
{
if (module.FileName.Equals(DllFile))
{
_log.Info("{0} already inside process.", module.FileName);
return false;
}
}
_log.Info("Opening process. Last Win32 error is now '{0}'.", new Win32Exception(Marshal.GetLastWin32Error()).Message);
IntPtr hProcess = OpenProcess(ProcessAccessFlags.VirtualMemoryWrite | ProcessAccessFlags.VirtualMemoryWrite | ProcessAccessFlags.VirtualMemoryOperation, false, process.Id);
_log.Info("Opening process resulted in message '{0}'.", new Win32Exception(Marshal.GetLastWin32Error()).Message);
_log.Info("Allocating memory for dll file.");
IntPtr allocAddress = VirtualAllocEx(hProcess, IntPtr.Zero, (uint)Encoding.Unicode.GetByteCount(DllFile.ToCharArray()), AllocationType.Commit, MemoryProtection.ReadWrite);
_log.Info("Allocating memory for '{0}' resulted in '{1}'.", DllFile, new Win32Exception(Marshal.GetLastWin32Error()).Message);
CloseHandle(hProcess);
foreach (ProcessModule module in process.Modules)
{
if (module.FileName.Equals(DllFile))
{
_log.Info("Success! {0} inside process.", module.FileName);
}
}
return true;
}
}
}
new Win32Exception(Marshal.GetLastWin32Error()).Message)
中的消息与上次通话有关?也许其他事情失败了?OpenProcess()
方法是否在C#中有效?是否正在检查hProcess
是否IntPtr.Zero
正常?答案 0 :(得分:2)
第一个找到答案的地方
我怎么知道(任何功能)是否起作用?
将在该功能的文档页面中。对于OpenProcess()
,文档页面为https://docs.microsoft.com/en-us/windows/desktop/api/processthreadsapi/nf-processthreadsapi-openprocess
除其他外,该页面包含以下语句:
如果函数成功,则返回值是指定进程的打开句柄。
如果函数失败,则返回值为NULL。要获取扩展的错误信息,请调用GetLastError。
将基本逻辑应用于第二条语句,我们得出结论
因此,比较返回值与IntPtr.Zero
是可以的,实际上是最好的方法。
还请注意,“要获取扩展的错误信息,请调用GetLastError。”属于“如果功能失败”。如果函数成功,则没有详细的错误信息,因此您没有理由调用GetLastError
,也没有理由解释它的结果。