Пользователь столкнулся с проблемой в процедуре SCANBYTE, которая предназначена для сканирования памяти на наличие определённого значения. Проблема заключается в том, что процедура возвращает одни и те же адреса памяти, несмотря на то, что, возможно, сканирование происходит достаточно быстро.
Контекст
Код процедуры SCANBYTE использует функцию VirtualQuery для получения информации о загруженных в память страницах. Однако, в цикле, который должен обходить все страницы, происходит ошибка в логике, из-за которой сканирование ограничивается одной и той же страницей памяти, что и приводит к повторению результатов.
Подтвержденный ответ
Проблема заключается в том, что цикл, который должен обходить память, не учитывает размеры страниц. Функция VirtualQuery возвращает информацию о памяти в виде страниц, и каждая страница имеет один общий базовый адрес. Согласно документации, значение базового адреса округляется вниз до следующей границы страницы.
Исправление процедуры SCANBYTE
Чтобы исправить ошибку, необходимо изменить логику цикла, который обрабатывает страницы памяти. Вместо вычитания фиксированного значения (-4096), нужно использовать информацию о размере региона памяти, полученную из структуры MEMORY_BASIC_INFORMATION. Вот пример исправленной процедуры:
procedure SCANBYTE(value: Integer);
var
lpflOldProtect: DWORD;
s: size_t;
mbi: MEMORY_BASIC_INFORMATION;
si: SYSTEM_INFO;
lpStartAddress, lpStopAddress: PChar;
addr, i: PInt64;
begin
GetSystemInfo(@si);
lpStartAddress := si.lpMinimumApplicationAddress;
lpStopAddress := si.lpMaximumApplicationAddress;
for addr := PInt64(lpStartAddress) to PInt64(lpStopAddress) do
begin
s := VirtualQuery(@addr, @mbi, SizeOf(MEMORY_BASIC_INFORMATION));
if (s = SizeOf(MEMORY_BASIC_INFORMATION)) and
(mbi.State = MEM_COMMIT) and
(mbi.Type = MEM_PRIVATE) and
(mbi.RegionSize > 0) and
(mbi.Protect = PAGE_READWRITE) then
begin
for i := mbi.BaseAddress to (mbi.BaseAddress + mbi.RegionSize) - SizeOf(Integer) do
begin
if value = PByte(i)^ then
ListBox1.Items.Add(IntToHex(i, 8));
end;
end;
end;
end;
Альтернативные подходы
Проверьте размер страницы, используя функцию GetSystemInfo, и убедитесь, что он учитывается в логике цикла.
Убедитесь, что все операции с указателями выполняются корректно и с учётом их типов.
Проверьте, не превышает ли размер шага цикла размер страницы, чтобы избежать повторного сканирования одной и той же страницы.
Рекомендации по оптимизации
Избегайте лишних операций, которые могут замедлять выполнение, например, проверку каждого байта в странице, если это не требуется.
Используйте более эффективные методы поиска, если это возможно, например, бинарный поиск или использование индексов.
Применение этих рекомендаций поможет устранить проблему с повторением адресов и улучшить производительность процедуры SCANBYTE.
Проблема в процедуре `SCANBYTE` заключается в ошибке в цикле, из-за которой сканирование ограничивается одной страницей памяти, что приводит к повторению результатов, несмотря на корректное использование функции `VirtualQuery`.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.