Maxim Menshikov

Static analysis reseacher and startup founder


OSBuilder8: процесс разработки Announcements, Research, По-русски

Я обычно не публикую подробности о проектах, находящихся в активной разработке. Но я решил напомнить читателям, что я всё ещё жив.

Как обычно, всё началось с идеи: «может, стоит перенести OSBuilder на Windows Phone 8?» Тут есть важное замечание: не очень много устройств могут запускать кастомные прошивки в настоящее время. Это Huawei W1, HTC 8X/8S (теоретически), Samsung Ativ S.

Возможно, читатель, незнакомый с темой, спросит: «А что вообще такое OSBuilder?». Поясняю: Это один из наиболее известных и полных инструментов для сборки самодельных прошивок для Windows Mobile и Windows Phone 7. В OSBuilder обычно интегрированы инструменты для сборки прошивки от начала для конца – можно даже не вылезать из интерфейса OSB. Программа изначально разработана Евгением (Barin’ом), а впоследствии к её разработке подключился и я.

Вернемся к теме.
Т.к. у меня имеется инженерный Samsung Ativ S с предрелизной версией Windows Phone, я решил написать инструмент, который бы позволил обновить ОС до чего-нибудь более-менее нового, например, до обновления GDR3.
Devices

Структура папок

В целом, почти все осталось в таком же виде, как оно было в Windows Mobile 6 или Windows Phone 7.
Folder structure
А что касается путей к пакетам, то встроенный в OSB8 распаковщик образов использует пути следующего вида:
%ТипАвтораПакета%\%Автор%\RES\_\*\LANG\_\*\%Компонент%\%Подкомпонент% (RES - разрешение экрана, LANG_ - язык).
Под «пакетами»; подразумеваются папки, содержащие всё необходимое для отдельных компонентов системы. Например, для калькулятора, календаря.

К примеру, путь к Microsoft.MainOS.Production (русской версии) выглядит примерно так:
SYS\Microsoft\LANG_ru-ru\MainOS\Production

О внутренностях пакетов

Пакет традиционно содержит *.dsm-файл (Device-Side Manifest – краткое описание пакета). Только теперь он в виде XML. Помимо этого, пакеты содержат файлы с записями реестра (.reg, .rga), с политиками безопасности (.policy.xml). Что касается названий файлов: Я долго думал, и решил оставить названия файлов в таком виде, в котором они бывают в обычных обновлениях системы в формате CAB (%магическое число%_%несколькобуквназвания%.%расширение%). Почему? Потому что зачастую бывает так, что папка содержит несколько файлов с одинаковыми названиями, которые после установки пакета на реальное устройство на самом-то деле уедут куда-нибудь далеко (обычно это касается языковых файлов: они имеют одинаковые названия, но разные папки установки). Я не стал ради красоты увеличивать размеры путей на жестком диске собирателя прошивок. Ибо не забываем про лимит длины пути в 260 символов, который до сих применим к большинству приложений Windows.
Folder structure

Реестр

Чтобы лучше контролировать процесс сборки реестра, я написал собственный парсер файлов реестра.
Что мы имеем:
.reg-файлы - просто добавляют или заменяют контент в финальном кусте реестра.
.rga-файлы - обычно добавляют новую запись в мультистроковые параметры. Обычно порядок здесь не важен, но я постарался приблизить его к оригиналу.

Проблема, собственно, в приближении порядка к оригиналу…

Порядок сборки пакетов

Порядок обычно записан в файлу \Windows\ImageUpdate\UpdateHistory.xml. Но не стоит ему полностью доверять. После многочисленных экспериментов я понял, что некоторые пакеты всё-таки надо двигать на верх списка. И хотя это не делает UpdateHistory.xml бесполезным, это ломает порядок сборки, что может вести к некорректным значениям в реестре, неактуальным политикам безопасным.

Политики безопасности

Это, возможно, самая трудозатратная часть всего процесса разработки. Нам надо пересобрать базу данных политик безопасности, чтобы она была синхронизирована с исходными .policy.xml. Данная база данных содержит все правила по типу Пользователь Иван может открыть папку C:\Смешные Котята, Администраторы могут добавлять новых котят в C:\Смешные Котята. Без корректной БД, Windows Phone просто не загрузится.

Представьте: имеем такой файл:

<?xml version="1.0" encoding="utf-8"?>
<PhoneSecurityPolicy xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" HashType="Sha256" PackageID="Microsoft.BaseOS.IpOverUsb" xmlns="urn:Microsoft.WindowsPhone/PhoneSecurityPolicyInternal.v8.00">
  <Capabilities>
    <Capability xsi:type="PrivateResources" ElementID="08826C28AC9B35E6DC9BEEE6CAB066A603CFBA91C157DD765F1EE7C475D0548D" AttributeHash="C4F906E3940D86900E1EDAE6241A799DF3918136DCB3686A3EBC66A71F9F12E1" Id="ID_CAP_PRIV_IPOVERUSB" SvcCapSID="S-1-5-80-3281897998-4027600974-1982452685-2998814832-604313930" FriendlyName="IPOVERUSB private capability" Visibility="Private">
      <CapabilityRules>
        <Rules>
          <SDRegValue ElementID="B5320ADB6B754E2CCC033A46DD49B63FE82C64ED8FB2694FCFC277FE10C3DDF7" DACL="(A;;0x111FFFFF;;;S-1-5-80-3281897998-4027600974-1982452685-2998814832-604313930)" Flags="2147483652" Path="HKEY_LOCAL_MACHINE\SYSTEM\CONTROLSET001\CONTROL\NOTIFICATIONS\41C61D22A3BC8075" Type="WNF" />
        </Rules>
      </CapabilityRules>
    </Capability>
  </Capabilities>
  <Components>
    <Service ElementID="EE71E815BB0E265E208AA56A3B2C4AEE3FFB782C26A41203AA65549F16F01780" AttributeHash="67E67DB70A5BE2BB6E8BCECABD139168A4E95C76A4E43A8E186C0C2527DFBBDF" SID="S-1-5-80-3281897998-4027600974-1982452685-2998814832-604313930" Name="IPOVERUSB" PrivateCapSID="S-1-5-80-3281897998-4027600974-1982452685-2998814832-604313930" Executable="\windows\System32\SvcHost.exe" IsTCB="No" SvcHostGroupName="IPOVERUSBGROUP">
      <RequiredCapabilities>
        <RequiredCapability CapId="S-1-5-21-2702878673-795188819-444038987-1543" />
      </RequiredCapabilities>
    </Service>
  </Components>
</PhoneSecurityPolicy>

На этот моменте вы, скорее всего, выкрикнули что-то непечатное. И вы будете правы. Таких записей много, они похожи, но нам-то всё равно их нужно читать!
И превращаем их в нечто подобное…

[HKEY_LOCAL_MACHINE\System\SecurityManager\Capabilities\ID_CAP_PRIV_IPOVERUSB]
"CapabilityFriendlyName"="IPOVERUSB private capability"
"CapabilityType"=dword:00000002
"ServiceCapabilitySID"=hex:01,06,00,00,00,00,00,05,50,00,00,00,0E,CA,9D,C3,4E,50,10,F0,CD,D3,29,76,70,48,BE,B2,4A,19,05,24
"Privileges"=hex:00,00,00,00
"EmbeddedWindowsCapabilitySIDs"=hex:00,00,00,00

[HKEY_LOCAL_MACHINE\System\SecurityManager\Capabilities\ID_CAP_PRIV_IPOVERUSB\Microsoft.BaseOS.IpOverUsb]
"PackagePrivileges"=hex(7):00,00,00,00
"PackageEmbeddedWindowsCapabilitySIDs"=hex(7):00,00,00,00
"SourceID"="ID_CAP_PRIV_IPOVERUSB@Microsoft.BaseOS.IpOverUsb"

[HKEY_LOCAL_MACHINE\System\SecurityManager\Capabilities\ID_CAP_PRIV_IPOVERUSB\Microsoft.BaseOS.IpOverUsb\PackageRules]
"B5320ADB6B754E2CCC033A46DD49B63FE82C64ED8FB2694FCFC277FE10C3DDF7"=dword:20000000

[HKEY_LOCAL_MACHINE\System\SecurityManager\ResourceAccessControl\OpaqueObject\B5320ADB6B754E2CCC033A46DD49B63FE82C64ED8FB2694FCFC277FE10C3DDF7\ID_CAP_PRIV_IPOVERUSB@Microsoft.BaseOS.IpOverUsb]
"DACL"="(A;;0x111FFFFF;;;S-1-5-80-3281897998-4027600974-1982452685-2998814832-604313930)"
"DefaultSettingsFlag"=dword:80000004

Немного лучше, хоть не сильно. Но Windows уже может использовать БД в такой форме.

Что характерно, тут в принципе нет документации «Как реализовать то-то». Приходится анализировать. Я обычно делаю так: пишу код, как считаю нужным, а потом сверяюсь с оригиналом, выругиваюсь, исправляю. Нахожу какой-нибудь непонятный момент (как, например, странные числа в списке идентификаторов безопасности), ищу кучу примеров подобных записей, сравниваю… и в конце-концов прихожу к нормальному решению. Такому, при котором было бы ноль отличий в оригинальной и итоговой базах данных. Policies

NTFS-разрешения

Вот прочитали мы эти политики безопасности. Теперь надо бы их применить к папкам и файлам. После сборки, разумеется.
В настоящий момент я устанавливаю пересобранную ОС сразу на телефон: форматирую разделы MainOS (файлы ОС) и Data (пользовательские файлы), кладу новые файлы, создаю т.н. символические ссылки (очень-очень грубо говоря, «незаметные пользователю ярлыки на папки/файлы»), а затем применяю права доступа и меняю владельцев файлов/папок. Это весьма быстрый процесс, но, опять же, без него система не загрузится.

Как выглядит OSBuilder?

И возникает мысль: а как же выглядит-то этот самый OSBuilder, о котором пишет автор данного поста? OSBuilder - 1
OSBuilder - 2
Пожалуйста, не толпитесь, когда будете пытаться нанять меня на работу дизайнером в вашу компанию.

«А как же все тестируется?»

Да просто: беру и сравниваю с оригиналом. Обычно это очень неплохая идея. Также я тестирую прошивку на Ativ S (время от времени). Раньше прошивки со старыми сборками ОС грузились прекрасно, а последние что-то перестали грузиться. Но исправлю.

И когда оно будет готово?

Неизвестно

Работай уже!

Работаю над проектом ровно столько, сколько могу. Обычно, два часа в месяц.

Спасибо за чтение и терпение при чтении столь скучной статьи.