Здравствуйте, Evgeniy Skvortsov, Вы писали:
ES>Здравствуйте
ES>Ещё один вопрос, система предполагается 64-битная. А как быть с 32-битными приложениями? ES>Собрать эту же dll и под 32 бита?
да
ES>А как их обе в ключ реестра AppSecDll засунуть?
насколько я помню, достаточно две версии длл с одинаковым названием, одну поместить в syswow64,другую в system32,соответственно одна запись в AppSecDll.
UPD. Название не обязательно должно быть AppSecDll, можно другое, главное в нужной ветке реестра.
Натолкнулся на такую странную штуку. Есть приложение, которое падает на моей dll-ке (Это MS VS 2005)
Падает так.
Я хотел для начала просто логировать приложения.
В результате dll-ка падала при открытии файла в fopen(_tfopen).
Я решил вывести отладочную информацию в MessageBox, оно тоже упало.
Стал тогда разбираться под дебагом, выяснил следующее:
MessageBox (это user32) обращается через таблицу импорта к LoadStringBaseExW, которая находится в kernel32.dll, но почему-то в таблице импорта на тот момент ноль (там целый блок нулей), от этого MessageBox падает, call по нулевому адресу. При этом GelModuleHandle(TEXT("kernel32")) валиден, и с него можно снять GetProcAddress для LoadStringBaseExW (к теме импорта это отношения не имеет, просто проверил, что модуль и функция присутствуют). С fopen ошибка возникает в другом месте, но подозреваю ошибка та же.
Что это такое? И как хотя бы понять, что нельзя звать MessageBox/fopen? Лезть в таблицу импорта программно не хочется.
Почему у других приложений всё ок (это при варианте того, что AppSecDll грузится самой первой, потому что так задумано, поэтому других dll-ей нету ещё)?
CEM>Натолкнулся на такую странную штуку. Есть приложение, которое падает на моей dll-ке (Это MS VS 2005)
CEM>... CEM>Что это такое? И как хотя бы понять, что нельзя звать MessageBox/fopen? Лезть в таблицу импорта программно не хочется. CEM>Почему у других приложений всё ок (это при варианте того, что AppSecDll грузится самой первой, потому что так задумано, поэтому других dll-ей нету ещё)?
А MessageBox, случайно, не из DllMain вызывается? Если что, так делать нельзя...
Здравствуйте, CEMb, Вы писали:
CEM>Из CreateProcessNotify, там получаю имя приложения и пишу его в файл CEM>И другие процессы работают нормально, все логируются, кроме студии 2005
А stack trace есть (в WinDBG команда k или kb)? Интересует падение с fopen.
И что показывает "!analyze -v" (WinDBG)?
Здравствуйте, okman, Вы писали:
O>Здравствуйте, CEMb, Вы писали:
CEM>>Из CreateProcessNotify, там получаю имя приложения и пишу его в файл CEM>>И другие процессы работают нормально, все логируются, кроме студии 2005
O>А stack trace есть (в WinDBG команда k или kb)? Интересует падение с fopen. O>И что показывает "!analyze -v" (WinDBG)?
WindbG нету
Падает в msvcr120d.dll в функции __crtIsPackegedApp, не в самой ней, а из неё делается call по смещению 0x13e5d0(msvcr120d версия 12.00.21005.1), я не знаю, что это, в таблице экспорта этой функции нет. И вот внутри неё делается call по указателю из стрека bsp-4, и там какой битый адрес
Здравствуйте, CEMb, Вы писали:
CEM>WindbG нету CEM>Падает в msvcr120d.dll в функции __crtIsPackegedApp, не в самой ней, а из неё делается call по смещению 0x13e5d0(msvcr120d версия 12.00.21005.1), я не знаю, что это, в таблице экспорта этой функции нет. И вот внутри неё делается call по указателю из стрека bsp-4, и там какой битый адрес
Ну если ни дампа, ни стек-трейса нету, остается только гадать
Предположу, что проблема, возможно, была вызвана загрузкой msvcr120d.dll, либо тем, что использовалась ее
отладочная версия (суффикс "d"). Можно попробовать пересобрать твою dll с флагом Runtime Library = Multi-Threaded (/MT) и
в режиме Release. Я бы начал с этого.
Не помню точно, в какой момент отрабатывают нотификаторы AppCertDlls, вроде бы это внутри kernel32 на начальном
этапе работы CreateProcess. Может быть, в них вообще ничего нельзя загружать, кроме нативных (т.е. использующих
строго ntdll) модулей. Т.е. никаких fopen и тем более MessageBox дергать оттуда нельзя...
CEM>Из CreateProcessNotify, там получаю имя приложения и пишу его в файл CEM>И другие процессы работают нормально, все логируются, кроме студии 2005
Может так быть что этот CreateProcessNotify прилетел из CreateProcess, который ктото вызвал из DllMain. Этот ктото, конечто же, негодяй, но прилетело вам. Очень похоже на недоинициализированные dll изза вызова их функций из DllMain в ситуации циклических зависимостей. То есть ваш CreateProcessNotify вызвался раньше чем user32 инициализировалась.
Глянуть полный стек конечно бы было очень полезно для подтверждения/опровержения.
В качестве фикса пальцем в потолок можно попробовать проверять результат RtlIsThreadWithinLoaderCallout и убегать в ужасе если она возвратнула Правду.
Как много веселых ребят, и все делают велосипед...
Здравствуйте, okman, Вы писали:
CEM>>WindbG нету CEM>>Падает в msvcr120d.dll в функции __crtIsPackegedApp, не в самой ней, а из неё делается call по смещению 0x13e5d0(msvcr120d версия 12.00.21005.1), я не знаю, что это, в таблице экспорта этой функции нет. И вот внутри неё делается call по указателю из стрека bsp-4, и там какой битый адрес
O>Ну если ни дампа, ни стек-трейса нету, остается только гадать
Малый дамп я могу выгрузить из студии. Стектрейс есть, но как его выгрузить в нормальном виде из студии, я не знаю. И символы не могу подгрузить, так как комп находится во внутренней закрытой сетке (приходится искать функции через dependse и смещения)
O>Предположу, что проблема, возможно, была вызвана загрузкой msvcr120d.dll, либо тем, что использовалась ее O>отладочная версия (суффикс "d"). Можно попробовать пересобрать твою dll с флагом Runtime Library = Multi-Threaded (/MT) и O>в режиме Release. Я бы начал с этого.
С релизом та же картина.
O>Не помню точно, в какой момент отрабатывают нотификаторы AppCertDlls, вроде бы это внутри kernel32 на начальном O>этапе работы CreateProcess. Может быть, в них вообще ничего нельзя загружать, кроме нативных (т.е. использующих O>строго ntdll) модулей. Т.е. никаких fopen и тем более MessageBox дергать оттуда нельзя...
А как бы можно было бы тогда это дело пологировать? Файловые потоки тоже не работают.
O>RtlIsThreadWithinLoaderCallout