Издательский дом ООО "Гейм Лэнд"ЖУРНАЛ ХАКЕР #82, ОКТЯБРЬ 2005 г.

Родные приложения

Николай «gorl» Андреев

Хакер, номер #082, стр. 082-114-4


#pragma comment(linker, "/ENTRY:native_main")

Хорошая функция получается ;), правда абсолютно бесполезная. Это поправимо.

[hello world!]

Давай для начала научим программу выводить что-нибудь на прелестный светло-голубой экран, предвещающий скорое появления окошка для ввода пароля. Для этого, прежде всего надо усвоить, что строка для низкоуровневой части Windows – это unicode-строка (а по этому поводу в срочном порядке лезь в настройки своего проекта, где в закладке General меняй Character Set на «Use Unicode Character Set», чтобы все строки по умолчанию создавались в юникоде). Причем не просто массив слов (слова - это такие штуки, в которые 2 байта влезают), а специальная структура данных, содержащая указатель на массив и его текущую и максимальную длины:

typedef struct _UNICODE_STRING {

USHORT Length;

USHORT MaximumLength;

PWSTR Buffer;

} UNICODE_STRING;

Этот тип данных тебе запомниться надолго, так как в другом виде строки здесь не перевариваются. Для удобной работы с подобными строками ntdll экспортирует целый ряд функций, из которых следует отметить:

+ VOID RtlInitUnicodeString(IN OUT PUNICODE_STRING, IN PWSTR) - функция, инициализирующая структуру UNICODE_STRING обычной unicode-строкой.

// запихиваю в string нужную мне строку

UNICODE_STRING string;

RtlInitUnicodeString(&string, L”\nHello... hm... World?”);

+ NTSTATUS RtlAnsiStringToUnicodeString(IN OUT PUNICODE_STRING, IN PANSI_STRING, IN BOOLEAN) – функция, преобразующая ANSI_STRING в UNICODE_STRING. Бывает очень полезна, если вдруг, по какой-нибудь никому неведомой причине у тебя появилась ansi-строка, да еще и в структуре ANSI_STRING (которая, к слову, отличается от похожей по названию unicode-структуры только указателем - в одной PWSTR, в другой PCHAR).

+ VOID RtlInitAnsiString(IN OUT PANSI_STRING, IN PCSZ) – а эта подруга нужна для того чтобы инициализировать упомянутую выше ANSI_STRING с помощью самой обычной строки.

// если не настроить проект на использование Unicode Character Set

// то придется делать так

UNICODE_STRING unicodeString;

ANSI_STRING ansiString;

RtlInitAnsiString(&ansiString, L“\nOh, damnet, not again!!!”);

RtlAnsiStringToUnicodeString(&unicodeString, &ansiString, TRUE);

// TRUE в третьем параметре определяет, выделять ли память

// под Unicode-строку. так как мы ее выделили, в последствии

// придется ее освободить с помощью RtlFreeUnicodeString

Этих трех функций хватит на все про все. Можно, конечно, покопать DDK в поисках еще нескольких, но они вряд ли тебе пригодятся.

Ну, а чтобы вывести на экран полученную в нужном формате строчку, нужна одна очень простая функция, всего с одним параметром. Угадай с каким?

// выводим многострадальную строку на голубой экран

NtDisplayString(&unicodeString);

[работа с файлами]

Вывод на экран – это просто замечательно! Можно удивить друзей ascii-графикой перед загрузкой, а, разобравшись с вводом с клавиатуры, и какую-нибудь простенькую диалоговую программку написать. Но всего это для нормального программирования мало. Для использования в целях разработки RAT тут нужно хотя бы с файлами работать, с реестром, уметь драйвера загружать. Это все не сложно, но требует определенного погружения в тему. К примеру, некоторым очень непривычно использование вместо обычного имени файла для функции NtCreateFile структуры OBJECT_ATTRIBUTES.

Назад на стр. 082-114-3  Содержание  Вперед на стр. 082-114-5