четверг, 13 декабря 2007 г.

Реинжект на FWPM_LAYER_INBOUND_IPPACKET_V4

В WFP есть одна маленькая хитрость для реинжекта входящих пакетов на сетевом уровне: необходимо что бы данные начинались с IP заголовка, а не сразу за ним как это происходит в буферах по дефолту.

Т.е. где то в коде (до или после клонирования) нужно вызвать NdisRetreatNetBufferDataStart на размер IP заголовка. Это будет выглядеть приблизительно следующим образом:

...
NdisRetreatNetBufferDataStart( pNetBuffer,
inMetaValues->ipHeaderSize, //размер IP заголовка
0, NULL );
...
FwpsAllocateCloneNetBufferList0(
pNetBufferList,
NULL,
NULL,
0,
&pClonedNetBufferList);

FwpsInjectNetworkReceiveAsync0( ... , pClonedNetBufferList, ... );

P.S. Как показала практика лучше делать NdisRetreatNetBufferDataStart до клонирования, иначе можно получить совсем не то что ожидается.

понедельник, 26 ноября 2007 г.

Плагины к Winamp

Нашел на диске свои плагины к Winamp, делал когда-то для удобства. Выложил на народе с сырцами.

SendTo (screenshot) - позволяет закидывать файлы в выбранную папку прямо с плейлиста.

Shutdown (screenshot) - вырубает комп по достижению конца плейлиста.

P.S. foobar2000 рулит :)

Дни разработчиков от Microsoft 2007. Одесса.

Сегодня с Андреем посетили это знаменательное событие, которое проходило в отеле "Валентина". Конечно, когда пришлось вставать в жуткую рань (находился этот отель на другом конце города), в невыспавшуюся голову то и дело приходили мысли на кой черт сдалось мне это событие со всей его знаменательностью. Само собой на регистрацию и утренний кофе тайм мы опоздали (в первую очередь благодаря мне), так что по приходу нас сразу же ждал средних размеров зал с сотрудником Майкрософт на сцене.

Да, во время регистрации нам задарили бейджики, ручку и блокнот с соответсвующей эмблемкой, а так же диск с Visual Studio 2008 b2. Эх знал бы, то не скачивал бы :). Ещё анкетку, которая затем, заполнившись, обменивалась на футболку с надписью Silverlight.

На повестке дня стояли следующие темы:
- silverlight
- Team Foundation Server
- SQL Server 2008
- VS 2008

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

Относительно содержания докладов тоже всё было в порядке. Интересно, с пользой, с юмором. Мило и ненавязчиво были политы грязью "неверные" а ля IBM, PHP, линуксоиды. В общем дух мелкомягких витал в воздухе :).
В принципе узнал много нового о продуктах ближайшего будущего, например тот же silverlight, это очень симпатичный веб клиент, облегченный родственник .net framework. Новая VS 2008 это просто блеск, все добавленные возможности относящиеся к анализу кода, тестированию, профилированию, оценке и тп. даже сложно перечислить. Уже поставил себе - балдею, осталось 109 дней. Team Foundation Server и SQL Server 2008 разработчики тоже не в потолок плевали.
Кстати, было акцентировано внимание на всесторонней поддержке Майкрософтом opensource community. В принципе ничего нового, слыхали такое и на channel 9, но всё равно чуть не прослезился от осознания бескрайнего альтруизма компании.

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

пятница, 2 ноября 2007 г.

Распространение приложений скомпилированных с Visual Studio 2005

Должно быть каждый, кто пытался запустить приложение скомпилированное с Visual Studio 2005 на чистой машине, был неприятно удивлен сообщением об ошибке. Причиной является невозможность найти библиотеки времени исполнения, указанные в встраиваемом по умолчанию манифесте.

Исходя из этого, у нас есть два основных метода распространения приложения:

1. Скомпилировать приложение со статической библиотекой времени исполнения.
Для этого следует:
- отключить манифест (Project Options -> Linker -> Manifest File -> Generate Manifest = No );
- указать статическую библиотеку времени исполнения (Project Options -> С\С++ -> Code Generation -> Runtime Library = Multi-threaded /MT ).

Недостатками этого метода является увеличенный размер приложения (теперь внутри него необходимые функции из библиотеки) и то что Microsoft всё же рекомендует его избегать .

2. Поставлять с приложением необходимую библиотеку.
Одно из решений предлагаемых Microsoft - использовать Visual C++ Runtime Libraries весом в 2.6 МБ, которые можно скачать здесь, либо найти в Visual Studio (%Путь к папке с VS2005%\SDK\v2.0\BootStrapper\Packages\vcredist_x86).

Более подробно о рекомендациях Microsoft можно прочесть в статье Choosing a Deployment Method.

пятница, 26 октября 2007 г.

Приоритет процесса при запуске

Раз уж зашла речь о приоритетах, то сразу скажу о возможности установки приоритета процесса при запуске средствами Windows.

Как известно Windows по умолчанию запускает процессы с приоритетом Normal, который можно повысить или понизить во время выполнения, к примеру, из TaskManager.
Если же мы хотим установить базовый приоритет при старте приложения, то можно воспользоваться командой start:

cmd /c start /[приоритет] application.exe

где, [приоритет] = LOW, BELOWNORMAL, NORMAL, ABOVENORMAL, HIGH, REALTIME

Что бы избавить себя от раздражающих задержек при одновременном просмотре фильма и игры, для игры был создан ярлык следующего содержания:

%windir%\system32\cmd.exe /c start /low d:\games\lineage2\system\la2.exe

Приоритет процесса в vmware

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

В общем если вдруг так случилось что кто то ещё не знает об этой фиче, то даю наводку: главное меню -> VM -> Settings... -> Options -> Advanced.
Там можно найти настройки приоритета для активного и неактивного случая.

четверг, 25 октября 2007 г.

XML в ядре

Существует замечательная мультиплатформеная библиотека для работы с XML именуемая The Expat XML Parser.Так вот оказалось что малой кровью её можно заставить работать и в ядре. Ниже я приведу шаги которые были применены для сборки отладочной версии статической библиотеки с драйвером.

Изменение кода Expat проекта в Visual Studio:
Нам нужно переопределить используемые CRTшные функции отсутсвующие в ядре. Это:
free
malloc
realloc
assert
memcmp

Для примера это можно сделать включив в проект файл со следующим содержанием:
#define _X86_
#include

void __cdecl free(void * _Memory)
{
if( _Memory )
ExFreePoolWithTag(_Memory, 'test');
}

void * __cdecl malloc( size_t _Size)
{
return (void*)ExAllocatePoolWithTag(NonPagedPool, _Size, 'test' );
}

void * __cdecl realloc( void * _Memory, size_t _NewSize)
{
if( _Memory )
ExFreePoolWithTag(_Memory, 'myma');
return (void*)ExAllocatePoolWithTag(NonPagedPool, _NewSize, 'test' );
}

int __cdecl memcmp(const void * _Buf1, const void * _Buf2, size_t _Size)
{
return (int)RtlCompareMemory( _Buf1, _Buf2, _Size );
}

void __cdecl assert( unsigned char something )
{

}

Кстати, для вышеприведенного кода нужно установить соглашение о вызове __stdcall. Это связано с тем что в прототипе
ExFreePoolWithTag это не указано явно.


Изменение настроек Expat проекта в Visual Studio:
1. C/C++ --> General --> Debug Information Format = Program Database (/Zi)
2. C/C++ --> CodeGeneration --> Basic Runtime Checks = Default
3. Подключить ntoskrnl.lib
4. Установить __stdcall для файла с переопределенными функциями (если используется ExFreePoolWithTag);

Код драйвера:
Если предполагается копмилировать статическую библиотеку (а это предполагается :) ), то нужно продефайнить:
#define XML_BUILDING_EXPAT 1

Ниже приведены заглушки которые можно реализовать (а можно пользоваться теми, что были переопределены выше):
..............
void * __cdecl MyMalloc(size_t size)
{
return ExAllocatePoolWithTag( NonPagedPool, size, '
test' );
}

void * __cdecl MyRealloc(void *ptr, size_t size)
{
if( ptr )
ExFreePoolWithTag(ptr, 'myma');
return ExAllocatePoolWithTag( NonPagedPool, size, '
test' );
}

void __cdecl MyFree(void *ptr)
{
if( ptr )
ExFreePoolWithTag(ptr, '
test');
}

NTSTATUS DriverEntry(
IN PDRIVER_OBJECT pDriverObject,
IN PUNICODE_STRING pusRegistryPath
)
{
XML_Memory_Handling_Suite memsuite;
...................

myMemSuite.malloc_fcn = (void *(__stdcall *)(size_t))&MyMalloc;
myMemSuite.realloc_fcn = (void *(__stdcall *)(void *,size_t))&MyRealloc;
myMemSuite.free_fcn = (void (__stdcall *)(void *))&MyFree;

parser = XML_ParserCreate_MM(NULL, &memsuite, NULL);
..........................
}

sources драйвера:
TARGETLIBS=XmlParser.lib

Пример библиотеки и вызывающего драйвера постараюсь выложить в ближайшее время.

Вот и всё. Вся эта морока с соглашениями о вызове нужна была что бы свести к минимуму вносимые изменения в код библиотеки.

Свежую версию Expat всегда можно найти на http://expat.sourceforge.net/

MAC адреса в Vista WFP (входящие пакеты)

Как известно в висте появилась чудесная и действительно удобная технология для анализа и редактирования IP трафика: WFP. Естественно, поскольку WFP охватывает только tcp/ip стэк (а это сетевой и транспортный уровень), то для работы с MAC адресом Microsoft предлагает поспользоваться старыми добрыми NDIS драйверами.

Но не всё так плохо в королевстве датском, оказывается что в случае с входящими пакетами на network inbound layer имеет смысл не делать оффсет на ip header, а взглянуть на 14 байт сразу перед ним. Там обнаруживается ethernet header для этого пакета, и что приятно обнаруживается всегда.

Парочка полезных инструментов в разработке драйверов.

Как оказалось для разработки и тестирования драйверов помимо WDK и Debugging tools существует целый ряд утилит, причем довольно приятные в использовании и в большинстве своём бесплатные. Всего за день уже настолько пристрастился к ним что даже не знаю как раньше обходился :).
Итак встречаем:
prefast - static analyze (поставляется вместе с WDK)
BullseyeCoverage - Run-Time analyze (хороша, хоть и не бесплатна. есть здесь http://www.bullseye.com/)
verifier - testing tool (отличная вещь, поставляется вместе с виндовз.)

How To configure Visual Studio 2005 for compiling drivers

As you should be know microsoft officially doesn`t support integration DDK with Visual Studio. So you can use Visual Studio editor (or any other editor) for make sources, but for compiling you should use the DDK build utility. Of course it is not very conveniently because you must always switch between editor and console window, but most terrible that developer spend much time for find lines with error in editor.

There are several ways to compile drivers with visual studio. Most of them you can find in nice Mark Roddy article "Windows Driver Build Methods and Tools" here: http://www.wd-3.com/archive/HowBuild.htm

Mark offers use some third party utilities. That`s good, but I will show more handly way (IMHO): how to configure and use Visual Studio for compiling drivers.


1. Setup Visual Studio 2005 (I guess it can be any other VS version)

2. Setup DDK (or WDK)

3. Add to VS pathes to DDK include files and libs.

4. Create new empty "Win32 project" and add source file (e.g. init.c).

5. Configure project properties (All Configurations)

5.1. C\C++ - General - Debug Information Format = Program Database (/Zi)
5.2. C\C++ - Preprocessor - Preprocessor Definitions = _X86_ [comment: add also DBG for Debug config]
5.3. C\C++ - Code Generation - Enable C++ Exceptions = No
5.4. C\C++ - Code Generation - Basic Runtime Checks = Default
5.5. C\C++ - Code Generation - Buffer Security Check = No (/GS-)
5.6. C\C++ - Advanced - Calling Convention = __stdcall (/Gz)
5.7. C\C++ - Advanced - Compile As = Compile as C Code (/TC) [comment: of course if you are going to use plain C]

5.8. Linker - General - Output File = $(OutDir)\$(ProjectName).sys
5.9. Linker - General - Enable Incremental Linking = Default
5.10. Linker - Input - Additional Dependencies = ntoskrnl.lib hal.lib $(NOINHERIT) [comment: you should add

needed libs here e.g. ntoskrnl.lib hal.lib]
5.11. Linker - Input - Ignore All Default Libraries = Yes (/NODEFAULTLIB)
5.12. Linker - Manifest File - Generate Manifest = No
5.13. Linker - System - SubSystem = Native (/SUBSYSTEM:NATIVE)
5.14. Linker - System - Driver = Driver (/DRIVER)
5.15. Linker - Advanced - Entry Point = DriverEntry
5.16. Linker - Advanced - Base Address = 0x10000

6. OK. Have done. Now you can test it with simple code, e.g.:

#include "ntddk.h"

NTSTATUS
DriverEntry(
PDRIVER_OBJECT DriverObject,
PUNICODE_STRING RegistryPath
)
{
return STATUS_UNSUCCESSFUL;
}


If you have founded some mistakes or misundestoods please let me know.

Good Luck guys.