Код Хаффмана. Як розпакувати таблиці, стислі Huffman Encoding, в Intel ME 11.x

  1. Зміст статті Як відомо , Багато модулі Intel ME 11.x зберігаються у Flash-пам'яті в упакованому...
  2. Постановка задачі
  3. Розбиття стислих даних на окремі сторінки
  4. Знаходження пар «стиснений текст - відкритий текст»
  5. Продовження доступно тільки учасникам
  6. Варіант 2. Відкрий один матеріал

Зміст статті Як відомо

, Багато модулі Intel ME 11.x зберігаються у Flash-пам'яті в упакованому вигляді, і для стиснення застосовуються два алгоритму - LZMA і Huffman Encoding . Для LZMА існує публічна реалізація , Яку можна використовувати для розпакування, але для Huffman все складніше. Розпакувальник Huffman Encoding в ME реалізований на апаратному рівні, і побудова еквівалентного програмного коду являє собою складну і нестандартну задачу.

Попередні версії ME

Ознайомившись з вихідними текстами, які є частиною проекту unhuffme , Легко побачити, що для попередніх версій ME існує два набори таблиць Хаффмана і в кожному з наборів присутній дві таблиці. Наявність двох таблиць (по одній для коду та для даних) обумовлено, ймовірно, тим, що статистичні властивості коду і даних сильно відрізняються.

Також примітні наступні властивості:

  • Для різних наборів таблиць діапазони довжин кодових слів розрізняються (7-19 і 7-15 біт включно).
  • Кожна кодова послідовність кодує ціле кількість байтів (від 1 до 15 включно).
  • В обох наборах використовується Canonical Huffman Coding (Це дозволяє швидко визначати довжину чергового кодового слова при розпакуванні).
  • В межах одного набору довжини закодованих значень для будь-якого кодового слова збігаються у всіх таблицях (Code і Data).

Постановка задачі

Можна припустити, що в таблицях Хаффмана для ME 11.x три останніх властивості також дотримуються. Тоді для повного відновлення таблиць потрібно знайти наступне:

  • діапазон довжин кодових слів;
  • межі значень кодових слів, що мають однакову довжину (Shape);
  • довжини закодованих послідовностей для кожного кодового слова;
  • закодовані значення для кожного кодового слова в обох таблицях.

Розбиття стислих даних на окремі сторінки

Для отримання інформації про окремі модулях можна використовувати наявні знання про внутрішні структури прошивки .

Розібравши Lookup Table, частина Code Partition Directory, легко визначити, для яких модулів застосовується кодування Хаффмана, де починаються їх упаковані дані і який розмір модуль буде мати після розпакування.

Розмір стислих і розпакованих даних і SHA-256 від розпакованих даних нескладно знайти, розібравши Module Attributes Extension для конкретного модуля.

Побіжний аналіз декількох прошивок для ME 11.x дозволяє помітити, що розмір даних після розпакування Хаффманом завжди кратний розміру сторінки (4096 == 0x1000 байт). На початку упакованих даних розташовується масив чотирьохбайтового цілочисельних значень. Кількість елементів масиву відповідає кількості сторінок в розпакованих даних.

Наприклад, для модуля розміром 81920 == 0x14000 байт масив буде займати 80 == 0x50 байт і складатися з 20 == 0x14 елементів.

Наприклад, для модуля розміром 81920 == 0x14000 байт масив буде займати 80 == 0x50 байт і складатися з 20 == 0x14 елементів

У двох старших бітах кожного з Little-Endian-значень зберігається номер таблиці (0b01 для коду та 0b11 для даних). У решти 30 бітах зберігається зміщення початку стислій сторінки щодо кінця масиву зсувів. Наведений вище фрагмент описує 20 сторінок:

Наведений вище фрагмент описує 20 сторінок:

Примітно, що зміщення упакованих даних для кожної сторінки відсортовані по зростанню, а розмір упакованих даних для кожної сторінки в явному вигляді ніде не фігурує. У наведеному вище прикладі упаковані дані для кожної конкретної сторінки починаються на кордоні, кратній 64 = 0x40 байтам, а невикористовувані області заповнені нулями. Але по інших модулів можна встановити, що вирівнювання не обов'язково. Це наштовхує на думку, що распаковщик зупиняється, коли обсяг даних розпакованої сторінки досягає 4096 байт.

Так як ми знаємо загальний розмір упакованого модуля (з Module Attributes Extension), ми можемо розділити упаковані дані на сторінки і працювати з кожною окремо. Початок упакованої сторінки визначається з масиву зсувів, а розмір - зміщенням початку наступної сторінки або загальним розміром модуля. При цьому після упакованих даних може йти довільну кількість незначущих біт (ці біти можуть мати будь-які значення, але на практиці вони зазвичай нульові).


На скріншоті видно, що остання стисла сторінка (починається зі зміщення 0xFA40) складається з байта 0xB2 == 0b10110010, за яким йде 273 байта зі значенням 0xEC == 0b11101100, і далі - тільки нулі. Так як бітова послідовність 11101100 (або 01110110) повторюється 273 рази, можна припустити, що вона кодує 4096/273 == 15 однакових байт (швидше за все, зі значеннями 0x00 або 0xFF). Тоді бітова послідовність 10110010 (або 1011001) кодує 4096-273 * 15 == 1 байт.

Це добре узгоджується з припущенням про те, що кожна кодова послідовність кодує ціле кількість байтів (від 1 до 15 включно). Однак повністю відновити таблиці Хаффмана таким чином неможливо.

Знаходження пар «стиснений текст - відкритий текст»

Як було показано раніше , В різних версіях прошивок для ME 11 модулі з однаковими назвами можуть упаковуватися різними алгоритмами. Якщо розібрати Module Attributes Extension для однойменних модулів, упакованих як LZMA, так і Хаффманом, і витягти значення SHA-256 для кожного модуля, то не виявиться жодної пари модулів, упакованих різними алгоритмами і мають однакові значення хеш-кодувань.

Але якщо згадати, що для модулів, упакованих LZMA, SHA-256 зазвичай вважається від стислих даних, і порахувати SHA-256 для модулів після розпакування LZMA, то виявиться досить багато відповідних пар. І для кожного такого «парного» модуля ми відразу отримаємо кілька пар сторінок - в упакованому Хаффманом і розпакованому вигляді.

Продовження доступно тільки учасникам

Варіант 1. Приєднайся до товариства «Xakep.ru», щоб читати всі матеріали на сайті

Членство в співтоваристві протягом зазначеного терміну відкриє тобі доступ до ВСІХ матеріалами «Хакера», збільшить особисту накопичувальну знижку і дозволить накопичувати професійний рейтинг Xakep Score! Детальніше

Варіант 2. Відкрий один матеріал

Зацікавила стаття, але немає можливості стати членом клубу «Xakep.ru»? Тоді цей варіант для тебе! Зверни увагу: цей спосіб підходить тільки для статей, опублікованих більше двох місяців тому.


Ru»?

Дополнительная информация

rss
Карта