hearthbuddy中的一段代码
// Token: 0x06001A79 RID: 6777 RVA: 0x000DD024 File Offset: 0x000DB224 internal IntPtr method_33(IntPtr intptr_37, string string_0, params Class276.Enum20[] enum20_0) { while (intptr_37 != IntPtr.Zero) { using (AllocatedMemory allocatedMemory = this.externalProcessMemory_0.CreateAllocatedMemory(256)) { allocatedMemory.AllocateOfChunk<IntPtr>("Itr"); IntPtr intPtr; while ((intPtr = this.method_35(intptr_37, allocatedMemory["Itr"])) != IntPtr.Zero) { IntPtr address = this.method_37(intPtr); if (this.externalProcessMemory_0.ReadStringA(address) == string_0) { if (enum20_0 != null) { Class276.Enum20[] array = this.method_31(intPtr); if (array.Length != enum20_0.Length || !array.SequenceEqual(enum20_0)) { continue; } } return intPtr; } } intptr_37 = this.method_25(intptr_37); } } return IntPtr.Zero; }
// Token: 0x04000D28 RID: 3368
private readonly ExternalProcessMemory externalProcessMemory_0;
public class ExternalProcessMemory : MemoryBase
// Token: 0x06000157 RID: 343 RVA: 0x0036DA50 File Offset: 0x00362E50 public AllocatedMemory CreateAllocatedMemory(int bytes) { return new AllocatedMemory(this, bytes); }
// Token: 0x060000C1 RID: 193 RVA: 0x0036F644 File Offset: 0x00364A44 public void AllocateOfChunk(string allocatedName, int bytes) { IntPtr value = (IntPtr)this._currentOffset; this._allocated.Add(allocatedName, value); this._currentOffset += bytes; ref int ptr = ref this._currentOffset; int num = ptr; int num2 = num % 4; if (num2 != 0) { ptr = num - num2 + 4; } } // Token: 0x060000C2 RID: 194 RVA: 0x0036D637 File Offset: 0x00362A37 public void AllocateOfChunk<T>(string allocatedName) where T : struct { this.AllocateOfChunk(allocatedName, MarshalCache<T>.Size); }
出处
https://github.com/lolp1/Process.NET 这个项目的致谢名单里有提到
GreyMagic - The best of both worlds, and then some
Download: https://dl.dropbox.com/u/2068143/GreyMagic.7z
So, I wrote this a while back for our bots (Honorbuddy, Demonbuddy, BuddyWing, etc). It's a full-featured memory lib for both in and out of process memory handling. Performance tests show that it's barely a tick slower than calling ReadProcessMemory directly on simple data types, and slightly over a tick slower than reading structures. (Write speeds have not been tested, as writing is not done nearly as often)
The following are for perf tests over 1 million iterations:
Read<int>(addr, relative: true) - 4.57 ticks
ReadProcessMemory (direct) - 3.54 ticks
Deref on ReadBytes(addr, relative: true) - 3.90 ticks
Read<NonMarshalStruct>(addr, relative: true) - 5.06 ticks
Read<MarshalStruct>(addr, relative: true) - 6.48 ticks
The library itself implements a neat little trick to avoid using the marshaler wherever possible. MarshalCache<T> provides a way to cache certain data for types (size, typeof(), whether the type needs to be run through the marshaler, etc), as well as implements a way for C# to take a pointer to a generic type. (You can't do &T in C#... well... at least you couldn't)
The lib itself takes into account quite a few things, and should hopefully be plug-and-play ready. It includes a few other things that aren't really useful (but tossed in for the sake of tossing it in). I will be adding more features in the future (it lacks a pattern scanner). Feel free to use and abuse, please let me know of any bugs you run into.
In-process memory class: InProcessMemoryReader
OOP memory class: ExternalProcessMemoryReader
Enjoy folks!