Как этот уникальный заголовок файла «специальный маркер» сообщает eCryptfs, что это файл eCryptfs?

#c #header #freepascal #ecryptfs

#c #заголовок #freepascal #ecryptfs

Вопрос:

Я пишу программу (используя Free Pascal, а не C), которая анализирует заголовок файлов eCryptfs.

Одно из значений в заголовке начинается с байта 7 и заканчивается на 15 (значение в 8 байтах). Для меня это полезно, потому что это значение, которое однозначно идентифицирует файлы как файлы eCryptfs. Итак, я пытаюсь закодировать свое приложение, чтобы оно распознавало его, когда оно находит такие значения в файлах.

Однако сам маркер генерируется путем преобразования случайно сгенерированного 4-байтового значения (X) с другим 4-байтовым статическим шестнадцатеричным значением 0x3c81b7f5 (Y). Сгенерированное значение равно 4 байтам, Z. X Z вместе образуют 8-байтовый специальный маркер. Сам Y не сохраняется в заголовке files. Итак, поскольку значение 0x3c81b7f5 (Y) никогда не сохраняется в заголовке, я не могу закодировать свое приложение для его поиска, а поскольку остальные 4 байта являются результатом XOR’d преобразования одного статического значения в другое случайное, я не могу понять, как оно распознается.

Задав вопрос, как программа eCryptfs распознает это значение как «файл eCryptfs» на сайте панели запуска eCryptfs (https://answers.launchpad.net/ecryptfs/ question/152821 , один из членов сообщества направил меня к соответствующему исходному коду C, на который я дал ссылку ниже. Однако я недостаточно хорошо понимаю C, чтобы понять, как он распознает специальные маркеры. Кто-нибудь может мне помочь, чтобы я мог закодировать такой же процесс распознавания в моем собственном приложении? Мне не нужен исходный код, но я просто хочу, чтобы кто-нибудь объяснил, как работает код C: «Ах да, это файл eCryptfs прямо здесь!», чтобы я знал, что мне нужно закодировать, чтобы мое приложение выполняло.

http://fxr.watson.org/fxr/source/fs/ecryptfs/crypto.c?v=linux-2.6 ;im= выдержки #L1029

Ответ №1:

Что вас действительно интересует, так это вот эта часть:

 m_1 = get_unaligned_be32(data);
m_2 = get_unaligned_be32(data   4);
if ((m_1 ^ MAGIC_ECRYPTFS_MARKER) == m_2)
    return 1;
  

get_unaligned_be32 Функция просто преобразует четыре байта из
data в четырехбайтовое целое число без знака с возможным порядком байтов
корректировки. data 4 Во втором вызове get_unaligned_be32
увеличивает адрес, переданный get_unaligned_be32 , на четыре байта:

 [0][3][2][4][4][5][6][7]   
^           ^
data        data   4
m_1         m_2          /* After adjusting byte order */
  

Итак, первые две строки просто извлекают два целых числа без знака из
первые восемь байтов data (возможно, с исправлениями порядка байтов).

Тогда у нас есть это выражение:

 (m_1 ^ MAGIC_ECRYPTFS_MARKER) == m_2
  

^ Это просто оператор XOR и MAGIC_ECRYPTFS_MARKER является
0x3c81b7f5 итак, этот тест просто XORing m_1 и 0x3c81b7f5 и
посмотрим, равно ли оно m_2 ; если это сравнение верно, то вы
укажите правильный тип файла.

Комментарии:

1. Большое вам спасибо, что нашли время объяснить это так подробно. Это превосходно, спасибо. Теперь я понимаю код.

Ответ №2:

Если под «X Z вместе образуют 8-байтовый специальный маркер» вы подразумеваете, что они объединены, тогда у вас есть следующее:

 Y = 0x3c81b7f5
X = some random value

Z = X ^ Y  (also a random value, due to X being random)
  

Теперь у вас есть X и Z из заголовка файла. Если вы выполняете xor их вместе, выполняется следующее соотношение:

 X ^ Z = X ^ (X ^ Y) = Y
  

Таким образом, вы должны получить значение 0x3c81b7f5.

Комментарии:

1. Спасибо вам обоим. Эти ответы в совокупности помогли мне бесконечно! Еще раз спасибо.