Вопрос:
В старой игре, которую я пытаюсь использовать, есть проверка CRC-32. У меня нет доступа к контрольной сумме CRC, поэтому я должен изменить файл, сохраняя тот же вывод контрольной суммы.
Информация у меня есть
-
Файл, если сам файл является единственным входом в программу CRC-32, я могу рассчитать, какая контрольная сумма CRC-32 должна быть.
-
32-битный полиномиальный код.
Лучший ответ:
Как говорит @MrSmith42, при условии, что вам не нужно поддерживать постоянную длину файла, можно легко вычислить “коллизию” (имя, данное для двух входных сообщений, которые приводят к одному и тому же хешу).
Это неловко, с большим количеством небольшого поворота, но очень быстро.
Предположим, что исходный файл в шестнадцатеричном виде:
1122334455667788
Тогда его контрольная сумма CRC-32 будет 0x9118E1C2 с использованием стандартного полинома CRC32. Если используемый алгоритм не является стандартным, его можно заменить. Я буду придерживаться стандарта для демонстрационных целей.
Сначала внесите необходимые изменения в файл. Например, я меняю байт посередине:
11223344FF667788
Первый шаг для восстановления CRC – заполнить файл четырьмя нулевыми байтами:
11223344FF66778800000000
Контрольная сумма CRC теперь 0x6BBE83C9.
Шаг второй, XOR две контрольные суммы:
0x9118E1C2 XOR 0x6BBE83C9 = 0xFAA6620B
Шаг третий, немного поменять результат:
Bit reverse of 0xFAA6620B = 0xD046655F
Шаг четвертый, и это немного странно, так что смотрите ниже, выполните обратный расчет CRC32:
0xD046655F * inverse(x32) mod crc_poly = 0xe4c7d232
Шаг пятый, побитовый результат, побайтно на этот раз:
0xe4c7d232 bit reversed byte-wise = 0x27E34B4C
Шаг шестой, замените заполненные байты на результат
11223344FF66778827E34B4C
Вуаля, значение контрольной суммы CRC32 теперь вернулось к 0x9118E1C2.
Самый простой способ сделать обратный расчет CRC – это пакет BitVector в Python:
>>> import BitVector as bv >>> poly = bv.BitVector(intVal = 0x104C11DB7) # «standard» CRC32 polynomial >>> inv = bv.BitVector(intVal = 0x100000000).gf_MI(poly, 32) >>> k = 0xD046655F >>> p = bv.BitVector(intVal = k).gf_multiply_modular(inv, poly, 32) >>> print(p.getHexStringFromBitVector()) e4c7d232
Этот алгоритм от Redditor/u/supersaw7 опубликован в этой теме. Я не встречал лучшего, несмотря на то, что более простая версия была невероятно возможной.
Ответ №1
Если размер файла не обязательно должен быть постоянным, вы можете просто изменить его содержимое столько, сколько хотите, и добавить несколько байтов (4), чтобы исправить контрольную сумму.
Какие байты для добавления могут быть
а) вычислен, если вы понимаете используемый CRC-алгоритм или
б) попробуйте попытку грубой силы найти подходящие байты (может занять некоторое время, но если вам не нужно часто это делать, это все еще возможно
Ответ №2
Используйте пародию. После того, как вы изменили свой файл, вам нужно будет определить набор битовых местоположений, которые вы позволите изменить, чтобы вернуть CRC в исходное значение. Вам нужно будет предоставить пародию исключительного или исходного CRC, к которому вы хотите вернуться, и текущего CRC, а также местоположения бит, которые вам не нужны, например, в символьных строках, а также некоторая информация о сам CRC и длина файла. затем spoof решает, для какого из этих битов перевернуться, чтобы получить желаемый CRC. В документации дается руководство по количеству изменяемых позиций бит, которые вам нужно будет предложить.
Вы можете оставить файл той же длины или добавить байты в файл для создания позиций, которые считаются изменчивыми.