Тут в PrxDecrypter я заметил некорректно написанный код сжатия. Вернее он сжимает и всё подсчитывает корректно, но алгоритм сжатия у него работает не так, как надо.
В ообщем тут такое дело, что если декриптовать тот же Astinishia Story 2 и попытаться обратно зашифровать его же родным заголовком, то так не получится, потому что декриптованный ELF-файл уже не поместится по размеру в свой родной заголовок - будет ошибка: Elf is to big. И это при том, что якобы в алгоритме энкриптера используется сжатие , причём после шифровки и последующей декриптовке явно отображается, что файл:
Аналогичная ситуация происходит со всеми файлами, например при попытке подписать файлы прошивки своими же заголовками.
Короче, я так понял, алгоритм шифрования происходит в следующем порядке:
Сравнение по размеру ELF-файла с размером, записанном в шифрованном заголовке по адресу 0x2C минус 0x15С
Если ELF-файл больше, то выдаётся сообщение об ошибке: Elf is to big
Затем, если файл меньше, то он в конце забивается нулями до размера, прописанного в шифрованном заголовке по адресу 0x28 (размер декриптованного ELF)
После применяется сжатие GZIP
Добивается архив в конце нулями до размера, указанного в шифрованном заголовке по адресу 0xB0 (размер архива)
И наконец файл шифруется и добавляется заголовок.
Тут требуется только поправить порядок действий на такой:
Если сжатый файл меньше, то он в конце забивается нулями до размера, прописанного в шифрованном заголовке по адресу 0x28
Применить сжатие GZIP
Добивается архив в конце нулями до размера, указанного в шифрованном заголовке по адресу 0xB0
Сравнение по размеру сжатого ELF-файла с размером, записанном в шифрованном заголовке по адресу 0x2C
Если ELF-файл больше, то выдаётся сообщение об ошибке: Elf is to big
И наконец файл шифруется и добавляется заголовок.
Это моё видение навскидку, но возможно там происходят более масштабные преобразования и придётся не просто поменять местами порядок выполнения функций, а ещё и переписывать код.
Хотя, сам код довольно короткий и простой, но я так и не понял, каким же образом происходит порядок сжатия.
Я хотел сказать, что СЖАТИЕ здесь вообще не имеет никакого смысла и эффекта, хотя оно явно используется.
То есть, файл размером 1 Мб должен ужаться и подписаться маленьким заголовком, однако он всегда подписывается большим заголовком, чем сам файл.
Провёл такой эксперимент. За основу взял оригинал DATA.PSP - Astinishia Story 2.
0x2C = 0x00059FA0 = 368'544 byte - размер всего файла с заголовком.
0xB0 = 0x00059E44 = 368'196 byte - размер архива.
Чтобы файл работал, все эти данные должны совпадать. Ну а мы пока работаем с оригинальным файлом, поэтому тут и так всё должно быть чётко.
Так как я знаю, что файл пожат в GZIP, то теперь я в PrxDecrypter отключаю декомпрессию (тупо в коде меняю сигнатуру 1F8B на любую другую, по которой программа определяет, что перед ней GZIP-архив). Это находится здесь:
// GZIP DECOMPRESSION
if (*(u16 *)&g_dataOut2[0] == 0x8B1F) {
Теперь программа будет только декриптовать шифрованный файл, но разархивировать не будет.
Декриптуем оригинальный DATA.PSP от Astinishia Story 2
В папке "enc" обнаруживаем декриптованный файл, но конечно там нет знакомой сигнатуры ELF, а видим знакомые цифры 1F8B - архив GZIP.
Смотрю его размер. Он в точности совпадает с указанным в заголовке:
0xB0 = 0x00059E44 = 368'196 byte - размер архива.
Смотрю у архива последние 4 байта -> 0x000EF008.
Они по спецификации GZIP указывают на размер разархивированного файла, что в точности совпадает с указанным в заголовке:
Для уверенности разархивирую с помощью 7-zip этот архив и получаю чистый ELF, как и положено ему быть.
Ликбез №3
Поехали дальше... Теперь проводим эксперимент с фейковой подписью.
Беру чистый декриптованный ELF от Astinishia Story 2 (978'952 byte - довольно большой )
Подписываю через PrxEncrypter.
Получаю на выходе подписанный файл размером 0x00164000 = 1'458'176 byte заголовком от Dynasty Warriors Strikeforce
Вот те ппц, приехали, наглядный пример сжатия PrxEncrypter
Ну это не удивительно, он всегда так подписывал, потому что сначала подбирает под декриптованный ELF подходящий заголовок, не меньше размером, забивает до нужного размера 0x28 нулями, а только потом сжимает, опять добивает уже архив всяким мусором до указанного в заголовке 0xB0 размера архива и затем шифрует.
Короче, подписанный фейковый файл опять декриптуем без декомпрессии.
Получаем на выходе архив 1F8B размером 0х00163EAE = 1'457'838 byte - собственно, как и указано в заголовке 0xB0Dynasty Warriors Strikeforce
Сразу разархивирую его с помощью 7-Zip и получаю декриптованный ELF размером 0x00433DBC = 4'406'716 - как и указано в заголовке 0x28.
1. По первому пункту получаем такой прикол - ищу конец архива - последние 4 байта в архиве, по уже известному размеру разархивированного файла BC3D4300 - настоящий архив кончается в 1/3 от начала и составляет 0x0005DD59 = 384'345 byte. Остальная 2/3 части забито оставшейся частью декриптованного ELF-файла и далее нулями. То есть, берётся сам декриптованный файл, архивируется в GZIP и затем архив вставляется в этот же файл в начало, и есстественно конец декриптованного файла остаётся. Но это не беда, архив GZIP имеет потоковый формат и разархивируется потоково, пока не дойдёт до своего конца, а что там после конца - ему на это пофиг. Не зря GZIP не имеет меток размера и конца, но в конце обязательно имеет последние 4 байта метки разархивированного размера.
Да, настоящий архив, без нулей и мусора от ELF, немного не дотягивает до "Astonishia Story 2" (368'544), но зато свободно бы влез в заголовок от "Everybody's Sukkiri #1" (430'176 byte).
2. По второму пункту - разархивированный файл так же забит на 2/3 нулями, чтобы подогнать его под размер заголовка в 0x28
В общем, суть в том, что энкриптер сначала подбирает заголовок под ELF-файл, потом под этот заголовок подгоняет его, а только потом архивирует и опять подгоняет.
А нужно, чтобы он сначала архивировал ELF, а только потом под архив подбирал заголовок.
Прошу любить и жаловать, Ваш Добро пожаловать в наш Чат в Telegram
Последний раз редактировалось ErikPshat; 28.04.2013 в 20:11.