Подтвердить что ты не робот

"xor eax, ebp" используется в выводе компилятора С++

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

xor eax, ebp

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

xor ecx, ebp

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

4b9b3361

Ответ 1

Это методы защиты от переполнения буфера и не имеют ничего общего с оптимизацией компилятора. 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, в зависимости от текущего указателя базы.

Это изменит то, что на самом деле помещено в стек на каждом уровне стека (а также в зависимости от количества и размеров параметров) и, вероятно, является попыткой дополнительной защиты кода от вредоносного намерения путем обеспечения записи переменной сигнатуры в стек, а не фиксированное значение (в противном случае злоумышленник может вводить символы, включая действительный файл 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 исходных файлов времени выполнения (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);
}

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