LINUX.ORG.RU

Массив byte: как взять integer, искать integer, сравнивать при частичном совпадении?

 


0

1

1. Программа blockread-ом читает из файла массив байтов (не кратный 4). Нужно из него взять несколько 4-байтных целых — integer или dword — по смещениям не обязательно кратным 4. Как это лучше сделать? (Извращаюсь с указателями, получил Access Violation на ровном месте.)

2. Тот же массив, нужно найти все вхождения заданного 4-байтного целого. Существуют ли стандартные процедуры или функции? (Вызываю CompareByte( x, y, 4) или CompareDWord( x, y, 1) для каждого байта.) — Ответ: IndexDWord, но только для кратных 4.

3. Тот же массив, нужно найти все вхождения определённой структуры длиной 50-100 байтов. Проблема в том, что некоторые поля этой структуры могут принимать любые значения, например: совпадают первые 20 байт, следующие 3 любые, следующие 10 должны совпасть, 5 любые, дальше все совпадают. Есть ли стандартное решение? (Ищу первые 4 байта как шаг 2, затем сравниваю побайтово, добавив условие «or buf[ i ]=$FF».)

Зачем это нужно? Выковыриваю ресурсы из игры.

★★★★★

Последнее исправление: question4 (всего исправлений: 5)

1. Сдвигами и битовыми операциями

2. Перейти на C/C++ и использовать memmem/std::search

3. Наверное искать первые 20 байт как в п.2, потом проверять остальное.

А вообще п 2. и 3. не нужны, нужно только найти таблицу со смещениями до нужных объектов.

slovazap ★★★★★
()
Ответ на: комментарий от Uter

поиск подстроки (с 0 не прокатит, но суть примерно та же)

Поиск подстроки не прокатывает, если между стартовой позицией и искомым куском есть нули.

question4 ★★★★★
() автор топика
Ответ на: комментарий от slovazap

1. Сдвигами и битовыми операциями

Типа dw := b[x] or (b[x+1] shl 8) or (b[x+2] shl 16) or (b[x+3] shl 24) ?

Это реально быстрее, чем присвоить указателю адрес и взять значение?

А вообще п 2. и 3. не нужны, нужно только найти таблицу со смещениями до нужных объектов.

Там проблема в том, что таблица указывает не на сами файлы ресурсов, а на блок служебной информации переменной длины, за которым следует файл.

question4 ★★★★★
() автор топика
Ответ на: комментарий от quest

запустить игру и искать в /proc/PID/mem более другими языками нежели чем pascal?

Я это затеял, чтобы увидеть то, до чего мне не хватит терпения дойти. Сомневаюсь, что игра хранит в памяти несколько десятков мегабайт ресурсов, когда файл сделат в расчёте на быстрый поиск на диске. Или же грузит файл целиком, что то же самое.

Кстати, /proc/PID/mem у меня все имеют нулевую длину, даже с

sudo less -L

Как их смотреть?

question4 ★★★★★
() автор топика
Последнее исправление: question4 (всего исправлений: 1)
Ответ на: комментарий от question4

Удалены из новых версий.

Давай я немного поищу за тебя

http://www.freepascal.org/docs.var

http://www.freepascal.org/docs-html/current/rtl/index.html

http://www.freepascal.org/docs-html/current/rtl/system/index.html

http://www.freepascal.org/docs-html/current/rtl/system/memoryfunctions.html

http://www.freepascal.org/docs-html/current/rtl/system/comparebyte.html

Поиск подстроки не прокатывает, если между стартовой позицией и искомым куском есть нули

О чём я и написал - но кроме строковых сравнений есть и побайтовые сравнения

Uter
()
Ответ на: комментарий от question4

Типа dw := b[x] or (b[x+1] shl 8) or (b[x+2] shl 16) or (b[x+3] shl 24) ?

Что-то вроде. При условии что в паскале сдвиги расширяют операнд (до dword в данном случае), иначе надо ещё кастовать.

Это реально быстрее, чем присвоить указателю адрес и взять значение?

Начнём с того что это единственно правильно, потому что остальные методы в лучшем случае непортабельны относительно требований по выравниванию и endianess, а в худшем всегда ведут к неопределённому поведению. А так, во-первых, нормальный компилятор оптимизирует такие чтения там где это безопасно, во-вторых, у вас это что, бутылочное горлышко чтобы задумываться тут о скорости?

Там проблема в том, что таблица указывает не на сами файлы ресурсов, а на блок служебной информации переменной длины, за которым следует файл.

Не понял что это значит, но игра явно не занималась поиском в своих данных строк и структур. Разберите до конца формат, поймите где хранятся смещения и всё.

slovazap ★★★★★
()
Ответ на: комментарий от slovazap

Разберите до конца формат, поймите где хранятся смещения и всё.

Вот для разбора поиск и понадобился.

question4 ★★★★★
() автор топика

Осиль уже си, он как раз для такого создавался.

Если надо «быстро, на коленке и на один раз» - perl + sysread() + unpack()

anonymous
()
Ответ на: комментарий от question4

Нашёл уже. Нужно смотреть /proc/$pid/maps и читать перечисленные там диапазоны.

question4 ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.