PSPx форум

PSPx форум (https://www.pspx.ru/forum/index.php)
-   PSP хакинг и девелопмент (https://www.pspx.ru/forum/forumdisplay.php?f=195)
-   -   [FAQ] GZIP-сжатие модулей с помощью консоли 7z.exe (https://www.pspx.ru/forum/showthread.php?t=102945)

ErikPshat 29.12.2012 12:05

[FAQ] GZIP-сжатие модулей с помощью консоли 7z.exe
 
Вложений: 2

Сжатие в GZIP с помощью консольных 7-ZIP

Как известно, файлы кастомных прошивок, программ, игр и т.п. пожаты в архивы GZIP. Поэтому часто приходится упаковывать таким образом файлы, чтобы они занимали меньше места, а самое важное то, что после кастомизации часто бывает необходимость вернуть файл на строго определённое место, ограниченное размером, когда нельзя делать сдвиг последующего кода.

Как мы знаем, сжимать в GZIP прекрасно умеет архиватор 7-ZIP. Но его GUI интерфейс имеет скромный потенциал и не позволяет гибко манипулировать сжатием. Зато набор консольных команд того же самого модуля архиватора 7z.exe имеет более расширенный функционал, где мы можем по своему желанию сжать файл до нужного нам размера, выбирая нужные нам параметры сжатия.

Какие параметры командной строки нам даёт архиватор 7-ZIP
Код:

7-Zip 9.20  Copyright (c) 1999-2010 Igor Pavlov  2010-11-18

Usage: 7z <command> [<switches>...] <archive_name> [<file_names>...]
      [<@listfiles...>]

<Commands>
  a: Add files to archive
  b: Benchmark
  d: Delete files from archive
  e: Extract files from archive (without using directory names)
  l: List contents of archive
  t: Test integrity of archive
  u: Update files to archive
  x: eXtract files with full paths

<Switches>
  -ai[r[-|0]]{@listfile|!wildcard}: Include archives
  -ax[r[-|0]]{@listfile|!wildcard}: eXclude archives
  -bd: Disable percentage indicator
  -i[r[-|0]]{@listfile|!wildcard}: Include filenames
  -m{Parameters}: set compression Method
  -o{Directory}: set Output directory
  -p{Password}: set Password
  -r[-|0]: Recurse subdirectories
  -scs{UTF-8 | WIN | DOS}: set charset for list files
  -sfx[{name}]: Create SFX archive
  -si[{name}]: read data from stdin
  -slt: show technical information for l (List) command
  -so: write data to stdout
  -ssc[-]: set sensitive case mode
  -ssw: compress shared files
  -t{Type}: Set type of archive
  -u[-][p#][q#][r#][x#][y#][z#][!newArchiveName]: Update options
  -v{Size}[b|k|m|g]: Create volumes
  -w[{path}]: assign Work directory. Empty path means a temporary directory
  -x[r[-|0]]]{@listfile|!wildcard}: eXclude filenames
  -y: assume Yes on all queries



Итак, для выполнения сжатия, из списка команд видно, что нам потребуется <Commands>
  • a: Add files to archive (Добавить файлы в архив) - буква ы зачёркнута, т.к. в GZIP нельзя архивировать более 1-го файла!
Далее нам нужны будут следующие <Switches>:
  • -t{Type}: Set type of archive (установить тип архива) - т.к. нас интересует архивирование в GZIP, то и выставляем тип: -tgzip
  • -m{Parameters}: set compression Method (установка метода сжатия) - для GZIP существует только метод Deflate и только 3 параметра, об этом ниже...


Сразу приведу пример демонстрации сжатия в архив GZIP с максимально возможным набором команд:

7z a -tgzip arhive.gz file.prx -mx=5 -mfb=4 -mpass=2
Разложим команды сжатия по запчастям...

КомандаОписание
7zсоответственно вызов 7z.exe (расширение обычно не пишут в командах вызова)
aдобавить в архив (от слова add), соответственно e - извлечение (Extract)
-tgzipпараметром -t указываем, что архив gzip, иначе, если не указывать, будет 7z.
archive.gzназвание будущего архива
file.prxназвание архивируемого файла.
-mx=5параметром -m указываем сжатие и следом x=5 уровень сжатия (от 1 до 9)
-mfb=4параметром -m указываем сжатие и следом fb=4 число быстрых байтов (от 3 до 258)
-mpass=2параметром -m указываем сжатие и следом pass=2 число проходов (от 1 до 15)


Теперь более подробнее о параметрах:

GZip использует те же самые параметры как Zip, но GZip сжимает только с методом Deflate.
Таким образом GZip поддерживает только следующие параметры: x, fb, pass.


ПараметрЗначение по-умолчаниюОписание
x=[0|1|3|5|7|9]5Устанавливает уровень сжатия
fb={NumFastBytes}32Устанавливает число быстрых байтов для Deflate кодера
pass={NumPasses}1Устанавливает число проходов для Deflate кодера

Разберём из 1-го столбика таблицы эти параметры поподробнее:

  1. x=[0|1|3|5|7|9]
    Устанавливает уровень сжатия. x=0 - означает режим Copy (никакого сжатия).
    Установки Deflate/Deflate64:

    УровеньЧисло быстрых байтовЧисло проходовОписание
    1321Самый быстрый
    3Быстрый
    5Нормальный
    7643Максимальный
    912810Ультра

    x=1 и x=3 с Deflate методом устанавливают быстрый режим для сжатия.
  2. fb={NumFastBytes}
    Установка числа быстрых байтов для Deflate/Deflate64 кодера. Оно может быть в диапазоне от 3 до 258 (257 для Deflate64). Обычно большее число дает немного лучшую степень сжатия и более медленный процесс сжатия. Большие числа параметра быстрых байтов может значительно увеличить степень сжатия в случае, когда файлы содержат длинные идентичные последовательности байтов.
  3. pass={NumPasses}
    Установка числа проходов для Deflate кодера. Оно может быть в диапазоне от 1 до 15 для Deflate.
    Обычно большее число дает немного лучшую степень сжатия и более медленный процесс сжатия.



P.S. Есть ещё чисто консольная версия 7za.exe (разница видимо только в том, что в ней нету GUI-интерфейса)
Ну и есть другие консольные утилиты именно для gzip.

Вложение 10956


lupus 29.12.2012 14:02

Меня интересует именно 7zip и его консольная часть, т.к. именно им я смог сжать данные так, чтобы игра запустилась на псп. Плясал с другими архиваторами - не вышло ничего путнего.
х=9 - Это будет минимальное сжатие?

что-то про "x" и "fb" архиватор у меня ругается :/
Код:

7z a -tgzip 1.gim.gz 1.gim
Так работает. Не разберусь с указанием минимального сжатия, точнее совсем без сжатия.

ErikPshat 29.12.2012 15:42

Цитата:

Сообщение от lupus (Сообщение 1060002)
х=9 - Это будет минимальное сжатие?

Это максимальное сжатие.
Насчёт fb не помню, вроде нужео ещё и букву указывать b|k|m (в байтах | килобайтах | мегабайтах)

А почему бы тебе просто не пользоваться контекстным меню гуи?
Нажимаешь просто правой кнопкой по файлу, выбираешь 7-Zip => Добавить к архиву...
В открывшемся Гуи выставляешь gzip, потом выставляешь грубо "Уровень сжатия" и потом более тонко "Размер слова".

Скрины
[IMG]http://img687.**************/img687/9153/73188325.png[/IMG]

[IMG]http://img201.**************/img201/919/2912.png[/IMG]


Ещё размер архива наиболее тонко регулируется названием архивированного файла.
Каждая буква в названии прибавляет 1 байт к архиву.

Название архива не имеет значения, т.к. это просто заголовок и он при распаковке отбрасывается. Я, когда запаковывал архивы в PRX, с точностью до байтика регулировал архивы, там название делал чуть-ли не из 100 букв английского и русского алфавита )))

И смысла нет сжимать совсем без сжатия, PSP легко и быстро распаковывает максимальное сжатие. По крайней мере "Нормальное" сжатие (уровень 5-6) будет самое оно, даже меньше необходимого.
И это, никогда не было такого, чтобы архив получался нерабочим. Нужно просто правильно вставлять и править размеры в 3-ёх местах.

lupus 29.12.2012 16:05

Ну всё делается для того, чтобы интегрировать консольную часть 7z в другую софтину, которая написана для того, чтобы распаковывать/упаковывать данные из контейнера, используемого в игре. Я тебя как-то просил глянуть Hysteria Project, так вот по твоему описанию формата написать софтину для распаковки не составило труда, а вот с упаковкой возникли сложности. Я именно 7z вручную и упаковывал файлы после изменения, а потом снова собирал контейнер нашей софтиной.
Почему именно консоль? Мы просто вложим 7z.exe и прога сама будет после этого правильно паковать файлы перед сборкой контейнера. Представь, если все манипуляции для сотни файлов проделывать руками?
А так - всё автоматизировано. После релиза перевода можно и выложить будет для людей.
Вроде всё получилось.

ErikPshat 30.12.2012 06:06

Цитата:

Сообщение от lupus (Сообщение 1060020)
написать софтину для распаковки не составило труда

Интересно, как распаковываются GZIP. У них ведь нет строгого указателя на размер, есть только Magik 1F8B и последние 4 байта, указывающие на размер распакованного файла ))
Я предполагал сделать такую универсальную утилитку...
  1. Там достаточно производить поиск на мэйджик и извлекать содержимое от него до конца файла и тут же распаковывать.
  2. Затем продолжать поиск далее.
  3. Если при распаковке возвращается ошибка, то удалять ложный архив.
  4. Вот и всё. Хитрость в том, что главное иметь начало, а конец сам найдётся без нашего участия. То есть, распаковка идёт только первого архива в извлечённых данных, даже если далее ещё куча архивов. То же самое будет происходить со следующим волшебным смещением и т.д. до последнего мэйджика.

Цитата:

Сообщение от lupus (Сообщение 1060020)
После релиза перевода можно и выложить будет для людей.

Давно мечтал о такой утилите! Чур первый, йухан :)

lupus 30.12.2012 09:31

Тебе то я и так могу кинуть, как будет дописана. Но она заточена под конкретную игру и конкретный алгоритм, не знаю, подойдёт ли тебе.
А так, можно попробовать написать именно такую, как ты хочешь, только подробно расписанное задание нужно и пример файлов, над которыми ставит эксперименты.

ErikPshat 30.12.2012 10:36

Цитата:

Сообщение от lupus (Сообщение 1060108)
А так, можно попробовать написать именно такую, как ты хочешь, только подробно расписанное задание нужно и пример файлов, над которыми ставит эксперименты.

Да просто обычную универсальную, как я написал выше. Просто чтобы выдёргивала все имеющиеся GZIP-архивы из контейнера по magic-заголовку 1F8B и сразу конечно распаковывала.

Вот такое скромное задание:
  • Там достаточно производить поиск на мэйджик и извлекать содержимое от него до конца файла и тут же распаковывать.
  • Затем продолжать поиск далее.
  • Если при распаковке возвращается ошибка, то удалять ложный архив.
  • Вот и всё. Хитрость в том, что главное иметь начало, а конец сам найдётся без нашего участия. То есть, распаковка идёт только первого архива в извлечённых данных, даже если далее ещё куча архивов. То же самое будет происходить со следующим волшебным смещением и т.д. до последнего мэйджика.

lupus 30.12.2012 14:12

Примеры, Эрик, примеры ))
Эксперименты надо же на чём-то ставить...

ErikPshat 30.12.2012 17:27

Цитата:

Сообщение от lupus (Сообщение 1060131)
Примеры, Эрик, примеры ))
Эксперименты надо же на чём-то ставить...

Да вот простой пример, взять тот же Лунар. Там в каждом дате находится по сотне архивов. Здесь полная спецификация.

Собственно что примеры, они кругом, в PRX-ах, в бинарниках засунуты в недра по нескольку штук и принцип везьде одинаковый, тупо вложен архив и приходится вручную искать на магический хедер 1F8B, часто просто попадаешь на ложное совпадение программного кода, ну там сразу видно, чаще всего идёт 1F8B0808, но не факт.

Для примера даю один из них, в нём более 500 GZIP архивов ))) SEPack.dat

lis5131 30.12.2012 20:14

Под лунар у меня есть распаковщик. А вообще если ты можешь просчитать смещения сам, то есть у меня софтинка называется DeArxiver она извлечет по твоим смещением файлы, а потом запросто соберет. Но файлы для сбора должны быть одинакового размера с файлами оригиналами байт в байт. Иначе он будет наслаивать. Если файлы будут разные тебе прийдется пересчитывать смещения.

lupus 30.12.2012 20:38

Если новый файл меньше старого, то это вообще не проблема. Тупо добиваешь в хексе 0x00 или 0xFF до нужного размера. Для этого даже софтинка есть "Magic File Resizer"
Эрик, твой заказ попробуем реализовать, только у нас не я главный кодер, так что с праздниками может слегка затянуться. Кроме того, меня тут осенило, что неплохо бы чтоб софтина ещё лог создавала, что с какого смещения вынуто.

Yoti 31.12.2012 21:20

Цитата:

Сообщение от ErikPshat (Сообщение 1060099)
Я предполагал сделать такую универсальную утилитку...

100 лет как выкладывал сканер в паблик и pspdevtool (pspDevTool_R5-3_private.rar) в привате.

ErikPshat 31.12.2012 23:02

Yoti, я тестил твой тул, но проблема была в том, что для gzip приходилось выставлять принудительно размер архива. А здесь предложение более конкретного рода.

Yoti 02.01.2013 17:23

ErikPshat,
а у меня всё работало, помнится.

ErikPshat 24.01.2013 12:28

Цитата:

Сообщение от lupus (Сообщение 1060183)
Эрик, твой заказ попробуем реализовать, только у нас не я главный кодер, так что с праздниками может слегка затянуться. Кроме того, меня тут осенило, что неплохо бы чтоб софтина ещё лог создавала, что с какого смещения вынуто.

Эмм, праздники закончились, пошли дни рождения...

Инструкцию в шапке обновил! Раньше через GUI всё мучался с размером сжатия, хотя это делается более тонко через консоль )))

lupus 24.01.2013 23:42

Теперь я до кодера нашего не особо могу достучаться, он чем-то по работе занят. Мне никак софтину не допишет, не говоря уже о чём-то новом :(
Я для себя ьакой вот батник накатал:
Код:

@echo off
del *.gz
for %%X in (*.gim) do 7z a -tgzip "%%X.gz" "%%X"
@for %%a in (*.*) do @for %%b in ("%%~Na") do @ren "%%a" "%%~Nb%%~Xa"
del *.gim
pause

Если его запустить, то все gim'ы жмутся в отдельные gz, а замет оригиналы удаляются.

Yoti 26.01.2013 23:34

lupus,
а почему не del /q?

lupus 27.01.2013 11:04

/q - это без запроса? Батник и так работает :)

Yoti 27.01.2013 14:50

lupus,
ну да, типа принудительное удаление. У меня просто все серьёзные (читай как "не make.bat") файлы написаны с использованием ключей.

ErikPshat 29.01.2013 01:47

Цитата:

Сообщение от lupus (Сообщение 1062643)
Я для себя ьакой вот батник накатал:
Код:

@echo off
del *.gz
for %%X in (*.gim) do 7z a -tgzip "%%X.gz" "%%X"
@for %%a in (*.*) do @for %%b in ("%%~Na") do @ren "%%a" "%%~Nb%%~Xa"
del *.gim
pause



Ну так мог бы взять полное управление под себя:
Цитата:

Код:

@echo off
del *.gz
for %%X in (*.gim) do 7z a -tgzip -mx=5 -mfb=128 -mpass=2 "%%X.gz" "%%X"
@for %%a in (*.*) do @for %%b in ("%%~Na") do @ren "%%a" "%%~Nb%%~Xa"
del *.gim
pause


И регулируй как хочешь уровень сжатия, число одинаковых байтов и количество проходов, кастомно и более тонко.
А так у тебя всё идёт по-умолчанию: -mx=5 -mfb=32 -mpass=1

lupus 02.02.2013 17:15

У меня с б0льшим сжатием, чем дефолтное игра не захотела запускаться :(

ErikPshat 02.02.2013 18:11

Цитата:

Сообщение от lupus (Сообщение 1063315)
У меня с б0льшим сжатием, чем дефолтное игра не захотела запускаться :(

Где-то значит допустил ошибку.

Уж поверь мне, уровень сжатия никак не влияет на запускаемость.
Уже сотни раз пережимал файлы, бывало по максимуму, ни разу такого не было, чтобы что-то не запускалось.
Не запустится может только при не правильной упаковке, проставления размеров.

ErikPshat 23.02.2013 13:01

lupus, как я говорил, уже сотни раз сжимал со всевозможными параметрами сжатия всякие VSH, Recovery и что только ни жал, ни разу такого не было, чтобы GZ вдруг становился не рабочим. Такого никаким образом быть не может. Я просто не пойму, что у тебя, что у lis5131, постоянно что-то не работает, а Лис ваще жал через Гуи 7-Zip, потом нашёл какой-то доисторический BZIP компрессор ))) и вдруг что-то получилось :D

Вот сегодня опять сжал ваще с неимоверными параметрами в GZIP и даже заснял видео :)

lupus 02.03.2013 10:38

Я жал не модули, а игровые архивы, в которых тоже используется gz

LaKosta 02.03.2013 18:51

lupus, а какая разница. Чем отличается GZIP от GZIP?
Тут просто более сильное сжатие - будет дольше расжиматься. Все эти параметры сжатия используются только в процессе сжатия, а при распаковке только распаковывается.

Это аналогично, когда кодируешь видео в 1 проход или 2 прохода и с фильтрами. Чем больше проходов и доппараметров, тем дольше будет происходить кодировка. Но вот проигрывать видео по-любому будет проигрыватель, даже не задумываясь о том, сколько проходов было использовано или какие там суперпродвинутые параметры кодирования были использованы.

И это, PROUpdater установщика прошивки сжимать в 3 прохода - это тебе не с игровыми ресурсами баловаться :)
Цитата:

Сообщение от ErikPshat (Сообщение 1064759)
7z a -tgzip PROUpdater.gz "ErikPshat PSPx Team" -mx=5 -mfb=4 -mpass=3


lupus 19.01.2018 14:55

Недавно снова столкнулся с похожей задачей, нужно было найти и извлечь сжатый кусок данных, а если их много, то автоматизировать процесс.
Для этого отлично подошла софтинка offzip:
Ссылка
Цитата:

Offzip 0.4 (offzip / Offset file unzipper) .image.
a very useful tool to unpack the zip (zlib/gzip/deflate) data contained in any type of file like raw files, packets, zip archives, executables and everything else.
it's needed only to specify the offset where the zip data starts or using the useful -S search option able to scan the file for possible deflate (-z -15) and zlib data.
there are also other options for extracting all the compressed streams (-a) or dumping them compressed (-A).
it's also possible to choose a windowBits value for scanning both the zlib (RFC1950) and deflate (RFC1951) blocks.
the -c option allows to work with chunked files and trying to build the original files.
the files will be dumped with a guessed extension that can be useful for their quick identification.
the tool has also a reimport option (-r) like QuickBMS.
how to dump all the zlib compressed files in an archive:
- offzip.exe -a input_archive output_folder 0
how to dump all the deflate compressed files in an archive:
- offzip.exe -z -15 -a input_archive output_folder 0
нам нужна команда
Код:

offzip.exe -z -15 -a input_archive output_folder 0
я использовал такую:
Код:

offzip.exe -z -15 -a orig_tr.nax temp 0 > tr_nax.txt
где:
Код:

orig_tr.nax
- мой файл, в котором я искал сжатые секции
Код:

temp
- папка, в которую извлекать найденные данные
Код:

> tr_nax.txt
- текстовик, куда сохранить лог

На выходе я получил файл 000003ae.lxc в папке temp и лог в текстовом файле tr_nax.txt рядом с offzip.exe

Файл 000003ae.lxc - содержимое того самого gz архива, который я искал. Обращаю внимание, что это уже распакованные данные!
Откуда имя файла:
000003ae - Поскольку заголовок gzip архива в данном конкретном случае не содержал имени сжатого файла, в качестве имени использовался адрес с которого в orig_tr.nax начинался поток сжатых данных.
.lxc - приложение offzip пытается по заголовкам извлечённых данных определить их MIME содержимое, что бывает очень полезно для стандартных типов файлов. Очень удобно, когда на выходе вы получаете всякие .png, .wav и т.п. В данном конкретном случае файл начинается с сигнатуры LXCE, отсюда и расширение.

Если хотите вырезать архив в исходном виде, то:
1. открываем исходный файл orig_tr.nax в хекс редакторе
2. переходим по адресу 0x000003ae т.е. к началу потока сжатых данных
3. с помощью поиска ищем значение hex 1f8b (magic сигнатура gz), направление поиска (обязательно!) назад от текущего положения курсора. Первое же совпадение должно быть началом нашего архива.

NB! Размер заголовка gzip архива может отличаться в зависимости от заданных при сжатии аргументов. Но его минимальная длина всегда равна 0x0A (10 байт)
Более подробно о заголовке (и не только) gzip прочитать здесь: http://www.forensicswiki.org/wiki/Gzip

Упражнение для начинающих
В данном конкретном случае :blush: мой заголовок размером, как раз 10 байт и выглядит так:
Код:

1F 8B 08 00 00 00 00 00 00 0B
Привёл его в качестве примера и для того, чтобы дать начинающим "копателям кода" возможность поупражняться и понять, какие данные хранятся в том заголовке.



Все данные, выше заголовка можно отбросить и сохранить файл, дав ему имя %filename%.gz (самый простой путь, о нём выше говорил Эрик), после чего извлечь данные с помощью того же 7zip.
Если всё сделано верно, то бинарное сравнение подтвердит идентичность данных извлечённых offzip и хекс-редактором.

позже продолжим...

Yoti 01.02.2018 00:20

Вложений: 3
А ещё программа для обработки заголовка gzip (0x1f8b...) от меня.
Использование: кинуть файл на программу или передать 1-ым параметром.

Версия 0.1 (31.01.18): первый релиз
Версия 0.2 (01.02.18): отображение времени из заголовка, добавлено значение 0 для поля сжатия
Версия 0.3 (03.02.18): исправлено отображение времени, когда оно не задано

Yoti 04.05.2019 04:18

Вложений: 2
Однострочные утилиты, которые написаны больше как тренировка для себя.

gzip - упаковщик
Синтаксис:
Код:

gzip.exe <input> [output]
Имя output по умолчанию это input с дополнительным расширением '.gz'.

ungz - распаковщик
Синтаксис:
Код:

ungz.exe <input> [output]
Имя output по умолчанию это input с обнулением последнего расширения.
Например, test.txt.gz -> test.txt; test.gz -> test (без расширения).

ErikPshat 04.05.2019 08:34

Yoti, вообще родная утилита от линукс - это tar.exe, она и в составе Windows 10 включена по умолчанию и пакует в gzip, bzip2.
Набери в консоли tar --help.
Код:

Compression options:

 -a, --auto-compress        use archive suffix to determine the compression program
 -I, --use-compress-program=PROG
                            filter through PROG (must accept -d)
 -j, --bzip2                filter the archive through bzip2
 -J, --xz                  filter the archive through xz
    --lzip                filter the archive through lzip
    --lzma                filter the archive through lzma
    --lzop                filter the archive through xz
    --no-auto-compress    do not use archive suffix to determine the ompression program
 -z, --gzip, --gunzip, --ungzip  filter the archive through gzip
 -Z, --compress, --uncompress  filter the archive through compress


Yoti 05.05.2019 03:32

ErikPshat,
никс подсистема не включена по умолчанию и у меня не десятка. Зато я сделал архивацию без имени файла, как и было в оригинале.


Текущее время: 14:29. Часовой пояс GMT +3.

Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2025, vBulletin Solutions, Inc. Перевод: zCarot
PSPx Forum - Сообщество фанатов игровых консолей.