<转> xor eax, ebp” being used

I just tried compiling a couple of C++ snippets on VS2010 and analyzed the executables on IDA Pro. Something I noticed is that there most of them have something like the following at the start(shortly after a call to __security_check_cookie)

xor eax, ebp

and something like

xor ecx, ebp

at the bottom. Why does this happen? The compiler optimization was turned off.

answer:

These are buffer overrun protection methods, and have nothing to do with compiler optimisation. MSVC will (if you specify the /GS switch) push a security cookie onto the stack near the return address so that it can detect a common case of stack corruption.

Stack corruption can either be caused by bad code along the lines of:

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

or by malicious users taking advantage of bad coding practices, like the use of scanf ("%s", myBuff) for user input. Carefully crafted attacks like that can suborn your program to do things you probably don’t want it to.

By placing a cookie close to the return address, a large number of bugs (and attack vectors) can be prevented, simply due to the fact that the memory corruptions tend to be sequential in nature. In other words, if you’ve overwritten the return address, it’s probably because you started writing on one side of the cookie and corrupted memory all the way up to the return address on the other side of the cookie (hence the cookie will be overwritten as well).

It doesn’t catch all bugs since you may have some code like:

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

which could potentially corrupt the return address without touching the cookie. But it will catch all those malicious ones which rely on entering a longer string than expected, which corrupt up to the return address (including cookie).

The sequence you’re probably seeing in the code is something like:

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

which is customising the cookie, depending on the current base pointer.

This will change what is actually put on the stack at each stack level (and also depending on parameter count and sizes as well) and is probably an attempt to further secure the code from malicious intent, by ensuring a variable signature is written to the stack rather than a fixed value (otherwise the attacker could enter characters including a valid cookie).

And the sequence at the end will run something like this:

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. 

It’s basically just the reverse process of that described above. The @__sec_check_cookie call will only return if ecx is set to the correct cookie value. Otherwise it will raise a fault, as confirmed here:

The __security_check_cookie() routine is straightforward: if the cookie was unchanged, it executes the RET instruction and ends the function call. If the cookie fails to match, the routine calls report_failure().

The report_failure() function then calls __security_error_handler(). Both functions are defined in the seccook.c file of the C run-time (CRT) source files.

CRT support is needed to make these security checks work. When a security check failure occurs, control of the program is passed to __security_error_handler(), which is summarized here:

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); 
} 

By default, an application that fails a security check displays a dialog that states “Buffer overrun detected!”. When the dialog is dismissed, the application terminates.

转载于:https://www.cnblogs.com/zhangdongsheng/archive/2012/06/07/2540879.html

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

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

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

或者恶意用户利用不好的编码做法,比如使用scanf ("%s", myBuff)进行用户input。 像这样精心制作的攻击可能会使你的程序无法做你可能不想要的东西。

通过将cookie放在返回地址附近,可以防止大量的错误(和攻击媒介),这仅仅是因为内存损坏往往是连续的。 换句话说,如果你覆盖了返回地址,这可能是因为你开始在cookie的一边写入内容,一直到cookie另一边的返回地址(因此cookie将被覆盖以及)。

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

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

这可能会在不接触cookie的情况下破坏返回地址。 但是它会捕获所有那些依赖于input比预期更长的string的恶意程序,这个恶意程序会破坏到返回地址(包括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。

这将改变每个堆栈级别上实际放置在堆栈上的内容(也取决于参数数量和大小),可能是通过确保将可变签名写入堆栈来尝试进一步保护恶意代码的安全而不是固定值(否则攻击者可以input包括有效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值时, @__sec_check_cookie调用才会返回。 否则会引发一个错误,正如这里所证实的那样:

__security_check_cookie()例程很简单:如果cookie没有改变,则执行RET指令并结束函数调用。 如果cookie不匹配,则例程调用report_failure() 。

report_failure()函数然后调用__security_error_handler() 。 这两个函数都在C运行时(CRT)源文件的seccook.c文件中定义。

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); 
} 

默认情况下,安全检查失败的应用程序将显示一个对话框,指出“检测到缓冲区溢出!”。 当对话框被解除时,应用程序终止。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值