2008-11-11 3 views
0

Я пытаюсь прочитать данные в Win32 ListView, принадлежащие другому процессу. К сожалению, мой вызов WriteProcessMemory() завершился с ошибкой «Эта функция не поддерживается в этой системе». когда я укажу «NULL» для базового адреса в моем вызове VirtualAlloc(). Если, однако, я компенсировал этот адрес VirtualAlloc() некоторым «магическим» значением, которому мне посчастливилось и выбрано наугад в момент разочарования, звонок работает в моей системе, но не работает на других. (см. код ниже)Win32 WriteProcessMemory() значение магического смещения

Может ли кто-нибудь предложить, какое это магическое смещение делает для меня? В результате проб и ошибок я могу найти значения, которые работают на определенных системах, но я не могу найти общее решение этой проблемы.

Спасибо, PaulH

(добавленные Cd-МАН)
#define MAGIC_OFFSET (DWORD)0x01020000 

LVHITTESTINFO hti = { 0 }; 
hti.pt    = clientPoint; 

LPVOID lpBuffer = ::VirtualAlloc(NULL, 1, MEM_RESERVE, PAGE_READWRITE); 
::VirtualFree(lpBuffer, 0, MEM_RELEASE); 

lpBuffer = ::VirtualAlloc((LPVOID)((DWORD)lpBuffer + MAGIC_OFFSET), sizeof(hti), MEM_RESERVER, PAGE_READWRITE); 
DWORD dwBuffer = (DWORD)lpBuffer + MAGIC_OFFSET - sizeof(hti); 

if(!::WriteProcessMemory(hProcess, (LPVOID)dwBuffer, (LPVOID)&hti, sizeof(hti), NULL)) 
    return 0; 

if(ListView_HitTest(hWndListView, (LPVOID)dwBuffer) < 0) 
    return 0; 

if(!::ReadProcessMemory(hProcess, (LPVOID)dwBuffer, (LPVOID)&hti, sizeof(hti), NULL)) 
    return 0; 

::VirtualFree(lpBuffer, 0, MEM_RELEASE); 

Разъяснение: это на платформе Windows Mobile, вероятно, не-x86 архитектуры. Таким образом, ситуация может быть различной (существуют ли отдельные адресные пространства в ARM-процессорах?).

ответ

3

Вместо того чтобы пытаться выделить память в другом процессе, почему бы не использовать именованную общую память вместо этого. В этой статье вы проведете базовую настройку shared memory, и я сделал быструю проверку, чтобы убедиться, что эти функции поддерживаются Windows Mobile 5.

+0

Это похоже на работу. Я не могу поверить, что все мои исследования в этой теме так и не разобрались. Большое спасибо – PaulH 2008-11-11 19:20:20

2

ВиртуальныйAlloc выделяет память в YOUR адрес. Абсолютно неверно использовать этот адрес при записи пространства памяти другого процесса. Вместо этого вы должны использовать VirualAllocEx и передать его в hProcess.

Вам просто повезет и надпись на случайном фрагменте памяти, когда она работает.

Если указание NULL на первый параметр VirtualAllocEx не поддерживается при запросе другого процесса (не знаю, есть оно или нет) ... тогда вы можете использовать VirtualQueryEx, чтобы отобразить адресное пространство другой процесс и найти действительную свободную область для перехода к VirtualAlloc.

Скорее всего, вам придется поместить это в цикл повтора, поскольку состояние другого пространства адресов может измениться, пока вы ищете пустое место.

0

Вы должны иметь в виду, что вы пишете на виртуальное адресное пространство программы. В Windows это часто начинается с адреса, такого как ваш магический номер.

Вы когда-нибудь отлаживали программу? Как выглядят адреса?

В моей системе исполняемые файлы обычно загружаются около 00400000 или 01000000. Они меняются от исполняемого файла к исполняемому, и я считаю, что Windows может изменять этот адрес даже в последовательных прогонах одного и того же исполняемого файла.

Кроме того, исполняемые файлы имеют разделы, которые имеют свои (и сравнительно меньшие) смещения. Например, раздел кода обычно составляет +1000, затем идут данные, обнуленные разделы данных и т. Д.

Что все это означает, что если ваш исполняемый файл имеет базу 00400000, а в его секции данных есть смещение + 2000, первый байт данных будет на 00402000. Чтобы прочитать/записать этот байт, вам нужно будет указать базовый адрес 00402000, а не 2000, и определенно не 0.

Попробуйте распечатать значение указатель. Если объект, на который указывает объект, имеет статическое время жизни, он, вероятно, будет находиться в разделе данных, и вы получите адрес, такой как 00402000. Затем, если вы WriteProcessMemory на этот адрес, вы измените объект.

Различные исполняемые форматы Win32 содержат этот базовый адрес «0040000», а также смещения различных разделов, но поскольку такой хак, считывающий другую память процесса, вероятно, будет нацелен на определенную версию конкретного исполняемого файла, вам может быть лучше, если оставить магический номер как есть.

Смежные вопросы