2 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд
Загрузка...

Ошибка при запуске приложения 0xc000007b

Ошибка при запуске приложения 0xc000007b

Если при запуске приложения, игры на экране возникла ошибка «Ошибка при запуске приложения (0xc000007b)», то можно с уверенностью сказать, что причина в DLL файлах вашей операционной системы.

Ошибка 0xc000007b при запуске приложений в Windows 10 в большинстве случаев возникает, после того как вы обновились виндовс 10 и запускаете уже установленную любимую игру или программу, которые созданы на языке C++ и для которых нужны корректные библиотеки, особенно при запуске новых игрушек (после 2012 года выпуска), таких как Grand Theft Auto V GTA V, NFS Most Wanted, Watch Dogs, Far Cry 4, Dying light, Civilization 5, X-com, Fallout и многих других. В этом-то и заключается причина ошибки.

Снова EA, снова NFS, снова баги. Чиним

Привет, Хабр! С вами снова спидраннинг коммьюнити NFS. И мы снова чиним старенькую игрушку — NFS Most Wanted. Я уже рассказывал о починке багов в своих предыдущих статьях, а сегодня хотел был пойти с вами немного глубже в дебри дизассемблирования. Заинтересовавшихся прошу под кат.

Предыстория

Когда-то давно, когда EA издавала хорошие NFS, вышла одна из известнейших гоночных игр — Most Wanted. Увы, написана она была не так хорошо, как продавалась, и периодически падала. Конечно, обычный человек на это обращает мало внимания — ну вылетела разок за прохождение, ничего страшного. А вот нам это создает огромные проблемы: сколько потенциальных рекордов было убито случайными падениями без внятных симптомов. Все закончилось тем, что KuruHS лично попросил меня разобраться в ситуации. Отказаться я не смог.

Что имеем

IDA — для дизассемблирования
Cheat Engine — для редактирования памяти и инструкций
Visual Studio — для отладки (Trace Points, оказались весьма удобной вещью)

У нас есть куча дампов. Приличная куча, гигабайт на 10. С них мы и начнем — проанализируем, на каких инструкциях падает игра. А падает она довольно рандомно, хотя некоторые закономерности прослеживаются. За время решения проблем мы нашли несколько потенциально опасных мест, которые иногда крашат игру. Например:

в функции вычисления хэша строки. Видимо, разработчики не ожидали получить null-pointer в этом месте, поэтому не добавили проверку на него. Из-за этого в редких случаях игра падала. Фикс довольно банальный — прыгнуть в первый пустой кусок экзешника, да сделать test edi, edi. Потом jz retun и jmp откуда прыгали изначально.

Другой похожий случай нашёлся в процедуре по адресу
0х0057D105 mov edx, [ecx] ; я так и не смог понять, что конкретно она делает

Разработчики снова не ожидали получить там null pointer, поэтому игра падала. Фикс абсолютно идентичен предыдущему.

Наиболее распространённая причина падения оказалась в функции AllocateMemory. Попытки ее дизассемблирования повергли в ужас всех, кто работал над проблемой падений игры. Внимания удостоен уже тот факт, что в игре как минимум 5 разных подсистем управления памятью. Во что я ввязался…

Ладно, нет времени ныть, надо реверсить. Несколько вечеров за разборами этого мусора принесли свои плоды: код, хоть все еще и не читаемый, стал более понятен. Судя по всему, эта подсистема работает по стандартной схеме: грабастаем некоторое количество памяти сразу, разбивая на блоки, храним их в двусвязном списке; по требованию выдаём свободные участки, а если таковых нету — пытаемся взять у системы еще. Ах, 2005-ый, когда операции с памятью были достаточно дорогими, чтобы ей разбрасываться как попало…

Некоторые места в этой функции вызывают у меня приступы головной боли, потому что мой мозг напрочь отказывается даже пытаться их обработать. Но одно мне ясно точно — где-то среди всех этих связных списков, состоящих из связных списков, кроется неправильный указатель, из-за которого все и падает. Единственное решение, пришедшее в голову — отключить проверку «use_best_fit» чтобы подсистема выдавала первый попавшийся свободный блок, а не искала тот, который она считает наиболее подходящим.

Конечно, проблемы целиком это не решило, но как минимум игра стала действительно стабильнее — за неделю тестирования в этом конкретном месте она упала всего несколько раз (при учете, что KuruHS проводит в игре по 10 часов в день), что я считаю довольно неплохим результатом.

Pure virtual function call.

Та самая ошибка, что проиллюстрирована в шапке. Люди, знакомые с С++ сразу поймут, в чем проблема. Однако без исходного кода все становится значительно сложнее. Ситуацию усложняет CRT, который, аки партизан, упорно не хочет генерировать дампы, если вылавливает этот тип ошибки.

Purecall означает, что код попытался вызвать «чисто виртуальную функцию» (виртуальную функцию класса, не имеющую реализации). Без сомнений, этого сделать у него не получается, поэтому единственное, на что он решается — сообщить об этом пользователю и завершиться с кодом . В итоге вроде бы все и хорошо с кодом, а на деле все плохо.

Спасибо Microsoft за замечательную функцию — _set_purecall_handler, которая позволяет заменить обработчик purecall’ов. Ищем в экзешнике упоминания/ссылки, находим саму функцию. Теперь осталось написать свой обработчик и не забыть установить его как хэндлер. Для этого нам нужно найти достаточно большой кусок неиспользуемого кода в самом экзешнике, который мы сможем перезаписать на наш код. Недолгий поиск показал, что это будет функция _CxxThrowException (ссылок на нее не было найдено). Беспощадно записываем все ее тело nop’ами и начинаем творить поверх нее:

Вот так будет выглядеть псевдокод новых процедур:

Компилируем (в моем случае руками вбиваем в Cheat Engine) и вставляем в код:

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

Единственная проблема заключается в том, что ошибка эта довольно редкая, а часами бесцельно играть не хочется. Я все же решил немного потестировать сам, и был приятно удивлен — игра упала буквально через 10 минут геймплея, причем упала на только что написанном мною участке. Перемещаемся по стеку вызовов немного выше:

Ничего не могу сказать, кроме как: «да, это вызов виртуальной функции». Первая же мысль — а что, если без него? Выпиливаем его nop’ами, тестируем — вроде живем. Игра работает как надо. Побочных эффектов нет. Собираем патч, отсылаем на тестирование. Через день прилетает дамп, где та же процедура падает несколькими байтами ниже. Выпиливаю и ее — игра начинает падать. Все ведет к тому, что нужно думать над более серьезным решением. Но в голову ничего не лезет, поэтому откладывается на неопределенный срок.

За ночь я успел все обдумать, и пришёл к выводу. Вы скажете, что С++ не умеет в рантайме определять тип объекта? А я скажу, что может. И очень просто — по адресу виртуальной таблицы в памяти. Изучив дампы, я пришел к выводу, что периодически в процедуру прилетает неправильный класс (vtbl @ 0x00890970), а значит мы можем отловить эту ситуацию:

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

Патчим и запускаем. И получаем всё ту же проблему: этот крах настолько редкий, что за почти 4 часа тестирования этот кусок кода был запущен всего пару раз, и все разы на вход был получен правильный класс.

Можно было оставить и так, но мне нужно было подтверждение тому, что это действительно работает. Поэтому отправляемся реверсить дальше и пытаться вызвать исключительную ситуацию руками.

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

убираем по максимуму «лишние» проверки и пытаемся насильно вызвать эту функцию. Запускаем тестирвоание и наконец-то получаем неправильный класс на вход. Ждём, пока отладчик студии допечатает весь текст, игра отвисает и… продолжает работать. Ура!


Скриншот мыльный, ибо запись со стрима

Заключение

Решение найдено — игра больше не падает, даже если на вход подали что-то не то. Это заметно на скриншоте выше — часть заграждения отсутствует, потому что игра попыталась поставить туда что-то не то. Что именно — загадка, покрытая мраком, но я уверен, что рано или поздно мы узнаем и это.

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

Весь фикс я решил оформить в виде asi скрипта, по принципу Widescreen патчей от ThirteenAG. Почитать исходники и скачать скрипты можно на гитхабе.

Need For Speed: High Stakes, PSone, PC, 1999

Старые аркадные гонки для PSone и ПК от Electronics Arts, 99 года выпуска, без лутбоксов, микротранзакций и прочего бреда. В версию для PC не играл, помню только консольный вариант. Кстати, разработкой для двух платформ занимались разные студии EA.

Эта часть является классическим продолжением серии прошлого века с заездами за городом, мимо лесов, гор, океанов, европейских городков. Помимо, более и менее, доступных марок автомобилей, есть и зверские спорткары типа Lamborghini, Ferrari. Причем на этот раз средства передвижение не обладают каким-то бронебойным покрытием, когда после дикого столкновения на тачке не остается не то что вмятины, но и не одной царапины, и даже пылинки. Разбить машину вдребезги на манер Burnout’а все еще нельзя (ведь не должны же владельцы лицензии видеть, как их серия автомобилей превращается в кусок паленого железа), но система повреждений присутствует. Мнется корпус, а изношенная модель отбрасывает

Читать еще:  Файлы Need for Speed: Heat

красивые искры по пути к финишу.

Но тут дело не только в добавлении визуального реализма, все это так же оказывает влияние на управление: сбрасывается скорость, чето вечно скрипит, как на пассажирском Пазике, тачка хуже входит в поворот. Исправить неполадки можно, отремонтировав автомобиль в гараже. Помимо получения медалей за первое место, теперь есть возможность зарабатывать деньги, которые будут тратиться как на ремонт, так и на добавлении различных модификаций, улучающие двигатель и «толстокожесть» выбранного транспорта. Есть обычные заезды, но теперь появился режим карьеры с несколькими вариантами заработка на еду и новую машину. Самый забавный — High Stakes: только два соперника, проиграл — отдавай тачку, выиграл — забирай машину соперника. Все по взрослому. Но и, конечно, классические гоночки, с несколькими соперниками, аркада и т. д. Полиция тоже никуда не делась, при желании можно попробовать свои силы в игре за сотрудников, только вместо одного полицейского, теперь в Вашем распоряжении целых отряд преследования, между которыми можно переключаться прямо на ходу.

Версия для PC

Управление осталось на аркадном уровне, оно и к лучше. Глюков нет, кататься приятно — ну и ладно.

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

Игрушка подойдет для запуска на смартфонах с использованием эмулятора. Но если хочется аналогов посерьезнее, то есть Hot Pursuit 2010, на который ценник в стиме, кажется, навечно застыл в скидках (сколько раз не захожу все время вижу ее в акциях, стоит около 100 р.). Скачиваем, вырубаем музыку, включаем нормальный плейлист из High Stakes и вперед.

⇡#Из Hot Pursuit

Most Wanted 2012 (вот так гораздо лучше) разрабатывается на движке Chameleon, который также был использован в Hot Pursuit. FrostByte 2 — основа прошлогодней The Run — остаётся не у дел: студии проще работать с уже знакомым механизмом и материалами. В какой-то степени это печально, ведь в графическом плане «Пробег» выглядел куда внушительнее и интереснее, чем «Горячее преследование», — получается, что Need for Speed образца 2012 года с точки зрения технологичности визуального ряда делает шаг назад по сравнению с предшественником.

В игре предусмотрен огромный игровой мир — агломерация Fairheaven City, предлагающая десятки километров улочек, шоссе, переулков и даже полей. На месте фирменная система разрушений — родом из Burnout, другой известной серии, автором которой также является Criterion Games. Обещают действительно эпический масштаб порчи имущества — ломать можно всё, от рекламных щитов до стен и целых сооружений. Вообще, в этом аспекте, а также с точки зрения дизайна и цветовой гаммы город больше напоминает Paradise City из последней Burnout, чем Rockport из Most Wanted 2005.

Традиционное аркадное управление опять же мало чем отличается от того, что мы видели два года назад в Hot Pursuit. Беспрепятственный набор огромной скорости, простое исполнение зрелищного дрифта, шкала «здоровья» на автомобиле. На месте и обязательное нитро-ускорение.

Система Autolog не отстает и обновляется до версии 2.0: теперь в статистику заносится абсолютно всё, что делает игрок в онлайне или в одиночном режиме, включая все очки, рекорды кругов на трассах и прочие цифры. Ну и само собой, система остаётся отличной площадкой для проведения сетевых заездов.

Как исправить ошибку 0xc000007b в Windows 10

Видео пример как создать точку восстановления в Windows 10

Сперва наперво необходимо разобраться какая всё таки разрядность вашей операционной системы. Для этого нажимаем сочетание клавиш + Pause

Обращаем внимание на выделенный фрагмент на рисунке Тип системы 32 или 64. В зависимости от того какие тут будут цифры, такие же должны быть и все системные файлы.

В большинстве случаев причина заключается в Распространяемом пакете Microsoft Visual C ++, когда он установлен не надлежащим образом, или же его файлы повреждены или отсутствуют (например из-за вирусов), так что, первое, что необходимо сделать это скачать Распространяемый пакет Microsoft Visual C ++ (x64) или Microsoft Visual C ++ (x32) в зависимости от разрядности Вашей операционной системы.

После загрузки файла, стандартным двойным щелчком мыши установите приложение.

Теперь перезагрузите компьютер и попытайтесь запустить вашу игру или программу, если ошибка всё же не исчезла, то вы все таки, что-то напутали с разрядностью ОС. В этом случае воспользуйтесь ниже приведенными вариантами по актуализации системных библиотек:

Способ первый (простой и быстрый)

  • Загрузите этот архив (ссылка на скачивание) в нем содержаться необходимые версии библиотек для x64 и для x32 типа операционных систем
  • Распакуйте содержимое архива в любую папку на любом диске. Главное не в корень диска. Будут распакованы две папки с файлами.
  • Теперь необходимо загрузиться в безопасном режиме. Для этого нажимаем сочетание кнопок WIN + R
  • В появившееся окошко вводим msconfig и нажимаем Enter
  • Переходим к вкладке Загрузка. Выбираем здесь Безопасный режим и тайм аут в 999 сек

  • Нажимаем Применить и Перезагрузка
  • Теперь загрузившись в безопасном режиме надо скопировать эти распакованные ранее папки и вставить их в C:Windows с заменой.
  • Перезагрузите компьютер и попробуйте запустить снова.
  • Второй способ (продвинутый универсальный)

    Есть на просторах Интернета замечательная утилита Dependecy Walker , которая сканирует приложения (в нашем случае игры) на используемые библиотеки, отображая полные пути к ним и самое главное их разрядность x32(x86) или x64.

    1. Всё что нужно, это скачать нужную версию программы под разрядность Вашего компьютера (как это сделать писалось выше).
      Скачать Dependecy Walker для x32(x86)
      Скачать Dependecy Walker для x64
    2. Распаковываем и запускаем программу Dependecy Walker
    3. В меню выбираем ViewsFull Paths или просто нажимаем F9 для того, чтобы видеть полные пути к файлам
    4. Выбираем FileOpen… , чтобы открыть файл игры. Переходим в папку с неработающей игрой и выбираем запускаемый файл
    5. Если появилось окно об ошибке игнорируем его и закрываем
    6. В окне Модулями (снизу) отображены все библиотеки, которые использует наша игра при запуске. И ближе к концу таблицы есть нужная нам колонка CPU (на рисунке ниже обведена красной рамкой).

  • Итак если Ваше приложение x32(x86), то будут подсвечены красным все x64 версии библиотек (dll файлов), которые используются игрой. И наоборот для x64 подсвечены будут x32(x86) версии.
    Как раз-то в этих файлах и заключается причина ошибки.
  • Теперь всё что вам остается сделать это скопировать имя библиотеки (dll файла) найти в Интернете нужную вам версию с разрядностью, скачать её и скопировать в папку с игрой, а еще лучше по тому пути, по которому она прописана в Dependecy Walker Если планируется файлы копировать в папку Windows, то рекомендуем Вам сделать точную восстановления системы (описано выше)
  • Третий способ (глобальный)

    Если первый способ не сработал, то пробуем следующее: загрузите All In One Runtimes и установите его на компьютере. Это приложение содержит все актуальные версии необходимых компонентов и библиотек для Windows 10, 8 , 7. Оно автоматически исправит все ошибки.

    В любом случае независимо от результата отпишитесь в комментариях помогли вам вышеприведенные методы или нет. Если да будем собирать положительную статистику, если же нет то пытаться сообща решить вашу проблему 0xc000007b

    Снова EA, снова NFS, снова баги. Чиним

    Привет, Хабр! С вами снова спидраннинг коммьюнити NFS. И мы снова чиним старенькую игрушку — NFS Most Wanted. Я уже рассказывал о починке багов в своих предыдущих статьях, а сегодня хотел был пойти с вами немного глубже в дебри дизассемблирования. Заинтересовавшихся прошу под кат.

    Предыстория

    Когда-то давно, когда EA издавала хорошие NFS, вышла одна из известнейших гоночных игр — Most Wanted. Увы, написана она была не так хорошо, как продавалась, и периодически падала. Конечно, обычный человек на это обращает мало внимания — ну вылетела разок за прохождение, ничего страшного. А вот нам это создает огромные проблемы: сколько потенциальных рекордов было убито случайными падениями без внятных симптомов. Все закончилось тем, что KuruHS лично попросил меня разобраться в ситуации. Отказаться я не смог.

    Что имеем

    IDA — для дизассемблирования
    Cheat Engine — для редактирования памяти и инструкций
    Visual Studio — для отладки (Trace Points, оказались весьма удобной вещью)

    У нас есть куча дампов. Приличная куча, гигабайт на 10. С них мы и начнем — проанализируем, на каких инструкциях падает игра. А падает она довольно рандомно, хотя некоторые закономерности прослеживаются. За время решения проблем мы нашли несколько потенциально опасных мест, которые иногда крашат игру. Например:

    в функции вычисления хэша строки. Видимо, разработчики не ожидали получить null-pointer в этом месте, поэтому не добавили проверку на него. Из-за этого в редких случаях игра падала. Фикс довольно банальный — прыгнуть в первый пустой кусок экзешника, да сделать test edi, edi. Потом jz retun и jmp откуда прыгали изначально.

    Другой похожий случай нашёлся в процедуре по адресу
    0х0057D105 mov edx, [ecx] ; я так и не смог понять, что конкретно она делает

    Разработчики снова не ожидали получить там null pointer, поэтому игра падала. Фикс абсолютно идентичен предыдущему.

    Наиболее распространённая причина падения оказалась в функции AllocateMemory. Попытки ее дизассемблирования повергли в ужас всех, кто работал над проблемой падений игры. Внимания удостоен уже тот факт, что в игре как минимум 5 разных подсистем управления памятью. Во что я ввязался…

    Ладно, нет времени ныть, надо реверсить. Несколько вечеров за разборами этого мусора принесли свои плоды: код, хоть все еще и не читаемый, стал более понятен. Судя по всему, эта подсистема работает по стандартной схеме: грабастаем некоторое количество памяти сразу, разбивая на блоки, храним их в двусвязном списке; по требованию выдаём свободные участки, а если таковых нету — пытаемся взять у системы еще. Ах, 2005-ый, когда операции с памятью были достаточно дорогими, чтобы ей разбрасываться как попало…

    Некоторые места в этой функции вызывают у меня приступы головной боли, потому что мой мозг напрочь отказывается даже пытаться их обработать. Но одно мне ясно точно — где-то среди всех этих связных списков, состоящих из связных списков, кроется неправильный указатель, из-за которого все и падает. Единственное решение, пришедшее в голову — отключить проверку «use_best_fit» чтобы подсистема выдавала первый попавшийся свободный блок, а не искала тот, который она считает наиболее подходящим.

    Конечно, проблемы целиком это не решило, но как минимум игра стала действительно стабильнее — за неделю тестирования в этом конкретном месте она упала всего несколько раз (при учете, что KuruHS проводит в игре по 10 часов в день), что я считаю довольно неплохим результатом.

    Pure virtual function call.

    Та самая ошибка, что проиллюстрирована в шапке. Люди, знакомые с С++ сразу поймут, в чем проблема. Однако без исходного кода все становится значительно сложнее. Ситуацию усложняет CRT, который, аки партизан, упорно не хочет генерировать дампы, если вылавливает этот тип ошибки.

    Purecall означает, что код попытался вызвать «чисто виртуальную функцию» (виртуальную функцию класса, не имеющую реализации). Без сомнений, этого сделать у него не получается, поэтому единственное, на что он решается — сообщить об этом пользователю и завершиться с кодом . В итоге вроде бы все и хорошо с кодом, а на деле все плохо.

    Спасибо Microsoft за замечательную функцию — _set_purecall_handler, которая позволяет заменить обработчик purecall’ов. Ищем в экзешнике упоминания/ссылки, находим саму функцию. Теперь осталось написать свой обработчик и не забыть установить его как хэндлер. Для этого нам нужно найти достаточно большой кусок неиспользуемого кода в самом экзешнике, который мы сможем перезаписать на наш код. Недолгий поиск показал, что это будет функция _CxxThrowException (ссылок на нее не было найдено). Беспощадно записываем все ее тело nop’ами и начинаем творить поверх нее:

    Вот так будет выглядеть псевдокод новых процедур:

    Компилируем (в моем случае руками вбиваем в Cheat Engine) и вставляем в код:

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

    Единственная проблема заключается в том, что ошибка эта довольно редкая, а часами бесцельно играть не хочется. Я все же решил немного потестировать сам, и был приятно удивлен — игра упала буквально через 10 минут геймплея, причем упала на только что написанном мною участке. Перемещаемся по стеку вызовов немного выше:

    Ничего не могу сказать, кроме как: «да, это вызов виртуальной функции». Первая же мысль — а что, если без него? Выпиливаем его nop’ами, тестируем — вроде живем. Игра работает как надо. Побочных эффектов нет. Собираем патч, отсылаем на тестирование. Через день прилетает дамп, где та же процедура падает несколькими байтами ниже. Выпиливаю и ее — игра начинает падать. Все ведет к тому, что нужно думать над более серьезным решением. Но в голову ничего не лезет, поэтому откладывается на неопределенный срок.

    За ночь я успел все обдумать, и пришёл к выводу. Вы скажете, что С++ не умеет в рантайме определять тип объекта? А я скажу, что может. И очень просто — по адресу виртуальной таблицы в памяти. Изучив дампы, я пришел к выводу, что периодически в процедуру прилетает неправильный класс (vtbl @ 0x00890970), а значит мы можем отловить эту ситуацию:

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

    Патчим и запускаем. И получаем всё ту же проблему: этот крах настолько редкий, что за почти 4 часа тестирования этот кусок кода был запущен всего пару раз, и все разы на вход был получен правильный класс.

    Можно было оставить и так, но мне нужно было подтверждение тому, что это действительно работает. Поэтому отправляемся реверсить дальше и пытаться вызвать исключительную ситуацию руками.

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

    убираем по максимуму «лишние» проверки и пытаемся насильно вызвать эту функцию. Запускаем тестирвоание и наконец-то получаем неправильный класс на вход. Ждём, пока отладчик студии допечатает весь текст, игра отвисает и… продолжает работать. Ура!


    Скриншот мыльный, ибо запись со стрима

    Заключение

    Решение найдено — игра больше не падает, даже если на вход подали что-то не то. Это заметно на скриншоте выше — часть заграждения отсутствует, потому что игра попыталась поставить туда что-то не то. Что именно — загадка, покрытая мраком, но я уверен, что рано или поздно мы узнаем и это.

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

    Весь фикс я решил оформить в виде asi скрипта, по принципу Widescreen патчей от ThirteenAG. Почитать исходники и скачать скрипты можно на гитхабе.

    SSD от Hewlett Packard Enterprise через 32 768 часов работы (примерно 4 года) УНИЧТОЖАЕТ хранящиеся на нём данные

    Ошибка в прошивке корпоративных SSD Hewlett Packard Enterprise приводит к потере накопителя и всех данных после 32 768 часов работы

    Компания Hewlett Packard Enterprise сообщила своим клиентам, что во встроенном программном обеспечении некоторых из ее SSD с интерфейсом SAS есть ошибка, которая приводит к отказу, когда срок эксплуатации достигает 32 768 часа (2 в 15 степени часа работы). Для SSD это означает 3 года, 270 дней и 8 часов суммарного использования.

    Исправление выпущено 9 декабря 2019 года, но оно не способно восстановить уже вышедшие из строя SSD

    Всем владельцам корпоративных SSD от Hewlett Packard Enterprise внимание! Если у вас какой-нибудь сервер использует данные девайсы, то через 2 в 15 степени часа работы (32 768) SSD уничтожает хранящиеся на нём данные. А в случае использования двух одинаковых — не поможет даже RAID. Умрут оба и одновременно. Там около 20 моделей

    Список моделей и лекарство опубликовано: Hewlett Packard Enterprise Центр поддержки

    Проблема затрагивает все твердотельные накопители HPE SAS с версиями прошивки до HPD8. Разработчики уверяют, что своевременное обновление прошивки до версии HPD8 полностью устраняет угрозу преждевременного отказа накопителя. Также в компании подчеркивают, что если устройство уже проработало 32 768 часов, и сбой уже произошел, восстановить сам SSD и данные с него будет невозможно.

    ⇡#Из Hot Pursuit

    Most Wanted 2012 (вот так гораздо лучше) разрабатывается на движке Chameleon, который также был использован в Hot Pursuit. FrostByte 2 — основа прошлогодней The Run — остаётся не у дел: студии проще работать с уже знакомым механизмом и материалами. В какой-то степени это печально, ведь в графическом плане «Пробег» выглядел куда внушительнее и интереснее, чем «Горячее преследование», — получается, что Need for Speed образца 2012 года с точки зрения технологичности визуального ряда делает шаг назад по сравнению с предшественником.

    В игре предусмотрен огромный игровой мир — агломерация Fairheaven City, предлагающая десятки километров улочек, шоссе, переулков и даже полей. На месте фирменная система разрушений — родом из Burnout, другой известной серии, автором которой также является Criterion Games. Обещают действительно эпический масштаб порчи имущества — ломать можно всё, от рекламных щитов до стен и целых сооружений. Вообще, в этом аспекте, а также с точки зрения дизайна и цветовой гаммы город больше напоминает Paradise City из последней Burnout, чем Rockport из Most Wanted 2005.

    Традиционное аркадное управление опять же мало чем отличается от того, что мы видели два года назад в Hot Pursuit. Беспрепятственный набор огромной скорости, простое исполнение зрелищного дрифта, шкала «здоровья» на автомобиле. На месте и обязательное нитро-ускорение.

    Система Autolog не отстает и обновляется до версии 2.0: теперь в статистику заносится абсолютно всё, что делает игрок в онлайне или в одиночном режиме, включая все очки, рекорды кругов на трассах и прочие цифры. Ну и само собой, система остаётся отличной площадкой для проведения сетевых заездов.

    Как исправить ошибку 0xc000007b в Windows 10

    Видео пример как создать точку восстановления в Windows 10

    Сперва наперво необходимо разобраться какая всё таки разрядность вашей операционной системы. Для этого нажимаем сочетание клавиш + Pause

    Обращаем внимание на выделенный фрагмент на рисунке Тип системы 32 или 64. В зависимости от того какие тут будут цифры, такие же должны быть и все системные файлы.

    В большинстве случаев причина заключается в Распространяемом пакете Microsoft Visual C ++, когда он установлен не надлежащим образом, или же его файлы повреждены или отсутствуют (например из-за вирусов), так что, первое, что необходимо сделать это скачать Распространяемый пакет Microsoft Visual C ++ (x64) или Microsoft Visual C ++ (x32) в зависимости от разрядности Вашей операционной системы.

    После загрузки файла, стандартным двойным щелчком мыши установите приложение.

    Теперь перезагрузите компьютер и попытайтесь запустить вашу игру или программу, если ошибка всё же не исчезла, то вы все таки, что-то напутали с разрядностью ОС. В этом случае воспользуйтесь ниже приведенными вариантами по актуализации системных библиотек:

    Способ первый (простой и быстрый)

    • Загрузите этот архив (ссылка на скачивание) в нем содержаться необходимые версии библиотек для x64 и для x32 типа операционных систем
    • Распакуйте содержимое архива в любую папку на любом диске. Главное не в корень диска. Будут распакованы две папки с файлами.
    • Теперь необходимо загрузиться в безопасном режиме. Для этого нажимаем сочетание кнопок WIN + R
    • В появившееся окошко вводим msconfig и нажимаем Enter
    • Переходим к вкладке Загрузка. Выбираем здесь Безопасный режим и тайм аут в 999 сек

  • Нажимаем Применить и Перезагрузка
  • Теперь загрузившись в безопасном режиме надо скопировать эти распакованные ранее папки и вставить их в C:Windows с заменой.
  • Перезагрузите компьютер и попробуйте запустить снова.
  • Второй способ (продвинутый универсальный)

    Есть на просторах Интернета замечательная утилита Dependecy Walker , которая сканирует приложения (в нашем случае игры) на используемые библиотеки, отображая полные пути к ним и самое главное их разрядность x32(x86) или x64.

    1. Всё что нужно, это скачать нужную версию программы под разрядность Вашего компьютера (как это сделать писалось выше).
      Скачать Dependecy Walker для x32(x86)
      Скачать Dependecy Walker для x64
    2. Распаковываем и запускаем программу Dependecy Walker
    3. В меню выбираем ViewsFull Paths или просто нажимаем F9 для того, чтобы видеть полные пути к файлам
    4. Выбираем FileOpen… , чтобы открыть файл игры. Переходим в папку с неработающей игрой и выбираем запускаемый файл
    5. Если появилось окно об ошибке игнорируем его и закрываем
    6. В окне Модулями (снизу) отображены все библиотеки, которые использует наша игра при запуске. И ближе к концу таблицы есть нужная нам колонка CPU (на рисунке ниже обведена красной рамкой).

  • Итак если Ваше приложение x32(x86), то будут подсвечены красным все x64 версии библиотек (dll файлов), которые используются игрой. И наоборот для x64 подсвечены будут x32(x86) версии.
    Как раз-то в этих файлах и заключается причина ошибки.
  • Теперь всё что вам остается сделать это скопировать имя библиотеки (dll файла) найти в Интернете нужную вам версию с разрядностью, скачать её и скопировать в папку с игрой, а еще лучше по тому пути, по которому она прописана в Dependecy Walker Если планируется файлы копировать в папку Windows, то рекомендуем Вам сделать точную восстановления системы (описано выше)
  • Третий способ (глобальный)

    Если первый способ не сработал, то пробуем следующее: загрузите All In One Runtimes и установите его на компьютере. Это приложение содержит все актуальные версии необходимых компонентов и библиотек для Windows 10, 8 , 7. Оно автоматически исправит все ошибки.

    В любом случае независимо от результата отпишитесь в комментариях помогли вам вышеприведенные методы или нет. Если да будем собирать положительную статистику, если же нет то пытаться сообща решить вашу проблему 0xc000007b

    Снова EA, снова NFS, снова баги. Чиним

    Привет, Хабр! С вами снова спидраннинг коммьюнити NFS. И мы снова чиним старенькую игрушку — NFS Most Wanted. Я уже рассказывал о починке багов в своих предыдущих статьях, а сегодня хотел был пойти с вами немного глубже в дебри дизассемблирования. Заинтересовавшихся прошу под кат.

    Предыстория

    Когда-то давно, когда EA издавала хорошие NFS, вышла одна из известнейших гоночных игр — Most Wanted. Увы, написана она была не так хорошо, как продавалась, и периодически падала. Конечно, обычный человек на это обращает мало внимания — ну вылетела разок за прохождение, ничего страшного. А вот нам это создает огромные проблемы: сколько потенциальных рекордов было убито случайными падениями без внятных симптомов. Все закончилось тем, что KuruHS лично попросил меня разобраться в ситуации. Отказаться я не смог.

    Что имеем

    IDA — для дизассемблирования
    Cheat Engine — для редактирования памяти и инструкций
    Visual Studio — для отладки (Trace Points, оказались весьма удобной вещью)

    У нас есть куча дампов. Приличная куча, гигабайт на 10. С них мы и начнем — проанализируем, на каких инструкциях падает игра. А падает она довольно рандомно, хотя некоторые закономерности прослеживаются. За время решения проблем мы нашли несколько потенциально опасных мест, которые иногда крашат игру. Например:

    в функции вычисления хэша строки. Видимо, разработчики не ожидали получить null-pointer в этом месте, поэтому не добавили проверку на него. Из-за этого в редких случаях игра падала. Фикс довольно банальный — прыгнуть в первый пустой кусок экзешника, да сделать test edi, edi. Потом jz retun и jmp откуда прыгали изначально.

    Другой похожий случай нашёлся в процедуре по адресу
    0х0057D105 mov edx, [ecx] ; я так и не смог понять, что конкретно она делает

    Разработчики снова не ожидали получить там null pointer, поэтому игра падала. Фикс абсолютно идентичен предыдущему.

    Наиболее распространённая причина падения оказалась в функции AllocateMemory. Попытки ее дизассемблирования повергли в ужас всех, кто работал над проблемой падений игры. Внимания удостоен уже тот факт, что в игре как минимум 5 разных подсистем управления памятью. Во что я ввязался…

    Ладно, нет времени ныть, надо реверсить. Несколько вечеров за разборами этого мусора принесли свои плоды: код, хоть все еще и не читаемый, стал более понятен. Судя по всему, эта подсистема работает по стандартной схеме: грабастаем некоторое количество памяти сразу, разбивая на блоки, храним их в двусвязном списке; по требованию выдаём свободные участки, а если таковых нету — пытаемся взять у системы еще. Ах, 2005-ый, когда операции с памятью были достаточно дорогими, чтобы ей разбрасываться как попало…

    Некоторые места в этой функции вызывают у меня приступы головной боли, потому что мой мозг напрочь отказывается даже пытаться их обработать. Но одно мне ясно точно — где-то среди всех этих связных списков, состоящих из связных списков, кроется неправильный указатель, из-за которого все и падает. Единственное решение, пришедшее в голову — отключить проверку «use_best_fit» чтобы подсистема выдавала первый попавшийся свободный блок, а не искала тот, который она считает наиболее подходящим.

    Конечно, проблемы целиком это не решило, но как минимум игра стала действительно стабильнее — за неделю тестирования в этом конкретном месте она упала всего несколько раз (при учете, что KuruHS проводит в игре по 10 часов в день), что я считаю довольно неплохим результатом.

    Pure virtual function call.

    Та самая ошибка, что проиллюстрирована в шапке. Люди, знакомые с С++ сразу поймут, в чем проблема. Однако без исходного кода все становится значительно сложнее. Ситуацию усложняет CRT, который, аки партизан, упорно не хочет генерировать дампы, если вылавливает этот тип ошибки.

    Purecall означает, что код попытался вызвать «чисто виртуальную функцию» (виртуальную функцию класса, не имеющую реализации). Без сомнений, этого сделать у него не получается, поэтому единственное, на что он решается — сообщить об этом пользователю и завершиться с кодом . В итоге вроде бы все и хорошо с кодом, а на деле все плохо.

    Спасибо Microsoft за замечательную функцию — _set_purecall_handler, которая позволяет заменить обработчик purecall’ов. Ищем в экзешнике упоминания/ссылки, находим саму функцию. Теперь осталось написать свой обработчик и не забыть установить его как хэндлер. Для этого нам нужно найти достаточно большой кусок неиспользуемого кода в самом экзешнике, который мы сможем перезаписать на наш код. Недолгий поиск показал, что это будет функция _CxxThrowException (ссылок на нее не было найдено). Беспощадно записываем все ее тело nop’ами и начинаем творить поверх нее:

    Вот так будет выглядеть псевдокод новых процедур:

    Компилируем (в моем случае руками вбиваем в Cheat Engine) и вставляем в код:

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

    Единственная проблема заключается в том, что ошибка эта довольно редкая, а часами бесцельно играть не хочется. Я все же решил немного потестировать сам, и был приятно удивлен — игра упала буквально через 10 минут геймплея, причем упала на только что написанном мною участке. Перемещаемся по стеку вызовов немного выше:

    Ничего не могу сказать, кроме как: «да, это вызов виртуальной функции». Первая же мысль — а что, если без него? Выпиливаем его nop’ами, тестируем — вроде живем. Игра работает как надо. Побочных эффектов нет. Собираем патч, отсылаем на тестирование. Через день прилетает дамп, где та же процедура падает несколькими байтами ниже. Выпиливаю и ее — игра начинает падать. Все ведет к тому, что нужно думать над более серьезным решением. Но в голову ничего не лезет, поэтому откладывается на неопределенный срок.

    За ночь я успел все обдумать, и пришёл к выводу. Вы скажете, что С++ не умеет в рантайме определять тип объекта? А я скажу, что может. И очень просто — по адресу виртуальной таблицы в памяти. Изучив дампы, я пришел к выводу, что периодически в процедуру прилетает неправильный класс (vtbl @ 0x00890970), а значит мы можем отловить эту ситуацию:

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

    Патчим и запускаем. И получаем всё ту же проблему: этот крах настолько редкий, что за почти 4 часа тестирования этот кусок кода был запущен всего пару раз, и все разы на вход был получен правильный класс.

    Можно было оставить и так, но мне нужно было подтверждение тому, что это действительно работает. Поэтому отправляемся реверсить дальше и пытаться вызвать исключительную ситуацию руками.

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

    убираем по максимуму «лишние» проверки и пытаемся насильно вызвать эту функцию. Запускаем тестирвоание и наконец-то получаем неправильный класс на вход. Ждём, пока отладчик студии допечатает весь текст, игра отвисает и… продолжает работать. Ура!


    Скриншот мыльный, ибо запись со стрима

    Заключение

    Решение найдено — игра больше не падает, даже если на вход подали что-то не то. Это заметно на скриншоте выше — часть заграждения отсутствует, потому что игра попыталась поставить туда что-то не то. Что именно — загадка, покрытая мраком, но я уверен, что рано или поздно мы узнаем и это.

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

    Весь фикс я решил оформить в виде asi скрипта, по принципу Widescreen патчей от ThirteenAG. Почитать исходники и скачать скрипты можно на гитхабе.

    Ссылка на основную публикацию
    Статьи c упоминанием слов:
    Adblock
    detector