книги хакеры / Защита_от_взлома_сокеты,_эксплойты,_shell_код_Фостер_Дж_
.pdf
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
|
hang |
e |
|
|
|
|
|
||
|
|
|
C |
|
E |
|
|
|
|
|
|
C |
|
E |
|
|
|
||||||
|
|
X |
|
|
|
|
|
|
|
|
X |
|
|
|
|
|
|
||||||
|
- |
|
|
|
|
|
d |
|
|
- |
|
|
|
|
|
d |
|
||||||
|
F |
|
|
|
|
|
|
|
t |
|
|
F |
|
|
|
|
|
|
|
t |
|
||
|
D |
|
|
|
|
|
|
|
|
i |
|
|
D |
|
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
|
r |
|
|
|
|
|
|
|
|
|
r |
||||
P |
|
|
|
|
|
NOW! |
o |
P |
|
|
|
|
|
NOW! |
o |
||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||||
|
|
|
|
|
BUY |
|
|
|
|
|
|
|
BUY |
|
|
||||||||
|
|
|
|
to |
|
|
|
|
|
|
Библиотека ATL 651 |
|
to |
|
|
|
|
|
|
||||
w Click |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||
|
|
|
|
|
|
|
m |
w Click |
|
|
|
|
|
|
|
m |
|||||||
w |
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
|
|
|
||
|
w |
|
|
|
|
|
|
|
|
o |
|
|
w |
|
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
g |
.c |
|
|
. |
|
|
|
|
g |
.c |
|
||||||
|
|
p |
|
-xcha |
|
|
|
|
|
p |
|
-x cha |
|
|
|
||||||||
|
|
|
|
|
|
Чтобы к внутрипроцессному модулю можно было обратиться извне, его |
|
|
e |
|
|||||||||||||
|
|
|
df |
|
|
n |
e |
|
|
|
|
df |
|
|
n |
|
|||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
необходимо зарегистрировать. Для этого нужно обратиться к экспортируемой функции DllRegisterServer. К сожалению, инсталлятор не всегда делает это, поэтому часто приходится регистрировать внутрипроцессные модули вручную. В этом может помочь утилита RegSvr32, которой просто передается имя модуля, например: RegSvr32 Mydll.dll.
Функция DllUnregisterServer
Эта функция выполняет действия, обратные тем, что проделала DllRegisterServer.
Для удаления внутрипроцессного модуля из системы также можно воспользоваться утилитой RegSvr32, передав ей, помимо имени модуля, флаг /u, например:
RegSvr32 /u Mydll.dll
Библиотека ATL
Получив некоторое представление о том, что такое технология COM, вы, вероятно, обратили внимание на то, что для обеспечения правильной работы всех ее составных частей нужно приложить немало усилий. Тут-то на сцене и появляется библиотека шаблонов ATL (Active Template Library). ATL – это самая компактная и быстрая из всех созданных Microsoft библиотек для создания COM-серверов на языке C++. Но особенно важно то, что она во много раз уменьшает объем работы, необходимой для реализации сервера и клиента.
При разработке клиентских приложений COM встречаются некоторые стандартные конструкции, которые хотелось бы использовать повторно, например, доступ к методам интерфейса IUnknown. В ATL для этой цели применяются так называемые интеллектуальные указатели, о которых мы расскажем чуть ниже.
При разработке серверных приложений COM очень многие аспекты можно вынести в поддерживающую библиотеку, как то:
реализация интерфейса IUnknown в той ее части, которая отвечает за подсчет ссылок и запросы на получение интерфейсов;
реализация интерфейса IClassFactory для всех совместимых классов;
регистрация и удаление COM-объектов;
реализация точек входа DllGetClassObject, DllCanUnloadNow, DllRegisterServer и DllUnregisterServer для внутрипроцессных серверов;
регистрация классов внепроцессного COM-сервера в среде исполнения.
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
|
hang |
e |
|
|
|
|
|
||
|
|
|
C |
|
E |
|
|
|
|
|
|
C |
|
E |
|
|
|
||||||
|
|
X |
|
|
|
|
|
|
|
|
X |
|
|
|
|
|
|
||||||
|
- |
|
|
|
|
|
d |
|
|
- |
|
|
|
|
|
d |
|
||||||
|
F |
|
|
|
|
|
|
|
t |
|
|
F |
|
|
|
|
|
|
|
t |
|
||
|
D |
|
|
|
|
|
|
|
|
i |
|
|
D |
|
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
|
r |
|
|
|
|
|
|
|
|
|
r |
||||
P |
|
|
|
|
|
NOW! |
o |
P |
|
|
|
|
|
NOW! |
o |
||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||||
|
|
|
|
|
BUY |
|
|
|
|
|
|
|
BUY |
|
|
||||||||
|
|
|
|
to |
|
|
|
654 Глава 13. Написание компонентов для задач, связанных с безопасностью |
|
|
|
|
to |
|
|
|
|
|
|
||||
w Click |
|
|
|
|
w Click |
|
|
|
|
|
|
|
|||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
m |
|||||||||||
|
|
|
|
|
|
|
m |
|
|
|
|
|
|
|
|||||||||
w |
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
|
|
|
||
|
w |
|
|
|
|
|
|
|
|
o |
|
|
w |
|
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
g |
.c |
|
|
. |
|
|
|
|
g |
.c |
|
||||||
|
|
p |
|
-xcha |
|
|
|
|
|
p |
|
|
|
|
|
|
|
||||||
|
|
|
|
|
|
BSTR-строки, вывода ее на экран и уничтожения необходимы такие вызовы-x cha |
|
e |
|
||||||||||||||
|
|
|
df |
|
|
n |
e |
|
|
|
|
df |
|
|
n |
|
|||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
функций:
BSTR bstrValue = SysAllocString(L"Hello, BSTR!"); wprintf(L"%s", bstrValue); SysFreeString(bstrValue);
Понятно, что так работать утомительно, да и ошибки легко допустить. Поэтому в библиотеке ATL есть класс CComBSTR, который упрощает использование BSTR-строк. Ниже показано, как та же самая последовательность действий реализуется с помощью класса CComBSTR:
wprintf(L"%s", CComBSTR(L"Hello, BSTR!"));
Тип данных VARIANT
Тип VARIANT – это, по сути дела, объединение разных типов данных. Он впервые появился в языке Visual Basic, а затем стал применяться во всех интерфейсах, совместимых с автоматизацией, так что используется весьма часто.
Прежде всего, переменную типа VARIANT необходимо инициализировать, указав, какие данные в ней будут храниться. Для этого в поле vt записывается подходящее значение. Это поле имеет тип перечисления VARENUM, описывающего все поддерживаемые типы. Ниже приведен список возможных значений vt:
1 /*
2 * порядок применения перечисления VARENUM:
3*
4* * [V] – может употребляться в VARIANT
5* * [T] – может употребляться в TYPEDESC
6* * [P] – может употребляться при задании значения свойства OLE
7 * * [S] – может употребляться в Safe Array
8 *
9*
10 |
* VT_EMPTY |
[V] |
[P] |
значение отсутствует |
11 |
* VT_NULL |
[V] |
[P] |
null в смысле SQL |
12 |
* VT_I2 |
[V] [T] [P] [S] двухбайтовое целое со знаком |
||
13 |
* VT_I4 |
[V] [T] [P] [S] четырехбайтовое целое со знаком |
||
14 |
* VT_R4 |
[V] [T] [P] [S] четырехбайтовое вещественное |
||
15 |
* VT_R8 |
[V] [T] [P] [S] восьмибайтовое вещественное |
||
16 |
* VT_CY |
[V] [T] [P] [S] денежная единица |
||
17 |
* VT_DATE |
[V] [T] [P] [S] äàòà |
||
18 |
* VT_BSTR |
[V] [T] [P] [S] строка для OLE-автоматизации |
||
19 |
* VT_DISPATCH |
[V] [T] |
|
[S] IDispatch * |
20 |
* VT_ERROR |
[V] [T] [P] [S] SCODE |
||
21 |
* VT_BOOL |
[V] [T] [P] [S] True=-1, False=0 |
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
|
hang |
e |
|
|
|
|
|
||
|
|
|
C |
|
E |
|
|
|
|
|
|
C |
|
E |
|
|
|
||||||
|
|
X |
|
|
|
|
|
|
|
|
X |
|
|
|
|
|
|
||||||
|
- |
|
|
|
|
|
d |
|
|
- |
|
|
|
|
|
d |
|
||||||
|
F |
|
|
|
|
|
|
|
t |
|
|
F |
|
|
|
|
|
|
|
t |
|
||
|
D |
|
|
|
|
|
|
|
|
i |
|
|
D |
|
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
|
r |
|
|
|
|
|
|
|
|
|
r |
||||
P |
|
|
|
|
|
NOW! |
o |
P |
|
|
|
|
|
NOW! |
o |
||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||||
|
|
|
|
|
BUY |
|
|
|
|
|
|
|
BUY |
|
|
||||||||
|
|
|
|
to |
|
|
|
|
|
|
Библиотека ATL 659 |
|
to |
|
|
|
|
|
|
||||
w Click |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||
|
|
|
|
|
|
|
m |
w Click |
|
|
|
|
|
|
|
m |
|||||||
w |
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
|
|
|
||
|
w |
|
|
|
|
|
|
|
|
o |
|
|
w |
|
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
g |
.c |
|
|
. |
|
|
|
|
g |
.c |
|
||||||
|
|
p |
|
-xcha |
|
|
|
|
|
p |
|
-x cha |
|
|
|
||||||||
|
|
|
|
|
|
Макрос BEGIN_COM_MAP принимает единственный аргумент – имя |
|
|
e |
|
|||||||||||||
|
|
|
df |
|
|
n |
e |
|
|
|
|
df |
|
|
n |
|
|||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
COM-класса. Вслед за ним нужно с помощью подходящих макросов объявить все интерфейсы компонента. В вашем распоряжении имеются такие макросы:
COM_INTERFACE_ENTRY – самый простой макрос для объявления интерфейса. Принимает только один аргумент: имя типа интерфейса;
COM_INTERFACE_ENTRY_IID – то же, что предыдущий, но принимает два аргумента: IID интерфейса и имя его типа;
COM_INTERFACE_ENTRY_CHAIN – позволяет делегировать вызов QueryInterface указанному базовому классу;
COM_INTERFACE_ENTRY_BREAK – отладочный макрос, который заставляет ATL вызвать функцию DebugBreak при запросе интерфейса с указанным IID.
Нам осталось только реализовать интерфейс IUnknown. Эта задача отлича- ется от предыдущих, поскольку для ее решения не нужно наследовать никаким классам. Вместо этого предоставляемый ATL шаблонный класс CComObject должен сам наследовать нашему классу, переданному ему в качестве параметра шаблона. Вот как это делается:
CComObject<CHotFixCheck> *pHFCheck;
Тем самым мы ассоциируем реализацию интерфейса с нашим COM-клас- сом. Следующий шаг – создать объект, поработать с ним, а затем освободить ссылку на него.
CComObject<CHotFixCheck>::CreateInstance(&pHFCheck);
//Это необходимо потому, что CreateInstance не увеличивает
//счетчик ссылок самостоятельно
pHFCheck->AddRef(); pHFCheck->IsPatchInstalled();
// объект удаляется, потому что счетчик ссылок на него стал равен 0 pHFCheck->Release();
Язык определения интерфейсов
Если COM-объект реализуется на языке C++, то его интерфейсы можно описать с помощью абстрактного базового класса. Этот подход будет работать для всех случаев создания объекта внутри процесса. Однако, стоит принять во внимание другие потоковые модели (раздельных, а не свободных потоков) и наличие различных контекстов загрузки в COM (CLSCTX_INPROC_SERVER и CLSCTX_LOCAL_SERVER), как становится понятно, что