книги хакеры / Защита_от_взлома_сокеты,_эксплойты,_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 |
|
|
|
|
|
|
Добавление СОМ расширений в программу RPCDUMP 685 |
|
to |
|
|
|
|
|
|
||||
w Click |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||
|
|
|
|
|
|
|
m |
w Click |
|
|
|
|
|
|
|
m |
|||||||
w |
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
|
|
|
||
|
w |
|
|
|
|
|
|
|
|
o |
|
|
w |
|
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
g |
.c |
|
|
. |
|
|
|
|
g |
.c |
|
||||||
|
|
p |
|
-xcha |
|
|
|
|
|
p |
|
-x cha |
|
|
|
||||||||
|
|
|
|
|
|
Поскольку в исходном файле RPCDump.C используются только строки |
|
|
e |
|
|||||||||||||
|
|
|
df |
|
|
n |
e |
|
|
|
|
df |
|
|
n |
|
|||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
в кодировке ANSI, то процедуры интеграции принимают строковые параметры как char *. Но наш COM-объект должен поддерживать также и обращения из программ на интерпретируемых языках (VBScript, JScript и т.д.), значит, нужны строки типа BSTR. Поэтому мы должны преобразовать переданную строку в другой формат и кодировку Unicode. Это легко сделать, воспользовавшись объектом класса CComBSTR и передав его конструктору полученную строку. Возвращенное значение сохраняется в текущей записи.
Определение интерфейсов COM3объектов
COM-расширение программы RPCDump включает три COM-объекта, у каждого из которых определено по одному интерфейсу (помимо IUnknown и IDispatch):
IrpcEnum;
IendPointCollection;
Iendpoint.
Определения всех этих интерфейсов показаны в примере 13.5.
Пример 13.5. Определения интерфейсов (из файла COMSupport.cpp)
1 |
[ |
|
2 |
object, |
// COM-объект |
3 |
dual, |
// поддержка IDispatch и vtable |
4 |
uuid("2F55A03C-9513-4CF1-9939-E0BD72E968E8") |
|
5 |
] |
|
6 |
__interface IEndpoint : IDispatch |
|
7 |
{ |
|
8[propget] HRESULT InterfaceID([out, retval] BSTR *bstrVal);
9 [propget] HRESULT Version([out, retval] BSTR *bstrVal);
10[propget] HRESULT Uuid([out, retval] BSTR *bstrVal);
11[propget] HRESULT Binding([out, retval] BSTR *bstrVal);
12};
13
14 [
15 |
object, |
// |
COM-объект |
16 |
dual, |
// |
поддержка IDispatch и vtable |
17uuid("7C7487E9-7F08-462C-85CF-CF23C08498AC")
18]
19__interface IEndpointCollection : IDispatch
20{
21[id(DISPID_NEWENUM), propget]
22HRESULT _NewEnum([out, retval] IUnknown** ppUnk);
24[id(DISPID_VALUE), propget]
25HRESULT Item(
|
|
|
|
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 |
|
|
|
|
|
|
Добавление СОМ расширений в программу RPCDUMP 687 |
|
to |
|
|
|
|
|
|
||||
w Click |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||
|
|
|
|
|
|
|
m |
w Click |
|
|
|
|
|
|
|
m |
|||||||
w |
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
|
|
|
||
|
w |
|
|
|
|
|
|
|
|
o |
|
|
w |
|
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
g |
.c |
|
|
. |
|
|
|
|
g |
.c |
|
||||||
|
|
p |
|
-xcha |
|
|
|
|
|
p |
|
-x cha |
|
|
|
||||||||
|
|
|
|
|
|
Атрибуты в строках 14–27 такие же, как для всех остальных интерфейсов: |
|
|
e |
|
|||||||||||||
|
|
|
df |
|
|
n |
e |
|
|
|
|
df |
|
|
n |
|
|||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
интерфейс объявляется дуальным и задается его IID.
Вы, наверное, обратили внимание на атрибут id в строках 21 и 24. Чтобы понять его назначение, надо кое-что знать об интерфейсе IDispatch. Этот интерфейс используется COM-клиентами, которые осуществляют позднее связывание. Такой механизм задействуется в ситуации, когда клиент не имеет доступа к информации о типе во время компиляции и должен обращаться к методам интерфейса косвенно (через IDispatch), а не напрямую через таблицу виртуальных функций. Это становится возможным из-за наличия в интерфейсе IDispatch двух методов: GetIDsOFNames и Invoke. Ниже приведены их прототипы:
HRESULT GetIDsOFNames( REFIID riid,
OLECHAR FAR* FAR* rgszNames, unsigned int cNames,
LCID lcid,
DISPID FAR* rgDispId
};
HRESULT Invoke( DISPID dispIdMember, REFIID riid,
LCID lcid, WORD wFlags,
DISPPARAMS FAR* pDispParams, VARIANT FAR* pVarResult, EXCEPINFO FAR* pExcepInfo, unsigned int FAR* puArgErr
};
Метод Invoke служит для обращения к конкретному методу, определяемому параметром dispIdMember. Его значение задается в библиотеке типов и, следовательно, должно быть частью описания метода. Именно это мы и видим в описаниях методов _NewEnum и Item. Если COM-клиент не имеет информации из библиотеки типов, он может запросить DISPID у метода GetIDsOFNames интерфейса IDispatch.
Метод _NewEnum возращает указатель на интерфейс IUnknown объектаэнумератора для набора. Обычно он вызывается из языков сценариев для реализации конструкций типа foreach.
Метод Item почти не нуждается в комментариях, он получает числовой индекс и возвращает соответствующий ему указатель на интерфейс IEndPoint. Если задан индекс вне допустимого диапазона, метод возвращает S_FALSE.
Метод Count возвращает число объектов в наборе.
|
|
|
|
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 |
|
|
690 Глава 13. Написание компонентов для задач, связанных с безопасностью |
|
|
|
|
to |
|
|
|
|
|
|
||||||
w Click |
|
|
|
w Click |
|
|
|
|
|
|
|
|||||||||||||
|
|
|
|
|
|
|
|
|
|
|
m |
|||||||||||||
|
|
|
|
|
|
|
m |
|
|
|
|
|
|
|
|
|||||||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
|
|
|
||
|
w |
|
|
|
|
|
|
|
|
o |
|
|
|
w |
|
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
g |
.c |
|
|
|
. |
|
|
|
|
g |
.c |
|
||||||
|
|
p |
|
-xcha |
|
|
|
|
|
|
p |
|
|
|
|
|
|
|
||||||
|
|
|
|
|
e |
|
Далее в примере 13.7 показан код энумератора набора. Это типичная для-x cha |
|
e |
|
||||||||||||||
|
|
|
df |
|
|
n |
|
|
|
|
|
df |
|
|
n |
|
||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ATL-проектов реализация.
Пример 13.7. Реализация кокласса CEndpointCollection (из файла COMSupport.cpp)
1 typedef CComEnumOnSTL<
2IEnumVARIANT,
3&__uuidof(IEnumVARIANT),
4VARIANT,
5_CopyEndpointIFToVariant,
6std::vector<IFACE_DATA_ENTRY>
7 > EnumType;
8
9 typedef ICollectionOnSTLImpl<
10IEndpointCollection,
11std::vector<IFACE_DATA_ENTRY>
12IEndpoint*,
13_CopyInformationToEndpointInterface,
14EnumType
15> EndpointCollectionType;
16
17
18[
19coclass,
20threading=apartment,
21uuid("2C793CBF-51FA-4146-022902FBDDCF"),
22noncreatable
23]
24class ATL_NO_VTABLE CEndpointCollection :
25public IDispatchImpl< EndpointCollectionType,
26 |
&__uuidof(IEndpointCollection) > |
27{
28public:
29// Для этого набора не нужны никакие методы
30}
Анализ
В строках 1–7 определяется синоним EnumType для типа объекта-энумератора набора. Напомним, что энумератор возвращается методом _NewEnum. Рассмотрим этот код внимательнее. Тип EnumType реализован с помощью шаблонного класса CComEnumOnSTL, который определен так:
template <class Base, const IID* piid, class T, class Copy,
class CollType, class ThreadModel = CComObjectThreadModel > class ATL_NO_VTABLE CComEnumOnSTL :
public IEnumOnSTLImpl<Base, piid, T, Copy, CollType>, public CComObjectRootEx< ThreadModel >