|
Alchemist
Модератор
Откуда: Арзамас-17 Регистрация: Дек. 2004
Всего: 298 сообщений
|
Для затравки продублирую пару из последних сообщений в тех-рассылке. ========== О компиляторе от BIS ========== Anchorite: Я тут с подачи Alchemist-а нашел в BIS-овом компиляторе достаточно неприятный баг. Компилятор ни при каких условиях не генерирует опкод O_BWXOR. Так что имейте это ввиду. Alchemist: Поясню, из-за этого бага во _ВСЕХ_ версиях Fallout2 сломаны скрипты dcCraps.int и zccrpdel.int. -------- Исходник -------- if (local_var((28)) bwand bit_32) then begin amount := local_var((28)) bwxor bit_32; dontbet := 1; end else ... ------- Результат ------- if (local_var(28) bwand bit_32) then begin asm_expr(local_var(28)); amount := bit_32; dontbet := 1; end else ... Если в вашем коде инструкция bwxor просто необходима, то компилятор от Iplay для этого не годится, и следует собрать скрипт одним из альтернативных. ========== О декомпиляторе Noid'а ========== Anchorite: Чтобы декомпильнуть скрипты скомпилированные IPP с помощью декомпиля от Noid-а нужно в файле decompile строчку remove_opcodes_from_tail([0xc001, 0x8003, 0xc001, 0x8004]) заменить на remove_opcodes_from_tail([0xc001, 0x8004]) После этого декомпилятор будет работать. В IPP не совсем "стандартный" Startup code Den Baster: Ну это когда на кусок тайла ругается да. нойд говорит: tail does not match ----------------------------- Alchemist: Есть ещё такой баг: в аргументы для op_gsay_option вместо символического указателя на процедуру попадает целое, являющееся индексом в таблице процедур. И BIS'овский, и Noid'овский компиляторы это не смущает и скрипт собирается нормально. Однако, если в процессе редактирования добавится процедура, которая будет расположена перед вызываемой в gsay_option, то индексы сдвинутся, и диалог перестанет правильно работать. Чтобы этого не происходило, лезем в decompile и в двух местах меняем строчку: 0x811f => ["prefix", "op_gsay_option", "S", "EEEE"], на строчку: 0x811f => ["prefix", "op_gsay_option", "S", "EEPE"],
----- /// What'ya be sain'? Vault 100+? We need nothing o'that!
|
Отправлено: 12:37 - 4 Апр., 2005
|
|
Alchemist
Модератор
Откуда: Арзамас-17 Регистрация: Дек. 2004
Всего: 298 сообщений
|
========== О декомпиляторе Noid'а ========== Alchemist: Декомпилятор Noid'а написан на языке Ruby, огромным достоинством которого является прозрачное преобразование типов данных "на лету". То есть, так называемая коэрция. Однако эта замечательная особенность в определённых случаях выходит боком. В декомпилированном коде в область инициализации переменных вместо отрицательного целого значения с лёгкостью может попасть его альтернативная интерпретация, выраженная зашкалившим за 31 бит положительным значением. Родной компилятор Noid'а, с таким значением справляется на ура, помещая в скрипт именно то, что нужно. Более того, даже компилятор BIS из-за одной очень распространённой ошибки в коде выдаст, как ни смешно, корректный результат. Однако, подобные вещи сильно ухудшают читабельность кода (скажем, вместо (-10) мы увидим 4294967286) и могут привести ошибкам при использовании альтернативных компиляторов. Лечится, как и ранее, редактированием decompile Находим вот такой фрагмент кода: def exported_var_definition(var) raise "no exported variable #{var}" unless @exported_vars.has_key?(var) "export variable #{var} := #{@exported_vars[var]};" end def script_var_definition(var) list = @script_vars.assoc(var) raise "no script variable #{var}" if list.nil? "variable #{list[0]} := #{list[1]};" def exported_var_definition(var) raise "no exported variable #{var}" unless @exported_vars.has_key?(var) "export variable #{var} := #{@exported_vars[var]};" end И заменяем его на такой фрагмент: def exported_var_definition(var) raise "no exported variable #{var}" unless @exported_vars.has_key?(var) if @exported_vars[var].to_i > 0x7FFFFFFF @exported_vars[var] = sprintf("%d", @exported_vars[var].to_i - 0x100000000) end "export variable #{var} := #{@exported_vars[var]};" end def script_var_definition(var) list = @script_vars.assoc(var) raise "no script variable #{var}" if list.nil? if list[1].to_i > 0x7FFFFFFF list[1] = sprintf("%d", list[1].to_i - 0x100000000) end "variable #{list[0]} := #{list[1]};" end Проверенно - мин нет. Однако я не уверен, что подобные проблемы не возникают в других местах. Если заметите - пишите. -------- Update -------- Как всегда, поторопился. Мины есть - после доработки под компилятором Noid'а результирующий код собираться перестанет. Нужна доработка компилятора. С этим ещё предстоит разобраться. (Отредактировал(а) Alchemist - 23:58 - 5 Апр., 2005)
----- /// What'ya be sain'? Vault 100+? We need nothing o'that!
|
Отправлено: 23:22 - 5 Апр., 2005
|
|
Alchemist
Модератор
Откуда: Арзамас-17 Регистрация: Дек. 2004
Всего: 298 сообщений
|
Обнаружен новый баг. И SSLC by Anchorite, и compile by Interplay, так же как в случае с O_BWXOR, отказываются генерировать опкод O_BWNOT (0x8043). Визуально это выглядит так, будто оператор побитовой инверсии bwnot, будучи использованным в коде, просто не работает. Декомпиляция показывает, что в бинарном скрипте его нет вообще. В качестве обхода бага можно вместо bwnot X использовать (-1) bwxor X. Но это сработает только на SSLC, так как в компиляторе Interplay операция bwxor тоже "сломана".
----- /// What'ya be sain'? Vault 100+? We need nothing o'that!
|
Отправлено: 0:52 - 8 Апр., 2007 | ИСПРАВЛЕНО: Alchemist - 11:20 - 8 Апр., 2007
|
|
Wasteland Ghost
Маленькое Злое Привидение
Откуда: Россия, Самара Регистрация: Дек. 2002
Всего: 2251 сообщение
|
Баг исправлен, новые версии компилера и декомпилера доступны в файловом разделе по старым ссылкам. Сырца тоже обновлены.
|
Отправлено: 13:56 - 3 Мая, 2007
|
|
Jordan 63
Пользователь
Откуда: Россия, Самара Регистрация: Июль 2007
Всего: 228 сообщений
|
При декомпилировании скриптов fallout1 программами int2ssl или noid_compiler1.01 заменяет названия импортируемых переменных пример скрипт killian заменяет import variable rndx; на variable SVar01 := 0; Таких замен я обнаружил в 35 скриптах Можно ли исправить этот баг в noid_compiler1.01
|
Отправлено: 20:55 - 19 Сент., 2007
|
|
Anchorite
Пользователь
Откуда: Не здесь Регистрация: Янв. 2003
Всего: 283 сообщения
|
Закинь этот скрипт мне на мыло. И "сырец" от него если есть Хотя я подозреваю в чем там дело - есть импортирование одной или нескольких переменных, но они не используются внутри скрипта. В этом случае невозможно найти соответствие между именами переменных, сохраненными в пространстве имен, и индексами этих переменных по которым к ним происходит обращение внутри процедур.
|
Отправлено: 20:42 - 21 Сент., 2007 | ИСПРАВЛЕНО: Anchorite - 20:54 - 21 Сент., 2007
|
|
|
Anchorite
Пользователь
Откуда: Не здесь Регистрация: Янв. 2003
Всего: 283 сообщения
|
Как я и говорил - импортированные переменные без ссылок на них. И как соотнести большее количество имен с меньшим числом переменных?
|
Отправлено: 21:19 - 21 Сент., 2007 | ИСПРАВЛЕНО: Anchorite - 21:23 - 21 Сент., 2007
|
|
Jordan 63
Пользователь
Откуда: Россия, Самара Регистрация: Июль 2007
Всего: 228 сообщений
|
Anchorite То есть невозможно узнать какая это переменная export или import?
|
Отправлено: 14:21 - 22 Сент., 2007
|
|
Anchorite
Пользователь
Откуда: Не здесь Регистрация: Янв. 2003
Всего: 283 сообщения
|
Вопрос не совсем корректен. Попробую разъяснить. Если в скрипте происходит ИМПОРТ переменной, но НЕ ПРОИСХОДИТ ОБРАЩЕНИЕ к ней их процедур этого скрипта, и в этом скрипте есть ГЛОБАЛЬНЫЕ переменные, то при декомпиляции такого скрипта будет НЕВОЗМОЖНО ОПРЕДЕЛИТЬ ИМЕНА импортированных и глобальных переменных. С экспорированными переменными как раз никаких проблем нету. Там все четко и однозначно. Если переменная экспортирована, то ее имя всегда можно определить.
|
Отправлено: 19:51 - 22 Сент., 2007 | ИСПРАВЛЕНО: Anchorite - 19:52 - 22 Сент., 2007
|
|
|
|