所以我制作了一个程序,为游戏的创建者提供更多级别的编辑器工具(通过使用高级算法调整游戏值,给出这些值的指针),并且为了快捷方式,我创建了设置/检索的方法来自输入指针的值。然而,游戏有Int32,Float和Boolean变量,所以对于相同数量的指针,我需要为每种数据类型使用3种不同的方法,并且每次还有5次重载,总共有15种不同的方法用于从指针中检索值。以下是方法(没有代码):
public static int GetIntFromPointers(IntPtr baseAddress, IntPtr offset0)
public static int GetIntFromPointers(IntPtr baseAddress, IntPtr offset0, IntPtr offset1)
public static int GetIntFromPointers(IntPtr baseAddress, IntPtr offset0, IntPtr offset1, IntPtr offset2)
public static int GetIntFromPointers(IntPtr baseAddress, IntPtr offset0, IntPtr offset1, IntPtr offset2, IntPtr offset3)
public static int GetIntFromPointers(IntPtr baseAddress, IntPtr offset0, IntPtr offset1, IntPtr offset2, IntPtr offset3, IntPtr offset4)
public static float GetFloatFromPointers(IntPtr baseAddress, IntPtr offset0)
public static float GetFloatFromPointers(IntPtr baseAddress, IntPtr offset0, IntPtr offset1)
public static float GetFloatFromPointers(IntPtr baseAddress, IntPtr offset0, IntPtr offset1, IntPtr offset2)
public static float GetFloatFromPointers(IntPtr baseAddress, IntPtr offset0, IntPtr offset1, IntPtr offset2, IntPtr offset3)
public static float GetFloatFromPointers(IntPtr baseAddress, IntPtr offset0, IntPtr offset1, IntPtr offset2, IntPtr offset3, IntPtr offset4)
public static bool GetBoolFromPointers(IntPtr baseAddress, IntPtr offset0)
public static bool GetBoolFromPointers(IntPtr baseAddress, IntPtr offset0, IntPtr offset1)
public static bool GetBoolFromPointers(IntPtr baseAddress, IntPtr offset0, IntPtr offset1, IntPtr offset2)
public static bool GetBoolFromPointers(IntPtr baseAddress, IntPtr offset0, IntPtr offset1, IntPtr offset2, IntPtr offset3)
public static bool GetBoolFromPointers(IntPtr baseAddress, IntPtr offset0, IntPtr offset1, IntPtr offset2, IntPtr offset3, IntPtr offset4)
现在我不问为什么他们中的一些人不工作;他们实际上工作得很好(我认为),但我也考虑过创建一个关于所有不同类型的通用方法的可能性,但我不知道怎么做,我也不确定关于创建这样的方法将是有用的...
以下是GetIntFromPointers(IntPtr baseAddress, IntPtr offset0, IntPtr offset1, IntPtr offset2, IntPtr offset3, IntPtr offset4)
方法的代码:
public static int GetIntFromPointers(IntPtr baseAddress, IntPtr offset0, IntPtr offset1, IntPtr offset2, IntPtr offset3, IntPtr offset4)
{
IntPtr baseAddressValue = new IntPtr(BitConverter.ToInt32(MemoryStuff.ReadMemory((int)baseAddress, 4, (int)processHandle), 0));
IntPtr offset0Value = new IntPtr(BitConverter.ToInt32(MemoryStuff.ReadMemory((int)baseAddressValue + (int)offset0, 4, (int)processHandle), 0));
IntPtr offset1Value = new IntPtr(BitConverter.ToInt32(MemoryStuff.ReadMemory((int)offset0Value + (int)offset1, 4, (int)processHandle), 0));
IntPtr offset2Value = new IntPtr(BitConverter.ToInt32(MemoryStuff.ReadMemory((int)offset1Value + (int)offset2, 4, (int)processHandle), 0));
IntPtr offset3Value = new IntPtr(BitConverter.ToInt32(MemoryStuff.ReadMemory((int)offset2Value + (int)offset3, 4, (int)processHandle), 0));
int value = BitConverter.ToInt32(MemoryStuff.ReadMemory((int)offset3Value + (int)offset4, 4, (int)processHandle), 0);
return value;
}
如果你想知道这个MemoryStuff.ReadMemory
是什么,那么这里的代码也是:
[DllImport("Kernel32.dll", SetLastError = true)]
public static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, uint nSize, ref uint lpNumberOfBytesRead);
public static byte[] ReadMemory(int address, int processSize, int processHandle)
{
byte[] buffer = new byte[processSize];
uint sth = 0;
ReadProcessMemory(new IntPtr(processHandle), new IntPtr(address), buffer, (uint)processSize, ref sth);
return buffer;
}
答案 0 :(得分:0)
这样的事情会起作用吗?
public static T GetFromPointers<T>(IntPtr baseAddress, IntPtr offset0, ...)
{
return (T)Convert.ChangeType(value, typeof(T));
}
你可以访问
var myResult = GetFromPointers<int>(baseAddress, offset0, ...);
您可以做的另一件事,如果您的转换逻辑对于每种类型的转换都非常具体,您可以将Func
与其他参数一起传递
public static T GetIntFromPointers<T>(IntPtr baseAddress, IntPtr offset0, Func<T, IntPtr, IntPtr> conversionFunc)
{
// some other generic work that goes on
return conversionFunc(baseAddress, offset0,); // specific conversion logic
}
再次,像
一样访问var myResult = GetFromPointers<int>(baseAddress, offset0, ourIntConversionFunction(baseAddress, offset0));
答案 1 :(得分:0)
你可以这样做:
static unsafe class BinaryStuff
{
public static TStruct BytesToStructure<TStruct>(byte[] data) where TStruct : struct
{
fixed (byte* dataPtr = data)
return (TStruct)Marshal.PtrToStructure(new IntPtr(dataPtr), typeof(TStruct));
}
public static byte[] StructureToBytes<TStruct>(TStruct st) where TStruct : struct
{
var bytes = new byte[Marshal.SizeOf(st)];
fixed (byte* ptr = bytes)
{
Marshal.StructureToPtr(st, new IntPtr(ptr), true);
}
return bytes;
}
}
只是在没有打字的情况下进行内存读取操作,然后你只需要用偏移做五个,就可以使用这个小的通用映射器。