Сейчас на форуме: Magister Yoda, vasilevradislav (+3 невидимых) |
eXeL@B —› Крэки, обсуждения —› Diablo II bug fix |
Посл.ответ | Сообщение |
Ранг: 419.0 (мудрец), 647thx Активность: 0.46↗0.51 Статус: Участник "Тибериумный реверсинг" |
Создано: 22 апреля 2015 20:45 · Личное сообщение · #1 Дело было вечером! Есть такая легендарная игрушка - Diablo II: Lord of Destruction. В ней можно устанавливать 2D и 3D режим (за последний ламеры не знают...впрочем, там особо и 3D нет-земля на текстуру натягивается и всё это в перспективе показывается, ну НЕ ВАЖНО короче!), Так вот, режимы меняются с помощью D2VidTst.exe, который валяется в том же каталоге с игрой. Файл изначально фурычит под 98-XP, но я его пропатчил (это просто!) - теперь в 2k3 и выше, при прямых видео-дровах он норм запуститься. Так вот, недавно я сменил видеокарту на новенькую AMD 7x00 series - до этого была старая и добрая HD 4850, где это 3D без проблем фурычило. А с новой 7 серией внезапно вываливается MessageBox диябловского обработчика с "необработанным ексепшеном 0xc0000005" Code:
Сначала я подумал, что гребаные и трижды треклятые криворукие говнокодеры из AMD снова накосячили и ситуация безнадежна. Однако, мой интерес не смог угаснуть и я, без особого энтузиазма, взял ольку и начал копать... (пропуская кучу технический подробностей), вышел я на следующее место в D2Direct3D.dll: Code:
падало на REP STOS из-за того, что ECX - принимало сумашедшее значение и инструкция врезалась в космос. Fog.#10042 - по виду, менеждер памяти, указатель выплевывал валидный. Крутим вверх: * SHR ECX,2 - кол-во итераций уменьшается в 4 раза (закос комплиятора под DWORD реп стоса?). * MOV ECX,EBP -> MOV EBP,EAX * CMP EAX,400 и результирующий условный переход JL * арифметика с EAX * MOV EAX,DWORD PTR SS:[ESP+10] - EAX берется с аргумента (16 байт - 4го?) в хекс-райс дает следующий код: Code:
ТАК В ЧЕМ ЖЕ СПРЯТАН КОВАРНЫЙ БАГ??? Догадались? А он кроется в Code:
JL для signed int(!!!) - что в принципе неправильно, т.к. условие if ( v6 >= 1024 ) v6 = 1024; попросту не срабатывает, когда в аргументе белиберда (неважно, откуда она появляется). Поэтому, signed int число докатывается до memset (REP STOS DWORD...) и получается заезд за пределы выделенной памяти. А ВЕДЬ ОЧЕВИДНО, ЧТО В НАШЕМ СЛУЧАЕ ДОЛЖНО БЫТЬ unsigned int (флаг переноса то), т.е. в D2Direct3D.dll должно быть Jump if below: Code:
ОК! Исправил, сохранил, запустил - РАБОТАЕТ 3D! Даже скрины есть! В связи с чем, шлю пламенный хакерский привет Blizzard Entertainment и прикладываю в аттаче пофикшенные D2VidTst.exe и D2Direct3D.dll p.s. Не забывайте, что игрушка еще поддерживает Creative EAX - не тот 8ab7_22.04.2015_EXELAB.rU.tgz - Diablo_II_3D_Fix__by_ELF.7z | Сообщение посчитали полезным: kp0m, zNob, Coderess, VodoleY, Rainbow, [Nomad], Hellspawn, ==DJ==[ZLO], serilo, Aldi777, WiperX |
|
Создано: 22 апреля 2015 20:54 · Поправил: dosprog · Личное сообщение · #2 Хуже было бы, если бы не диабловский обработчик выдавал сообщение, а система. А так естественно желание полезть взглянуть, что там за фигня. Что касается <JL>, то лично я ею избегаю пользоваться вообще. Эта инструкция - рудимент. Использование чревато такими вот багами. Между тем в массе учебников по ассемблеру в примерах используется именно она, видимо, потому, что звучит привычнее. Справедливости ради замечу, что это скорей всего не диабловцевский баг, он им самим достался вместе с библиотекой (компилятором). --добавлено-- Хотя, если их переменная объявлена как int и по умолчанию действует signed (а он в настройках по умолчанию таков), тогда да, их прокол. --добавлено ещё-- Сам сейчас пользуюсь старинной WIN16 версией одной программы, которая всеми признана неудачной, глючной, и похерена ещё двадцать лет назад. Понадобился простой патч ошибки библиотеки компилятора - и вполне годная программа работает и меня устраивает. |
|
Создано: 22 апреля 2015 22:00 · Личное сообщение · #3 |
|
Создано: 23 апреля 2015 00:12 · Поправил: DenCoder · Личное сообщение · #4 ELF_7719116 пишет: JL для signed int(!!!) - что в принципе неправильно, т.к. условие if ( v6 >= 1024 ) v6 = 1024; попросту не срабатывает, когда в аргументе белиберда (неважно, откуда она появляется). Да, тут достаточно, чтобы было a3 < a2, либо одно из условий (a5 < 0) или (a4 < 0) или (dword_6F85BB58 < 0) = TRUE, а 2 других из них = FALSE или TRUE... да, странно использовать для подсчёта кол-ва выделяемой памяти тип знаковых целых. Хорошо, когда время есть для собственных копаний... Мне не хватило вот, чтоб в d3d9.dll найти реальную причину вылетов... Запатчил только место, где имели место вылеты - вставил простенькую проверку на валидность указателя. ) Место вылетов - CD3DDDIDX8::SetPixelShaderConstantF + 0x32 Code:
заменил на Code:
адрес по прыжку - свовободное место между функциями для выравнивания по границе 16 байт, уложил патчик в него: Code:
Ошибка проявляла себя при включенном аппаратном ускорении с видюхой ATI Radeon X1050 в некоторых играх, unity3D, или при переключении в полноэкранный режим видеоролика на ютубе. Конечно, пользоваться таким патчем не айс, поскольку ролика в режиме "на всю" не было вообще видно, а в юнити всё мерцало разными цветами. Но хотя бы браузеры перестали падать. Кому интересно продолжить, а может и улучшить (на случай вдруг тоже нестыковки с видюхой) - ----- IZ.RU | Сообщение посчитали полезным: ELF_7719116 |
|
Создано: 23 апреля 2015 08:15 · Поправил: Gideon Vi · Личное сообщение · #5 |
|
Создано: 23 апреля 2015 09:21 · Личное сообщение · #6 |
|
Создано: 23 апреля 2015 09:45 · Личное сообщение · #7 http://www.playground.ru/files/diablo_ii_unofficial_resolution_patch-20301/ | Сообщение посчитали полезным: Coderess |
|
Создано: 23 апреля 2015 09:50 · Поправил: VodoleY · Личное сообщение · #8 ELF_7719116 пишет: Diablo II: Lord of Destruction поклон в ножки.. как же я на него залипал.. это был ппц ЗЫ просто за тему получи лайк))) ----- Наша работа во тьме, Мы делаем, что умеем. Мы отдаем, что имеем, Наша работа во тьме.... | Сообщение посчитали полезным: ELF_7719116 |
|
Создано: 23 апреля 2015 17:22 · Личное сообщение · #9 |
Ранг: 419.0 (мудрец), 647thx Активность: 0.46↗0.51 Статус: Участник "Тибериумный реверсинг" |
Создано: 23 апреля 2015 17:28 · Личное сообщение · #10 VodoleY пишет: ЗЫ просто за тему получи лайк))) Взаимовыгодный обмен Coderess пишет: А нет ли патчей для игры с большим разрешением Там вроде окно через CreateWindow создается изначально и можно добавить, сколь угодное душе, разрешение - оно в переменных потом пропишется. dosprog пишет: Хуже было бы, если бы не диабловский обработчик выдавал сообщение, а система. Так олька же всё равно отловит исключение первой, в случае с 0xc0000005 - это не шибко кретично. DenCoder пишет: да, странно использовать для подсчёта кол-ва выделяемой памяти тип знаковых целых. Я, чес говоря, больше не понимаю, почему v6 = (a3 - a2) / v5; нельзя было вывести за пределы функи, т.е. если позволяет код программы, компиль мог static посчитать результат и прописать. И вообще, вроде, можно функу можно оптимизировать и по кол-ву аргмуентов и по коду внутри. Ну и SSE2 добавить (инфа для разрабов)-там работа с массивами. Добавлено спустя 3 минуты скриншотэ (3D |
|
Создано: 23 апреля 2015 19:03 · Личное сообщение · #11 |
Ранг: 419.0 (мудрец), 647thx Активность: 0.46↗0.51 Статус: Участник "Тибериумный реверсинг" |
Создано: 23 апреля 2015 19:21 · Личное сообщение · #12 |
|
Создано: 27 апреля 2015 08:51 · Личное сообщение · #13 |
|
Создано: 27 апреля 2015 13:46 · Личное сообщение · #14 |
|
Создано: 03 мая 2015 01:13 · Личное сообщение · #15 |
eXeL@B —› Крэки, обсуждения —› Diablo II bug fix |