gpt4 book ai didi

c# - 在 Visual Studio 中调试时,循环变量 (i) 在每次循环后神秘地重置为 0(在不调试时有效)

转载 作者:太空宇宙 更新时间:2023-11-03 19:59:03 25 4
gpt4 key购买 nike

我正在尝试从 C# 中的进程中读取一些内存。这是我的辅助函数,用于从一系列偏移量中获取指针地址,以及相关的其他函数:

    [DllImport("kernel32.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Auto, SetLastError = true)]
public static extern Int32 ReadProcessMemory(
IntPtr hProcess,
IntPtr lpBaseAddress,
[In, Out] byte[] buffer,
UInt32 size,
out int lpNumberOfBytesRead);

public static bool ReadProcessMemoryHelper(
IntPtr hProcess,
long lpBaseAddress,
[In, Out] byte[] buffer,
UInt32 size,
out int lpNumberOfBytesRead)
{
return ReadProcessMemory(
hProcess,
new IntPtr(lpBaseAddress),
buffer,
size,
out lpNumberOfBytesRead) != 0;
}
public long Pointer(params int[] Offsets)
{
long pointerAddress = _baseAddr;

if (Offsets.Length > 1)
{
byte[] buff = new byte[4];
for (int i = 0; i < Offsets.Length - 1; i++)
{
int bytesRead;
var cur = pointerAddress;
var offset = Offsets[i];
var next = cur + offset;
Console.WriteLine("i = {0}", i);
Console.WriteLine("[{0}+{1}], {2}", cur.ToString("X"), offset.ToString("X"), next.ToString("X"));

if (0 == cur)
{
return 0;
}

var readProcess = ReadProcessMemoryHelper(
_process.Handle,
next,
buff,
4,
out bytesRead);
if (readProcess)
{
pointerAddress = BitConverter.ToUInt32(buff, 0);
}
else
{
return 0;
}
Console.WriteLine("i = {0}", i);
}
}

return pointerAddress + Offsets[Offsets.Length - 1];
}

莫名其妙的是,调用ReadProcessMemoryHelper后,循环变量i变成了0,这个循环只是因为最终未能从进程中读取内存,返回0而终止。

这是一些示例输出:

i = 0
[170000+FB02F0], 11202F0
i = 0
i = 1
[11469240+1C], 1146925C
i = 0
i = 1
[12DCC690+1C], 12DCC6AC
i = 0
i = 1
[114673A0+1C], 114673BC
i = 0
i = 1
[10F2C830+1C], 10F2C84C
i = 0
i = 1
[111561E0+1C], 111561FC
i = 0
i = 1
[E972CAE+1C], E972CCA
i = 0
i = 1
[1302736E+1C], 1302738A
i = 0
i = 1
[3E49+1C], 3E65

也许更神秘。这仅在附加调试器时发生(谈论 Heisenbug)。如果我从命令行运行它,我会得到以下(正确的)输出:

i = 0
[170000+FB02F0], 11202F0
i = 0
i = 1
[11469240+1C], 1146925C
i = 1
i = 2
[12DCC690+10], 12DCC6A0
i = 2
i = 3
[113E4430+130], 113E4560
i = 3
i = 4
[10F2CEF0+1C], 10F2CF0C
i = 4

我不知道这是怎么回事,这让我抓狂。

最佳答案

我将猜测您的进程是 64 位的。如果是这种情况,则互操作签名不正确,因为最后一个参数的大小 lpNumberOfBytesRead 应该是 64 位而不是 32 位。

BOOL WINAPI ReadProcessMemory(
_In_ HANDLE hProcess,
_In_ LPCVOID lpBaseAddress,
_Out_ LPVOID lpBuffer,
_In_ SIZE_T nSize,
_Out_ SIZE_T *lpNumberOfBytesRead);



#if defined(_WIN64)
typedef unsigned __int64 ULONG_PTR;
#else
typedef unsigned long ULONG_PTR;
#endif

typedef ULONG_PTR SIZE_T;

您可以想象这将如何导致堆栈损坏。由于您无论如何都忽略了 out 参数,因此您可以在签名中使用 IntPtr。

关于c# - 在 Visual Studio 中调试时,循环变量 (i) 在每次循环后神秘地重置为 0(在不调试时有效),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30427514/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com