Z0mbie
Top Device Online [6]
Июнь 2000
Когда большинство вирусов было бутовыми, когда обновлялся аидстестовский вирлист, лозинский еще не впал в маразм, а касперский еще только сосал не причмокивая... Жил-был вирус, и как только он не назывался - Doodle, Yankee, Music, и еще хрен знает как.
И была в том вирусе фича, а именно - коли патчил в вирусе бедняга-программист какой байт, так байт этот на место возвращался. То есть становился обратно, как был.
И с тех пор мучают вирмэйкеры себя и людей, доставая их вопросами - как же енто он, проклятый, восстанавливается, не делая второй своей копии?
Интуитивно ясно, что внесение избыточности в информацию позволяет находить и восстанавливать помехи. Пример тому - избыточность естественных языков. Сколько избыточности вносить и как ее считать, можно прочитать у Шеннона.
Мы, вирмэйкеры, люди простые, нам Шеннон ни к чему, всякие там теоремы мы вообще знать не желаем, и поэтому требуется простой способ восстанавливать вирус после патча.
Итак, представляем защищаемый блок данных в виде матрицы. По каждому столбцу и каждой строке матрицы считаем контрольную сумму, попросту XORим байты один на другой.
Теперь представим, что изменился один байт. Тогда изменятся контрольные суммы соответствующих столбца/строки матрицы, своими номерами указывая координаты байта.
Вот и все. Максимальное количество восстанавливаемых подряд байт равно числу столбцов. Количество строк и столбцов выбирается как вам удобнее.
Конечно, можно попросту хранить вторую копию вируса. Но ее будет легко пропатчить. И вообще, это уже совсем другая байка.
Кстати, судя по всему похожая фишка используется в RARе для защиты архивов от глюков, для -rr1 число столбцов (длина строки) соответственно 512 байт - один сектор.
Пример.
Есть данные, и есть контрольные суммы по строкам и по столбцам, посчитанные XORом. Пусть байт 74 (jz) изменили на EB (jmp).
| до изменения | после изменения | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| 90 | 90 | 90 | 90 | 90 | 90 | 90 | 90 | 90 | 90 | 90 | 90 |
| 90 | 74 | 12 | 90 | 90 | F6 | 90 | EB | 12 | 90 | 90 | 69 |
| 90 | 90 | 90 | 90 | 90 | 90 | 90 | 90 | 90 | 90 | 90 | 90 |
| 90 | 90 | 90 | 90 | 90 | 90 | 90 | 90 | 90 | 90 | 90 | 90 |
| 00 | E4 | 82 | 00 | 00 | 00 | 7B | 82 | 00 | 00 | ||
В результате изменятся два байта контрольных сумм - один в суммах по строкам и один в суммах по столбцам. Таким образом мы узнали координаты измененного байта в массиве данных. Как вычислить старое значение байта? - проXORить старую контрольную сумму на новую и на новое значение байта.
F6 xor 69 xor EB = 74, либо E4 xor 7B xor EB = 74.
Следующую мысль выражу кратко: если и здесь не понятно, то это пиздец.
Пример на C++
Примечание (для тех кто не знает C):
| с++ | pascal |
|---|---|
| c = d ^ e; | c := d xor e; |
| a ^= b; | a := a xor b; |
| a++; | a := a + 1; |
Результат работы программы:
randomizing a[3][3]: 51 --> A6 randomizing a[3][2]: FC --> 11 found error in a[3][2] trying to correct 11 -> FC found error in a[3][3] correcting A6 -> 51
Может возникнуть вопрос: какими должны быть изменения, чтобы подобный метод не смог восстановить пропатченый байт?
В основном такими:
00 00 00 00 00 nn Нельзя определить, какие из указанных четырех байтов 00 A B 00 00 ** изменились: это могут быть A и D либо B и C, 00 C D 00 00 ** либо любые комбинации по 3 байта, либо все 4. 00 00 00 00 00 nn 00 00 00 00 00 nn nn ** ** nn nn
То есть такая схема подсчета контрольных сумм хорошо работает только если изменения произошли в пределах одной строки/столбца. Поэтому строки эффективно делать длиннее столбцов.
Если вас заинтересовало помехозащищенное кодирование - ищите линейный блоковый код, коды M из N, коды Хэмминга и тому подобную хрень.
[Вернуться к списку] [Комментарии (0)]