Предыдущие статьи о реверсе данных автомобильных навигаторов Siemens VDO Dayton CARMiN Реверс черного тессеракта 01 Сшей красное с красным, желтое с желтым, белое с белым. Наверняка будет хорошо 02. Я уже даже не вижу код. Я вижу блондинку, брюнетку и рыжую Получив в прошлой статье полную раскладку по значениям чисел и цифр типа блока 0xA, информации по странам, естественным следующим шагом будет попытка провести разбор типа блока 0x0С, информации по городам. Напомню карту расположения информации в блоке стран 0xA.  Со смещения 0 по 0x30 - заголовок блока и TOC - table of contents, список LIST на полные списки различной информации в блоке. Сразу после заголовка - LIST на главную часть, brief, список записей по каждой из стран с краткой основной информацией. (Выделено желтым) Со смещения 0x30 - 8-байтовые записи brief каждой из стран. (Красненькое) Затем - по каждой стране расширенная информация (Фиолетовый) Следующая часть - категории интересных мест, известность которых позволяет относить их к уровню достопримечательностей страны. Вернее, далекие ссылки (FAR_LIST) на списки points of interests, POI. (Синенькое) Завершающая часть - список локальных названий (на местных языках) стран. Английские наименования (и, возможно и на других языках, зависящих от настроек навигатора)  с высокой долей вероятности определяются по кодам стран, список кодов en_ENG_COUNTRY_NAME - не найден в открытом доступе, и восстановить его можно только аналитически в части стран, представленных в наличных данных. Информация по каждой стране "собирается" из секций блока следующим образом: BRIF_0xA - краткая информация, с ссылкой PTR на MORE_INFO_0xA. MORE_INFO_0xA - дополнительная информация о стране, с набором ссылок FAR_LIST на города страны. Точнее, на список элементов CH_IDX блока типа BT_0x0B_0x0D_0x0F_0x11, которые ссылаются (иногда через несколько итераций внутри BT_0x0B_0x0D_0x0F_0x11, "набирая" последовательность необходимых для однозначного получения списка букв) на города, элементы блоков типа 0xC. Кроме этого, содержит ссылку на набор категорий (LIST) точек интереса (POI) масштаба страны, ADDINFO_0xA, который правильнее назвать POI_CATEGORY. POI_CATEGORY - enum en_PLACE_CATEGORY категории POI, FAR_LIST на список элементов CH_IDX блока типа BT_0x0B_0x0D_0x0F_0x11, указывающих на элементы внутри блока типа 0x10, и указатель на начало строковых данных блока (выглядит бесполезно). В паре мест используются указатели на списки внутри BT_0x0B_0x0D_0x0F_0x11, элементы CH_IDX, которые или рекурсивно содержат списки CH_IDX, или ведут "наружу", на информацию в других типах. Если изменить выводимую в Variables строку в функции Read_CH_IDX так, что копипаст этой информации в темплейт описывал вызов адресуемого блока и относительного смещения, то трудоемкость анализа значительно снизится. Кроме этого, можно вообще не задействовать описание блока BT_0x0B_0x0D_0x0F_0x11 в темплейте, вместо этого прописывая декларацию  его структур-элементов в блоке 0xA в тех местах, где на них ссылаются. В MORE_INFO_0xA тоже есть FAR_LIST idx_ch_cityes? Так тут же прописать массив структур CH_IDX, что позволит прямо в этом месте получать все города страны в человекопознаваемом виде. Представление блока 0xA теперь включает в себя информацию от адресуемых элементов блока 0xD, при этом сам этот блок объявлять нет необходимости. Чтобы прописать блок 0xC с информацией о конкретном городе достаточно раскрыть список городов конкретной страны, найти необходимый и скопировать информацию из колонки Variables в темплейт.  Анализируемая структура блока типа 0xC, информации о городах, сходна с 0xA. Описываю очевидные поля структуры, добавляю её тип в функцию block() и перечисление типов блоков. Практически то же самое, но некоторые нулевые 32битные константы в блоке типа 0xC обретают значения: Последние 2 uint заголовка - адреса блоков типа 0xC, идущие "после" текущего, и "до". Пришлось переделать структуру BL_ADDR - теперь значение 0 не является ошибкой (оплачено возможностью вызвать block(0) как описание блока, начинающегося с нулевого абсолютного смещения). С новыми LIST pl_new_list_ofic (которых нет в русской версии) и LIST pl_new_list_ru (которых нет в официальных  carindb) будем разбираться дальше. Следующей секцией в типе 0xA шли восьмибитные структуры краткой информации brief по каждой из стран. Размер и значение этих структур в блоках типа 0xC не изменилось. Разве что в brief бывшая нулевая константа в 0xA так же обрела значение, ссылку на строку, PSTR pstr_region, несущую информацию о локальном наименовании региона, в котором находится город. Интересной оказалась ex- CONST_B is_synonim, которая уж точно не константа. В 0xA все значения - 0, кроме одного раза, Австрии и её синонима. В 0xC известные варианты {0, 1, 2h, 10h, 12h} Не битовая ли маска, кстати? Называю ubyte place_bitemask и пытаюсь отыскать закономерности. 00h относится к районам, областям, муниципалитетам, городам 10h - деревни, районы городов, минимальные части населений 02h - коммуны, 5й уровень самоуправления в Бельгии и Франции 12h - коммуны, субмуниципалитеты Для окончательных выводов данных маловато, продолжаем наблюдение. Структура MORE_INFO_0xС, которая описывает дополнительную информацию о городе, от аналогичной в 0xA отличается значительно. Для анализа возьму живописный курортный Хель — город в Польше, входит в Поморское воеводство, Пуцкий повят. Расположен на одноимённой косе. Занимает площадь 21,72 км². Население составляет 3480 человек. 54°36′42″ с. ш. 18°48′29″ в. д. Отдыхал с семьёй там пару недель, и знакомство с местностью может стать полезным для понимания данных. В carindb_ee последовательно раскрываю Poland, moreinfo, city[7] == h [8]> a e i l o r u y, дочерний элемент struct CH_IDX childs[1] которого имеет значение  block(0x0C1108); //of:608C78 'e' [38]>0c()>, hebdow, hecznarowice, hedwizyn, hejdyk, hel.  Копипаст значения в текст template, применение его <F5>, и в фокусе внимания информация блока 0xC, идущая после brif.Размер данных будущей структуры MORE_INFO_0xC наглядно дается ссылками из BRIF_0xС на начала экземпляров.  Очевидно, что первые 8 байт выглядят как FAR_LIST, затем 4 байта еще один LIST, затем 4 байта неясного назначения (может, BL_ADDR?), 2 байта - вообще непонятно, наконец, 6 байт, равных 0. Для первичного описания структуры достаточно. unk_1 - список FAR_LIST в блоке CH_idx_F типа BT_0x0B_0x0D_0x0F_0x11, как в странах был список на города, так в городах - список на дороги-улицы, переименовать в ch_roads и добавить определение данных из индексного блока CH_IDX road[ch_roads.pl_data.cnt]. unk_2 - список LIST на категории POI, точек интереса, в конкретном городе. Ссылается на структуру определенно совпадающую с POI_CATEGORY из блока типа 0xA, не буду выдумывать новые сущности, использую прямо её же. unk_3 - ссылка на один блок типа 0x00, не знаю пока что о нем ничего. may_be_ptr - не указатель, т.к. указывает у разных городов на совершенно разные разделы данных в блоке. Предположу, что это уникальный ID города. Константы и есть константы.... Стоп, на русской карте 64битная константа - иногда LIST, ведущий на непонятные данные, определение данных ставлю в зависимость от официальности карты.  Получил у каждого города "внутри" список строковых названий улиц, и списки POI, разбитые по категориям. Некоторые категории уже известны по странам (Interesting, Museum, Sport, Architecture, Nature_park).  Категория 0x0C -  stacja paliw - прямым польским по-белому: автозаправка, в en_PLACE_CATEGORY добавляю Gas_station  = 0xC Категория 0x0E - biala foka, strzezony, ul. adm. steyera w., ul. boczna, ul. kuracyjna, ul. lesna, ul. szkolna. Помню, на местности повеселила креативность - назвать автостоянку "Белый тюлень" (biala foka). А strzezony и переводится как "охраняемая парковка", значит, категория Parking = 0x0E Категория 0x14 - уже известна по блоку стран, интересные места, не попадающие под другие категории, Interesting. Если вы подумали, что focarium - это тюлений зоопарк, то вы не ошиблись, hel cypel plaza - купальный пляж в Хеле, latarnia morska hel - если знать, что latarnia по-польски это маяк (а прожив в Хеле неделю вы не сможете не получить этого знания), то и эта достопримечательность понятна. Категории 0x1E и 0x17, обе содержат элементы, относящиеся к банкам. В одной категории один элемент, в другой - два. Отделение банка в Хеле одно, а банкоматов - сам видел. Так что вывод - где Bank, где ATM очевиден. И так далее... Для "восстановления" значения категории по названиям POI удобно, когда язык хотя бы близок к родному. И отлично, когда описание идет по спискам значений, местонахождение которых хоть чуть знакомо на местности. В Хеле 19 категорий POI - солидное число, объяснимое туристическо-курортной ориентацией городка. Некоторые категории распознаны с недостаточной долей уверенности. Категория Hospital  = 0x2d - пара медицинских заведений: "115 szpital wojskowy z przychodnia" и "przych. lek. samodzielny nzoz". А так же __city_railst_    =0x33 - в представителях только "Hel", как и в типе 0x30, и может быть, как железнодорожной станцией, так и автовокзалом. В carindb_rus вообще у всех городов, в том числе и у польского Хеля, в наличии единственная категория POI (City = 0x30), с единственным представителем - этим самым городом. Возвращаюсь в block countries, 0xA, и нахожу блок с еще одним немного знакомым польским городом: Ольштыном:  block(0x0DE006); //of:6F0030 ''' [1]>0c(CITY)>, ol'shtyn Аналогично просматриваю категории POI, и по именам внутри назначаю новым неизвестным категориям читабельное значение в enum. Большая поликлиника, воеводство - крупнейшая административная единица Польши. А представителей типа POI 2Dh - 12 штук. Похоже, правильно когда Hospital=29h, а бывший госпиталь переименовать в Clinic=2Dh Без сомнений, Police = 0x2A Olsztyn Gutkowo - есть такая ж/д станция, как и станции Ольштын Центральный и Ольштын Западный, подсказывает гугл. RailStation=0x33 Вот так, раскрывая с гуглом содержимое категорий, пополняю перечисление. После Хеля, Ольштына и Варшавы оно принимает вид: Явно есть еще пробелы в последовательности, но это все варианты из блоков типа 0xA и 0xC всех трех вариантов carindb. Структура POI_CATEGORY из блока типа 0xA несла в себе неиспользуемый в 0xA элемент PTR unkn_str_begin, абсолютно во всех имеющихся примерах указывавший на константное место - начало первой строки. В блоках тип 0xC переменная reference_addr_start, заменившая unkn_str_begin, у некоторых категорий POI указывает на структуру {FAR_LIST, PSTR, CONST_S(0)}, из области pl_new_list_ofic заголовка блока. Тип PTR не несет количеств, только указатель на первую. Причем, судя по голубым "пятнашкам", для различных категорий POI число этих структур - неодинаковое.  После перечисления всех POI_CATEGORY из LIST pl_all_cat_pois в заголовке, внезапно в хвосте нахожу еще одну, пустую POI_CATEGORY, содержащую только значение reference_addr_start (или unkn_str_begin).И этот экземпляр подсказывает, как определяется число элементов новой структуры, на которые есть ссылка на начальный адрес, но нет количества или адреса окончания.Навигатор, "заглядывает вперёд", в следующий экземпляр POI_CATEGORY, беря оттуда значение reference_addr_start - использует его, как значение, до которого размещаются данные текущей структуры. Меняю с учетом вышесказанного POI_CATEGORY, которая теперь будет отображать для категорий POI новые структуры POI_REFERENCE. Назначение их не ясно однозначно. В Хеле, например, они есть только у 2 категорий: Банки Банкоматы Я предположил бы, что это перечень альтернатив, ближайших к описываемым POI (адреса блоков типа 0x10 - разные). Но в разных блоках может быть и одинаковая информация по этим точкам.Пока не будет понимания структуры блока типа 0x10 минимум до уровня 0xC - дать ответ "что это было" не представляется возможным. Ссылки "наружу" данных блока 0xC и вложенность структур представления. Тезисно главное. Блок типа 0xC содержит информацию о городах. Кстати, в блоке сведений нет сведений, к какой стране относится город. "Город" - условность, это может быть и район или территориально-административная единица страны. Заголовок блока 0xC равен по размеру заголовку блока стран 0xA (30h), однако дополнен значащими полями на месте нулевых констант: адресами предыдущего и следующего блоков городов, указатель на все категории точек интереса (POI), указатель на все "дополнительные" точки интереса POI_REFERENCE (предположительно ближайшие аналогичные, или ориентиры для поиска) Краткая информация - BRIF - наименование города на местном языке (вот не всегда, есть и английские варианты), наименование административной территории, к которой относится город, язык (не без смешных ошибок, в Ольштыне, например, по мнению картографов, говорят по-чешски, а не по-польски) и признак, возможно ли отнесение к этому городу/поселению какой-то части, или данный населенный пункт - минимальная единица. Структурно соответствует аналогичной в 0xA, но с ссылкой на строку региона на месте константы. Расширенная информация - MORE_INFO - содержит указатель на список улиц, дорог города или территории (через тип CH_idx_f на тип Eh), указатель на внутриблоковый список категорий POI этого города, адрес блока типа 00(block_type_00), ID города (под вопросом). В русском варианте карты - указатель на список значений размером 1 байт, с возможными значениями 0, 1 и 2. Для чего эти структуры - неясно. В русском варианте карты (а там впихнули 42, СТРАНЫ, Карл!) список дорог/улиц у городов крайне скудный (Санкт-Петербург - 81 улица на многомиллионный город; Калининград - 17 улиц и 11 автодорог; Хель - 1 дорога, против 58 в "официальной"; Белгород - 2 дороги, они же улицы {p185, p186}, вся Белгородская область - аж 9 дорог {e105, m2, p185, p186, p187, p188, p189}; белорусский Брест - город, не область - 5 улиц: {e30, e581, m1, p17, p83}) Категории POI - структура POI_CATEGORY, по данным совпадающая с такой же в типе  0xA, но в официальной карте указатель структуры не константа в пределах блока, а ссылка на дополнительные списки POI POI_REFERENCE. Списки POI конкретной категории даны через блоки типа CH_idx_11 на блоки типа 10h, как в POI_REFERENCE, так и в POI_CATEGORY. В русской карте единственный вариант категории POI у городов - City=30h, с единственным представителем у каждого города - самим этим городом. Значительно расширен список возможных значений en_PLACE_CATEGORY - кодификации мест интереса. Важно: впервые встретил и определил новый механизм указания количества адресуемых структур, когда есть указатель на начало, а из следующего экземпляра структуры берется её указатель на начало, как указатель на окончание данных текущей. Признак: после всех экземпляров структур (в данном случае POI_CATEGORY) есть дополнительная хвостовая "пустая" структура, с единственно заполненным полем указателя. Используется в блоке типа 0xC для определения количества экземпляров списка POI_REFERENCE, присутствующего не у всех категорий POI. Продолжение анализа - в следующей статье.