Прежде чем перейти к статье, хочу вам представить, экономическую онлайн игру Brave Knights, в которой вы можете играть и зарабатывать. Регистируйтесь, играйте и зарабатывайте!
Привет, Хабр!
Возможно, здесь стоило написать какое-то длинное лирическое вступление или порассуждать о морально-этической части «пиратства» продукции крупнейших корпораций, ну или хотя бы просто сказать что это моя первая статья в Вашем сообществе. Но, к сожалению, даже не задумывался над всем этим и поэтому переедем сразу к делу и по существу.
На абордаж!
Итак, исходя из публично имеющейся информации мы знаем, что Google официально объявила версию своего браузера Chrome под номером 109 (109.0.5414.75) самой последней для операционной системы Windows 7 (8, 8, 8.1, 2012, 2019).
Прекрасно понимая, что данное решение было продиктовано в наибольшей степени корыстными побуждениями (а не реальной технической необходимостью), скачал актуальную (на тот момент) версию браузера 114.0.5735.134 x64, установил на виртуалке под управлением Windows 10.
Задача проста и одновременно сложна: заставить запуститься сие поделие под управлением Microsoft Windows 7 SP1... желательно за один вечер.
Разведка боем
Перемещаемся в установочную папку Chrome на виртуалке с Windows 10:
C:\Program Files\Google\Chrome\Application
и копируем её без изменений на виртуалку под управлением Windows 7 в любое свободное место (хоть в папку C:\Windows, но не обязательно).
Прежде всего, интересуемся исполняемым PE COFF форматом файлов. В смысле файлы с расширениями .exe и .dll. Под подозрение попадают три PE файла:
chrome.exe - основной исполняемый PE-файл, расположенный в корневой установочной директории;
114.0.5735.134\chrome_elf.dll - на него ссылается таблица экспорта (export table) в chrome.exe;
chrome.dll - судя по внушительному размеру в 210 Мегабайт, он может быть защищен DENUVO это и есть основной движок браузера. Как выяснилось чуть позже - который подгружается с помощью обычного вызова WinAPI LoadLibrary. В одной папке с chrome.dll находилась библиотека d3dcompiler_47.dll, что немного намекало на то, что движок браузера основан на рендеринге через DirectX. Но это так к слову о чём пришлось вспомнить в самом конце работы - в качестве ответа на вопрос «почему эта балалайка до сих пор не заводится??»;
Шаг 1. WinAPI calls
Самая опасная миссия этой операции. Выполнима ли она? Несмотря на разницу между цифрами 7 и 10, которая равняется всего навсего трём - количество недостающих WinAPI явно на порядок больше! Впрочем если поразмыслить чисто технически - большинство нововведений будет связано или с безопасностью или с энергопотреблением или с уникальными feature, которые нужны лишь для Windows 10/11 и не тарахтели для «семёрки» в принципе.
Для визуальной оценки масштабов недостающих WinAPI для Microsoft Windows 7 проще всего воспользоваться бесплатной утилитой Dependency Walker.
Недостающие WinAPI в системных PE-библиотеках dll отмечены красной карточкой справа. Такие dll так-же подсвечены красным цветом в самой утилите слева. Визуально отмечаем, что кроме отдельных WinAPI не достают целые системные библиотеки типа API-MS-WIN-POWER-BASE-L1-1-0.DLL (обозначены желтым цветом с восклицательным знаком). Убедившись, что API-MS-WIN-POWER-BASE-L1-1-0.DLL действительно отсутствует изначально в комплектации «семёрки», приходим к неутешительному, на первый взгляд, выводу: кроме отдельных реализаций процедур придётся писать за всю компанию Microsoft ещё целые PE dll. Т.е. миссия подразделяется на две карты:
реализация отдельных WinAPI в существующих системных PE dll;
реализация целых системных библиотек, которые попросту изначально не предусмотрены для Windows 7;
Ну ладно бы с chrome.exe или с chrome_elf.dll, которые занимают небольшой размер и не играют основной роли. Наиболее весомый, во всех смыслах, вклад вносит chrome.dll (на понимаю, что её размер свыше 200 Мегабайт, что естественно очень много для PE COFF формата в целом).
В итоге, получился следующий расклад для WinAPI:
Компонент браузера | Affected system dlls | Need WinAPI |
chrome.exe | KERNEL32.DLL | 4 |
USERENV.DLL | 2 | |
chrome_elf.dll | KERNEL32.DLL | 1 |
chrome.dll | KERNEL32.DLL | 7 |
USERENV.DLL | 2 | |
WINHHTP.DLL | 4 | |
USER32.DLL | 5 | |
MFPLAT.DLL | 4 | |
NETAPI32.DLL | 2 |
И недостающих system dlls:
API-MS-WIN-CORE-WINRT-ERROR-L1-1-0.dll |
API-MS-WIN-CORE-WINRT-L1-1-0.dll |
API-MS-WIN-CORE-WINRT-STRING-L1-1-0.dll |
API-MS-WIN-POWER-BASE-L1-1-0.dll |
API-MS-WIN-SHCORE-SCALING-L1-1-1.dll |
Первые три dll «отлетели» в Visual Studio сразу - из-за отсутствия AppX (MS Store) в Windows 7 писать какой либо вразумительный С/С++ код было попросту незачем. С power и shcore пришлось за несколько минут добавить фукнционал до нативного кода в NTDLL и масштабирования дисплея (DPI), соответственно.
А вот с WinAPI пришлось повозиться несколько больше. Во-первых мы явно остаёмся без новой песочницы (параметр --no-sandbox), ибо митигаций (GetProcessMitigationPolicy/SetProcessMitigationPolicy) в 7ке (минимум требуется Windows 8) действительно нет кроме DEP и ASLRP policy. С этим придётся чинить хромиумные worker'ы в mojom.
Во-вторых, всё остальное, в большинстве своём чинится банальным NOP без какой либо потери в функциональности браузера.
В третьих, почему-то после всего этого Chrome 114 запустился на Windows 7 и сразу же браузер грохнулся. В отладчике наблюдается, что окно «Новая вкладка» как-бы создаётся, но это максимум обычная верхняя часть окна Windows, ну разве что с добавленной адресной строкой. В смысле рендеринга тела страницы попросту не происходит - в лучшем случае пользователь будет набирать запросы в адресной строке, которые отображаются где-то в /dev/null:
Казалось бы... всё плохо? Да нет конечно! Не просто так написал за d3dcompiler_47.dll - определенно и очевидно, что именно придётся поправить в обращении Chrome с Microsoft DirectX. Опуская большое количество технологических реализаций, разработанную методику отладки ошибок в браузере и остальных технических деталей, предоставляю публике готовый Chrome 114 под Windows 7 (который необходимо запускать с ключом -no-sadnbox):
Шаг 2. Правка Major/Minor OS number
На самом деле, всегда это первое, что делают для разблокирования возможности запуска PE COFF на более ранних версиях Microsoft Windows. А именно понижают значение version number в PE Header.Optional Header, иначе системный загрузчик Windows попросту не запустит PE-файл. Но вспомнил за это уже после успешного запуска Chrome 114 на Windows 7, т.е. банально правка версии не потребовалась.
Чисто логически, линкер в Google должен был изначально ввести значения 0xA и 0x0, соответственно (Windows 10 же минимальная ось для запуска Chrome, как бы по официальному заявлению).
Вместо этого открываем замечательную утилиту PeTools и видим ... что там вообще находится Windows Server 2003. Сделав соответствующие выводы, просто закрыл PeTools.
WebGPU for Windows 7
Добавить параметры в строку запуска (флаг unsafe WebGPU и выбрать DirectX 11 в качестве рендера):
--enable-unsafe-webgpu --use-webgpu-adapter=d3d11
В самом браузере после запуска проверить:
chrome://flags/#enable-webgpu-developer-features
chrome://flags/#ignore-gpu-blocklist
Работает нестабильно или до первого креша отдельного процесса gpu рендера. Тут уж вопросы к самой реализации в браузере от корпорации, так как пилится всё это по чайной ложке.
P.S.
Вполне возможно, что наибольшей популярностью будет пользоваться вопрос «зачем?». Однако не вижу смысла давать прямой ответ на него.
Ограничусь лишь следующим утверждением: Microsoft Windows 7 до сих пор пользуются миллионы пользователей и она по праву считается одной из лучших ОС. И в один прекрасный момент кто-то из менеджеров некой корпорации G решил в прямом смысле «забить» на них, спустив указание выкинуть часть кода для исключения совместимости. Тем самым - оставив множество пользователей без обновлений функционала и безопасности. Благо не все конкуренты так поступают.
И вот спустя несколько месяцев возникают «пираты», которые демонстрируют абсолютно рабочий вариант браузера 114.0.5735.134 (114.0.5735.199) для Windows 7 (SP1). Т.е. пираты играют роль добрых самаритян, которые больше заботятся о пользователях, чем сама мистическая корпорация G.
К тому, что если завтра корпорация G внезапно прекратит поддержку Windows 10, насильно погнав всех вениками на следующую по инкременту циферку 11 - все также повинуясь (извиняюсь за выражение) «стадному принципу» скажут «О! Великий гугол, слушаемся и повинуемся»?!? При том что различий по WinAPI между 10 и 11 в разы меньше, чем между 10 и 7 для рассматриваемого случая.
А потом жалуются что весь технический прогресс скатился к банальному инкременту циферок в версии ПО.
Спасибо за внимание!