Вопрос № 178126: Здравствуйте, у меня следующая проблема, которую я и сам бы смог решить, но не знаю как в Turbo Pascal напрямую работать с памятью (внутри и вне программы). Проблема следующая: В одной игре на PSX я хочу отслеживать данные о развитии некоторых...
Вопрос № 178128: Добрый день! Уважаемые эксперты помогите мне исправить программу. Условие такое : Нужно ввести последовательность. Среди элементов найти колличество противополжных пар например "3 5 -3 -5" колличсетво равно 2. И еще одно условие,нужно...
Вопрос № 178126:
Здравствуйте, у меня следующая проблема, которую я и сам бы смог решить, но не знаю как в Turbo Pascal напрямую работать с памятью (внутри и вне программы).
Проблема следующая: В одной игре на PSX я хочу отслеживать данные о развитии некоторых карт (дополнительный квест). При помощи ArtMoney я нашел последовательный диапазон памяти в котором определенным образом записана вся информация о картах (целочисленные значения), причем карты в памяти записываются хаотически (по принципу заполнения жесткого
диска). Карты могут повторяться, но с различными свойствами. На основании полученного диапазона памяти я хотел бы отсканировать выбранную память, определенным образом переработать полученную информацию и записать обратно. Я все время обрабатываю эти данные прямо в ArtMoney, но приходится постоянно "бегать" в разные концы таблицы что очень нудно.
Необходимо реализовать: 1. Отсканировать известный диапазон памяти 2. Обработать полученную информацию (оп
ределение максимума, минимума и перезапись, возможно понадобятся циклы) 3. Записать в отсканированную память обработанную информацию
Проблемы: 1. Я знаю язык Turbo Pascal (и Free Pascal) на уровне элементарных операций (+,-,*,/, побитовые, циклы, условия). 2. Не знаю как можно отсканировать определенную последовательность байтов в памяти (вне Pascal) и записать обработанную информацию обратно в память
Ожидаемые результаты: 1. Фрагмент программы для Turbo Pascal (Free Pascal) который
позолял бы скопировать выбранный диапазон памяти в переменную Turbo Pascal (Free Pascal), например в массив, а после обработки записать данные массива обратно в исходный диапазон памяти. 2. Предполагая, что для сканирования памяти потребуется ассемблер не откажус от краткой информации (программы) как в ассемблере реализовать циклы, поиск максимума, минимума, сканирование памяти и перезапись.
Отвечает Boriss, Академик :
Здравствуйте, Тепляков Константин Владимирович. Найти мою личную почту легко: щёлкните по Boriss - перейдете на страничку моего профиля, а там есть "Личная почта" А копировать можно так:
Код:
const msg: String = '1234567890'; var mas: String;
begin
move(msg, mas, length(msg)+1); WriteLn(mas); end.
Копируется одна строка в другую. +1 - так как нужно еще скопировать байт длины строки, который в Паскале находится в начале каждой строки
----- Вывод - то место в тексте, где вы устали думать
Ответ отправил: Boriss, Академик
Ответ отправлен: 04.05.2010, 21:29
Номер ответа: 261204
Вам помог ответ? Пожалуйста, поблагодарите эксперта за это! Как сказать этому эксперту "спасибо"?
Отправить SMS#thank 261204
на номер 1151 (Россия) |
Еще номера »
Отвечает amnick, 10-й класс :
Здравствуйте, Тепляков Константин Владимирович.
а) ArtMoney показывает, что в приведенной однобайтной памяти (009СF26E) ...
Из этого я делаю
вывод, что у Вас Win32 (ArtMoney есть для DOS и Windows, Вы привели 32-битный адрес).
В Win32 каждая программа выполняется в своем адресном пространстве и доступ к памяти чужого процесса можно получить с помощью функций Win32 API (и именно так и нужно получать, попытки обойти это ни к чему хорошему не приведут).
Для чтения памяти (Вам ведь надо "отсканировать известный диапазон памяти") используется функция (синтаксис C):
Код:
BOOL ReadProcessMemory( HANDLE hProcess, // handle to the process LPCVOID lpBaseAddress, // base of memory area LPVOID lpBuffer, // data buffer SIZE_T nSize, // number of bytes to read SIZE_T * lpNumberOfBytesRead // number of bytes
read );
Аналогично, для записи в память другого процесса надо использовать функцию
Код:
BOOL WriteProcessMemory( HANDLE hProcess, // handle to process LPVOID lpBaseAddress, // base of memory area
LPCVOID lpBuffer, // data buffer SIZE_T nSize, // count of bytes to write SIZE_T * lpNumberOfBytesWritten // count of bytes written );
Детальное описание этих функций приведено в MSDN. Вам нужен будет компилятор Паскаля, который генерирует 32-битный код для Windows. Подходит Delphi, Free Pascal. Тогда Вы сможете обращаться к функциям Win32 API.
Знание ассемблера для решения Вашей задачи не требуется. После получения требуемого блока
памяти с помощью ReadProcessMemory, его можно просканировать средствами Паскаля. Объявите, например, указатель на byte, присвойте ему адрес первого байта блока, а затем инкрементируйте указатель для побайтового просмотра. Аналогично для других типов — инкремент указателя продвигает его к следующему элементу массива. Вот Вам простой пример на Turbo Pascal (извините, у меня не установлен Free Pascal):
Код:
program test; {$X+} { расширенный синтаксис }
const s : string = '1234567890'; al: array[0..5] of longint = ( 1234, 5678, 90123, 45678, 901234, 567890 );
var pc : ^char; pl : ^longint; i : integer;
begin pc := @s[1]; for i := 0 to 5 do begin write( pc^, ' ' ); inc( pc ); { к следующему
символу строки } end; writeln;
pl := @al[0]; for i := 0 to 5 do begin write( pl^, ' ' ); inc( pl ); { к следующему элементу массива } end; writeln; end.
Успехов!
P.S. Есть еще аналогичные функции NtReadVirtualMemory/NtWriteVirtualMemory, но для Вашей задачи они не нужны.
Ответ отправил: amnick, 10-й класс
Ответ отправлен: 04.05.2010, 23:26
Номер ответа: 261205
Вам помог ответ? Пожалуйста, поблагодарите эксперта за это! Как сказать этому эксперту "спасибо"?
Отправить SMS#thank 261205
на номер 1151 (Россия) |
Еще номера »
Вопрос № 178128:
Добрый день! Уважаемые эксперты помогите мне исправить программу. Условие такое : Нужно ввести последовательность. Среди элементов найти колличество противополжных пар например "3 5 -3 -5" колличсетво равно 2. И еще одно условие,нужно ввести число и вывести те элементы,которые делятся на него и не делится на это число в квадрате. Я эту задачу решила,но у меня возникает ошибка,когда я заново запускаю файл(где находится уже созданная последовательность),и просматриваю его,потом обрабатываю,и
вывожу результат,но у меня всегда пишет колличество пар =0. Помогите исправить ошибки.
Отвечает lamed, Бакалавр :
Здравствуйте, Екатерина Малинина. Ответ в приложении. ABC Pascal. Старался не использовать понятия, которые Вы не использовали, за исключением not eof(rez) и seek(rez,0); 1. Добавил обработку условия: "делятся на m, но не делятся на m^2", соответственно, добавил один файл для результата. 2. Убрал, где смог, глобальные переменные. 3. Убрал массивы, где явно можно обойтись без них. 4. Разделил процедуру "счет". Пожалуйста, вопросы, замечания.
Приложение:
Ответ отправил: lamed, Бакалавр
Ответ отправлен: 03.05.2010, 10:24
Номер ответа: 261173
Вам помог ответ? Пожалуйста, поблагодарите эксперта за это! Как сказать этому эксперту "спасибо"?
Отправить SMS#thank 261173
на номер 1151 (Россия) |
Еще номера »
Оценить выпуск »
Нам очень важно Ваше мнение об этом выпуске рассылки!
* Стоимость одного СМС-сообщения от 7.15 руб. и зависит от оператора сотовой связи.
(полный список тарифов)
** При ошибочном вводе номера ответа или текста #thank услуга считается оказанной, денежные средства не возвращаются.
*** Сумма выплаты эксперту-автору ответа расчитывается из суммы перечислений на портал от биллинговой компании.