PDA

Просмотр полной версии : Баг в depacker от hrust1.3?



moroz1999
03.12.2006, 02:32
Обнаружил странную проблему - depacker от hrust1.3 не желает распаковывать запакованный им же файл.
Вот код:

ORG 30000
LD SP,29999
DI
JP START

DEHRUST INCBIN "dehrust.bin"
START
LD HL,FILE
LD DE,#c000
CALL DEHRUST
DI
HALT
FILE INCBIN "packed.bin"
длина упакованного файла - 2701, распакованного - 6144.
Файл скорее всего упакован нормально, потому что это - только один кусок из 9-и подобных, и остальные распаковываются нормально. сам dehrust сохранен из программы.
результат работы dehrust - нетронутая область #c000.

исходник с самим файлом - на http://www.zone.ee/obmen/test2.zip


если это действительно баг hrust1.3, то посоветуйте пожалуйста другой упаковщик со схожим функционалом. hrust 2.1 пробовал, но он почему-то мой список файлов не осилил, как я ни пробовал.

elfh
03.12.2006, 09:33
послушай, я много всего пробовал, сейчас остановился на megalz от mayhem - он хоть пакует и не круче всех, зато все без проблем распаковывается - не надо забивать себе голову лишними трудностями.

jtn
03.12.2006, 12:46
уважаемый, почему у вас да диск пишется 300 байт, а не 2975, что является длиной файла test.out. во-вторых файл запакован hrust1.x, а распаковщик от hrust2.x парадокс!
послушай, я много всего пробовал, сейчас остановился на megalz от mayhem - он хоть пакует и не круче всех, зато все без проблем распаковывается - не надо забивать себе голову лишними трудностями.действительно! дельный совет =)))

moroz1999
03.12.2006, 14:59
уважаемый, почему у вас да диск пишется 300 байт, а не 2975, что является длиной файла test.out. во-вторых файл запакован hrust1.x, а распаковщик от hrust2.x парадокс!опа! сорри, накосячил при сборке файлов с примером. я поправил всё, перезапаковал и залил заново - http://www.zone.ee/obmen/test2.zip
также приложил незапакованный исходный файл, длиной в 5596 (не 6144 как я писал выше).
теперь как результат - распаковщик hrust падает.

moroz1999
03.12.2006, 14:59
послушай, я много всего пробовал, сейчас остановился на megalz от mayhem - он хоть пакует и не круче всех, зато все без проблем распаковывается - не надо забивать себе голову лишними трудностями.спасибо, попробую!

upd: хм, http://lvd.nm.ru/MegaLZ/ не открывается у меня сейчас, а на VT его почему-то не нашел.

axor
03.12.2006, 17:08
спасибо, попробую!

upd: хм, http://lvd.nm.ru/MegaLZ/ не открывается у меня сейчас, а на VT его почему-то не нашел.
Надеюсь авторы не будут против выкладывания.
Упаковщик для писи, распаковщик для Спектрума.

Хотя проблем с распаковкой Хруст не наблюдал. Обратись к Spectre или Alco - они авторы последних доработок в распаковщике Хруста.

jtn
03.12.2006, 18:09
опа! сорри, накосячил при сборке файлов с примером. я поправил всё, перезапаковал и залил заново - http://www.zone.ee/obmen/test2.zip
также приложил незапакованный исходный файл, длиной в 5596 (не 6144 как я писал выше).
теперь как результат - распаковщик hrust падает.все правильно, в начале данные слишком плотные - известная бага хруста (описана в документации). лечится исправлением депакера. в общем случае - распаковывать надо из одной области памяти в другую, чтобы они не пересекались

moroz1999
03.12.2006, 18:36
все правильно, в начале данные слишком плотные - известная бага хруста (описана в документации). лечится исправлением депакера.Есть ли уже где-то поправленный? Сорри за глупые вопросы, я просто не так давно нормальной разработкой занялся, и потому у меня в голове по этой теме пробел :)


в общем случае - распаковывать надо из одной области памяти в другую, чтобы они не пересекалисьну, у меня вроде в примере так и получается, а всё равно бага есть?

moroz1999
03.12.2006, 18:37
Надеюсь авторы не будут против выкладывания.
Упаковщик для писи, распаковщик для Спектрума.
Спасибо! сегодня попробую его.

axor
03.12.2006, 20:20
Спасибо! сегодня попробую его.
Вот исходники Дехрустов разных версий.

moroz1999
03.12.2006, 20:53
Вот исходники Дехрустов разных версий.отлично, сегодня попробую!

jtn
03.12.2006, 20:57
ну, у меня вроде в примере так и получается, а всё равно бага есть?в самом начале депакера стоит LDDR перебрасывающий блок под конец блока куда будет идти распаковка. надо его убрать и выставить соответствующим образом регистры

moroz1999
04.12.2006, 15:43
всем огромное спасибо, после некоторых проб я всё же остановился на MegaLZ.

Shadow Maker
23.08.2012, 13:28
Поделитесь пофикшенной версией депакера плиз...

jerri
23.08.2012, 15:51
поясню что происходит пожалуй

у мороза данные находятся по адресу 30000
распаковывает он данные на адрес 49152
поэтому распаковщик делает как он считает правильную вещь переносит данные за область распаковки - выше 49152
но данные очень плохо сжаты - распакованные данные наползают на упакованные данные в конце файла - потому глюк
если бы мороз этот блок держал выше - например на #db00 то проблем бы не было
распаковщик ничего бы не копировал

проблема не в распаковщике - проблема в данных в конце файла там видимо лежит блок плохопакующийся

Shadow Maker
23.08.2012, 16:02
поясню что происходит пожалуй

у мороза данные находятся по адресу 30000
распаковывает он данные на адрес 49152
поэтому распаковщик делает как он считает правильную вещь переносит данные за область распаковки - выше 49152
но данные очень плохо сжаты - распакованные данные наползают на упакованные данные в конце файла - потому глюк
если бы мороз этот блок держал выше - например на #db00 то проблем бы не было
распаковщик ничего бы не копировал

проблема не в распаковщике - проблема в данных в конце файла там видимо лежит блок плохопакующийся
Юр, это я понимаю. Вот у меня есть файл скажем. Плохо сжатый.
Скажем лежит в #c020 и распаковывается туда же. Распаковщик мне данные переносит вниз и их всё равно не хватает, блок налазит при распаковке. Что делать? Перенести блок скажем в #d020 и оттуда распаковывать в #c020?

jerri
23.08.2012, 16:17
Shadow Maker, если используешь стандартный депакер (тот что отгружается автоматом) то да
если у тебя депакер в исходнике и собирается с загрузчиком - то просто убираешь вначале депакера проверку и переброску

---------- Post added at 16:17 ---------- Previous post was at 16:16 ----------

Keeper, это не решение
для каждого пакера есть свой орешек

Shadow Maker
23.08.2012, 16:17
Да, стандартный. Должно помочь по идее.

MegaLZ не панацея, там такие же ограничения с плохо пакующимися данными, только там авторы в депакере вообще не заморачиваются этим, весь контроль на пользователе.

Vitamin
23.08.2012, 16:17
Перенести блок скажем в #d020 и оттуда распаковывать в #c020?
Чтоб гарантированно работало, упакованный блок не должен никак пересекаться с распакованным. Если распакованный блок у тебя меньше #1000, то адрес #d020 вполне подходит.

Shadow Maker
23.08.2012, 16:24
Чтоб гарантированно работало, упакованный блок не должен никак пересекаться с распакованным. Если распакованный блок у тебя меньше #1000, то адрес #d020 вполне подходит.
Я б с радостью, но так не выйдет, памяти нет. Но вроде сейчас вот переместил - не наползает, нормально распаковало.

Vitamin
23.08.2012, 16:33
Я б с радостью, но так не выйдет, памяти нет. Но вроде сейчас вот переместил - не наползает, нормально распаковало.
Ну значит надо перемещать трудноупаковываемые данные в начало блоков.

Кстати об этих самых трудноупаковываемых данных. По хорошему, их быть не должно - это либо подгруженные уже упакованные блоки (что есть глюк) или de facto плохо пакующиеся данные (но в этом случае они должны равномерно плохо паковаться, что опять же наводит на мысль о первом случае).
Многократное вложение пакованных блоков друг в друга- крайне часто встречающаяся вещь, к сожалению...

Shadow Maker
23.08.2012, 16:46
Ну это хорошо, если ты можешь перенести блоки куда захочешь. А есть такая ситуация, когда уже поздно чего-то переносить, всё уже готово и тут бац - и проблема на этапе сборки финальной версии.

Вот тот блок, который у меня. Это не пакованные данные, тем не менее, всё налазиет, если распаковывать в то же место.

Vitamin
23.08.2012, 17:17
Вот тот блок, который у меня. Это не пакованные данные, тем не менее, всё налазиет, если распаковывать в то же место.
Ну, в принципе, даже в сыром виде заметно, что в конце идут более хаотичные и уникальные данные, нежели в начале. И допустимого нахлеста в 6 байт явно не хватит.

Shadow Maker
23.08.2012, 17:39
Ну это понятно, что нахлест идёт. Сделал бы кто-нить универсальный 256-байтный депакер для хруста, чтобы тот распаковывал всегда - вот это было бы здорово. А то часто и не поймешь, что вообще-то неправильно распаковалось, пока вдруг баги не полезут.

Vitamin
23.08.2012, 17:43
Сделал бы кто-нить универсальный 256-байтный депакер для хруста, чтобы тот распаковывал всегда - вот это было бы здорово.
Это невозможно:) Даже если просто логически подумать

psb
23.08.2012, 17:54
выход из ситуации - добавить в конец пакуемого блока кучу нулей. штук так 50-200.

moroz1999
23.08.2012, 18:47
поясню что происходит пожалуй

у мороза данные находятся по адресу 30000
распаковывает он данные на адрес 49152
поэтому распаковщик делает как он считает правильную вещь переносит данные за область распаковки - выше 49152
но данные очень плохо сжаты - распакованные данные наползают на упакованные данные в конце файла - потому глюк
если бы мороз этот блок держал выше - например на #db00 то проблем бы не было
распаковщик ничего бы не копировал

проблема не в распаковщике - проблема в данных в конце файла там видимо лежит блок плохопакующийся
Я, честно говоря, ничего не понял :)
Как я тогда слабо понимал причину проблемы, так и сейчас, перечитав всё, не понял ничего.

Shadow Maker
23.08.2012, 20:02
Это невозможно:) Даже если просто логически подумать
Нуууууу :) Хочется.

NovaStorm
23.08.2012, 21:47
Если так хочется, то можно подумать о буферизации этих несчастных 6ти байт в регистрах, но 100п овчинка выделки не стоит.

Vitamin
23.08.2012, 22:14
Если так хочется, то можно подумать о буферизации этих несчастных 6ти байт в регистрах, но 100п овчинка выделки не стоит.
6 байт нахлеста уже предусмотрены пакером и форматом сжатого блока. Т.е. распаковщик их обычно копирует вместе с собой. ЕМНИП.

psb
23.08.2012, 23:25
выход из ситуации - добавить в конец пакуемого блока кучу нулей. штук так 50-200.

psb
24.08.2012, 00:03
именно так.

moroz1999
24.08.2012, 02:05
http://imglink.ru/pictures/23-08-12/8ad3798a2ea24a27e77292f2c20b5d08.jpgА разве распаковщик не знает, каков размер неупакованного блока? Всё еще с трудом понимаю, почему нахлест возникает. Ему для распаковки нужен какой-то буфер, который приплюсовывается к архиву, и поэтому оно не влезло?
Просто я почитал первоначальный пример - там у меня распакованный файл весил примерно 6кб. Упакованный, соответственно, тоже не больше. Распаковка велась на 49152 - то есть 16 кб до конца памяти было, должен был влезть и упакованный, и распакованный вариант.
Кстати, а megalz тоже так свободно по памяти катается?

psb
24.08.2012, 05:11
следите за руками:

0. допустим, есть у нас исходный файл в 6к, сжатый до 3х.

1. распаковщик перемещает упакованный 3к блок так, что последний байт упакованного блока совпадает с посл. байтом будущего распакованного (т.е. он старается не занимать места больше, чем распакованный блок, не вылезать из этого окна).

2. начинает распаковывать. чем дальше к окончанию распаковки, тем указатели ОТКУДА (упак.) и КУДА (распак.) ближе друг к другу. в идеале, в самом конце они совпадают:)

3. при определенных условиях (те самые плохо сжимающиеся данные в конце) распакованные данные начинают перезатирать еще не распакованные... всё, капут.

таким образом, просто добавляем много нулей в конец пакуемого блока и бережем нервы. когда ничего не перезатирается, когда есть запас, все хорошо:)

Vitamin
24.08.2012, 07:24
таким образом, просто добавляем много нулей в конец пакуемого блока и бережем нервы. когда ничего не перезатирается, когда есть запас, все хорошо
Ну не всегда есть такая возможность. Иногда блок находится четко в конце памяти.

John North
24.08.2012, 08:35
Непонятен этот шаг с перемещением запакованного блока в конец распакованного.
Для чего?
Ведь запакованный блок УЖЕ находится в памяти. Неужели нельзя брать байты для распаковки прямо оттуда?
Зачем его таскать по памяти то лишний раз?

jerri
24.08.2012, 10:11
John North,
еще раз

hrust программа универсальная и считает что файл который она распаковывает имеет размер #a000 и находится по адресу #6000
поэтому он всегда старается переместить упакованный блок как можно дальше

что и видно на данном фрагменте исходника



DEHRUST PUSH DE
PUSH HL
берем размер распакованого блока
INC HL
INC HL
LD C,(HL)
INC HL
LD B,(HL)
INC HL

вычисляем конец распакованых данных

DEC BC
EX DE,HL
ADD HL,BC
EX DE,HL

берем длину пакованого блока

LD C,(HL)
INC HL
LD B,(HL)
DEC BC

проверяем на вероятность затирания

по умолчанию считается что блок будет загружен туда же куда будет распакован


POP HL
ADD HL,BC
SBC HL,DE
ADD HL,DE

JR C,LL4019
оставляем на месте

LD D,H
LD E,L
LL4019 LDDR

но последние 6 байт упакованного файла всегда сохраняются вместе с упаковщиком

но если блок находится по адресу 60000
а распаковывать надо например заставку он этот блок трогать не будет

psb
24.08.2012, 10:14
Иногда блок находится четко в конце памяти.
ну тогда ппц. городить костыльчик с перебрасыванием откуда-то еще.


Ведь запакованный блок УЖЕ находится в памяти. Неужели нельзя брать байты для распаковки прямо оттуда?
они могут пересекаться. универсальное решение, типа, привести к такому вот виду.

Vitamin
24.08.2012, 10:16
Непонятен этот шаг с перемещением запакованного блока в конец распакованного.
Для чего?
Ведь запакованный блок УЖЕ находится в памяти. Неужели нельзя брать байты для распаковки прямо оттуда?
Зачем его таскать по памяти то лишний раз?
Ё-моё... ну ты хоть соображалку включи и представь что будет, если распаковывать в ту же память, где лежит упакованный оригинал.

moroz1999
24.08.2012, 10:49
Мне, честно говоря, даже в голову не приходило, что можно попытаться распаковать блок с пересечением с упакованным файлом.
Имхо, в таком случае в распаковщик нужно добавить проверку - если в памяти достаточно места, то не делать копирование. Размер распаковщика, конечно, вырастет, но геморроя уменьшится.
С MegaLZ я не встречал такой ситуации ни разу - MegaLZ работает иначе или мне еще "повезет"? :)

Vitamin
24.08.2012, 11:07
Мне, честно говоря, даже в голову не приходило, что можно попытаться распаковать блок с пересечением с упакованным файлом.
Имхо, в таком случае в распаковщик нужно добавить проверку - если в памяти достаточно места, то не делать копирование. Размер распаковщика, конечно, вырастет, но геморроя уменьшится.
С MegaLZ я не встречал такой ситуации ни разу - MegaLZ работает иначе или мне еще "повезет"?
Блин, да невозможно в общем случае это предвидеть!
Представь, что ты бежишь наперегонки с другим человеком. Причем у тебя фора, примерно в половину дистанции. Ты бежишь практически равномерно, а твой соперник- нет. Иногда бежит немного медленнее тебя, иногда быстрее на два порядка. В среднем- чуть быстрее. Но прийти к финишу раньше тебя не может.
Вот на основании таких данных скажи- обгонит ли твой соперник тебя в процессе движения?

Shadow Maker
24.08.2012, 11:32
С MegaLZ я не встречал такой ситуации ни разу - MegaLZ работает иначе или мне еще "повезет"? :)
Потому что он ничего никуда не перебрасывает. Типа "тебе надо - ты и перебрасывай, если надо". А Хруст пытается дать хоть какую-то возможность для распаковки с минимальными затратами памяти. Короче вот когда у тебя будет ситуация, что занята вся память и распаковать можно только поверх и запас у тебя там байтов 10 - тогда и "повезет" :)

John North
24.08.2012, 12:14
Ё-моё... ну ты хоть соображалку включи и представь что будет, если распаковывать в ту же память, где лежит упакованный оригинал.

Не понял меня никто..
Имелось в виду, что запакованный блок лежит, напр, по адресу 30000, а распаковать надо, напр, в 49152..

Vitamin
24.08.2012, 12:17
Имелось в виду, что запакованный блок лежит, напр, по адресу 30000, а распаковать надо, напр, в 49152..
1) Это совершенно не гарантирует, что перекрытия не будет
2) Требует усложнения процедуры генерации кодового блока с депакером

jerri
24.08.2012, 12:36
John North, в данном случае программа предполагает что длина блока может быть 20000 тогда еще нераспакованные данные вполне успешно убиваются данными распакованными
введение дополнительной проверки лишь усложняет код и увеличивает и так немаленький распаковщик

Vitamin
24.08.2012, 15:46
Как-то трудно мне представить что будет перекрытие в таком случае...
Упакованный блок длинее 19152 байта:)

Vitamin
24.08.2012, 15:54
ну это логично конечно, но вряд ли 16кб (максимум) удастся упаковать в 19152 байта
Вообще да. Согласно формату Hrust, абсолютно неупакованный блок размером 16384 байта займет на выходе 12+16378+16378/8=18437 байт.

jerri
24.08.2012, 16:21
вы это распаковщику обьясните :) в 3-4 байта

Shadow Maker
21.09.2012, 14:11
Как мне вот такой блок распаковать? Как до нулей перед самым концом доходит - лезут глюки, нули не кончаются - причем даже если в другой области памяти лежат исходные данные. Непонятно как побороть. Депакер чтоли особый какой надо?

jerri
21.09.2012, 16:40
Shadow Maker, по смещению #2236 находится набор нулей
а с адреса #2277 находится труднопакуемый кусок который успешно херит все

возьми депакер который ничего никуда не двигает

Shadow Maker
21.09.2012, 16:58
Да, этим распаковывает. А не расскажешь, как мне стековый стандартный депакер модифицировать под мои нужды? А то не хочется два депакера держать. Могу сурс дать.

jerri
21.09.2012, 17:31
Shadow Maker, этот обычный :) просто контролируй что у тебя где находится

---------- Post added at 17:31 ---------- Previous post was at 17:28 ----------

а чем тебя этот не устраивает?

Shadow Maker
21.09.2012, 17:57
Это не обычный, этот без стековой переброски. Тем, что в буфер принтера не лезет и мне оригинальную версию надо тоже, c LDDR (чтобы я мог просто в B внести 0 и вызвать с того места, где у тебя начинается nomove, только это всё в 256 байт надо, как оригинальный депакер).

jerri
21.09.2012, 20:46
Shadow Maker, тебе обязательно перемещаемый?

jerri
21.09.2012, 21:03
вот здесь вот чуть измененная версия
сделаны кой какие изменения и сокращения

если есть исходник стекового депакера то можно модифицировать его без проблем

Shadow Maker
21.09.2012, 23:35
Исходников конечно нет, но это не проблема, сейчас сделаю. Чего уж, 256 байтов-то дизассемблировать.

Готово, во вложении.

jerri
22.09.2012, 00:58
Shadow Maker, #102 байта 2 точки входа - с перемещением и без
можно сократить на 4 байта убрав восстановление HL'

не тестировал

jerri
22.09.2012, 23:24
Shadow Maker, пробовал депакер?

Shadow Maker
25.09.2012, 18:10
Нет еще, на выходных наверное гляну, дел вагон.

goblinish
25.09.2012, 18:58
Нет еще, на выходных наверное гляну, дел вагон.

ну а машинку починили хоть?)

Shadow Maker
25.09.2012, 21:55
нет :(

Shadow Maker
17.10.2013, 20:29
Проверил, работает.

А можно подогнать под 256 байт c восстановлением HL'? Чтобы лишний сектор не гонять.

jerri
17.10.2013, 22:18
Shadow Maker, не прошло и года :)
не лезет, я не Хрумер
тебе HL зачем?
может сам восстановишь?

Shadow Maker
18.10.2013, 04:09
Ага, год ниче не паковал :) Могу и сам. Просто так красивее же, если выйдет в 256 байт :) Два байта всего осталось съэкономить же! :)

jerri
18.10.2013, 09:22
Shadow Maker,
ну не лезет блин :)
если отрезать HR то полезет, а так нет :)

Hrumer
17.04.2014, 10:39
Укорачивать надо?

В цикле подсчета длины


ld e, 1

ll4046
ld a, #80

ll4048
add hl, hl
djnz ll404D
pop hl
ld b, c

ll404D
rla
jr c, ll4048
cp 3
jr c, ll4059
add a, e
ld e, a
xor c
jr nz, ll4046

ll4059
add a, e
cp 4
jr z, ll40B8
adc a, #FF





использовать не реальный подсчет длины, а сдвинутый на минус 16. При LEN = 16 при суммировании получаем 0, и в связи с этим исключаем команду xor.

ll4042

ld e, 1

заменить на ld e,1-16

далее выбросить xor c, и быстрее и короче.

cp 4 заменить на cp 4-16

adc a, #ff заменить на adc a,#ff-16

Не? В константах могу и ошибаться. Надо тестить, т.к. вдруг идет влияние на переменные и флаги, которые потом учитываются.

Вроде 1 байт нашли. А кто второй найдет?

---------- Post added at 13:30 ---------- Previous post was at 13:23 ----------

Не, вряд ли пройдет трюк. Там при LEN = 16 флаг С неправильно выставляется :(

---------- Post added at 13:39 ---------- Previous post was at 13:30 ----------

Но убрать из цикла одну команду, и поставить вне цикла другую это тоже неплохо, надо будет использовать.