Skip to content

Commit 54d0818

Browse files
committed
Make the module name comparison less strict
1 parent 752a6f4 commit 54d0818

File tree

4 files changed

+69
-39
lines changed

4 files changed

+69
-39
lines changed

src/SharpMonoInjector.Gui/ViewModels/MainWindowViewModel.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,12 @@ private async void ExecuteRefreshCommand(object parameter)
4848

4949
await Task.Run(() =>
5050
{
51+
int cp = Process.GetCurrentProcess().Id;
52+
5153
foreach (Process p in Process.GetProcesses()) {
54+
if (p.Id == cp)
55+
continue;
56+
5257
const ProcessAccessRights flags = ProcessAccessRights.PROCESS_QUERY_INFORMATION | ProcessAccessRights.PROCESS_VM_READ;
5358
IntPtr handle;
5459

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
using System;
2+
3+
namespace SharpMonoInjector
4+
{
5+
public struct ExportedFunction
6+
{
7+
public string Name;
8+
9+
public IntPtr Address;
10+
11+
public ExportedFunction(string name, IntPtr address)
12+
{
13+
Name = name;
14+
Address = address;
15+
}
16+
}
17+
}

src/SharpMonoInjector/Injector.cs

Lines changed: 7 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -121,31 +121,13 @@ public void Dispose()
121121

122122
private void ObtainMonoExports()
123123
{
124-
int e_lfanew = _memory.ReadInt(_mono + 0x3C);
125-
IntPtr ntHeaders = _mono + e_lfanew;
126-
IntPtr optionalHeader = ntHeaders + 0x18;
127-
IntPtr dataDirectory = optionalHeader + (Is64Bit ? 0x70 : 0x60);
128-
IntPtr exportDirectory = _mono + _memory.ReadInt(dataDirectory);
129-
IntPtr names = _mono + _memory.ReadInt(exportDirectory + 0x20);
130-
IntPtr ordinals = _mono + _memory.ReadInt(exportDirectory + 0x24);
131-
IntPtr functions = _mono + _memory.ReadInt(exportDirectory + 0x1C);
132-
int count = _memory.ReadInt(exportDirectory + 0x18);
133-
134-
for (int i = 0; i < count; i++) {
135-
int offset = _memory.ReadInt(names + i * 4);
136-
string name = _memory.ReadString(_mono + offset, 32, Encoding.ASCII);
137-
138-
if (!Exports.ContainsKey(name))
139-
continue;
140-
141-
short ordinal = _memory.ReadShort(ordinals + i * 2);
142-
IntPtr address = _mono + _memory.ReadInt(functions + ordinal * 4);
143-
144-
if (address == IntPtr.Zero)
145-
throw new InjectorException($"Failed to obtain the address of {name}()");
146-
147-
Exports[name] = address;
148-
}
124+
foreach (ExportedFunction ef in ProcessUtils.GetExportedFunctions(_handle, _mono))
125+
if (Exports.ContainsKey(ef.Name))
126+
Exports[ef.Name] = ef.Address;
127+
128+
foreach (var kvp in Exports)
129+
if (kvp.Value == IntPtr.Zero)
130+
throw new InjectorException($"Failed to obtain the address of {kvp.Key}()");
149131
}
150132

151133
public IntPtr Inject(byte[] rawAssembly, string @namespace, string className, string methodName)

src/SharpMonoInjector/ProcessUtils.cs

Lines changed: 40 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,72 @@
11
using System;
2+
using System.Collections.Generic;
23
using System.ComponentModel;
3-
using System.Diagnostics;
4+
using System.Linq;
45
using System.Runtime.InteropServices;
56
using System.Text;
67

78
namespace SharpMonoInjector
89
{
910
public static class ProcessUtils
1011
{
12+
public static IEnumerable<ExportedFunction> GetExportedFunctions(IntPtr handle, IntPtr mod)
13+
{
14+
using (Memory memory = new Memory(handle)) {
15+
int e_lfanew = memory.ReadInt(mod + 0x3C);
16+
IntPtr ntHeaders = mod + e_lfanew;
17+
IntPtr optionalHeader = ntHeaders + 0x18;
18+
IntPtr dataDirectory = optionalHeader + (Is64BitProcess(handle) ? 0x70 : 0x60);
19+
IntPtr exportDirectory = mod + memory.ReadInt(dataDirectory);
20+
IntPtr names = mod + memory.ReadInt(exportDirectory + 0x20);
21+
IntPtr ordinals = mod + memory.ReadInt(exportDirectory + 0x24);
22+
IntPtr functions = mod + memory.ReadInt(exportDirectory + 0x1C);
23+
int count = memory.ReadInt(exportDirectory + 0x18);
24+
25+
for (int i = 0; i < count; i++) {
26+
int offset = memory.ReadInt(names + i * 4);
27+
string name = memory.ReadString(mod + offset, 32, Encoding.ASCII);
28+
short ordinal = memory.ReadShort(ordinals + i * 2);
29+
IntPtr address = mod + memory.ReadInt(functions + ordinal * 4);
30+
31+
if (address != IntPtr.Zero)
32+
yield return new ExportedFunction(name, address);
33+
}
34+
}
35+
}
36+
1137
public static bool GetMonoModule(IntPtr handle, out IntPtr monoModule)
1238
{
1339
int size = Is64BitProcess(handle) ? 8 : 4;
1440

15-
IntPtr[] modulePointers = new IntPtr[0];
41+
IntPtr[] ptrs = new IntPtr[0];
1642

1743
if (!Native.EnumProcessModulesEx(
18-
handle, modulePointers, 0, out int bytesNeeded, ModuleFilter.LIST_MODULES_ALL)) {
44+
handle, ptrs, 0, out int bytesNeeded, ModuleFilter.LIST_MODULES_ALL)) {
1945
throw new InjectorException("Failed to enumerate process modules", new Win32Exception(Marshal.GetLastWin32Error()));
2046
}
2147

2248
int count = bytesNeeded / size;
23-
modulePointers = new IntPtr[count];
49+
ptrs = new IntPtr[count];
2450

2551
if (!Native.EnumProcessModulesEx(
26-
handle, modulePointers, bytesNeeded, out bytesNeeded, ModuleFilter.LIST_MODULES_ALL)) {
52+
handle, ptrs, bytesNeeded, out bytesNeeded, ModuleFilter.LIST_MODULES_ALL)) {
2753
throw new InjectorException("Failed to enumerate process modules", new Win32Exception(Marshal.GetLastWin32Error()));
2854
}
2955

3056
for (int i = 0; i < count; i++) {
3157
StringBuilder path = new StringBuilder(260);
58+
Native.GetModuleFileNameEx(handle, ptrs[i], path, 260);
3259

33-
Native.GetModuleFileNameEx(
34-
handle, modulePointers[i], path, 260);
60+
if (path.ToString().IndexOf("mono", StringComparison.OrdinalIgnoreCase) > -1) {
61+
if (!Native.GetModuleInformation(handle, ptrs[i], out MODULEINFO info, (uint)(size * ptrs.Length)))
62+
throw new InjectorException("Failed to get module information", new Win32Exception(Marshal.GetLastWin32Error()));
3563

36-
if (path.ToString().EndsWith("mono.dll", StringComparison.OrdinalIgnoreCase)) {
37-
if (!Native.GetModuleInformation(
38-
handle, modulePointers[i], out MODULEINFO info, (uint)(size * modulePointers.Length))) {
39-
throw new InjectorException("Failed to get module information for mono.dll", new Win32Exception(Marshal.GetLastWin32Error()));
40-
}
64+
var funcs = GetExportedFunctions(handle, info.lpBaseOfDll);
4165

42-
monoModule = info.lpBaseOfDll;
43-
return true;
66+
if (funcs.Any(f => f.Name == "mono_get_root_domain")) {
67+
monoModule = info.lpBaseOfDll;
68+
return true;
69+
}
4470
}
4571
}
4672

0 commit comments

Comments
 (0)