В коде происходит вызов wsprintf. Шаблон динамический. Часто попадают инвалидные параметры. Как красивее всего обрабатывать исключение внутри wsprintf? Пока повесил SEH, в _except_handler-е делаю просто ContextRecord->Eip+=2 (катит для всех ложных "%s", т.к. падает на двухбайтных командах типа mov DL,[EAX]), но нужно обрабатывать еще и "%ls" (там уже четырехбайтные инструкции типа mov cx,[eax]). Лезть в шаблон или в код команды и вручную парсить неохота... Может есть очевидный вариант?)
имхо, очевидного точно нет, если бы был printf format string vulnerabilities не былобы в таком случае =)
а толку от сырцов sprintf? все равно проверку на валидность нужно реализовывать самому. Я тут отрыл какой-то StringCbPrintfEx - там вроде какая-то проверка есть. Но вроде только буфера.
что-то я не понял, что приводит к падению? а нельзя использовать безопасные сишные функции вместо wsprintf ?
не использовать wsprintf. для асма я набросал набор макросов для динамического построения строк. если интересно - здесь cs_test.
просто надо нормально генерить format-string для wsprintf и все проверки перенести именно в место генерации.
Asterix, к падению приводит неправильный параметр, переданный в wsprintf. Например, в шаблоне значится "%s", а переданный параметр - не указатель на строку, а какое-нибудь число (например, 500h). Падение происходит внутри wsprintf при попытке чтения по адресу 500h (mov dl, [eax] ; eax=500h). Какие безопасные ты имеешь ввиду? Я пробовал StringCbPrintfEx - но он проверяет только буфер от переполнения, а мой случай не обрабатывается. shoo с созданием шаблонов проблем никаких нет.
mrhx Дело в том, что в моем случае это невозможно. Я пишу логгер вызовов api, есть такие хитрые функции, у которых один и тот же параметр может быть как указателем, так и числом. Например, LoadImage вторым параметром понимает как указатель на имя bmp, так и идентификатор из ресурсов.
Broken Sword ну значит должны быть некие правила формирования строки для wsprintf. по умолчанию там будет то, что у тебя сейчас есть, а в какихто отдельных случаях - другое.
mrhx Количество перехватываемых API - несколько тысяч. Формат строки для каждой функции (для wsprintf) генерится скриптом на Perl-е, используя заголовочные файлы из VC. Вручную пересмотреть все форматы и заменить сомнительные %s на %#X, к примеру, нет никакой возможности. Необходимо обрабатывать исключения в проге, другого пути нет. Неужели нет безопасной версии wsprintf, с внутренним SEH-ом ?
у которых один и тот же параметр может быть как указателем, так и числом > вообще-то в данном конкретном случае достаточно проверить старшее слово: если оно равно 0, значит, это идентификатор, иначе - указатель. (но в общем случае это еще не значит, что это указатель на строку) ========== я почему за макросы сказал: если заниматься проверкой каждого параметра, а потом вызывать wsprintf, то возможно проще сразу составить конечную строку в процессе проверки. кстати, на базе этих макросов можно и аналог wsprintf слепить несложно (в т.ч. с дополнительной внутренней "интеллектуальной" проверкой или SEH) у меня мысль была, но не было потребности в таком аналоге. ========== идея2: создав собственную функцию можно расширить набор управляющих символов, типа \# - функция сама будет проверять - указатель это или идентификатор, и принимать правильное решение
Broken Sword почему нельзя SEH самому юзать я не понял ? Код (Text): __try { wsprintf(...); } __except(EXCEPTION_EXECUTE_HANDLER){} .........
Broken Sword Может не ленится и всетаки написать оболочку для wsprintf, мельком пройтись по параметрам и самые неприятные %p %s проверить, например, функциями IsBadReadPtr/IsBadStringPtr.
Asterix А что писать в обработчике (__except)? Убивать процесс нельзя. Вернуться на инструкцию ПОСЛЕ вызова wsprintf было бы отлично, только как это сделать? Нужно ж стек вернуть в корректное состояние, регистры восстановить и т.п. Smile IsBadReadPtr/IsBadStringPtr - похоже, это то на чем придется остановиться.
Broken Sword ничего не писать, вызовется дефолтный обработчик, управление перейдет на код за __except(EXCEPTION_EXECUTE_HANDLER){} подробности у Рихтера
Asterix в двух фразах выразил то, чего нельзя найти в размазанных по 10 страницам статьям Питрека про SEH, все заработало. Просто на С только начинаю писать. Thx. Тема закрыта.
Broken Sword Лентяй API функции с неверными параметрами отобраджатся ведь не будут? Так как wsprintf упадет ничего не отпечатав. А вот если параметры проверить можно подменить %s на %X