&引用;xor eax,ebp“;用于C++;编译器输出 我只是尝试在VS2010上编译两个C++片段,分析了IDA Pro上的可执行文件。我注意到,他们中的大多数人一开始都有如下内容(在打电话给_security\u check\u cookie后不久)

&引用;xor eax,ebp“;用于C++;编译器输出 我只是尝试在VS2010上编译两个C++片段,分析了IDA Pro上的可执行文件。我注意到,他们中的大多数人一开始都有如下内容(在打电话给_security\u check\u cookie后不久),c++,assembly,reverse-engineering,compiler-optimization,buffer-overflow,C++,Assembly,Reverse Engineering,Compiler Optimization,Buffer Overflow,异或eax,ebp 什么的 异或ecx,ebp 在底部。为什么会发生这种情况?编译器优化已关闭。这些是缓冲区溢出保护方法,与编译器优化无关。MSVC将(如果您指定开关)将安全cookie推送到返回地址附近的堆栈上,以便它可以检测堆栈损坏的常见情况 堆栈损坏可能是由以下错误代码引起的: char buff[5]; strcpy (buff, "Man, this string is waaay too long!!"); 或者恶意用户利用糟糕的编码实践,例如使用scanf(“

异或eax,ebp

什么的

异或ecx,ebp


在底部。为什么会发生这种情况?编译器优化已关闭。

这些是缓冲区溢出保护方法,与编译器优化无关。MSVC将(如果您指定开关)将安全cookie推送到返回地址附近的堆栈上,以便它可以检测堆栈损坏的常见情况

堆栈损坏可能是由以下错误代码引起的:

char buff[5];
strcpy (buff, "Man, this string is waaay too long!!");
或者恶意用户利用糟糕的编码实践,例如使用
scanf(“%s”,myBuff)
进行用户输入。像这样精心设计的攻击可以诱使你的程序做你可能不想做的事情

通过将cookie放在靠近返回地址的位置,可以防止大量的bug(和攻击向量),这仅仅是因为内存损坏在本质上往往是连续的。换句话说,如果您覆盖了返回地址,可能是因为您开始在cookie的一侧写入,并且内存一直损坏到cookie另一侧的返回地址(因此cookie也将被覆盖)

它不会捕获所有的bug,因为您可能有以下代码:

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.
这基本上与上述过程相反。只有当
ecx
设置为正确的cookie值时,
@\u sec\u check\u cookie
调用才会返回。否则,它将引发故障,如已确认的:

\uuu security\u check\u cookie()
例程非常简单:如果cookie没有更改,它将执行
RET
指令并结束函数调用。如果cookie不匹配,例程将调用
report\u failure()

然后,
report\u failure()
函数调用
\u security\u error\u handler()
。这两个函数都在c运行时(CRT)源文件的
seccook.c
文件中定义

要使这些安全检查正常工作,需要CRT支持。当安全检查失败时,程序的控制权将传递给
\uu security\u error\u 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);
}