«Пиратим» Firefox в Windows 7
Актуальная версия Mozilla Firefox 131 заработала на Windows 7. Получилось даже проще, чем с Google Chrome Windows 7.
GitHUB, который ПОКА не задизейблили
Просто напонимаю, что за автором популярного пакета VxKex ночью пришли и увезли на пативене. Так что ещё непонятно что опасней всего: ломать SecuROM/DENUVO или пиратить продукты популярных корпораций для одной из самых успешных операционных систем Microsoft.
Техническая часть
Принципиально в ней ничего не поменялось.
Ну разве что кроме названий: chrome.exe
> firefox.exe, chrome.dll
> xul.dll и тд.
Первым делом идём в Dependency Walker. Из привычных bryprimitives.dll, kernel32.dll, user32.dll, для которых таблица импорта различается ... всего на несколько новых фукнций (2-4). Всякие CreateSyntheticPointerDevice, InjectSyntheticPointerInput — наследие плиток Windows 8.1.
Из новенького WinAPI: ntdll.(x64).RtlAddGrowableFunctionTable и ole32.RoGetAgileReference.
Чтобы не заморачиваться с написанием оберток всего лишь из-за одной фукнции в каждой dll, сразу подправил их таблице экспорта PETools на безобидные:
RtlAddGrowableFunctionTable >> NtClose
RoGetAgileReference >> CoInitialize
WinAPI RtlAddGrowableFunctionTable вызывалась при старте процесса, поэтому пришлось дополнительно за'nop'ить её вызов с возвратом в регистре общего назначения EAX = 1. Впрочем, ничего нового.
После релиза Chrome 125 (который случился после всего описываемого безобразия в этих строках для Windows 7), Google начала стандартно вставлять небольшие палки в колёса правки Major/Minor SubSystem version в PE Header. Значения 0xA/0
нужно изменить на 6/0
или 5/2
.
Что НЕ пришлось менять совсем
Забавно, но ЗА БОРТОМ внезапно остались:
митигации WinAPI GetProcessMitigationPolicy/SetProcessMitigationPolicy;
WinAPI RegNotifyChangeKeyValue с флагом REG_NOTIFY_THREAD_AGNOSTIC;
Ещё более странно, это отсутствие необходиости менять интерфейс IID_IDWriteFactory3
{9A1B41C3-D3BB-466A-87FC-FE67556A3B65}
на IID_DWriteFactory{B859EE5A-D838-4B5B-A2E8-1ADC7D93DB48}
. «Сомнительно, ну окей»;Ещё пару мелких ньюансов, которые НЕ были реализованы в Mozilla Firefox, но имелись в Chrome, Brave, Opera, Spotify, MS EDGE, Vivaldi, ElectronMail и, наверняка, в остальных Chromium-подобных браузерах;
Иными словами, потребовалась самая минимальная правка бинарного (и ассемблерного) кода для запуска процесса firefox.exe в среде Windows 7 её стандартным загрузчиком PE COFF формата..
100% CPU LOAD
Наверняка уважаемый читатель помнит о проблеме HUGE MEMORY в Chrome x64, которой страдает WinAPI VirtualAlloc (,MEM_RESERVED,)
в «семёрке». В двух словах, прямо с пустой стартовой страницы можно получить сразу свыше 4,7 Гигайбат оперативной памяти, которая будет сьедена браузером. И это при том, что мы даже самый простой сайт ещё не открыли из начала 2000х, который с тормозами и нехваткой памяти разве что мог открыться на Nokia 3310.
В случае огнелисы, как и подразумевалось на протяжении существования битвы между корпорациями Google и Mozilla, вышло всё ровно противоположно — с памятью всё ок, зато 100% загрузка центрального процессора (CPU).
Если верить менеджеру процессов FurryFox, то родительский процесс Windows «Графический процессор» сумел превзойти все законы физики и здравого рассудка, загрузив CPU на 300%. Наверное это считается как-то в сумме: CPU + GPU + NetworkCPU, иначе у меня нет логического обьяснения как получается такая безумная величина, которая выше единицы (100%) одного физического объекта в операционной системе.
Хотя, использовав Process Hacker, какие-то зачатки разума в этом поведении нашлись. Очевидно, дело в сихнронизации потоков (threads), если каждый из них выжирает такое дикое количество процессорного времени.
Копнув чуть глубже с помощью x64dbg (ну или WinDBG. Самое главное не gdb), несложно было догадаться, что сии потоки активно вызывают три функции из API-MS-WIN-CORE-SYNCH-L1-2-0.dll
WaitOnAddress
WakeByAddressAll
WakeByAddressSingle
Суть таковых — синхронизация по изменяемому адресу в памяти. Сама библиотека API-MS-WIN-CORE-SYNCH-L1-2-0.dll из нашего батальона API-MS libs. Реализацию трёх вышеупомянутых фукнций можно найти в сорцах Wine (это типа отсылка про gdb выше). Сама реализация состоит из стандартных обвесов и нативных фукнций NtWaitForAlertByThreadId, NtAlertThreadByThreadId, реализация которых в ядре Windows 7 не предусмотрена. Что же делать, если хочется как в прошлый раз, завести это с полоборота?
Быстрое решение нашлось, как ни банально повторятся — довольно быстро:
Sleep(1); SwitchToThread();
Быстро спим + быстро переключаемся на другой поток. Таким простым способом удалось нормализовать загрузку процессора. Небольшим побочным эффектом стало возможное появление микрофризов, так как полноценная сихронизация всё-таки отсуствует на данном этапе.
Да, прекрасно помню, что в открытой природе существуют лисичкины исходные коды и даже заголовчный файл с define HWY_DISABLE_FUTEX:..\firefox-131.0.source\firefox-131.0\third_party\highway\hwy\contrib\thread_pool\futex.h
Что по багам?
Из багов, кроме возможно небольших микрофризов, упомянутых выше — разве что crash после создания OLE-объекта CLSID {00021401-0000-C000-000000000046}. Он же MS-LINK
. Пришлось за'nop'ить вызов на уровень выше от WinAPI CoCreateInstance(). В остальном — фурри невероятно приятно удивила стабильностью работы. Именно под Windows 7.
Telemetry
Нечаянно поставил точку останова (breakpoint) на фукнцию nss3.PR_GetAddrInfoByName
— удивительно, что даже при отключенной телеметрии столько разных адресов этой телеметрии. Так, намёк на эту новость — заглядывайте чаще в отладчик.
nss3.dll из состава FurryFox.
Вместо послесловия
А) Да, Mozilla до сих пор официально поддерживает Windows 7 версией 115.ESR своего огненного браузера;
Б) Для всех неравнодушных — «сами возьмите и скомпилите» из исходных кодов. Собственно, лишний раз убедитесь в том, что на «семёрке» оно заведётся (даже на самой актуальной версии). Список всех возможных изменений в тех части;
В) на youtube заходит без задержек, проигрывает видео без промедлений... и вообще всё хорошо!
Написать комментарий