Компания
300,25
рейтинг
22 марта в 12:38

Разработка → Изучаем дерево исходников Windows 10: от телеметрии до open source

image

Насколько бы закрытым ни было программное обеспечение Microsoft, информации о своем внутреннем устройстве оно выдает предостаточно. К примеру, экспорт функций из библиотеки по именам дает представление о ее интерфейсах. В свободном доступе есть и отладочные символы, которые повсеместно используются для диагностики ошибок в ОС. Однако на руках у нас все равно имеются только скомпилированные бинарные модули. Становится интересно: а какими они были до компиляции? Давайте попробуем разобраться, как вытащить побольше информации об исходных кодах, не делая ничего незаконного.

Идея, конечно, не нова. В свое время подобное делали и Марк Руссинович, и Алекс Ионеску. Мне лишь было интересно получить свежие данные, немного дополнив и уточнив уже проделанную другими работу. Для эксперимента нам понадобятся пакеты отладочных символов, которые есть в свободном доступе. Я взял пакеты для последней релизной версии «десятки» (64 бита), причем решил исследовать и релизный пакет (free build), и отладочный (checked build).

Отладочные символы — это набор файлов с расширением pdb (program database, база данных программы), в которых хранится различная информация для расширения возможностей отладки бинарных модулей в ОС, включая имена глобалов, функций и структур данных, иногда вместе с их содержимым.

Помимо символов можно взять условно доступную отладочную сборку «десятки». Такая сборка богата на ассерты, в которых бывают описаны не только недокументированые и отсуствующие в символьных файлах имена переменных, но и номер строки в файле, в котором сработал ассерт.

image

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

Натравливаем на файлы символов утилиту strings от sysinternals и получаем около 13 ГБ сырых данных. А вот кормить все файлы из дистрибутива отладочной сборки подряд — так себе идея, ненужных данных будет слишком много. Ограничимся набором расширений: exe — исполняемые файлы, sys — драйвера, dll — билиотеки, ocx — ActiveX-компоненты, cpl — компоненты панели управления, efi — EFI-приложения, в частности загрузчик. Сырых данных от дистрибутива набралось 5,3 ГБ.

К своему удивлению я обнаружил, что не так много программ способны хотя бы открыть файлы размером в десяток гигабайт, и уж тем более единицы смогли поддержать функцию поиска внутри таких файлов. В данном эксперименте для ручного просмотра сырых и промежуточных данных использовался 010 Editor. Фильтрация данных дешево и сердито осуществлялась скриптами на питоне.

Фильтрация данных из символьных файлов


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

image


  • Зацепка-фильтр № 1: ищем строки по маске ":\\".


Получаем абсолютные пути, сортируем, удаляем дубликаты. К слову, мусора получилось не так много, и он был удален вручную.

При осмотре полученных данных стала понятна примерная структура дерева исходных кодов. Корень — «d:\th», что по всей видимости означает threshold, в соответствии с названием ноябрьской версии Windows 10 — Threshold 1. Однако файлов с корнем «d:\th» оказалось мало. Это объясняется тем, что компоновщик принимает уже собранные файлы. А сборка объектников осуществляется в папки «d:\th.obj.amd64fre» для релизной сборки и «d:\th.obj.amd64chk» для отладочной.

  • Зацепка-фильтр № 2: предполагаем, что исходные файлы хранятся по аналогии с объектными файлами после сборки, и осуществляем «разборку» объектных файлов в исходные. Внимание! Этот шаг может внести искажение структуры для некоторых папок, потому как достоверно не известны параметры сборки исходников.


Для примера:
d:\th.obj.amd64fre\shell\osshell\games\freecell\objfre\amd64\freecellgame.obj
это бывший
d:\th\shell\osshell\games\freecell\freecellgame.c??

По поводу расширения файлов: объектный файл получается из кучи разных типов исходного файла: «c», «cpp», «cxx», «asm» и т. д. На данном этапе неясно, какой именно тип исходного файла использовался, поэтому оставим расширение «c??».

Помимо папки «d:\th» наблюдается множество других корней. Например, «d:\th.public.chk» и «d:\th.public.fre». Данную папку мы опустим ввиду того, что в ней хранится публичная часть sdk, то есть она нам не очень интересна. Также стоит отметить различные пути проектов для драйверов, которые, судя по всему, собираются где-то на рабочих местах разработчиков:

c:\users\joseph-liu\desktop\sources\rtl819xp_src\common\objfre_win7_amd64\amd64\eeprom.obj
C:\ALLPROJECTS\SW_MODEM\pcm\amd64\pcm.lib
C:\Palau\palau_10.4.292.0\sw\host\drivers\becndis\inbox\WS10\sandbox\Debug\x64\eth_tx.obj
C:\Users\avarde\Desktop\inbox\working\Contents\Sources\wl\sys\amd64\bcmwl63a\bcmwl63a\x64\Windows8Debug\nicpci.obj

Другими словами, существует набор драйверов устройств, отвечающих стандартам, например, USB XHCI, которые входят в дерево исходных кодов ОС. А все специфичные драйвера собираются где-то в другом месте.

  • Зацепка-фильтр № 3: удаляем бинарные файлы, поскольку нам интересны только исходные. Удаляем «pdb», «lib», «exp» и т. п. Файлы «res» откатываем до «rc» — исходного кода ресурсного файла.


image


Выходные данные становятся все красивее! Однако на этом этапе дополнительные данные получить уже практически невозможно. Переходим к следующему набору сырых данных.

Фильтрация данных из исполняемых файлов


Поскольку абсолютных путей в сырых данных оказалось мало, фильтровать строки будем по расширениям:
  • «c» — исходные файы на языке C,
  • «cpp» — исходные файлы на языке C++,
  • «cxx» — исходные файлы на C или C++,
  • «h» — заголовочные файлы на языке C,
  • «hpp» — заголовочные файлы на языке C++,
  • «hxx» — заголовочные файлы на C или C++,
  • «asm» — исходные файлы на MASM,
  • «inc» — заголовочные файлы на MASM,
  • «def» — описательный файл для библиотек

После фильтрации данных становится видно, что хотя у полученный путей и нет корня, структура каталогов говорит о том, что она строится относительно него. То есть, всем путям достаточно добавить в начале корень «d:\th».

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

  • Зацепка-фильтр № 4: проверим, есть ли совпадения между путями до объектных файлов и путями до исходных.


И они действительно есть! То есть, для большинства каталогов можно утверждать, что их структура восстановлена правильно. Конечно, все еще остаются сомнительные каталоги, но думаю, эта погрешность вполне приемлема. Попутно можно смело заменять расширение «c??» на расширение совпавшего по пути исходника.

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

Третья проблема: мы все еще не знаем большинство расширений исходных файлов.

  • Зацепка-фильтр № 5: будем считать, что в пределах одной папки хранятся исходные файлы одинакового типа.


То есть, если в какой-либо из папок уже присутствует файл с расширением «cpp», скорее всего все его соседи будут иметь такое же расширение.
image

Ну а как же исходники на ассемблере? За последним штрихом можно обратиться к Windows Research Kernel — исходным кодам Windows XP — и часть исходников на ассемблере переименовать вручную.

Изучаем полученные данные


Телеметрия


Какое-то время я изучал вопрос об устройстве телеметрии в Windows 10. К сожалению, анализ на скорую руку не выявил ничего стоящего. Я не нашел никаких кейлоггеров, никакой утечки чувствительных данных, ничего, к чему можно было бы прикопаться. И первым ключевым словом для поиска среди исходных файлов было «telemetry». Результат превзошел мои ожидания: 424 совпадения. Самые интересные приведу ниже.

Телеметрия в исходных файлах
d:\th\admin\enterprisemgmt\enterprisecsps\v2\certificatecore\certificatestoretelemetry.cpp
d:\th\base\appcompat\appraiser\heads\telemetry\telemetryappraiser.cpp
d:\th\base\appmodel\search\common\telemetry\telemetry.cpp
d:\th\base\diagnosis\feedback\siuf\libs\telemetry\siufdatacustom.c??
d:\th\base\diagnosis\pdui\de\wizard\wizardtelemetryprovider.c??
d:\th\base\enterpriseclientsync\settingsync\azure\lib\azuresettingsyncprovidertelemetry.cpp
d:\th\base\fs\exfat\telemetry.c
d:\th\base\fs\fastfat\telemetry.c
d:\th\base\fs\udfs\telemetry.c
d:\th\base\power\energy\platformtelemetry.c??
d:\th\base\power\energy\sleepstudytelemetry.c??
d:\th\base\stor\vds\diskpart\diskparttelemetry.c??
d:\th\base\stor\vds\diskraid\diskraidtelemetry.cpp
d:\th\base\win32\winnls\els\advancedservices\spelling\platformspecific\current\spellingtelemetry.c??
d:\th\drivers\input\hid\hidcore\hidclass\telemetry.h
d:\th\drivers\mobilepc\location\product\core\crowdsource\locationoriontelemetry.cpp
d:\th\drivers\mobilepc\sensors\common\helpers\sensorstelemetry.cpp
d:\th\drivers\wdm\bluetooth\user\bthtelemetry\bthtelemetry.c??
d:\th\drivers\wdm\bluetooth\user\bthtelemetry\fingerprintcollector.c??
d:\th\drivers\wdm\bluetooth\user\bthtelemetry\localradiocollector.c??
d:\th\drivers\wdm\usb\telemetry\registry.c??
d:\th\drivers\wdm\usb\telemetry\telemetry.c??
d:\th\ds\dns\server\server\dnsexe\dnstelemetry.c??
d:\th\ds\ext\live\identity\lib\tracing\lite\microsoftaccounttelemetry.c??
d:\th\ds\security\base\lsa\server\cfiles\telemetry.c
d:\th\ds\security\protocols\msv_sspi\dll\ntlmtelemetry.c??
d:\th\ds\security\protocols\ssl\telemetry\telemetry.c??
d:\th\ds\security\protocols\sspcommon\ssptelemetry.c??
d:\th\enduser\windowsupdate\client\installagent\common\commontelemetry.cpp
d:\th\enduser\winstore\licensemanager\lib\telemetry.cpp
d:\th\minio\ndis\sys\mp\ndistelemetry.c??
d:\th\minio\security\base\lsa\security\driver\telemetry.cxx
d:\th\minkernel\fs\cdfs\telemetry.c
d:\th\minkernel\fs\ntfs\mp\telemetry.c??
d:\th\minkernel\fs\refs\mp\telemetry.c??
d:\th\net\netio\iphlpsvc\service\teredo_telemetry.c
d:\th\net\peernetng\torino\telemetry\notelemetry\peerdistnotelemetry.c??
d:\th\net\rras\ip\nathlp\dhcp\telemetryutils.c??
d:\th\net\winrt\networking\src\sockets\socketstelemetry.h
d:\th\shell\cortana\cortanaui\src\telemetrymanager.cpp
d:\th\shell\explorer\traynotificationareatelemetry.h
d:\th\shell\explorerframe\dll\ribbontelemetry.c??
d:\th\shell\fileexplorer\product\fileexplorertelemetry.c??
d:\th\shell\osshell\control\scrnsave\default\screensavertelemetryc.c??
d:\th\windows\moderncore\inputv2\inputprocessors\devices\keyboard\lib\keyboardprocessortelemetry.c??
d:\th\windows\published\main\touchtelemetry.h
d:\th\xbox\onecore\connectedstorage\service\lib\connectedstoragetelemetryevents.cpp
d:\th\xbox\shellui\common\xbox.shell.data\telemetryutil.c??

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

Kernel Patch Protection


Следующая находка — всеми любимый PatchGuard. Правда, в дереве исходников ОС присутствует только один файл непонятного, скорее всего бинарного типа.
d:\th\minkernel\ntos\ke\patchgd.wmp
Поискав совпадения в нефильтрованных данных, я обнаружил, что на самом деле Kernel Patch Protection — это отдельный проект.
d:\bnb_kpg\minkernel\oem\src\kernel\patchgd\mp\xcptgen00.c??
d:\bnb_kpg\minkernel\oem\src\kernel\patchgd\mp\xcptgen01.c??
d:\bnb_kpg\minkernel\oem\src\kernel\patchgd\mp\xcptgen02.c??
d:\bnb_kpg\minkernel\oem\src\kernel\patchgd\mp\xcptgen03.c??
d:\bnb_kpg\minkernel\oem\src\kernel\patchgd\mp\xcptgen04.c??
d:\bnb_kpg\minkernel\oem\src\kernel\patchgd\mp\xcptgen05.c??
d:\bnb_kpg\minkernel\oem\src\kernel\patchgd\mp\xcptgen06.c??
d:\bnb_kpg\minkernel\oem\src\kernel\patchgd\mp\xcptgen07.c??
d:\bnb_kpg\minkernel\oem\src\kernel\patchgd\mp\xcptgen08.c??
d:\bnb_kpg\minkernel\oem\src\kernel\patchgd\mp\xcptgen09.c??
d:\bnb_kpg\minkernel\oem\src\kernel\patchgd\mp_noltcg\patchgd.c??
d:\bnb_kpg\minkernel\oem\src\kernel\patchgd\mp_noltcg\patchgda.c??
d:\bnb_kpg\minkernel\oem\src\kernel\patchgd\mp_noltcg\patchgda2.c??
d:\bnb_kpg\minkernel\oem\src\kernel\patchgd\mp_noltcg\patchgda3.c??
d:\bnb_kpg\minkernel\oem\src\kernel\patchgd\mp_noltcg\patchgda4.c??

Сомнительные файлы


Не придумав больше ничего меня интересующего, я начал искать все подряд — и остался доволен!

d:\th\windows\core\ntgdi\fondrv\otfd\atmdrvr\umlib\backdoor.c??
в драйвере шрифтов?

d:\th\inetcore\edgehtml\src\site\webaudio\opensource\wtf\wtfvector.h
Web Template Framework, это всего лишь Web Template Framework, спорная аббревиатура. Погодите,

Open source?


d:\th\printscan\print\drivers\renderfilters\msxpsfilters\util\opensource\libjpeg\jaricom.c??
d:\th\printscan\print\drivers\renderfilters\msxpsfilters\util\opensource\libpng\png.c??
d:\th\printscan\print\drivers\renderfilters\msxpsfilters\util\opensource\libtiff\tif_compress.c??
d:\th\printscan\print\drivers\renderfilters\msxpsfilters\util\opensource\zlib\deflate.c??
Думаю, на этой находке пора закругляться.

Архив с текстовым файлом со списком исходников приведен по ссылке. Делитесь своими находками в комментариях!
Автор: @HonoraryBoT
Positive Technologies
рейтинг 300,25

Комментарии (36)

  • +12
    d:\th\windows\core\ntgdi\fondrv\otfd\atmdrvr\umlib\backdoor.c??

    Бэкдор в шрифтах??? Серьезно?
    • +8
      Вся соль в том, что остается только гадать. Или искать код в бинарнике...
    • +9
      Если подумать, очень хорошее решение. Ведь шрифты используются в абсолютном большинстве приложений, так что внедриться можно будет куда угодно. Кроме того, сейчас популярны web fonts, т.е. загружаемые из интернета шрифты для конкретного сайта. А это уже универсальный вектор атаки.
      • 0
        Вам не кажется такое решение странным? Конечно прятать лучше всего на виду, но все-таки это уже слишком.
        • +6
          Решение разместить бэкдор в шрифте — нет, а вот называть файл бэкдора backdoor.c — да, это странно. Но не исключено, что это сделано для отвода глаз, а настоящий бэкдор прячется в коде, отвечающем за отрисовку заголовка окна и активируемый специально сформированным названием. Его тоже можно поставить в браузере через тег title удалённо, большинство браузеров пишут заголовок сайта в заголовок окна.
          • +2
            В нулевых было модно называть вирусню explorer.exe и etc...
          • +5
            Между прочим, хорошее объяснение, почему в Windows графика работает на уровне ядра.
            • +1
              Насколько я помню, ответ на этот вопрос тривиальный — постоянные переключения из юзер-мод в кернел заставляли пользователей страдать, и достаточно микроядерная NT была вынуждена пойти на такой шаг. Никаких жидомассонов.
    • +5
      Объяснение нашли — www.reddit.com/r/technology/comments/4bhuqy/russian_reverse_engineer_revealed_backdoor_in/d19tf6k

      «Backdoor» — устоявшееся понятие в официальной документации «Adobe Type Manager Software API: Windows» 1997 года, встречается в инструкциях к функциям управления шрифтами.
  • +7
    Прекрасная работа, даже с учетом возможных неточностей.
    • 0
      Спасибо!
  • 0
    Есть ли представители мелкософта на хабре? Что они скажут?
    • +6
      А что они могут сказать? Не они же писали код и не компилировали бинарники.
  • 0
    Последняя находка не удивила. libjpeg, zlib и прочие опенсорсные библиотеки используются в Windows с древних времён.
  • –1
    Хаб Open Source и Windows. Что-то здесь не так:)
  • 0
    Следующая находка — всеми любимый PatchGuard. Правда, в дереве исходников ОС присутствует только один файл непонятного, скорее всего бинарного типа.

    Его не могли скрыть в отладочных файлах? Есть ли там что-то про RMS?
    • 0
      Пардон, а что есть RMS?
      • 0
        Active Directory Rights Management Services — DRMDLP от MS для корпораций.
        • 0
          d:\th\ds\security\efs\rmshost\rmsinterface\rmsinterface.c??
          типа этого?
          • 0
            Возможно, а pdb файлы для него есть?
            Интересен подход MS к огораживанию ценных или потенциально небезопасных компонентов, вроде отсутствия отладочных символов для Office.
            • 0
              Проверьте в пакетах отладочных символов
  • 0
    Конечно исходников ждать не стоит =)
  • +6
    На реддите объяснили: "backdoor" — это способ Adobe Type Manager ("atm"), позволяющая добавлять шрифты в систему "на лету", без перезагрузки.

    В документации написано:
    To determine if ATM can properly render a font that is not currently enumerated on the system, an application should use the ATM backdoor API call, ATMFontAvailable() (see Section 6.1).

    • 0
      Спасибо!
  • 0
    Подскажите,
    есть ли какое-нибудь сообщество,
    занимающееся разбором микромягких постоянно и системно?
    • +6
      ReactOS, наверное )
    • 0
      Это огромная работа. Зачем на нее регулярно и системно тратить силы?
      Те, кому оченб важна приватность — не пользуются виндой или не отдают ей ничего важного и приватного.
  • +1
    C:\Users***\Desktop\

    Серьёзно? На рабочем столе?
  • 0
    Очень интересно, спасибо. Пожалуйста, продолжайте.
    Еще, скажите, пожалуйста. Что сейчас из книг считается актуальным по внутреннему устройству Windows? WinAPI / Native API уже не интересуют, интересно информация именно о том как оно работает внутри.
    • 0
      Если я правильно понял, что именно вы хотите, то попробуйте "Современные операционные системы" Таненбаума.
      Есть ещё "Внутреннее устройство Microsoft Windows. Основные подсистемы ОС" Русиновича, Ионеску и Соломона.
  • +1
    Хабр снова торт!
  • 0
    Спасибо. Крайне интересно! Буду ждать новых статей.
  • –1
    Спасибо!
    По количеству и типу мест ОС, в которые встроена "телеметрия" (я воспринимаю это слово как эвфемизм для таких понятий, как "слежка за пользователем" или "подсматривание"), я еще более укрепился в мысли попрощаться с продукцией Microsoft, хотя мне она всегда и нравилась.
  • 0
    А как же самый главный вопрос. Сколько процентов винды собрано в вижуал студии?
    • 0
      Вполне может быть и сто: студией можно собрать и загрузчик, и драйвера.

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.

Самое читаемое Разработка