Манипулирование двоичными данными структуры C в автономном режиме - PullRequest
0 голосов
/ 02 декабря 2010

У меня есть практическая проблема, которую нужно решить. Во встроенной системе, над которой я работаю, у меня есть довольно большая структура, содержащая системные параметры, которые включают int, float и другие структуры. Структура может быть сохранена во внешнем хранилище.

Я подумываю о написании программного обеспечения для ПК для изменения определенных значений внутри двоичной структуры без изменения общего макета файла. Идея состоит в том, что можно изменить 1 или 2 параметра и загрузить их обратно в память из внешнего хранилища. Так что это специальный шестнадцатеричный редактор.

То, как я это вычисляю: могу ли я построить таблицу, которая содержит: - имя параметра - смещение параметра в памяти - тип Я должен быть в состоянии изменить все, что я хочу.

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

Кто-нибудь знает инструмент, который может помочь?

EDIT Рассматриваемая система работает на основе 32 ARM в режиме с прямым порядком байтов. Компилятору не требуется упаковывать структуру, поэтому для моей цели она такая же, как на компьютере x86. Проблема заключается в размере структуры: она содержит в общей сложности не менее 1000 параметров, разбросанных по нескольким уровням вложенных структур. Поэтому невозможно (или, скорее, я не желаю) написать короткий фрагмент кода, чтобы вывести все смещения. Я предполагаю, что ключевая проблема заключается в синтаксическом анализе заголовков C и автоматическом генерировании смещений или кода для сброса их смещений. Пожалуйста, предложите такой инструмент разбора.

Спасибо

Ответы [ 6 ]

4 голосов
/ 02 декабря 2010

Обычно это делается путем простого обмена заголовочным файлом, который также определяет структуру, с другим (ПК) приложением. После этого вы сможете загружать байты, приводить их к такой структуре и редактировать.

Прежде чем сделать это, вам нужно знать о (и, возможно, обработать):

  1. Типоразмеры. Если две платформы сильно различаются (16-битная или 32-битная) и т. Д., У вас могут быть разные размеры ints / float и др.
  2. Выравнивание поля. Если компилятор / цель отличаются, правила упаковки для полей не обязательно будут одинаковыми. Как правило, вы можете заставить их быть одинаковыми с #pragma s.
  3. Порядок байтов. Это то, что нужно быть осторожным во всех случаях. Если ваше встроенное устройство отличается порядком байтов от целевого ПК, вам придется поменять местами каждое поле при загрузке на ПК.

Если здесь слишком много различий, чтобы беспокоиться о них, и вы создаете что-то быстрее / грязнее, я не знаю инструментов для автоматического создания структурных смещений, но, как говорит другой автор, вы могли бы написать некоторый короткий код на C который использует offsetof или эквивалент (или, как вы предлагаете, арифметику указателей) для вывода таблицы полей и смещений.

2 голосов
/ 03 декабря 2010

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

1 голос
/ 02 декабря 2010

Чтобы убедиться, что я понимаю вопрос:

Во встроенной системе у вас есть структура, содержащая системные настройки, которая выглядит примерно так:

struct SubStruct{
    int               subSetting1;
    float             subSetting2;
}

/* ... some other substructure definitions. ... */

struct Settings{
    float             setting1;
    int               setting2;
    struct SubStruct  setting3; 
    /* ... lots of other settings ... */
}

А ваша проблема в том, что вы хотите взять двоичный файл, содержащий указанную структуру, и изменить значения на другом компьютере?

Учитывая, что вы знаете размеры целочисленных типов и упаковку, используемую встроенной системой, у вас может быть два варианта. Если порядковый номер вашей встроенной системы и системы ПК отличается, вам также придется иметь дело с этим, например, используя hton при написании полей.

Вариант 1: Объявите ту же структуру в вашей программе на ПК, с прагмами для принудительного выравнивания байтов, что и во встроенной системе, и с любыми целочисленными типами, которые различаются по размеру между встроенной и ПК-системами, «перепечатанными» до конкретных размеров, например, используя int16_t, int32_t, если у вас есть stdint.h, или ваши собственные typedefs, если нет, на вашей программе для ПК.

Вариант 2: Вы можете просто составить список типов, например, список, который выглядит так:

Name                        Type
setting1                    float
setting2                    int
subStruct1SubSetting1       int
subStruct1SubSetting2       float

А затем рассчитайте местоположения на основе размеров и упаковки, используемых встроенной системой, например, если во встроенной системе используется 4-байтовое выравнивание, 4-байтовые числа с плавающей запятой и 2-байтовые числа, вышеприведенная таблица рассчитывает:

Name                        Type         Calculated Offset
setting1                    float        0
setting2                    int          4
subStruct1SubSetting1       int          8
subStruct1SubSetting2       float        12

или если встроенная система упаковывает структуру в 1-байтовое выравнивание (например, если это 8-битный микро)

Name                        Type         Calculated Offset
setting1                    float        0
setting2                    int          4
subStruct1SubSetting1       int          6
subStruct1SubSetting2       float        8
1 голос
/ 02 декабря 2010

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

1 голос
/ 02 декабря 2010

Учитывая полностью определенную структуру в вашем коде, вы можете использовать макрос offsetof () , чтобы узнать, как расположены поля.Это не поможет, если вы пытаетесь программно определить макет на другой машине, хотя.

0 голосов
/ 02 декабря 2010

Я не уверен, какие возможности отладки у вас есть в вашей системе.В Windows я использовал бы простой сценарий отладки с преобразованием текста поверх него (отладчик можно запустить в пакетном режиме для генерации информации о типе).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...