Я пытаюсь прочитать некоторую память из процесса на C#. Вот моя вспомогательная функция, чтобы получить адрес указателя из серии удалений, наряду с другими соответствующими функциями:переменная цикла (i) таинственно сбрасывается до 0 после каждого цикла при отладке в Visual Studio (работает, когда не отлаживается)
[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 называется, переменная цикла я становлюсь 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
Я понятия не имею, что могло бы делать это, и это сводит меня с ума.
Ну, отладчик возился с потоками, чтобы установить точки останова. Вы пытались использовать старомодный вывод консоли для отслеживания? –
Нет точек останова. Вывод представлен, как вы выразились, старомодным выходом консоли. Единственное различие между ними заключается в том, что один из них запускается через F5, а другой через ctrl-F5 из Visual Studio (отладчик подключен или отсутствует отладчик). –
Любопытный и любопытный. Если я добавлю эту строку: var tmpBSVariable = 0xDEADBEEF; В первой строке цикла for эта переменная имеет значение 0 после вызова, и я обычно увеличивает/код работает, как ожидалось. Моя единственная теория заключается в том, что отладчик Visual Studio просто перегружен в VS2013 при взаимодействии с kernel.dll /, возможно, с другими родными компонентами и беспорядок со стеком в управляемом коде. –