"xor eax,ebp"用于C++编译器输出

43 c++ assembly reverse-engineering buffer-overflow compiler-optimization

我只是尝试在VS2010上编译几个C++片段并分析IDA Pro上的可执行文件.我注意到的是,他们中的大多数在开始时都有类似的内容(在调用__security_check_cookie之后不久)

xor eax, ebp

和类似的东西

xor ecx, ebp

在底部.为什么会这样?编译器优化已关闭.

pax*_*blo 69

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

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

char buff[5];
strcpy (buff, "Man, this string is waaay too long!!");
Run Code Online (Sandbox Code Playgroud)

或恶意用户利用不良编码实践,例如scanf ("%s", myBuff)用于用户输入.像这样的精心制作的攻击可以让你的程序能够做你可能不想要的事情.

通过将cookie放置在返回地址附近,可以防止大量错误(和攻击向量),这仅仅是因为存储器损坏本质上是顺序的.换句话说,如果你已经覆盖了返回地址,可能是因为你开始在cookie的一侧写入并且损坏内存一直到cookie另一端的返回地址(因此cookie将被覆盖)以及).

它没有捕获所有错误,因为您可能有一些代码,如:

char buff[5];
buff[87] = 'x';
Run Code Online (Sandbox Code Playgroud)

这可能会在触及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.
Run Code Online (Sandbox Code Playgroud)

这是自定义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.
Run Code Online (Sandbox Code Playgroud)

它基本上只是上述相反的过程.该@__sec_check_cookie如果调用将只返回ecx被设置为正确的cookie的值.否则,它会引发故障,证实这里:

__security_check_cookie()程序很简单:如果cookie是不变的,它执行的RET指令,并结束函数调用.如果cookie无法匹配,则例程调用report_failure().

report_failure()然后该函数调用__security_error_handler().这两个函数都在seccook.cC运行时(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);
}
Run Code Online (Sandbox Code Playgroud)

默认情况下,未通过安全检查的应用程序会显示一个对话框,指出"检测到缓冲区溢出!".解除对话框后,应用程序终止.