public void KernelReadWriteTest() { /* * */ string s1 = "foo"; var proc = Process.GetCurrentProcess(); var addr = Mem.AddressOf(ref s1); var s1New = "bar"; Mem.WriteProcessMemory(proc, addr, s1New); Assert.AreEqual(s1, s1New); var s2 = Mem.ReadProcessMemory <string>(proc, addr); Assert.AreEqual(s2, s1New); /* * */ int i1 = 123; var addr2 = Mem.AddressOf(ref i1); var i1New = 321; Mem.WriteProcessMemory(proc, addr2, i1New); Assert.AreEqual(i1, i1New); var i2 = Mem.ReadProcessMemory <int>(proc, addr2); Assert.AreEqual(i2, i1New); }
public void setup() { p = Mem.AddressOf(ref i); fixed(int *x = &i) { p2 = x; } }
public void Test1() { int i = 256; var ptr1 = Mem.AddressOf(ref i); Assert.AreEqual(ptr1.Value, i); Assert.AreEqual(ptr1.Reference, i); var rg = new int[] { 1, 2, 3 }; Pointer <int> ptr2 = Mem.AddressOfHeap(rg, OffsetOptions.ArrayData); fixed(int *p1 = rg) { int *cpy = p1; for (int j = 0; j < rg.Length; j++) { Assert.True(ptr2.Address == Marshal.UnsafeAddrOfPinnedArrayElement(rg, j)); Assert.True(cpy++ == ptr2++); } } }
// https://github.com/dotnet/coreclr/blob/master/src/inc/daccess.h /// <summary> /// Alias: PTR_HOST_MEMBER_TADDR (alt) /// </summary> internal static Pointer <byte> FieldOffsetAlt <T>(ref T value, long ofs, Pointer <byte> fieldValue) where T : unmanaged { return(Mem.AddressOf(ref value).Add((long)fieldValue).Add(ofs).Cast()); }
public static string Dump <T>(ref T value, DumpOptions options, InspectorOptions options2) { switch (options) { case DumpOptions.Info: // var addrTable = new ConsoleTable("Addresses", ""); var addr = Mem.AddressOf(ref value); addrTable.AddRow("Address", addr); if (Mem.TryGetAddressOfHeap(value, out var heap)) { addrTable.AddRow("Address (heap)", heap); } addrTable.Write(ConsoleTableFormat.Minimal); // var infoTable = new ConsoleTable("Sizes", ""); infoTable.AddRow("Intrinsic", Mem.SizeOf <T>()); infoTable.AddRow("Auto", Mem.SizeOf(value, SizeOfOptions.Auto)); infoTable.Write(ConsoleTableFormat.Minimal); // var propTable = new ConsoleTable("Runtime info", ""); propTable.AddRow("Pinnable", RuntimeProperties.IsPinnable(value)); propTable.AddRow("Blittable", RuntimeProperties.IsBlittable(value)); propTable.AddRow("Boxed", RuntimeProperties.IsBoxed(value)); propTable.AddRow("Nil", RuntimeProperties.IsDefault(value)); propTable.AddRow("Uninitialized", RuntimeProperties.IsNullMemory(value)); propTable.AddRow("In GC heap", GCHeap.IsHeapPointer(Mem.AddressOfData(ref value))); return(propTable.ToMinimalString()); case DumpOptions.Sizes: var layoutTable = new ConsoleTable("Size Type", "Value"); var options1 = Enum.GetValues <SizeOfOptions>().ToList(); options1.Remove(SizeOfOptions.Heap); foreach (var option in options1) { var sizeOf = Mem.SizeOf(value, option); if (sizeOf == Native.INVALID) { continue; } layoutTable.AddRow(Enum.GetName(option), sizeOf); } var mt = value.GetMetaType(); if (!mt.RuntimeType.IsValueType) { layoutTable.AddRow(nameof(SizeOfOptions.Heap), Mem.SizeOf(value, SizeOfOptions.Heap)); } return(layoutTable.ToString()); case DumpOptions.Layout: var layoutTable1 = new ConsoleTable(); var flags = EnumHelper.GetSetFlags(options2); if (options2 == InspectorOptions.All) { flags.Remove(InspectorOptions.All); } layoutTable1.AddColumn(flags.Select(Enum.GetName)); // Rewrite options options2 = default; foreach (var flag in flags) { options2 |= flag; } var mt1 = value.GetMetaType(); var fields = mt1.Fields.Where(x => !x.IsStatic); int s = Mem.SizeOf(value, SizeOfOptions.Auto); var p = Mem.AddressOf(ref value); foreach (var metaField in fields) { var rowValues = new List <object>(); if (options2.HasFlag(InspectorOptions.Offset)) { rowValues.Add($"{metaField.Offset:X}"); } if (options2.HasFlag(InspectorOptions.Size)) { rowValues.Add(metaField.Size); } if (options2.HasFlag(InspectorOptions.Type)) { rowValues.Add(metaField.FieldType.Name); } if (options2.HasFlag(InspectorOptions.Name)) { rowValues.Add(metaField.Name); } if (options2.HasFlag(InspectorOptions.Address)) { var addr1 = Mem.AddressOfData(ref value) + metaField.Offset; rowValues.Add(addr1.ToString()); } if (options2.HasFlag(InspectorOptions.Value)) { object fieldVal; if (!mt1.RuntimeType.IsConstructedGenericType) { fieldVal = metaField.Info.GetValue(value); } else { fieldVal = "?"; } rowValues.Add($"{fieldVal}"); } layoutTable1.AddRow(rowValues.ToArray()); } if (value is string str) { for (int i = 1; i < str.Length; i++) { char c = str[i]; var rowValues = new List <object>(); int offsetBase = (i * sizeof(char)); if (options2.HasFlag(InspectorOptions.Offset)) { rowValues.Add($"{offsetBase + RuntimeProperties.StringOverhead - sizeof(char):X}"); } if (options2.HasFlag(InspectorOptions.Size)) { rowValues.Add(sizeof(char)); } if (options2.HasFlag(InspectorOptions.Type)) { rowValues.Add(nameof(Char)); } if (options2.HasFlag(InspectorOptions.Name)) { rowValues.Add($"Char #{i + 1}"); } if (options2.HasFlag(InspectorOptions.Address)) { if (Mem.TryGetAddressOfHeap(value, OffsetOptions.StringData, out var addr2)) { addr2 += offsetBase; rowValues.Add(addr2.ToString()); } } if (options2.HasFlag(InspectorOptions.Value)) { rowValues.Add($"{c}"); } layoutTable1.AddRow(rowValues.ToArray()); } } return(layoutTable1.ToString()); default: throw new ArgumentOutOfRangeException(nameof(options)); } }