|
1 | 1 | using System;
|
| 2 | +using System.Collections.Generic; |
2 | 3 | using System.ComponentModel;
|
3 |
| -using System.Diagnostics; |
| 4 | +using System.Linq; |
4 | 5 | using System.Runtime.InteropServices;
|
5 | 6 | using System.Text;
|
6 | 7 |
|
7 | 8 | namespace SharpMonoInjector
|
8 | 9 | {
|
9 | 10 | public static class ProcessUtils
|
10 | 11 | {
|
| 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 | + |
11 | 37 | public static bool GetMonoModule(IntPtr handle, out IntPtr monoModule)
|
12 | 38 | {
|
13 | 39 | int size = Is64BitProcess(handle) ? 8 : 4;
|
14 | 40 |
|
15 |
| - IntPtr[] modulePointers = new IntPtr[0]; |
| 41 | + IntPtr[] ptrs = new IntPtr[0]; |
16 | 42 |
|
17 | 43 | 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)) { |
19 | 45 | throw new InjectorException("Failed to enumerate process modules", new Win32Exception(Marshal.GetLastWin32Error()));
|
20 | 46 | }
|
21 | 47 |
|
22 | 48 | int count = bytesNeeded / size;
|
23 |
| - modulePointers = new IntPtr[count]; |
| 49 | + ptrs = new IntPtr[count]; |
24 | 50 |
|
25 | 51 | if (!Native.EnumProcessModulesEx(
|
26 |
| - handle, modulePointers, bytesNeeded, out bytesNeeded, ModuleFilter.LIST_MODULES_ALL)) { |
| 52 | + handle, ptrs, bytesNeeded, out bytesNeeded, ModuleFilter.LIST_MODULES_ALL)) { |
27 | 53 | throw new InjectorException("Failed to enumerate process modules", new Win32Exception(Marshal.GetLastWin32Error()));
|
28 | 54 | }
|
29 | 55 |
|
30 | 56 | for (int i = 0; i < count; i++) {
|
31 | 57 | StringBuilder path = new StringBuilder(260);
|
| 58 | + Native.GetModuleFileNameEx(handle, ptrs[i], path, 260); |
32 | 59 |
|
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())); |
35 | 63 |
|
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); |
41 | 65 |
|
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 | + } |
44 | 70 | }
|
45 | 71 | }
|
46 | 72 |
|
|
0 commit comments