首页 > 编程语言 >为何vs编译边出来的程序ebp-4存放的不是第一个局部变量?而是security_cookie——本质上就是存的随机数和ebp异或的值

为何vs编译边出来的程序ebp-4存放的不是第一个局部变量?而是security_cookie——本质上就是存的随机数和ebp异或的值

时间:2023-04-15 17:12:08浏览次数:50  
标签:__ 函数 异或 cookie ebp security

快速识别

 

最后那个call就是比较存的随机数和ebp异或的值是否和之前是否一样:

 

 

 

 

探究security_cookie在程序中的作用

 

from:https://www.kn0sky.com/?p=66

学习环境:Windows 10 20H2 + Visual Studio 2019

前言

在学习看反汇编程序的时候,使用VS2019编译的release版本的程序里经常会出现__security_cookie相关的代码

经过查阅资料,了解到这块代码会编译器增加到函数的开始与结束的位置,用来防止栈溢出

好奇心驱使本文来探究一番这个机制是怎么防止栈溢出的

随便写一段简单的代码:

#include<stdio.h>
int main(){
	char szName[] = "hello selph";
	printf("%s",szName);
	return 0;
}

使用VS2019编译release版本,调试运行,查看反汇编:

int main()
{
; 这里是函数栈帧操作, 保存ebp, 抬高esp留出栈空间给局部变量使用
00621040  push        ebp  
00621041  mov         ebp,esp  
00621043  sub         esp,10h

; 这里将一个常量(__security_cookie)拿出来放到eax里
00621046  mov         eax,dword ptr [__security_cookie (0623004h)]  

; 然后将eax和ebp进行异或操作, 这里的ebp是进入函数前的esp
0062104B  xor         eax,ebp  

; 将计算结果存入ebp-4的位置, 实际上就是存到第一个局部变量里了
0062104D  mov         dword ptr [ebp-4],eax  

; 以下部分是程序内容本身, 本文不对此进行分析, 故省略
...
	return 0;
}
; 程序执行结束后 
; 将程序开头计算的结果取出来放到ecx
00621073  mov         ecx,dword ptr [ebp-4]  

; 对printf函数的参数进行平栈操作, C/C++默认是_cdecl函数调用约定,故调用者负责平栈
00621076  add         esp,8  

; 将取出来的值再次与ebp进异或计算
00621079  xor         ecx,ebp  

; 清空eax, 准备接收返回值
0062107B  xor         eax,eax  

; 调用函数
0062107D  call        __security_check_cookie (0621086h)  

; 栈帧操作, 还原栈帧到进入调用前
00621082  mov         esp,ebp  
00621084  pop         ebp  
00621085  ret  

这里在进入程序之前,将进入函数前的栈顶指针esp与一个常量进行异或操作

在位操作里,仅有异或和取反是可以反推的,连续对同一个数异或2次的值=没有进行任何计算的时候的值

这里在程序结束之后,将之前计算的结果再次与进入函数前的栈顶指针esp进行异或操作

此时如果不出意外的话,计算结果应该会变回先前用来异或的那个常量__security_cookie,值存在ecx里

然后调用函数__security_check_cookie

查看该函数的反汇编:

; 这里将ecx, 也就是经过对同一个值两次异或操作的__security_cookie 与 __security_cookie进行对比
06211086  cmp         ecx,dword ptr [__security_cookie (6213004h)]  

; 不相同就跳转到 failure
0621108C  bnd jne     failure (6211091h)
; 相同就返回
0621108F  bnd ret

; 无条件跳转到 __report_gsfailure 函数中去
failure:
06211091  bnd jmp     __report_gsfailure (6211310h)  

网上复制了一段关于BND前缀的介绍:

BND前缀是Intel MPX(内存保护扩展)的一部分,指示应根据BND0至BND3寄存器中指定的界限检查返回目标(或通常为分支目标,因为BND可以应用于任何控制流指令) ,否则将产生异常-表示潜在的堆栈溢出,编程错误或恶意代码攻击。

关于bnd前缀嘛,这里就当他没用吧

__security_check_cookie函数非常简单,判断__security_cookie经过进入程序前,程序结束后两次异或操作后,是否为原来的值,为原来的值则表示栈中的该位置没有被各种栈操作影响,也就是说不影响程序接下来的执行,接下来就直接返回

如果该值变了,则表示发生了栈溢出,则跳转到__report_gsfailure函数中去报告错误,程序将不再继续执行

程序的栈结构变化

进入函数前后的栈的变化:

image-20210518114526023

通过call进入函数,会压入返回地址,然后进入函数代码

在函数代码里,会入栈保存原来的ebp然后抬高esp栈顶指针

是否有防溢出机制__security_cookie的区别就体现在接下来的操作上了:

  • 如果有该机制,则会往ebp-4的位置上存入__security_cookie异或值,用于后来再次进行异或检查栈中该位置是否被改变用
  • 如果无该机制,则ebp-4开始就是局部变量了
  • __security_cookie 的值是一个随机值,每次运行程序该值都不一样

关于该值是如何进行计算的,可通过搜索编译器CRT下的gs_support.cgs_cookie.c文件进行查看了解,会进行如下的运算:

  1. 获得 system time
  2. 与 GetCurrentProcessId() 异或
  3. 与 GetCurrentThreadId() 异或
  4. 与 GetTickCount() 异或
  5. 与 QueryPerformanceCounter()异或

这里用来计算的值能确保计算出来结果的唯一性,从而能保证cookie的唯一随机性,这里就不进行深入了。

参考链接:https://www.cnblogs.com/adylee/p/9936954.html

  • __security_cookie 机制并不是会给所有代码都进行生成,只会在存在溢出可能的函数里进行生成

  • 这种保护机制是由编译器提供的,可通过编译器设置进行关闭

    VS2019的设置位置在:项目右键->属性->C/C++->代码生成->安全检查->启用安全检查(/GS)

总结

__security_cookie 机制通过往局部变量的位置新增一个随机值,在程序开头和结尾分别与进入函数前的esp的值进行异或操作,经过两次异或如果相同,则表示栈中操作不会影响到程序接下来的执行

如果能在栈中的这个位置手工构造出这个用于检测的值,则栈溢出无法避免。

标签:__,函数,异或,cookie,ebp,security
From: https://www.cnblogs.com/bonelee/p/17321442.html

相关文章

  • 给webpack提了一个pr之后......
    前言我不是标题党啊,是真的给webpack提了一个pr,提交之后,脑子里就是一句话:“纸上学来终觉浅,绝知此事要躬行”。欲知来龙去脉,听我娓娓道来。pr如下,<https://github.com/webpack/webpack/pull/16292>,目前还是unreviewed状态。\\阅读此文章你将会了解以下知识点,webstrom调试webpack源......
  • cookies、sessionStorage与localStorage在Vue中的使用
    目录简介localStorage的使用语法示例sessionStorage的操作语法示例cookie的操作vue-cookie语法示例vue-cookies语法示例js-cookie的使用简介cookies临时存储在客户端中,并且有过期事件,到过期时间会被自动清理。sessionStorage临时存储在客户端中,关闭浏览器后......
  • cookie的相关作用
    cookie除了使用js文件来将相关的用户名密码存储到cookie里面,并执行保留7天的操作之外,我们同样可以是使用servlet进行相关问题的解决若是用户名以及密码的登录条件符合要求,则可以使用cookie对其进行存储:知乎实现登录成功之后的跳转:如果已经登录过如果已经登录过,那么可以定义......
  • 1835. 所有数对按位与结果的异或和
    题目描述给了列表异或和的定义现在的列表是arr1和arr2构造出来的,元素对是arr[i]andarr[j]问以上列表的异或和?f1-依次确定答案的每一位基本分析为什么考虑计算答案的每一位?表达式只包含位运算(按位与和按位异或)具体怎么计算?要知道答案的第k为是1还是0->分别计算arr1和arr......
  • js注入cookie不生效的情况
    场景直接使用js注入cookie发现不生效,其实只设置了key和values值,没有注意其他字段。后来发现还有个domain的字段需要配置,不然注入是不会生效的document.cookie="token=123;domain=.baidu.com"#使用;分号隔开......
  • UVa 11507 Bender B. Rodríguez Problem (模拟&异或)
    11507-BenderB.RodríguezProblemTimelimit:4.000secondshttp://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=24&page=show_problem&problem=2502Benderisarobotbuiltby Mom'sFriendlyRobotCompany atits......
  • vue项目通过外部配置文件读取接口地址- 在webpack-index.html模板中使用环境变量
    概述:在index.html模板中判断当前环境,处于开发环境下时读取process环境变量、处于生产环境下时读取根目录配置文件(./config.js),两种环境下将配置统一挂载到window全局变量上(SET_CONFIG)config.jswindow.SITE_CONFIG={appTitle:'系统测试',version:'1.0.0',apiURL:''......
  • C#:Cookie设置
    记录工作中遇到的一些Cookie设置的问题:异常:参数“{0}”不能是空字符串。参数名:cookie.Domain解决方案:在Cookie设置中加上你访问的域名,例:将Cookie设置Cookiec1=newCookie("name_xxxx","value_xxxx");修改为Cookiec1=newCookie("name_xxxx","value_xxxx","/&qu......
  • 前端临时储存cookies、sessionStorage、localStorage
    cookies、sessionStorage、localStorage的区别是什么?(浏览器)1、cookie(1)本身用于客户端和服务端通信(2)但是它有本地存储的功能,于是就被“借用”(3)document.cookie=…获取和修改即可(4)cookie用于存储的缺点①存储量太小,只有4kb②所有http请求都带着,会影响获取资源的效率③api简单,需......
  • vue项目中webpack编译glsl文件的配置
    1、 安装webpack-glsl-loader npminstallwebpack-glsl-loader2、修改vue.config.js配置,添加内容如下module.exports=defineConfig({configureWebpack:(config)=>{config.module.rules.push({test:/\.glsl$/,use:[......