«xor eax, ebp» используется в выводе компилятора C ++ - PullRequest
43 голосов
/ 15 июня 2011

Я только что попытался скомпилировать пару фрагментов C ++ на VS2010 и проанализировал исполняемые файлы на IDA Pro.Что-то, что я заметил, - там у большинства из них есть что-то вроде следующего в начале (вскоре после вызова __security_check_cookie)

xor eax, ebp

и что-то вроде

xor ecx, ebp

внизу.Почему это происходит?Оптимизация компилятора отключена.

1 Ответ

69 голосов
/ 15 июня 2011

Это методы защиты от переполнения буфера и не имеют ничего общего с оптимизацией компилятора. MSVC (если вы укажете переключатель /GS) поместит cookie-файл безопасности в стек рядом с обратным адресом, чтобы он мог обнаружить общий случай повреждения стека.

Повреждение стека может быть вызвано неверным кодом, например:

char buff[5];
strcpy (buff, "Man, this string is waaay too long!!");

или злонамеренными пользователями, использующими плохие методы кодирования, например использование scanf ("%s", myBuff) для ввода данных пользователем Тщательно подобранные атаки могут заставить вашу программу делать то, что вы, вероятно, не хотите.

Поместив файл cookie рядом с обратным адресом, можно предотвратить большое количество ошибок (и векторов атак) просто из-за того, что повреждения памяти имеют тенденцию быть последовательными по своей природе. Другими словами, если вы перезаписали адрес возврата, это возможно потому, что вы начали писать на одной стороне файла cookie и повредили память вплоть до адреса возврата на другой стороне файла cookie (следовательно, файл cookie будет перезаписан а также).

Он не улавливает всех ошибок, поскольку у вас может быть такой код, как:

char buff[5];
buff[87] = 'x';

, который потенциально может повредить обратный адрес без касания файла cookie. Но он поймает все те злонамеренные, которые полагаются на ввод более длинной строки, чем ожидалось, которые повреждают до обратного адреса (включая cookie).

Последовательность, которую вы, вероятно, видите в коде, выглядит примерно так:

mov  eax, dword ptr ds:___sec_cookie   ; fixed value.
xor  eax, ebp                          ; adjust based on base pointer.
mov  [ebp+SOMETHING], eax              ; store adjusted value.

, который настраивает куки, в зависимости от текущего базового указателя.

Это изменит то, что фактически помещается в стек на каждом уровне стека (а также зависит от количества параметров и размеров) и, вероятно, является попыткой дополнительной защиты кода от злонамеренных намерений, обеспечивая переменную подпись записывается в стек, а не в фиксированное значение (в противном случае злоумышленник может ввести символы , включая действительный файл cookie).

И последовательность в конце запустится примерно так:

mov  ecx, [ebp+SOMETHING]              ; get the adjusted cookie.
xor  ecx, ebp                          ; un-adjust it, since
                                       ;   ((N xor X) xor X) == N.
call @__sec_check_cookie               ; check the cookie.

Это в основном обратный процесс, описанный выше. Вызов @__sec_check_cookie будет возвращен только в том случае, если для ecx установлено правильное значение cookie. В противном случае возникнет ошибка, подтвержденная здесь :

Процедура __security_check_cookie() проста: если файл cookie не изменился, он выполняет инструкцию RET и завершает вызов функции. Если cookie не совпадает, программа вызывает report_failure().

Затем функция report_failure() вызывает __security_error_handler(). Обе функции определены в файле seccook.c исходных файлов C времени выполнения (CRT).

Поддержка CRT необходима, чтобы эти проверки безопасности работали. Когда происходит сбой проверки безопасности, управление программой передается на __security_error_handler(), который суммирован здесь:

void __cdecl __security_error_handler(int code, void *data)
{
    if (user_handler != NULL) {
      __try {
        user_handler(code, data);
      } __except (EXCEPTION_EXECUTE_HANDLER) {}
    } else {
      //...prepare outmsg...

      __crtMessageBoxA(
          outmsg,
          "Microsoft Visual C++ Runtime Library",
          MB_OK|MB_ICONHAND|MB_SETFOREGROUND|MB_TASKMODAL);
    }
    _exit(3);
}

По умолчанию приложение, не прошедшее проверку безопасности, отображает диалоговое окно с сообщением «Обнаружено переполнение буфера!». Когда диалог закрывается, приложение закрывается.

...