<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Волчьи IT-мысли &#187; драйвер</title>
	<atom:link href="http://sww-it.ru/tag/%d0%b4%d1%80%d0%b0%d0%b9%d0%b2%d0%b5%d1%80/feed" rel="self" type="application/rss+xml" />
	<link>http://sww-it.ru</link>
	<description>Компьютерная безопасность, IT, антивирусная индустрия.</description>
	<lastBuildDate>Wed, 18 Jan 2012 11:20:32 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=</generator>
		<item>
		<title>IsDebug-ли?</title>
		<link>http://sww-it.ru/2011-03-21/520?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=isdebug-%25d0%25bb%25d0%25b8</link>
		<comments>http://sww-it.ru/2011-03-21/520#comments</comments>
		<pubDate>Mon, 21 Mar 2011 17:10:02 +0000</pubDate>
		<dc:creator>SWW</dc:creator>
				<category><![CDATA[Вирусный анализ]]></category>
		<category><![CDATA[rootkit]]></category>
		<category><![CDATA[драйвер]]></category>
		<category><![CDATA[юмор]]></category>

		<guid isPermaLink="false">http://sww-it.ru/?p=520</guid>
		<description><![CDATA[<p align="justify">Пришлось мне тут анализировать один элементарный руткит, никак не срасталось у нашего анти-руткита кое-что с ним. Ерунда в принципе, бага не критичная, но разобраться все-таки стоило. В последнее время не часто выпадает возможность проанализировать что-либо, но тут повезло, можно немного отвлечься от процесса исследования/кодинга. </p> <p></p> <p align="justify">Для дальнейшего понимания сути поста надо запомнить [...]]]></description>
			<content:encoded><![CDATA[<p align="justify">Пришлось мне тут анализировать один элементарный руткит, никак не срасталось у нашего анти-руткита кое-что с ним. Ерунда в принципе, бага не критичная, но разобраться все-таки стоило. В последнее время не часто выпадает возможность проанализировать что-либо, но тут повезло, можно немного отвлечься от процесса исследования/кодинга.
</p>
<p><span id="more-520"></span></p>
<p align="justify">Для дальнейшего понимания сути поста надо запомнить то, что дата компиляции дроппера &#8212; <strong>27 февраля 2011 года</strong>, т.е. сэмпл далеко не старый.</p>
<p align="justify">В процессе <strong>динамического анализа</strong> я натолкнулся на полнейший отказ руткита работать, во-первых, под виртуальной машиной, а во-вторых, под виртуальной машиной с отладчиком ядра. Дроппер, кстати, также использовал парочку элементарных и устаревших проверок виртуальной машины, но не о дроппере речь.</p>
<p>Вот такой код я обнаружил в драйвере:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">char</span> __cdecl IsDebug<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
  UNICODE_STRING DestinationString<span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// [sp+4h] [bp-Ch]@4</span>
  PVOID Object<span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// [sp+Ch] [bp-4h]@4</span>
&nbsp;
  <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> KdDebuggerEnabledAddr <span style="color: #339933;">&amp;&amp;</span> <span style="color: #339933;">*</span><span style="color: #009900;">&#40;</span>_BYTE <span style="color: #339933;">*</span><span style="color: #009900;">&#41;</span>KdDebuggerEnabledAddr <span style="color: #009900;">&#41;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #0000dd;">1</span><span style="color: #339933;">;</span>
  RtlInitUnicodeString<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>DestinationString<span style="color: #339933;">,</span> L<span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\\</span>Driver<span style="color: #000099; font-weight: bold;">\\</span>NTICE&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #339933;">!</span>ObReferenceObjectByName<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>DestinationString<span style="color: #339933;">,</span> 0x40u<span style="color: #339933;">,</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">,</span> 0x1F01FFu<span style="color: #339933;">,</span> IoDriverObjectType<span style="color: #339933;">,</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">,</span> <span style="color: #339933;">&amp;</span>Object<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    ObfDereferenceObject<span style="color: #009900;">&#40;</span>Object<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #0000dd;">1</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
  <span style="color: #b1b100;">return</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p align="justify">Способ, основанный на проверке переменной <strong>KdDebuggerEnabled</strong>, известен очень давно, однако, проверка на наличие в системе активного отладчика Soft(Win)Ice (наличие драйвера NTICE) &#8212; это что-то из ряда вон выходящее. Неужели авторы думают, что антивирусные лаборатории до сих пор используют этот устаревший инструмент?</p>
<p align="justify">Что ж, живы еще олдскул разработчики в родных селениях!</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fsww-it.ru%2F2011-03-21%2F520&amp;title=IsDebug-%D0%BB%D0%B8%3F" id="wpa2a_2"><img src="http://sww-it.ru/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://sww-it.ru/2011-03-21/520/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Использование мэппинга драйверов</title>
		<link>http://sww-it.ru/2010-07-08/485?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=%25d0%25b8%25d1%2581%25d0%25bf%25d0%25be%25d0%25bb%25d1%258c%25d0%25b7%25d0%25be%25d0%25b2%25d0%25b0%25d0%25bd%25d0%25b8%25d0%25b5-%25d0%25bc%25d1%258d%25d0%25bf%25d0%25bf%25d0%25b8%25d0%25bd%25d0%25b3%25d0%25b0-%25d0%25b4%25d1%2580%25d0%25b0%25d0%25b9%25d0%25b2%25d0%25b5%25d1%2580%25d0%25be%25d0%25b2</link>
		<comments>http://sww-it.ru/2010-07-08/485#comments</comments>
		<pubDate>Thu, 08 Jul 2010 11:50:08 +0000</pubDate>
		<dc:creator>SWW</dc:creator>
				<category><![CDATA[Отладка]]></category>
		<category><![CDATA[windbg]]></category>
		<category><![CDATA[драйвер]]></category>
		<category><![CDATA[мэппинг]]></category>
		<category><![CDATA[трюки]]></category>

		<guid isPermaLink="false">http://sww-it.ru/?p=485</guid>
		<description><![CDATA[<p align="justify">В отладчике WinDbg существует специальная возможность – мэппинг драйвера. Отладчик может перехватить момент загрузки драйвера на тестовой машине и загрузить в память копию драйвера с машины разработчика. Эта способность избавляет разработчика от проблемы копирования файла драйвера на тестовую машину и, конечно, от забывчивости.</p> <p></p> <p align="justify">Прежде всего, необходимо внести в переменные окружения компьютера разработчика [...]]]></description>
			<content:encoded><![CDATA[<p align="justify">В отладчике WinDbg существует специальная возможность – мэппинг драйвера. Отладчик может перехватить момент загрузки драйвера на тестовой машине и загрузить в память копию драйвера с машины разработчика. Эта способность избавляет разработчика от проблемы копирования файла драйвера на тестовую машину и, конечно, от забывчивости.</p>
<p><span id="more-485"></span></p>
<p align="justify">Прежде всего, необходимо внести в переменные окружения компьютера разработчика параметр <strong>_NT_KD_FILES</strong>, где значением этого параметра должен быть полный путь до специального map-файла, например, <strong>c:\driver.map</strong>.</p>
<p align="justify">Далее, необходимо создать сам map-файл по выбранному пути с указанным содержимым:</p>
<blockquote><p>map<br />
\??\C:\1\driver32.sys<br />
C:\project_path\out\debug\driver32.sys
</p></blockquote>
<p align="justify">Во второй строке файла необходимо указать путь до драйвера на тестовой машине (например, на VmWare) так, как он указан в реестре данного сервиса. В третьей строке необходимо указать путь до файла на машине разработчика. Удобнее всего использовать путь до директории, в которой собирается chk-билд драйвера. Тогда каждый раз при загрузке драйвера будет загружена его новая версия.
</p>
<p align="justify">В отладчике процесс загрузки драйвера с машины разработчика на тестовую машину выглядит примерно так:</p>
<blockquote><p>kd> g<br />
KD: Accessing &#8216;C:\project_path\out \debug\driver32.sys&#8217; (\??\C:\1\driver32.sys)<br />
  File size 91K&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;.<br />
MmLoadSystemImage: Pulled \??\C:\1\driver32.sys from kd</p></blockquote>
<p align="justify">Удачной отладки!</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fsww-it.ru%2F2010-07-08%2F485&amp;title=%D0%98%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%20%D0%BC%D1%8D%D0%BF%D0%BF%D0%B8%D0%BD%D0%B3%D0%B0%20%D0%B4%D1%80%D0%B0%D0%B9%D0%B2%D0%B5%D1%80%D0%BE%D0%B2" id="wpa2a_4"><img src="http://sww-it.ru/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://sww-it.ru/2010-07-08/485/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Getting Started with the Windows Driver Development Environment</title>
		<link>http://sww-it.ru/2010-05-28/465?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=getting-started-with-the-windows-driver-development-environment</link>
		<comments>http://sww-it.ru/2010-05-28/465#comments</comments>
		<pubDate>Fri, 28 May 2010 12:13:30 +0000</pubDate>
		<dc:creator>SWW</dc:creator>
				<category><![CDATA[Без перевода]]></category>
		<category><![CDATA[build]]></category>
		<category><![CDATA[wdk]]></category>
		<category><![CDATA[драйвер]]></category>

		<guid isPermaLink="false">http://sww-it.ru/?p=465</guid>
		<description><![CDATA[<p>Getting started with Microsoft Windows device drivers can be difficult, even for experienced developers. This paper presents an overview of the debugging and testing tools that developers use to create a device driver for Windows operating systems. In particular, the paper examines ways to find and fix bugs early in development, to help you produce [...]]]></description>
			<content:encoded><![CDATA[<p><em>Getting started with Microsoft Windows device drivers can be difficult, even for experienced developers. This paper presents an overview of the debugging and testing tools that developers use to create a device driver for Windows operating systems. In particular, the paper examines ways to find and fix bugs early in development, to help you produce a high-quality device driver.</p>
<p>WDK MVP Don Burn shares his experience and insights about the hardware and software you need for driver development, how to get started with the WDK build environments and Build utility, and tips, techniques, and tools for all phases of development.</em></p>
<p>Неплохая <a href="http://www.microsoft.com/whdc/driver/foundation/drvdev_intro.mspx">статья для начинающих</a>. Рекомендуется к просмотру.</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fsww-it.ru%2F2010-05-28%2F465&amp;title=Getting%20Started%20with%20the%20Windows%20Driver%20Development%20Environment" id="wpa2a_6"><img src="http://sww-it.ru/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://sww-it.ru/2010-05-28/465/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Функции уведомления и функции обратного вызова в Windows (ч.1, Ps*)</title>
		<link>http://sww-it.ru/2010-02-21/362?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=%25d1%2584%25d1%2583%25d0%25bd%25d0%25ba%25d1%2586%25d0%25b8%25d0%25b8-%25d1%2583%25d0%25b2%25d0%25b5%25d0%25b4%25d0%25be%25d0%25bc%25d0%25bb%25d0%25b5%25d0%25bd%25d0%25b8%25d1%258f-%25d0%25b8-%25d1%2584%25d1%2583%25d0%25bd%25d0%25ba%25d1%2586%25d0%25b8%25d0%25b8-%25d0%25be%25d0%25b1%25d1%2580%25d0%25b0%25d1%2582%25d0%25bd</link>
		<comments>http://sww-it.ru/2010-02-21/362#comments</comments>
		<pubDate>Sun, 21 Feb 2010 11:35:19 +0000</pubDate>
		<dc:creator>SWW</dc:creator>
				<category><![CDATA[Программирование]]></category>
		<category><![CDATA[callback]]></category>
		<category><![CDATA[notify]]></category>
		<category><![CDATA[wdk]]></category>
		<category><![CDATA[драйвер]]></category>

		<guid isPermaLink="false">http://sww-it.ru/?p=362</guid>
		<description><![CDATA[<p style="text-align: justify;">В операционной системе Windows разработчиками было предусмотрено довольно много механизмов получения каких-либо уведомлений и событий. В некоторых случаях разработчик может влиять на возвращаемый результат, в некоторых – нет. В основном считается, что программист не может влиять на возвращаемый результат функций уведомления (notifications) и может влиять на возвращаемый результат функций обратного вызова (callbacks). Однако [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">В операционной системе Windows разработчиками было предусмотрено довольно много механизмов получения каких-либо уведомлений и событий. В некоторых случаях разработчик может влиять на возвращаемый результат, в некоторых – нет. В основном считается, что программист не может влиять на возвращаемый результат функций уведомления (notifications) и может влиять на возвращаемый результат функций обратного вызова (callbacks). Однако это совсем не означает, что функции уведомления вызываются асинхронно, поэтому необходимо обязательно возвращать управление из тех и из других.</p>
<p style="text-align: justify;">Предоставленные функции связаны с различными объектами операционной системы, такими как  процессы, потоки, файловые образы, объекты системного реестра и так далее.</p>
<p><span id="more-362"></span></p>
<h3 style="text-align: center;">PsSetLoadImageNotifyRoutine</h3>
<p style="text-align: justify;"><span style="color: #0000ff;">PsSetLoadImageNotifyRoutine</span> регистрирует функцию уведомления, которая вызывается в момент загрузки образа или отображения образа в память.</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;">NTSTATUS
  PsSetLoadImageNotifyRoutine<span style="color: #009900;">&#40;</span>
    IN PLOAD_IMAGE_NOTIFY_ROUTINE  NotifyRoutine
    <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p style="text-align: justify;">Функция уведомления должна быть определена следующим образом:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;">VOID
<span style="color: #009900;">&#40;</span><span style="color: #339933;">*</span>PLOAD_IMAGE_NOTIFY_ROUTINE<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#40;</span>
    IN PUNICODE_STRING  FullImageName<span style="color: #339933;">,</span>
    IN HANDLE  ProcessId<span style="color: #339933;">,</span>
    IN PIMAGE_INFO  ImageInfo
    <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p style="text-align: justify;">После регистрации данной функции она будет вызываться операционной системой после отображения в память исполняемого образа в пространстве ядра или в пользовательском пространстве, до начала исполнения образа. Данная функция вызывается, в том числе и в момент загрузки DLL в пользовательском пространстве.</p>
<p style="text-align: justify;">В момент загрузки основного исполняемого образа в память нового процесса данная функция уведомления вызывается в контексте создаваемого процесса.</p>
<p style="text-align: justify;">Пример регистрации функции уведомления:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;">NTSTATUS SetLoadImageNotifyRoutine<span style="color: #009900;">&#40;</span>IN PLOAD_IMAGE_NOTIFY_ROUTINE Routine<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	PAGED_CODE<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #339933;">!</span>Routine <span style="color: #009900;">&#41;</span>
		<span style="color: #b1b100;">return</span> STATUS_INVALID_PARAMETER<span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #b1b100;">return</span> PsSetLoadImageNotifyRoutine<span style="color: #009900;">&#40;</span> Routine <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
VOID LoadImageNotifyRoutine<span style="color: #009900;">&#40;</span>IN PUNICODE_STRING FullImageName<span style="color: #339933;">,</span> IN HANDLE ProcessId<span style="color: #339933;">,</span> IN PIMAGE_INFO ImageInfo<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	PAGED_CODE<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	KdPrint<span style="color: #009900;">&#40;</span> <span style="color: #009900;">&#40;</span> <span style="color: #ff0000;">&quot;LoadImageNotifyRoutine called with FullImageName = %wZ, ProcessId = 0x%08X<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span> FullImageName<span style="color: #339933;">,</span> ProcessId <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p style="text-align: justify;">Из переменной <span style="color: #0000ff;">ImageInfo</span> можно получить дополнительную информацию. Причем для систем Windows Vista и выше данная структура содержит больше информации, чем для предыдущих версий ОС (см. WDK Help).</p>
<p style="text-align: justify;">Операционная система содержит список (массив) функций уведомления. Например, для Windows XP/2003 – это глобальный массив <span style="color: #0000ff;">PspLoadImageNotifyRoutine</span>. Вызов каждой зарегистрированной процедуры происходит последовательно в функции <span style="color: #0000ff;">PsCallImageNotifyRoutines</span>.</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;">NTSTATUS
MmLoadSystemImage <span style="color: #009900;">&#40;</span>
    IN PUNICODE_STRING ImageFileName<span style="color: #339933;">,</span>
    IN PUNICODE_STRING NamePrefix OPTIONAL<span style="color: #339933;">,</span>
    IN PUNICODE_STRING LoadedBaseName OPTIONAL<span style="color: #339933;">,</span>
    IN ULONG LoadFlags<span style="color: #339933;">,</span>
    OUT PVOID <span style="color: #339933;">*</span>ImageHandle<span style="color: #339933;">,</span>
    OUT PVOID <span style="color: #339933;">*</span>ImageBaseAddress
    <span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
…
&nbsp;
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>PsImageNotifyEnabled<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            IMAGE_INFO ImageInfo<span style="color: #339933;">;</span>
&nbsp;
            ImageInfo.<span style="color: #202020;">Properties</span> <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
            ImageInfo.<span style="color: #202020;">ImageAddressingMode</span> <span style="color: #339933;">=</span> IMAGE_ADDRESSING_MODE_32BIT<span style="color: #339933;">;</span>
            ImageInfo.<span style="color: #202020;">SystemModeImage</span> <span style="color: #339933;">=</span> TRUE<span style="color: #339933;">;</span>
            ImageInfo.<span style="color: #202020;">ImageSize</span> <span style="color: #339933;">=</span> DataTableEntry<span style="color: #339933;">-&gt;</span>SizeOfImage<span style="color: #339933;">;</span>
            ImageInfo.<span style="color: #202020;">ImageBase</span> <span style="color: #339933;">=</span> <span style="color: #339933;">*</span>ImageBaseAddress<span style="color: #339933;">;</span>
            ImageInfo.<span style="color: #202020;">ImageSelector</span> <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
            ImageInfo.<span style="color: #202020;">ImageSectionNumber</span> <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
&nbsp;
            PsCallImageNotifyRoutines<span style="color: #009900;">&#40;</span>ImageFileName<span style="color: #339933;">,</span> <span style="color: #009900;">&#40;</span>HANDLE<span style="color: #009900;">&#41;</span>NULL<span style="color: #339933;">,</span> <span style="color: #339933;">&amp;</span>ImageInfo<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
…
<span style="color: #009900;">&#125;</span>
&nbsp;
PsCallImageNotifyRoutines<span style="color: #009900;">&#40;</span>
    IN PUNICODE_STRING FullImageName<span style="color: #339933;">,</span>
    IN HANDLE ProcessId<span style="color: #339933;">,</span>
    IN PIMAGE_INFO ImageInfo
    <span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    ULONG i<span style="color: #339933;">;</span>
    PEX_CALLBACK_ROUTINE_BLOCK CallBack<span style="color: #339933;">;</span>
    PLOAD_IMAGE_NOTIFY_ROUTINE Rtn<span style="color: #339933;">;</span>
&nbsp;
    PAGED_CODE<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>PsImageNotifyEnabled<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> 
        <span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span>i<span style="color: #339933;">=</span><span style="color: #0000dd;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> PSP_MAX_LOAD_IMAGE_NOTIFY<span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            CallBack <span style="color: #339933;">=</span> ExReferenceCallBackBlock <span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>PspLoadImageNotifyRoutine<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>CallBack <span style="color: #339933;">!=</span> NULL<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                Rtn <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>PLOAD_IMAGE_NOTIFY_ROUTINE<span style="color: #009900;">&#41;</span> ExGetCallBackBlockRoutine <span style="color: #009900;">&#40;</span>CallBack<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                Rtn <span style="color: #009900;">&#40;</span>FullImageName<span style="color: #339933;">,</span>
                     ProcessId<span style="color: #339933;">,</span>
                     ImageInfo<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                ExDereferenceCallBackBlock <span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>PspLoadImageNotifyRoutine<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> CallBack<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p style="text-align: justify;">Удалить функцию уведомления можно с помощью вызова <span style="color: #0000ff;">PsRemoveLoadImageNotifyRoutine</span>, передав указатель на зарегистрированный обработчик.</p>
<h3 style="text-align: center;">PsSetCreateProcessNotifyRoutine и PsSetCreateProcessNotifyRoutineEx</h3>
<p style="text-align: justify;"><span style="color: #0000ff;">PsSetCreateProcessNotifyRoutine</span> и <span style="color: #0000ff;">PsSetCreateProcessNotifyRoutineEx</span> позволяют зарегистрировать функцию уведомления на создание и завершение процессов в системе. Последняя из перечисленных функций присутствует только начиная с Windows Vista SP1 и предоставляет больше информации и более удобный интерфейс для использования.</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;">NTSTATUS
  PsSetCreateProcessNotifyRoutine<span style="color: #009900;">&#40;</span>
    IN PCREATE_PROCESS_NOTIFY_ROUTINE  NotifyRoutine<span style="color: #339933;">,</span>
    IN BOOLEAN  Remove
    <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
NTSTATUS
  PsSetCreateProcessNotifyRoutineEx<span style="color: #009900;">&#40;</span>
    IN PCREATE_PROCESS_NOTIFY_ROUTINE_EX  NotifyRoutine<span style="color: #339933;">,</span>
    IN BOOLEAN  Remove
    <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p style="text-align: justify;">В отличие от <span style="color: #0000ff;">PsSetLoadImageNotifyRoutine</span> для удаления обработчика не нужно вызывать другую функцию, достаточно вызвать ту же самую с параметром <span style="color: #0000ff;">Remove</span> равным TRUE.</p>
<p style="text-align: justify;">Обработчики должны быть определены следующим образом:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;">VOID
<span style="color: #009900;">&#40;</span><span style="color: #339933;">*</span>PCREATE_PROCESS_NOTIFY_ROUTINE<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#40;</span>
    IN HANDLE  ParentId<span style="color: #339933;">,</span>
    IN HANDLE  ProcessId<span style="color: #339933;">,</span>
    IN BOOLEAN  Create
    <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
VOID
  CreateProcessNotifyEx<span style="color: #009900;">&#40;</span>
    __inout PEPROCESS  Process<span style="color: #339933;">,</span>
    __in HANDLE  ProcessId<span style="color: #339933;">,</span>
    __in_opt PPS_CREATE_NOTIFY_INFO  CreateInfo
    <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p style="text-align: justify;">Структура с дополнительной информацией:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">typedef</span> <span style="color: #993333;">struct</span> _PS_CREATE_NOTIFY_INFO <span style="color: #009900;">&#123;</span>
  __in SIZE_T  Size<span style="color: #339933;">;</span>
  <span style="color: #993333;">union</span> <span style="color: #009900;">&#123;</span>
    __in ULONG  Flags<span style="color: #339933;">;</span>
    <span style="color: #993333;">struct</span> <span style="color: #009900;">&#123;</span>
      __in ULONG  FileOpenNameAvailable <span style="color: #339933;">:</span> <span style="color: #0000dd;">1</span><span style="color: #339933;">;</span>
      __in ULONG  Reserved <span style="color: #339933;">:</span> <span style="color: #0000dd;">31</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
  __in HANDLE  ParentProcessId<span style="color: #339933;">;</span>
  __in CLIENT_ID  CreatingThreadId<span style="color: #339933;">;</span>
  __inout <span style="color: #993333;">struct</span> _FILE_OBJECT  <span style="color: #339933;">*</span>FileObject<span style="color: #339933;">;</span>
  __in PCUNICODE_STRING  ImageFileName<span style="color: #339933;">;</span>
  __in_opt PCUNICODE_STRING  CommandLine<span style="color: #339933;">;</span>
  __inout NTSTATUS  CreationStatus<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span> PS_CREATE_NOTIFY_INFO<span style="color: #339933;">,</span> <span style="color: #339933;">*</span>PPS_CREATE_NOTIFY_INFO<span style="color: #339933;">;</span></pre></div></div>

<p style="text-align: justify;">После регистрации функции уведомления операционная система вызывает зарегистрированный обработчик  в двух случаях: когда процесс создается и когда процесс завершается. В случае создания процесса функция уведомления вызывается после того как создан начальный поток, но исполнение его еще не началось. В случае завершения процесса операционная система вызывает функцию уведомления, перед тем как последний поток в процессе завершится. В обработчике, зарегистрированном с помощью <span style="color: #0000ff;">PsSetCreateProcessNotifyRoutineEx</span>, можно влиять на результат создания процесса. Для этого необходимо использовать член <span style="color: #0000ff;">CreationStatus</span> структуры <span style="color: #0000ff;">PS_CREATE_NOTIFY_INFO</span>.</p>
<p style="text-align: justify;">В момент создания нового процесса функция уведомления вызывается в контексте потока, который инициировал создание этого процесса. В момент уничтожения процесса функция уведомления вызывается в контексте последнего потока завершаемого процесса.</p>
<p style="text-align: justify;">Пример регистрации функции уведомления:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">typedef</span> NTSTATUS <span style="color: #009900;">&#40;</span>NTAPI<span style="color: #339933;">*</span> PSSETCREATEPROCESSNOTIFYROUTINEEX_PROC<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span>
	IN PCREATE_PROCESS_NOTIFY_ROUTINE_EX NotifyRoutine<span style="color: #339933;">,</span>
	IN BOOLEAN Remove
	<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
NTSTATUS SetCreateProcessNotifyRoutine<span style="color: #009900;">&#40;</span>VOID<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	NTSTATUS                               status<span style="color: #339933;">;</span>
	UNICODE_STRING                         szCreateProcessEx <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
	PSSETCREATEPROCESSNOTIFYROUTINEEX_PROC pCreateProcessEx  <span style="color: #339933;">=</span> NULL<span style="color: #339933;">;</span>
&nbsp;
	PAGED_CODE<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	RtlInitUnicodeString<span style="color: #009900;">&#40;</span> <span style="color: #339933;">&amp;</span>szCreateProcessEx<span style="color: #339933;">,</span> L<span style="color: #ff0000;">&quot;PsSetCreateProcessNotifyRoutineEx&quot;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	pCreateProcessEx <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>PSSETCREATEPROCESSNOTIFYROUTINEEX_PROC <span style="color: #009900;">&#41;</span>MmGetSystemRoutineAddress<span style="color: #009900;">&#40;</span> <span style="color: #339933;">&amp;</span>szCreateProcessEx <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> pCreateProcessEx <span style="color: #009900;">&#41;</span>
	<span style="color: #009900;">&#123;</span>
		status <span style="color: #339933;">=</span> pCreateProcessEx<span style="color: #009900;">&#40;</span> CreateProcessNotifyRoutineEx<span style="color: #339933;">,</span> FALSE <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
	<span style="color: #b1b100;">else</span>
	<span style="color: #009900;">&#123;</span>
		status <span style="color: #339933;">=</span> PsSetCreateProcessNotifyRoutine<span style="color: #009900;">&#40;</span> CreateProcessNotifyRoutine<span style="color: #339933;">,</span> FALSE <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #b1b100;">return</span> status<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
VOID CreateProcessNotifyRoutine<span style="color: #009900;">&#40;</span>IN HANDLE ParentId<span style="color: #339933;">,</span> IN HANDLE ProcessId<span style="color: #339933;">,</span> IN BOOLEAN Create<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	PAGED_CODE<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	KdPrint<span style="color: #009900;">&#40;</span> <span style="color: #009900;">&#40;</span> <span style="color: #ff0000;">&quot;CreateProcessNotifyRoutine called with ParentId = 0x%08X, ProcessId = 0x%08X, Create = %d<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span> ParentId<span style="color: #339933;">,</span> ProcessId<span style="color: #339933;">,</span> Create <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
VOID CreateProcessNotifyRoutineEx<span style="color: #009900;">&#40;</span>__inout PEPROCESS Process<span style="color: #339933;">,</span> __in HANDLE ProcessId<span style="color: #339933;">,</span> __in_opt PPS_CREATE_NOTIFY_INFO CreateInfo<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	PAGED_CODE<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	KdPrint<span style="color: #009900;">&#40;</span> <span style="color: #009900;">&#40;</span> <span style="color: #ff0000;">&quot;CreateProcessNotifyRoutineEx called with Process = 0x%08X, ProcessId = 0x%08X<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span> Process<span style="color: #339933;">,</span> ProcessId <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p style="text-align: justify;">Как и в случае с <span style="color: #0000ff;">PsLoadImageNotifyRoutine</span> операционная система содержит список (массив) функций уведомления в глобальной переменной <span style="color: #0000ff;">PspCreateProcessNotifyRoutine</span> (Windows XP/2003). Вызов каждой зарегистрированной функции происходит из системных функций <span style="color: #0000ff;">PspCreateThread</span> и <span style="color: #0000ff;">PspExitProcess</span>.</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;">VOID
PspExitProcess<span style="color: #009900;">&#40;</span>
    IN BOOLEAN LastThreadExit<span style="color: #339933;">,</span>
    IN PEPROCESS Process
    <span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
&nbsp;
…
&nbsp;
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>LastThreadExit<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
…
&nbsp;
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>PspCreateProcessNotifyRoutineCount <span style="color: #339933;">!=</span> <span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            ULONG i<span style="color: #339933;">;</span>
            PEX_CALLBACK_ROUTINE_BLOCK CallBack<span style="color: #339933;">;</span>
            PCREATE_PROCESS_NOTIFY_ROUTINE Rtn<span style="color: #339933;">;</span>
&nbsp;
            <span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span>i <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> PSP_MAX_CREATE_PROCESS_NOTIFY<span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                CallBack <span style="color: #339933;">=</span> ExReferenceCallBackBlock <span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>PspCreateProcessNotifyRoutine<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>CallBack <span style="color: #339933;">!=</span> NULL<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                    Rtn <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>PCREATE_PROCESS_NOTIFY_ROUTINE<span style="color: #009900;">&#41;</span> ExGetCallBackBlockRoutine <span style="color: #009900;">&#40;</span>CallBack<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                    Rtn <span style="color: #009900;">&#40;</span>Process<span style="color: #339933;">-&gt;</span>InheritedFromUniqueProcessId<span style="color: #339933;">,</span>
                         Process<span style="color: #339933;">-&gt;</span>UniqueProcessId<span style="color: #339933;">,</span>
                         FALSE<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                    ExDereferenceCallBackBlock <span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>PspCreateProcessNotifyRoutine<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
                                                CallBack<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                <span style="color: #009900;">&#125;</span>
            <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
…
&nbsp;
<span style="color: #009900;">&#125;</span></pre></div></div>

<h3 style="text-align: center;">PsSetCreateThreadNotifyRoutine</h3>
<p style="text-align: justify;"><span style="color: #0000ff;">PsSetCreateThreadNotifyRoutine</span> регистрирует функцию уведомления, которая вызывается в момент создания и уничтожения потока.</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;">NTSTATUS
  PsSetCreateThreadNotifyRoutine<span style="color: #009900;">&#40;</span>
    IN PCREATE_THREAD_NOTIFY_ROUTINE  NotifyRoutine
    <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p style="text-align: justify;">Функция уведомления должна быть определена следующим образом:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;">VOID
<span style="color: #009900;">&#40;</span><span style="color: #339933;">*</span>PCREATE_THREAD_NOTIFY_ROUTINE<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#40;</span>
    IN HANDLE  ProcessId<span style="color: #339933;">,</span>
    IN HANDLE  ThreadId<span style="color: #339933;">,</span>
    IN BOOLEAN  Create
    <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p style="text-align: justify;">Для удаления обработчика необходимо использовать функцию <span style="color: #0000ff;">PsRemoveCreateThreadNotifyRoutine</span>.</p>
<p style="text-align: justify;">В момент создания нового потока функция уведомления вызывается в контексте потока, который инициировал его создание. В момент уничтожения потока функция уведомления вызывается в контексте завершаемого потока.</p>
<p style="text-align: justify;">Пример регистрации функции уведомления:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;">NTSTATUS SetCreateThreadNotifyRoutine<span style="color: #009900;">&#40;</span>IN PCREATE_THREAD_NOTIFY_ROUTINE NotifyRoutine<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	PAGED_CODE<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #339933;">!</span>NotifyRoutine <span style="color: #009900;">&#41;</span>
		<span style="color: #b1b100;">return</span> STATUS_INVALID_PARAMETER<span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #b1b100;">return</span> PsSetCreateThreadNotifyRoutine<span style="color: #009900;">&#40;</span> NotifyRoutine <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
VOID CreateThreadNotifyRoutine<span style="color: #009900;">&#40;</span>IN HANDLE ProcessId<span style="color: #339933;">,</span> IN HANDLE ThreadId<span style="color: #339933;">,</span> IN BOOLEAN Create<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	PAGED_CODE<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	KdPrint<span style="color: #009900;">&#40;</span> <span style="color: #009900;">&#40;</span> <span style="color: #ff0000;">&quot;CreateThreadNotifyRoutine called with ProcessId = 0x%08X, ThreadId = 0x%08X, Create = %d<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span> ProcessId<span style="color: #339933;">,</span> ThreadId<span style="color: #339933;">,</span> Create <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p style="text-align: justify;">Как и во всех вышеперечисленных функциях, операционная система хранит список (массив) функций уведомления в глобальной переменной <span style="color: #0000ff;">PspCreateThreadNotifyRoutine</span> (Windows XP/2003). Вызов каждой зарегистрированной функции происходит из функций <span style="color: #0000ff;">PspCreateThread</span> и <span style="color: #0000ff;">PspExitThread</span>.</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;">NTSTATUS
PspCreateThread<span style="color: #009900;">&#40;</span>
    OUT PHANDLE ThreadHandle<span style="color: #339933;">,</span>
    IN ACCESS_MASK DesiredAccess<span style="color: #339933;">,</span>
    IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL<span style="color: #339933;">,</span>
    IN HANDLE ProcessHandle<span style="color: #339933;">,</span>
    IN PEPROCESS ProcessPointer<span style="color: #339933;">,</span>
    OUT PCLIENT_ID ClientId OPTIONAL<span style="color: #339933;">,</span>
    IN PCONTEXT ThreadContext OPTIONAL<span style="color: #339933;">,</span>
    IN PINITIAL_TEB InitialTeb OPTIONAL<span style="color: #339933;">,</span>
    IN BOOLEAN CreateSuspended<span style="color: #339933;">,</span>
    IN PKSTART_ROUTINE StartRoutine OPTIONAL<span style="color: #339933;">,</span>
    IN PVOID StartContext
    <span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
&nbsp;
…
&nbsp;
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>PspCreateThreadNotifyRoutineCount <span style="color: #339933;">!=</span> <span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        ULONG i<span style="color: #339933;">;</span>
        PEX_CALLBACK_ROUTINE_BLOCK CallBack<span style="color: #339933;">;</span>
        PCREATE_THREAD_NOTIFY_ROUTINE Rtn<span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span>i <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> PSP_MAX_CREATE_THREAD_NOTIFY<span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            CallBack <span style="color: #339933;">=</span> ExReferenceCallBackBlock <span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>PspCreateThreadNotifyRoutine<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>CallBack <span style="color: #339933;">!=</span> NULL<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                Rtn <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>PCREATE_THREAD_NOTIFY_ROUTINE<span style="color: #009900;">&#41;</span> ExGetCallBackBlockRoutine <span style="color: #009900;">&#40;</span>CallBack<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                Rtn <span style="color: #009900;">&#40;</span>Thread<span style="color: #339933;">-&gt;</span>Cid.<span style="color: #202020;">UniqueProcess</span><span style="color: #339933;">,</span>
                     Thread<span style="color: #339933;">-&gt;</span>Cid.<span style="color: #202020;">UniqueThread</span><span style="color: #339933;">,</span>
                     TRUE<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                ExDereferenceCallBackBlock <span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>PspCreateThreadNotifyRoutine<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
                                            CallBack<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
…
&nbsp;
<span style="color: #009900;">&#125;</span></pre></div></div>

<p style="text-align: justify;">На этом первая часть цикла о функциях уведомления и функциях обратного вызова закончена. Исходные тексты к статье можно <a href="http://sww-it.ru/wp-content/uploads/2010/cbtest.zip">скачать здесь</a>. После каждой новой главы я буду их обновлять.</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fsww-it.ru%2F2010-02-21%2F362&amp;title=%D0%A4%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%B8%20%D1%83%D0%B2%D0%B5%D0%B4%D0%BE%D0%BC%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F%20%D0%B8%20%D1%84%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%B8%20%D0%BE%D0%B1%D1%80%D0%B0%D1%82%D0%BD%D0%BE%D0%B3%D0%BE%20%D0%B2%D1%8B%D0%B7%D0%BE%D0%B2%D0%B0%20%D0%B2%20Windows%20%28%D1%87.1%2C%20Ps%2A%29" id="wpa2a_8"><img src="http://sww-it.ru/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://sww-it.ru/2010-02-21/362/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Грамотная документация</title>
		<link>http://sww-it.ru/2009-07-02/268?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=%25d0%25b3%25d1%2580%25d0%25b0%25d0%25bc%25d0%25be%25d1%2582%25d0%25bd%25d0%25b0%25d1%258f-%25d0%25b4%25d0%25be%25d0%25ba%25d1%2583%25d0%25bc%25d0%25b5%25d0%25bd%25d1%2582%25d0%25b0%25d1%2586%25d0%25b8%25d1%258f</link>
		<comments>http://sww-it.ru/2009-07-02/268#comments</comments>
		<pubDate>Thu, 02 Jul 2009 12:53:59 +0000</pubDate>
		<dc:creator>SWW</dc:creator>
				<category><![CDATA[Внутренности Windows]]></category>
		<category><![CDATA[ZwNotifyChangeKey]]></category>
		<category><![CDATA[драйвер]]></category>

		<guid isPermaLink="false">http://sww-it.ru/?p=268</guid>
		<description><![CDATA[<p style="text-align: justify;">Грамотная документация &#8212; залог здоровья и спокойствия программиста. Причем начинающего программиста, так как эксперт проблему решит намного быстрее. Да и не впервой ему &#8212; эксперту сталкиваться с плохой документацией, с программным кодом без комментариев и прочими неприятными вещами.</p> <p style="text-align: justify;">Одной из самых объемных и важных документаций для программистов является MSDN (Microsoft Developer [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Грамотная документация &#8212; залог здоровья и спокойствия программиста. Причем начинающего программиста, так как эксперт проблему решит намного быстрее. Да и не впервой ему &#8212; эксперту сталкиваться с плохой документацией, с программным кодом без комментариев и прочими неприятными вещами.</p>
<p style="text-align: justify;">Одной из самых объемных и важных документаций для программистов является <a href="http://msdn.microsoft.com/">MSDN</a> (Microsoft Developer Network). Для низкоуровневых программистов и программистов драйверов существует отдельная документация WDK (Windows Driver Kit), входящая в состав MSDN. В MSDN перечислены функции, параметры к ним, объяснения, примеры кода и многое другое.</p>
<p style="text-align: justify;">Большая документация &#8212; сложный продукт. В любом сложном продукте есть недочеты, ошибки и недоработки. Встречаются они и в документации, ведь все мы люди, все мы ошибаемся. Недавно с такой ошибкой столкнулся и я.</p>
<p style="text-align: justify;">Операционная система Windows предоставляет специальную функцию, которая позволяет отслеживать различные изменения в системном реестре указанного ключа. Она есть как в пользовательском пространстве (<a href="http://msdn.microsoft.com/en-us/library/ms724892(VS.85).aspx">RegNotifyChangeKeyValue</a>), так и в пространстве ядра (<a href="http://msdn.microsoft.com/en-us/library/bb981785.aspx">ZwNotifyChangeKey</a>), там, где работает сама операционная система и драйверы. Этой функцией пользуются как антивирусные продукты, так и вредоносный код, который следит за изменениями своих вредоносных веток антивирусом (обычно это лечение веток реестра).</p>
<p><span id="more-268"></span></p>
<p style="text-align: justify;">Прототип функции ZwNotifyChangeKey выглядит так:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;">NTSTATUS
ZwNotifyChangeKey<span style="color: #009900;">&#40;</span>
  __in HANDLE  KeyHandle<span style="color: #339933;">,</span>
  __in_opt HANDLE  Event<span style="color: #339933;">,</span>
  __in_opt PIO_APC_ROUTINE  ApcRoutine<span style="color: #339933;">,</span>        <span style="color: #666666; font-style: italic;">// указатель на нашу функцию</span>
  __in_opt PVOID  ApcContext<span style="color: #339933;">,</span>
  __out PIO_STATUS_BLOCK  IoStatusBlock<span style="color: #339933;">,</span>
  __in ULONG  CompletionFilter<span style="color: #339933;">,</span>
  __in BOOLEAN  WatchTree<span style="color: #339933;">,</span>
  __out_bcount_opt<span style="color: #009900;">&#40;</span>BufferSize<span style="color: #009900;">&#41;</span> PVOID  Buffer<span style="color: #339933;">,</span>
  __in ULONG  BufferSize<span style="color: #339933;">,</span>
  __in BOOLEAN  Asynchronous
  <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p style="text-align: justify;">Через параметр KeyHandle необходимо передать дескриптор открытого ключа, изменения которого мы хотим отслеживать. Параметр ApcRoutine &#8212; это указатель на нами реализованную функцию, которая будет вызываться в случае изменений в указанной ветке реестра.</p>
<p style="text-align: justify;">Функция должна быть определена так:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">typedef</span> VOID <span style="color: #009900;">&#40;</span>NTAPI <span style="color: #339933;">*</span>PIO_APC_ROUTINE<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#40;</span> IN PVOID ApcContext<span style="color: #339933;">,</span> IN PIO_STATUS_BLOCK IoStatusBlock<span style="color: #339933;">,</span> IN ULONG Reserved <span style="color: #009900;">&#41;</span></pre></div></div>

<p style="text-align: justify;">Не суть важно, что тут за параметры, главное &#8212; то, что у функции три аргумента. Это важно.</p>
<p style="text-align: justify;">В одном из драйверов мне понадобилась эта функция. Я написал весь сопутствующий код, использовал функцию, скомпилировал драйвер, положил в нужное место и запустил. Система упала в BSOD. &#8216;Не в первый и не в последний раз&#8217;, &#8212; подумал я и начал проверять параметры функции. Все было идеально, все было правильно, а BSOD повторялся каждый раз.</p>
<p style="text-align: justify;">Google не смог мне помочь с данной проблемой и пришлось разбираться самому. Потратив некоторое количество часов, я выяснил, что в недрах операционной системы при определенных обстоятельствах указатель PIO_APC_ROUTINE  трактуется совершенно по-другому, как указатель на структуру WORK_QUEUE_ITEM, в которой содержится указатель на нами определенную функцию. И этого не было в документации, эту информацию я даже не смог найти в сети.</p>
<p style="text-align: justify;">Структура выглядит следующим образом:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">typedef</span> <span style="color: #993333;">struct</span> _WORK_QUEUE_ITEM <span style="color: #009900;">&#123;</span>
    LIST_ENTRY List<span style="color: #339933;">;</span>
    PWORKER_THREAD_ROUTINE WorkerRoutine<span style="color: #339933;">;</span>        <span style="color: #666666; font-style: italic;">// указатель на нашу функцию</span>
    __volatile PVOID Parameter<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span> WORK_QUEUE_ITEM<span style="color: #339933;">,</span> <span style="color: #339933;">*</span>PWORK_QUEUE_ITEM<span style="color: #339933;">;</span></pre></div></div>

<p style="text-align: justify;">Функция должна быть определена так:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">typedef</span> VOID <span style="color: #009900;">&#40;</span><span style="color: #339933;">*</span>PWORKER_THREAD_ROUTINE<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span> IN PVOID Parameter <span style="color: #009900;">&#41;</span></pre></div></div>

<p style="text-align: justify;">И она принимает всего один параметр. И это важно.</p>
<p style="text-align: justify;">Довольно быстро я переписал код, и драйвер перестал рушить операционную систему. Сразу после этого я написал письмо в компанию Microsoft где указал им на это досадное упущение с их стороны. Примерно через три часа (около четырех часов утра) я получил от них ответ, в котором они обещали исправить документацию в ближайшее время (в конце месяца).</p>
<p style="text-align: justify;">Ошибки бывают разные, но ошибки в документации дорогого стоят. До следующих ошибок, а они обязательно будут.</p>
<p><a href="http://www.securelist.com/ru/weblog/35135/Gramotnaya_dokumentatsiya">Оригинал</a></p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fsww-it.ru%2F2009-07-02%2F268&amp;title=%D0%93%D1%80%D0%B0%D0%BC%D0%BE%D1%82%D0%BD%D0%B0%D1%8F%20%D0%B4%D0%BE%D0%BA%D1%83%D0%BC%D0%B5%D0%BD%D1%82%D0%B0%D1%86%D0%B8%D1%8F" id="wpa2a_10"><img src="http://sww-it.ru/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://sww-it.ru/2009-07-02/268/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Ребутни меня жестко</title>
		<link>http://sww-it.ru/2009-03-17/76?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=%25d1%2580%25d0%25b5%25d0%25b1%25d1%2583%25d1%2582%25d0%25bd%25d0%25b8-%25d0%25bc%25d0%25b5%25d0%25bd%25d1%258f-%25d0%25b6%25d0%25b5%25d1%2581%25d1%2582%25d0%25ba%25d0%25be</link>
		<comments>http://sww-it.ru/2009-03-17/76#comments</comments>
		<pubDate>Tue, 17 Mar 2009 09:45:26 +0000</pubDate>
		<dc:creator>SWW</dc:creator>
				<category><![CDATA[Программирование]]></category>
		<category><![CDATA[reboot]]></category>
		<category><![CDATA[драйвер]]></category>

		<guid isPermaLink="false">http://sww-it.ru/?p=76</guid>
		<description><![CDATA[<p style="text-align: justify">В некоторых ситуациях возникает потребность перезагрузить операционную систему прямо из ядра. Когда-то давно я был озадачен такой проблемой, так как существующие способы меня не устраивали по разным причинам. Пришлось копать, искать и спрашивать. В результате были найдены следующие варианты.</p> <p style="text-align: justify"></p> <p style="text-align: justify">В режиме пользователя можно использовать функцию ExitWindowsEx (она ведет [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify">В некоторых ситуациях возникает потребность перезагрузить операционную систему прямо из ядра. Когда-то давно я был озадачен такой проблемой, так как существующие способы меня не устраивали по разным причинам. Пришлось копать, искать и спрашивать. В результате были найдены следующие варианты.</p>
<p style="text-align: justify"><span id="more-76"></span></p>
<p style="text-align: justify">В режиме пользователя можно использовать функцию <strong>ExitWindowsEx</strong> (она ведет в <strong>NtShutdownSystem</strong>):</p>
<p>
<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;">BOOL WINAPI ExitWindowsEx<span style="color: #009900;">&#40;</span>
                                       __in UINT    uFlags<span style="color: #339933;">,</span>
                                       __in DWORD dwReason
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

</p>
<p>Все достаточно подробно <a href="http://msdn.microsoft.com/en-us/library/aa376868(VS.85).aspx" target="_blank">описано</a> в MSDN и, конечно, не забываем про включенную <strong>Shutdown</strong> привилегию.</p>
<p>Давайте рассмотрим варианты, которые нам доступны из режима ядра. Один из них &#8212; это использование функции <strong>NtShutdownSystem</strong>. Конечно, она недокументированная. Реализация для Windows XP выглядит так (вот такой забавный switch, видимо из-за оптимизаций):</p>
<p>
<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;">NTSTATUS __stdcall NtShutdownSystem<span style="color: #009900;">&#40;</span>SHUTDOWN_ACTION Action<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
        POWER_ACTION SystemAction<span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> Action <span style="color: #009900;">&#41;</span>
        <span style="color: #009900;">&#123;</span>
                <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> Action <span style="color: #339933;">==</span> <span style="color: #0000dd;">1</span> <span style="color: #009900;">&#41;</span> <span style="color: #666666; font-style: italic;">// ShutdownReboot</span>
                <span style="color: #009900;">&#123;</span>
                        SystemAction <span style="color: #339933;">=</span> <span style="color: #0000dd;">5</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// PowerActionShutdownReset</span>
                <span style="color: #009900;">&#125;</span>
                <span style="color: #b1b100;">else</span> <span style="color: #666666; font-style: italic;">// ShutdownPowerOff</span>
                <span style="color: #009900;">&#123;</span>
                        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> Action <span style="color: #339933;">!=</span> <span style="color: #0000dd;">2</span> <span style="color: #009900;">&#41;</span>
                                <span style="color: #b1b100;">return</span> STATUS_INVALID_PARAMETER<span style="color: #339933;">;</span>
                        SystemAction <span style="color: #339933;">=</span> <span style="color: #0000dd;">6</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// PowerActionShutdownOff</span>
                <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #b1b100;">else</span> <span style="color: #666666; font-style: italic;">// ShutdownNoReboot</span>
        <span style="color: #009900;">&#123;</span>
                SystemAction <span style="color: #339933;">=</span> <span style="color: #0000dd;">4</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// PowerActionShutdown</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #b1b100;">return</span> NtSetSystemPowerState<span style="color: #009900;">&#40;</span>SystemAction<span style="color: #339933;">,</span> PowerSystemSleeping3<span style="color: #339933;">,</span> 0xC0000004u<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

</p>
<p>
<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">typedef</span> <span style="color: #000000; font-weight: bold;">enum</span> _POWER_ACTION <span style="color: #009900;">&#123;</span>
        PowerActionNone            <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">,</span>
        PowerActionReserved<span style="color: #339933;">,</span>
        PowerActionSleep<span style="color: #339933;">,</span>
        PowerActionHibernate<span style="color: #339933;">,</span>
        PowerActionShutdown<span style="color: #339933;">,</span>
        PowerActionShutdownReset<span style="color: #339933;">,</span>
        PowerActionShutdownOff<span style="color: #339933;">,</span>
        PowerActionWarmEject
<span style="color: #009900;">&#125;</span> POWER_ACTION<span style="color: #339933;">,</span> <span style="color: #339933;">*</span>PPOWER_ACTION<span style="color: #339933;">;</span></pre></div></div>

</p>
<p>Вышеуказанные функции нужно использовать тогда, когда вам необходимо все сделать красиво и чисто.</p>
<p>Следующий вариант &#8212; это использовать функцию <strong>HalReturnToFirmware</strong>. Она также <a href="http://msdn.microsoft.com/en-us/library/bb510367.aspx" target="_blank">описана</a> в MSDN.</p>
<p>VOID <strong>HalReturnToFirmware</strong>(IN FIRMWARE_REENTRY  <span style="color: #0000ff;">Routine</span>);</p>
<p>На вход функция может принимать параметр <strong>HalRebootRoutine</strong>, что нам собственно и нужно. Честно говоря, меня смущает то, что написано в MSDN:</p>
<p style="text-align: justify"><em>Requirements</em></p>
<p style="text-align: justify"><em>Versions: Available in Microsoft Windows Server 2003 and Windows XP.</em></p>
<p><em> DLL: Requires Hal.dll.</em></p>
<p style="text-align: justify">Под рукой у меня нет Hal.dll от Windows 2000, так что проверить экспортируется ли она или нет, я не могу, а память меня подводит.</p>
<p>Третий вариант &#8212; это спровоцировать BSOD. Шучу, шучу, но близко к правде. Вызовем <strong>KeBugcheckEx</strong> с параметром <strong>POWER_FAILURE_SIMULATE</strong>. <strong>KeBugcheckEx</strong> &#8212; это обыкновенная обертка над <strong>KeBugcheck2</strong>:</p>
<p>
<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">int</span> __stdcall KeBugCheck2<span style="color: #009900;">&#40;</span><span style="color: #993333;">int</span> BugCheckCode<span style="color: #339933;">,</span> <span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
&nbsp;
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> BugCheckCode <span style="color: #339933;">==</span> POWER_FAILURE_SIMULATE <span style="color: #009900;">&#41;</span>
        <span style="color: #009900;">&#123;</span>
                KiScanBugCheckCallbackList<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                HalReturnToFirmware<span style="color: #009900;">&#40;</span><span style="color: #0000dd;">3</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// HalRebootRoutine</span>
        <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

</p>
<p>Знакомая картина, но помнится мне, что на каких-то системах вместо перезагрузки я получал самый натуральный BSOD с <strong>POWER_FAILURE_SIMULATE</strong>. Однако поехали дальше.</p>
<p>Мне, как любителю минимализма хотелось чего-нибудь быстрого, без проверок. Хоп и готово. Не знаю, что может быть быстрее этого:</p>
<pre>WRITE_PORT_UCHAR( (PUCHAR )0x64, 0xFE ); // пишем RESET
                                         // в контроллер клавиатуры</pre>
<p>При таких перезагрузках не забывайте предупреждать ваших пользователей о том, чтобы они сохранили свои документы.</p>
<p>Кто какие способы знает еще?</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fsww-it.ru%2F2009-03-17%2F76&amp;title=%D0%A0%D0%B5%D0%B1%D1%83%D1%82%D0%BD%D0%B8%20%D0%BC%D0%B5%D0%BD%D1%8F%20%D0%B6%D0%B5%D1%81%D1%82%D0%BA%D0%BE" id="wpa2a_12"><img src="http://sww-it.ru/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://sww-it.ru/2009-03-17/76/feed</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Супер BUILD</title>
		<link>http://sww-it.ru/2009-02-22/11?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=%25d1%2581%25d1%2583%25d0%25bf%25d0%25b5%25d1%2580-build</link>
		<comments>http://sww-it.ru/2009-02-22/11#comments</comments>
		<pubDate>Sun, 22 Feb 2009 14:04:45 +0000</pubDate>
		<dc:creator>SWW</dc:creator>
				<category><![CDATA[Программирование]]></category>
		<category><![CDATA[build]]></category>
		<category><![CDATA[wdk]]></category>
		<category><![CDATA[драйвер]]></category>

		<guid isPermaLink="false">http://sww-it.ru/?p=11</guid>
		<description><![CDATA[<p>Рано или поздно драйверописатель сталкивается с необходимостью использовать в своем проекте чужой код. Обычно, для сборки драйвера используется утилита BUILD, идущая в поставке WDK. Буквально недавно я столкнулся с очевидной проблемой данного инструмента:</p> <p>С:\path1\path2\path3&#62;build -g BUILD: Compile and Link for x86 BUILD: Loading c:\winddk\6001\build.dat&#8230; BUILD: Computing Include file dependencies: BUILD: Start time: Fri Feb 06 [...]]]></description>
			<content:encoded><![CDATA[<p>Рано или поздно драйверописатель сталкивается с необходимостью использовать в своем проекте чужой код. Обычно, для сборки драйвера используется утилита <strong>BUILD</strong>, идущая в поставке WDK. Буквально недавно я столкнулся с очевидной проблемой данного инструмента:</p>
<p>С:\path1\path2\path3&gt;<span style="color: #3366ff;">build -g</span><br />
<span style="color: #339966;">BUILD: Compile and Link for x86<br />
BUILD: Loading c:\winddk\6001\build.dat&#8230;<br />
BUILD: Computing Include file dependencies:<br />
BUILD: Start time: Fri Feb 06 15:50:51 2009</span><br />
<span style="color: #ff0000;">errors in directory С:\path1\path2\path3</span></p>
<p><span style="color: #ff0000;">Ignoring invalid directory prefix in SOURCES= entry: D:\somepath1\somepath2\somepath3\somepath4\somepath5\file.c</span></p>
<p><span style="color: #ff0000;"><span id="more-11"></span><span style="color: #000000;">Поиск в гугле вывел меня на <a href="http://www.osronline.com/showThread.cfm?link=59562" target="_blank">ветку</a> форума OSR Online:</span></span></p>
<blockquote><p><span style="color: #000000;">&#171;Welcome to the wonderful world of BUILD. It can only deal with source code in the same or parent directory of the &#171;sources&#187; file. It cannot use source files from arbitrary locations.&#187;</span></p></blockquote>
<p><span style="color: #000000;"> Таким образом, подключить в свой проект чужие исходные коды по произвольному пути не получится. Выходов из сложившейся ситуации я вижу два:</span></p>
<ol>
<li><span style="color: #000000;">Чужой код должен быть реализован в виде статической библиотеки. У этого способа есть как очевидные плюсы, так и очевидные минусы. Одним из минусов я считаю то, что разработчику, который пишет код для вас, придется часто собирать эту самую библиотеку или это должна делать build-машина.</span></li>
<li>Использовать преимущества современных <a href="http://ru.wikipedia.org/wiki/Система_управления_версиями" target="_blank">систем управления версиями</a>. Проблема решается выкачиванием нужного проекта в директорию, которая доступна инструменту <strong>BUILD</strong>. Свою проблему я решил именно так. Конечно, не стоит забывать и о синхронизации выкаченных файлов.</li>
</ol>
<p>Иногда на форумах появляются вопросы, в которых люди спрашивают можно ли управлять инструментом <strong>BUILD</strong>. В MSDN есть отдельный раздел, посвященный этой утилите: <strong>Win32 and COM Development -&gt; Windows Driver Kit -&gt; Driver Development Tools -&gt; Tools for Building Drivers -&gt; Build</strong>. Подраздел <strong>Build Utility Macros</strong> самый интересный.</p>
<p><span style="color: #000000;"> </span></p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fsww-it.ru%2F2009-02-22%2F11&amp;title=%D0%A1%D1%83%D0%BF%D0%B5%D1%80%20BUILD" id="wpa2a_14"><img src="http://sww-it.ru/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://sww-it.ru/2009-02-22/11/feed</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
	</channel>
</rss>

