Будет очень сложно уменьшить объем этого вопроса, но здесь мы идем.
Контекст
Я нахожусь в контексте 32-битного элемента управления ActiveX, которыйзагружен в хост (TstCon.exe
).После выгрузки и перезагрузки элемента управления я получаю серию ошибок от NtMapViewOfSection
, первая из которых возникает, когда odbc32.dll
использует LoadLibraryExW
для загрузки C:\Windows\system32\odbcint.dll
.В этот момент исключение SEH генерируется где-то внутри NtMapViewOfSection
с кодом 0xC0000023
(AKA STATUS_BUFFER_TOO_SMALL
в соответствии с отладчиком).
Aftermath
Вот как выглядит стек вызововкогда отладчик перехватывает исключение:
ntdll.dll!_NtMapViewOfSection@40()
KernelBase.dll!BasepLoadLibraryAsDataFileInternal()
KernelBase.dll!BasepLoadLibraryAsDataFile()
KernelBase.dll!LoadLibraryExW()
odbc32.dll!_InitializeDll@0()
odbc32.dll!_SQLAllocEnv@4()
<OurDll>.dll!<OurFunction>()
...
В этот момент я использовал совершенно вменяемые методы для извлечения аргументов для вызова NtMapViewOfSection
, выполнив thisдокументация :
*(void**)(ESP + 4 + 0) /*SectionHandle*/ 0x000003b0 void *
*(void**)(ESP + 4 + 4) /*ProcessHandle*/ 0xffffffff void *
*(void**)(ESP + 4 + 8) /*BaseAddress*/ 0x00daae30 void *
*(unsigned long*)(ESP + 4 + 12) /*ZeroBits*/ 0x00000000 unsigned long
*(unsigned long*)(ESP + 4 + 16) /*CommitSize*/ 0x00000000 unsigned long
*(long long**)(ESP + 4 + 20) /*SectionOffset*/ 0x00000000 {???} __int64 *
*(unsigned long**)(ESP + 4 + 24) /*ViewSize*/ 0x00daae28 {0x00000000} unsigned long *
*(int*)(ESP + 4 + 28) /*InheritDisposition*/ 0x00000001 int
*(unsigned long*)(ESP + 4 + 32) /*AllocationType*/ 0x00800000 unsigned long
*(unsigned long*)(ESP + 4 + 36) /*Protect*/ 0x00000002 unsigned long
Пошаговое руководство по сборке
Первоначально я обнаружил исключение, включив функцию отрыва на броске в отладчике VS, затем я смог точно определить первый сбойпозвоните и установите точку останова прямо перед собой.Вот что я вижу по отладке внутри разборки (>
отмечает текущую инструкцию):
_NtMapViewOfSection@40:
76F2EF60 mov eax,28h
76F2EF65 mov edx,offset _Wow64SystemServiceCall@0 (76F43430h)
> 76F2EF6A call edx
76F2EF6C ret 28h
76F2EF6F nop
... шаг в :
_Wow64SystemServiceCall@0:
> 76F43430 jmp dword ptr [_Wow64Transition (76FD2218h)]
... шаг в :
> 74A37000 jmp 0033:74A37009
74A37007 add byte ptr [eax],al
74A37009 inc ecx
74A3700A jmp dword ptr [edi+0F8h]
... шаг в :
_NtQueryObject@20:
76F2EDC0 mov eax,10h
76F2EDC5 mov edx,offset _Wow64SystemServiceCall@0 (76F43430h)
76F2EDCA call edx
> 76F2EDCC ret 14h
76F2EDCF nop
И следующий шагв запускается исключение.
Нарушает среду программы, например:
- Обновление компиляторов и сред выполнения (между MSVC90 и MSVC141), которые выявляли ошибку впервое место;
- Переключение между конфигурациями выпуска и отладки;
- Форсирование базового адреса для OCX с помощью флага компоновщика
/base
; - Запуск с подключенным отладчиком;
- Мониторинг системных вызовов с помощью
drstrace.exe
;
... изменение, которое вызывает NtMapViewOfSection
, будет успешным или неуспешным, на первый взгляд случайным образом: не все из них терпят неудачу, нозначительное число делают.Фактически, первое возникновение ошибки, вероятно, не указывает на то, откуда на самом деле возникает проблема, поскольку я редко мог вызвать ее аварийное завершение раньше (после выгрузки элемента управления), и даже получил сбой, при котором нет нашего кода находилось в стеке вызовов (путем непосредственного выхода из TstCon.exe
).
Я не могу найти никакой документации (официальной или иной), упоминающей код STATUS_BUFFER_TOO_SMALL
или 0xC0000023
в этом контексте,Мне не удалось найти образец в сбойных вызовах, и я не увидел соответствующих ошибок доступа после запуска Dr. Memory.
Итак ... Что может происходить в этом процессе, чтобы появились такие симптомы