问题
TL;DR
I want to implement functions from kernel32.dll
in pure C# (ReadProcessMemory
and CloseHandle
) because kernel32.dll
is Windows specific and I need to run them with Mono under GNU/Linux.
I have the following C# code to read contents at a specific address of a given process; it relies on extern
functions based on kernel32.dll
:
using System;
using System.Runtime.InteropServices;
using System.Diagnostics;
namespace MyProject
{
public enum ProcessAccess : int
{
VM_READ = 0x0010,
}
class ReadMemory
{
[DllImport("kernel32.dll")]
static extern IntPtr OpenProcess(ProcessAccess dwDesiredAccess,
bool bInheritHandle, int dwProcessId);
[DllImport("kernel32.dll")]
static extern bool ReadProcessMemory(IntPtr hProcess, UIntPtr lpBaseAddress,
byte[] lpBuffer, IntPtr dwSize, ref int lpNumberOfBytesRead);
[DllImport("kernel32.dll")]
static extern bool CloseHandle(IntPtr hObject);
static string GetProcessContentAtAddress(string processName, int address, int contentLength) {
Process process = Process.GetProcessesByName(processName)[0];
IntPtr processHandle = OpenProcess(ProcessAccess.VM_READ, false, process.Id);
UIntPtr addressPtr = (UIntPtr)address;
byte[] buffer = new byte[contentLength];
int lpNumberOfBytesRead = 0;
ReadProcessMemory(processHandle, addressPtr, buffer,
(IntPtr)buffer.Length, ref lpNumberOfBytesRead);
string contents = BitConverter.ToString(buffer);
CloseHandle(processHandle);
return contents;
}
static void Main(string[] args)
{
// read 4 bytes at address 0x12345678 of my_process
Console.WriteLine(
GetProcessContentAtAddress("my_process", 0x12345678, 4)
);
}
}
}
This works under Windows, here is an example of the expected result :
00-04-A8-00
but using Mono on GNU/Linux, kernel32.dll
is not present and executing the code returns an error :
[ERROR] FATAL UNHANDLED EXCEPTION:
System.EntryPointNotFoundException: OpenProcess assembly:<unknown assembly> type:<unknown type> member:(null)
at (wrapper managed-to-native) MyProject.ReadMemory.OpenProcess(MyProject.ProcessAccess,bool,int)
at MyProject.ReadMemory.GetProcessContentAtAddress (System.String processName, System.Int32 address, System.Int32 contentLength) [0x00029] in <e1ed4e23c9fb45098da80208134b52bb>:0
at MyProject.ReadMemory.Main (System.String[] args) [0x00001] in <e1ed4e23c9fb45098da80208134b52bb>:0
My idea was to rewrite in pure C# the 3 extern
functions (OpenProcess
, ReadProcessMemory
and CloseHandle
), to avoid relying on kernel32.dll
:
static IntPtr OpenProcess(ProcessAccess dwDesiredAccess,
bool bInheritHandle, int dwProcessId) {
return System.Diagnostics.Process
.GetProcessById(dwProcessId).Handle;
}
static bool ReadProcessMemory(IntPtr hProcess, UIntPtr lpBaseAddress,
byte[] lpBuffer, IntPtr dwSize, ref int lpNumberOfBytesRead) {
// ???
return true;
}
static bool CloseHandle(IntPtr hObject) {
// ???
return true;
}
OpenProcess
appears to work with Mono on GNU/Linux. But, since I don't use dwDesiredAccess
and bInheritedHandle
, I think it may not work on Windows (I don't have a Windows machine to test it).
I have no idea how to write the other 2 functions (ReadProcessMemory
and CloseHandle
) in pure C# (or at least that does not rely on kernel32.dll
) that will work both in Windows and under GNU/Linux using Mono.
Does anybody have ideas of implementation or just classes that would work to use in these functions? Maybe should I rely on another DLL present on Windows and Mono that already does that job? I am not an expert in C#.
Edit
When replacing [DllImport("kernel32.dll")]
to [DllImport("kernel32")]
, I got a new error when running with Mono under GNU/Linux :
[ERROR] FATAL UNHANDLED EXCEPTION:
System.DllNotFoundException: kernel32 assembly:<unknown assembly> type:<unknown type> member:(null)
at (wrapper managed-to-native) MyProject.ReadMemory.OpenProcess(MyProject.ProcessAccess,bool,int)
at MyProject.ReadMemory.GetProcessContentAtAddress (System.String processName, System.Int32 address, System.Int32 contentLength) [0x00013] in <411171bde77146b8b0aa4953209bbc2e>:0
at MyProject.ReadMemory.Main (System.String[] args) [0x00001] in <411171bde77146b8b0aa4953209bbc2e>:0
If that could help.
来源:https://stackoverflow.com/questions/61438447/rewrite-code-using-extern-kernel32-dll-functions-in-pure-c-sharp-to-work-with