Проверка параметров wsprintf

Тема в разделе "WASM.RESEARCH", создана пользователем Broken Sword, 24 окт 2006.

  1. Broken Sword

    Broken Sword Robert

    Публикаций:
    0
    Регистрация:
    30 авг 2002
    Сообщения:
    433
    В коде происходит вызов wsprintf. Шаблон динамический. Часто попадают инвалидные параметры. Как красивее всего обрабатывать исключение внутри wsprintf? Пока повесил SEH, в _except_handler-е делаю просто ContextRecord->Eip+=2 (катит для всех ложных "%s", т.к. падает на двухбайтных командах типа mov DL,[EAX]), но нужно обрабатывать еще и "%ls" (там уже четырехбайтные инструкции типа mov cx,[eax]). Лезть в шаблон или в код команды и вручную парсить неохота... Может есть очевидный вариант?)
     
  2. nobodyzzz

    nobodyzzz New Member

    Публикаций:
    0
    Регистрация:
    13 июл 2005
    Сообщения:
    475
    имхо, очевидного точно нет, если бы был printf format string vulnerabilities не былобы в таком случае =)
     
  3. CnCVK

    CnCVK New Member

    Публикаций:
    0
    Регистрация:
    9 авг 2006
    Сообщения:
    108
    А взять сырцы от C/C++ компилера?
    Неподходит?
    Там есть sprintf :)
     
  4. Broken Sword

    Broken Sword Robert

    Публикаций:
    0
    Регистрация:
    30 авг 2002
    Сообщения:
    433
    а толку от сырцов sprintf? все равно проверку на валидность нужно реализовывать самому.
    Я тут отрыл какой-то StringCbPrintfEx - там вроде какая-то проверка есть. Но вроде только буфера.
     
  5. Asterix

    Asterix New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2003
    Сообщения:
    3.576
    что-то я не понял, что приводит к падению?
    а нельзя использовать безопасные сишные функции вместо wsprintf ?
     
  6. shoo

    shoo New Member

    Публикаций:
    0
    Регистрация:
    17 июл 2003
    Сообщения:
    1.537
    Адрес:
    Ukraine
    не использовать wsprintf. для асма я набросал набор макросов для динамического построения строк. если интересно - здесь cs_test.
     
  7. mrhx

    mrhx New Member

    Публикаций:
    0
    Регистрация:
    11 окт 2006
    Сообщения:
    63
    просто надо нормально генерить format-string для wsprintf и все проверки перенести именно в место генерации.
     
  8. Broken Sword

    Broken Sword Robert

    Публикаций:
    0
    Регистрация:
    30 авг 2002
    Сообщения:
    433
    Asterix, к падению приводит неправильный параметр, переданный в wsprintf. Например, в шаблоне значится "%s", а переданный параметр - не указатель на строку, а какое-нибудь число (например, 500h). Падение происходит внутри wsprintf при попытке чтения по адресу 500h (mov dl, [eax] ; eax=500h). Какие безопасные ты имеешь ввиду? Я пробовал StringCbPrintfEx - но он проверяет только буфер от переполнения, а мой случай не обрабатывается.

    shoo
    с созданием шаблонов проблем никаких нет.
     
  9. Broken Sword

    Broken Sword Robert

    Публикаций:
    0
    Регистрация:
    30 авг 2002
    Сообщения:
    433
    mrhx
    Дело в том, что в моем случае это невозможно. Я пишу логгер вызовов api, есть такие хитрые функции, у которых один и тот же параметр может быть как указателем, так и числом. Например, LoadImage вторым параметром понимает как указатель на имя bmp, так и идентификатор из ресурсов.
     
  10. mrhx

    mrhx New Member

    Публикаций:
    0
    Регистрация:
    11 окт 2006
    Сообщения:
    63
    Broken Sword
    ну значит должны быть некие правила формирования строки для wsprintf.
    по умолчанию там будет то, что у тебя сейчас есть, а в какихто отдельных случаях - другое.
     
  11. Broken Sword

    Broken Sword Robert

    Публикаций:
    0
    Регистрация:
    30 авг 2002
    Сообщения:
    433
    mrhx
    Количество перехватываемых API - несколько тысяч. Формат строки для каждой функции (для wsprintf) генерится скриптом на Perl-е, используя заголовочные файлы из VC. Вручную пересмотреть все форматы и заменить сомнительные %s на %#X, к примеру, нет никакой возможности. Необходимо обрабатывать исключения в проге, другого пути нет. Неужели нет безопасной версии wsprintf, с внутренним SEH-ом ?
     
  12. shoo

    shoo New Member

    Публикаций:
    0
    Регистрация:
    17 июл 2003
    Сообщения:
    1.537
    Адрес:
    Ukraine
    у которых один и тот же параметр может быть как указателем, так и числом > вообще-то в данном конкретном случае достаточно проверить старшее слово: если оно равно 0, значит, это идентификатор, иначе - указатель. (но в общем случае это еще не значит, что это указатель на строку)
    ==========
    я почему за макросы сказал: если заниматься проверкой каждого параметра, а потом вызывать wsprintf, то возможно проще сразу составить конечную строку в процессе проверки. кстати, на базе этих макросов можно и аналог wsprintf слепить несложно (в т.ч. с дополнительной внутренней "интеллектуальной" проверкой или SEH) у меня мысль была, но не было потребности в таком аналоге.
    ==========
    идея2: создав собственную функцию можно расширить набор управляющих символов, типа \# - функция сама будет проверять - указатель это или идентификатор, и принимать правильное решение ;)
     
  13. Asterix

    Asterix New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2003
    Сообщения:
    3.576
    Broken Sword
    почему нельзя SEH самому юзать я не понял ?
    Код (Text):
    1.     __try
    2.     {
    3.         wsprintf(...);
    4.     }
    5.     __except(EXCEPTION_EXECUTE_HANDLER){}
    6.     .........
     
  14. Smile

    Smile New Member

    Публикаций:
    0
    Регистрация:
    28 июл 2004
    Сообщения:
    129
    Broken Sword
    Может не ленится и всетаки написать оболочку для wsprintf, мельком пройтись по параметрам и самые неприятные %p %s проверить, например, функциями IsBadReadPtr/IsBadStringPtr.
     
  15. Broken Sword

    Broken Sword Robert

    Публикаций:
    0
    Регистрация:
    30 авг 2002
    Сообщения:
    433
    Asterix
    А что писать в обработчике (__except)? Убивать процесс нельзя. Вернуться на инструкцию ПОСЛЕ вызова wsprintf было бы отлично, только как это сделать? Нужно ж стек вернуть в корректное состояние, регистры восстановить и т.п.

    Smile
    IsBadReadPtr/IsBadStringPtr - похоже, это то на чем придется остановиться.
     
  16. Asterix

    Asterix New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2003
    Сообщения:
    3.576
    Broken Sword
    ничего не писать, вызовется дефолтный обработчик, управление перейдет на код за
    __except(EXCEPTION_EXECUTE_HANDLER){}

    подробности у Рихтера
     
  17. mrhx

    mrhx New Member

    Публикаций:
    0
    Регистрация:
    11 окт 2006
    Сообщения:
    63
    Smile дело говорит. IsBad**Ptr() это то что надо :)
     
  18. Broken Sword

    Broken Sword Robert

    Публикаций:
    0
    Регистрация:
    30 авг 2002
    Сообщения:
    433
    Asterix в двух фразах выразил то, чего нельзя найти в размазанных по 10 страницам статьям Питрека про SEH, все заработало. Просто на С только начинаю писать. Thx. Тема закрыта.
     
  19. Smile

    Smile New Member

    Публикаций:
    0
    Регистрация:
    28 июл 2004
    Сообщения:
    129
    Broken Sword
    Лентяй :) API функции с неверными параметрами отобраджатся ведь не будут? Так как wsprintf упадет ничего не отпечатав.

    А вот если параметры проверить можно подменить %s на %X
     
  20. RedLord

    RedLord Member

    Публикаций:
    0
    Регистрация:
    23 июн 2005
    Сообщения:
    183
    Адрес:
    Ukraine
    см. MSDN: IS_INTRESOURCE