"xor eax, ebp" C++编译器输出中使用
"xor eax, ebp" being used in C++ compiler output
我刚刚尝试在VS2010上编译几个C++片段,并在IDA Pro上分析了可执行文件。我注意到,它们中的大多数在开始时(在调用__security_check_cookie后不久)都有如下内容
xor eax, ebp
以及类似的东西
xor ecx, ebp
底部。为什么会发生这种情况?编译器优化已关闭。
这些是缓冲区溢出保护方法,与编译器优化无关。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.
这基本上只是上面描述的相反过程。只有当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);
}
默认情况下,未通过安全检查的应用程序显示一个对话框;检测到缓冲区溢出&";。当对话框被取消时,应用程序将终止。
- C++编译器命令 C++ 不会生成输出
- 编译器资源管理器和 GCC 具有不同的输出
- 与其他编译器相比,相同的代码在工作室Microsoft提供不同的输出
- 编译器没有显示错误,但我没有得到任何输出.怎么了?
- 在MSDOS编译器上,用大于最大值的值初始化int时输出混乱
- 我不明白我的编译器是如何获得此输出的
- C++编译器只显示数字,不显示正确的输出
- 乘以时输出错误.这是我编译器中的错误吗?C
- Web 编译器输出奇怪的结果
- 输出错误:两个不同编译器上的不同输出:Prime Cryptarithm USACO
- 编译器将输出的流运算符<<解释为用于按位左移的二进制运算符<<
- 构建 C/C++ 代码时的 Gradle 编译器输出
- C 编译器输出由于Permisson误差而未运行
- GCC 编译器对类型转换有什么作用?为什么 mac 和 Linux 上的输出不同
- VS说"Too few arguments...",但其他编译器给了我正确的输出?
- GCC 8 交叉编译器输出 ARMv7 可执行文件而不是 ARMv6
- 以下代码的输出是什么(答案因差异编译器而异)
- 简单构造函数的复杂编译器输出
- C++程序中的输出编译器版本
- 最后的所有输出——c++编译器