Нарушение доступа внутри inetinfo.exe при передаче байтового массива через IMSAdminBase из приложения .NET, скомпилированного в AnyCPU - PullRequest
0 голосов
/ 15 июля 2011

Рассмотрим следующий фрагмент кода .NET:

byte[] hash = { 0x60, 0x2B, 0x45, 0x9D, 0xA0, 0x6D, 0xD5, 0x02, 0x43, 0x86, 0xC1, 0xBA, 0x6B, 0x14, 0x37, 0x88, 0x63, 0x08, 0x39, 0xA0 };
using (var adminBase = TemporaryComObject.Wrap(new MSAdminBase_W()))
using (var ptrHash = new AllocHGlobal(hash))
{
  using (var siteKey = new AdminBaseKey(adminBase.Com, adminBase.Com.OpenKey(METADATA_MASTER_ROOT_HANDLE, "/LM/W3SVC/1", METADATA_PERMISSION_READ | METADATA_PERMISSION_WRITE, 10000)))
  {
    var record = new METADATA_RECORD
    {
      dwMDIdentifier = 5506,
      dwMDAttributes = METADATA_INHERIT,
      dwMDUserType = IIS_MD_UT_SERVER,
      dwMDDataType = BINARY_METADATA,
      pbMDData = ptrHash.Buffer,
      dwMDDataLen = hash.Length
    };
    adminBase.Com.SetData(siteKey.Handle, string.Empty, ref record);
  }
  adminBase.Com.SaveData();
}

Этот код пытается установить свойство метабазы ​​SSLCertHash IIS6 из .NET.

Он работает абсолютно нормально, если приложение .NETскомпилирован для x86, что означает, что в соответствующем файле .csproj найдена следующая строка:

<PlatformTarget>x86</PlatformTarget>

Однако драконы приходят, когда я пропускаю эту строку и компилирую для AnyCPU.А именно, происходит то, что inetinfo.exe падает с нарушением прав доступа.Вот соответствующий снимок окна вывода windbg:

(24f0.cbc): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
msvcrt!memmove+0x1e5:
000007fe`fe371111 8b040a          mov     eax,dword ptr [rdx+rcx] ds:00000000`00000010=????????
0:001> k
Child-SP          RetAddr           Call Site
00000000`008ee1f8 000007fe`f5a64e71 msvcrt!memmove+0x1e5
00000000`008ee200 000007fe`f5a64da0 abocomp!PROPERTY_ENTRY::Create+0x79
00000000`008ee230 000007fe`f5a5c21b abocomp!PROPERTY_BAG::SetData+0xbc
00000000`008ee270 000007fe`f5a6088a abocomp!ABO_NODE::SetData+0xa3
00000000`008ee2a0 000007fe`f5a9456f abocomp!ABO_WRAPPER::SetData+0x1ca
00000000`008ee580 000007fe`f5ad3e54 COADMIN!CADMCOMW::SetData+0x127
00000000`008ee630 000007fe`fdfd51d0 ADMWPROX!IMSAdminBaseW_R_SetData_Thunk+0xb4
00000000`008ee6b0 000007fe`fdedf16e RPCRT4!NdrStubCall2+0xa36
00000000`008eecd0 000007fe`fdee0ccd ole32!CStdStubBuffer_Invoke+0x8b
00000000`008eed00 000007fe`fdee0c43 ole32!SyncStubInvoke+0x5d
00000000`008eed70 000007fe`fdd9a4f0 ole32!StubInvoke+0xdb
00000000`008eee20 000007fe`fdee14d6 ole32!CCtxComChnl::ContextInvoke+0x190
00000000`008eefb0 000007fe`fdee122b ole32!AppInvoke+0xc2
00000000`008ef020 000007fe`fdedfd6d ole32!ComInvokeWithLockAndIPID+0x52b
00000000`008ef1b0 000007fe`fdfa50f4 ole32!ThreadInvoke+0x30d
00000000`008ef250 000007fe`fdfa4f56 RPCRT4!DispatchToStubInCNoAvrf+0x14
00000000`008ef280 000007fe`fdfa775b RPCRT4!RPC_INTERFACE::DispatchToStubWorker+0x146
00000000`008ef3a0 000007fe`fdfa769b RPCRT4!RPC_INTERFACE::DispatchToStub+0x9b
00000000`008ef3e0 000007fe`fdfa7632 RPCRT4!RPC_INTERFACE::DispatchToStubWithObject+0x5b
00000000`008ef460 000007fe`fdfa532d RPCRT4!LRPC_SCALL::DispatchRequest+0x422
00000000`008ef540 000007fe`fdfc2e7f RPCRT4!LRPC_SCALL::HandleRequest+0x20d
00000000`008ef670 000007fe`fdfc2a35 RPCRT4!LRPC_ADDRESS::ProcessIO+0x3bf
00000000`008ef7b0 00000000`7753b68b RPCRT4!LrpcIoComplete+0xa5
00000000`008ef840 00000000`7753feff ntdll!TppAlpcpExecuteCallback+0x26b
00000000`008ef8d0 00000000`76e5652d ntdll!TppWorkerThread+0x3f8
00000000`008efbd0 00000000`7754c521 kernel32!BaseThreadInitThunk+0xd
00000000`008efc00 00000000`00000000 ntdll!RtlUserThreadStart+0x1d
0:001> g
(24f0.cbc): Access violation - code c0000005 (!!! second chance !!!)
msvcrt!memmove+0x1e5:
000007fe`fe371111 8b040a          mov     eax,dword ptr [rdx+rcx] ds:00000000`00000010=????????

Я абсолютно не знаю, что происходит.А вы?

Дополнительная информация

  1. Я использую 64-разрядную версию Windows 7, IIS 7.5 с включенной метабазой IIS6
  2. Я не используюSystem.DirectoryServices для изменения свойства метабазы ​​SSLCertHash, потому что это невозможно - http://support.microsoft.com/kb/313624 объясняет это. Эта статья содержит более полезную информацию по теме.
  3. Типы TemporaryComObject, AllocHGlobal, AdminBaseKey гарантируют, что COM-объект, неуправляемая память и базовый ключ администратора освобождены от свойства./closed.
  4. Сборка взаимодействия для COM-объекта MSAdminBase была получена с использованием варианта описанной здесь методики - http://www.moserware.com/2009/04/using-obscure-windows-com-apis-in-net.html. Только я не воссоздал код взаимодействия, а скорее соответствующий файл IDL.Затем я скомпилировал его с помощью MIDL для создания соответствующего файла TLB, который я передал в TlbImp для создания сборки взаимодействия.

Определение C типа METADATA_RECORD найдено в файле mddefw.h из SDK.:

typedef struct _METADATA_RECORD
{
  DWORD dwMDIdentifier;
  DWORD dwMDAttributes;
  DWORD dwMDUserType;
  DWORD dwMDDataType;
  DWORD dwMDDataLen;
  unsigned char *pbMDData;
  DWORD dwMDDataTag;
} METADATA_RECORD;

В созданной мной сборке взаимодействия тип объявляется так:

[StructLayout(LayoutKind.Sequential, Pack=4), ComConversionLoss]
public struct METADATA_RECORD
{
    public int dwMDIdentifier;
    public int dwMDAttributes;
    public int dwMDUserType;
    public int dwMDDataType;
    public int dwMDDataLen;
    [ComConversionLoss]
    public IntPtr pbMDData;
    public int dwMDDataTag;
}

Обратите внимание на наличие атрибута ComConversionLoss.Я не знаю, имеет ли это значение или нет, но когда я создал сборку взаимодействия, я получил следующее предупреждение:

TlbImp : warning TI3016: The type library importer could not convert the signature for the member 'MSAdminBaseLib.METADATA_RECORD.pbMDData'. [C:\Work\IISCertObj\SimpleNCServerSecurity.csproj]

Есть еще один мой пост (пока без ответа), который касаетсяименно с этой проблемой.

Большое спасибо.

РЕДАКТИРОВАТЬ

У меня такое ощущение, что оно имеет отношение к StructLayout.Pack = 4.Я еще учусь, как заставить TlbImp не вставлять его ...

EDIT2

И действительно, это проблема.Как выясняется, вывод, производимый TlbImp, требует дальнейшей настройки.Мне пришлось разобрать его с помощью Reflector.NET и удалить явные инструкции Pack.Теперь все отлично работает.

1 Ответ

0 голосов
/ 16 июля 2011

Я нашел проблему - действительно, Pack = 4 помог.

...