【学习笔记】0day安全

admin 2022年12月3日16:30:04评论17 views字数 1861阅读6分12秒阅读模式
【学习笔记】0day安全

[huayang]

来了来了,兄弟们来了

还是老样子,这本书过于难,可能说不了多少

建议看完之后再来看此文章

此文章仅为摘录,仅做复习时使用

一些小知识

函数

函数调用的过程中,我们要为函数开辟栈空间用于临时变量的保存、现场的保护(函数的返回值和参数、调用前寄存器的状态,调用前栈帧的顶部和底部的地址),这块栈空间我们称之为
函数

栈帧

当x86-64过程调用需要的存储空间超过寄存器能够存放的大小时,就会在栈上分配空间,这个部分就称为栈帧

漏洞利用原理

栈溢出原理与实践

内存的不同用途

进程使用的内存可以按照功能分为以下4个部分

代码区:这个区域存储着被装入执行的二进制机器代码,处理器会到这个区域取指并执行

数据区:用于存储全局变量

堆区:进程可以在堆区动态地请求一定大小的内存,并在用完之后归还给堆区。动态分配和回收是堆区的特点

栈区:用于动态地存储函数之间的调用关系,以保证被调用函数在返回时恢复到母函数中继续执行

栈与系统栈

栈最常见的操作有两个:压栈(PUSH)、弹栈(POP)叫出栈也行,无伤大雅。用于标识栈的属性也有两个:栈顶(TOP)、栈底(BASE)

TOP:栈顶的位置是动态变化的,没做一次PUSH它都会自增一,相反每做一次POP它都会自减一
BASE:标识栈底,用于防止栈空之后继续出栈。一般情况下栈底是不会变动的

函数调用时发生了什么

 int func_B(int arg_B1, int arg_B2) 
{ 
 int var_B1, var_B2; 
 var_B1=arg_B1+arg_B2; 
 var_B2=arg_B1-arg_B2; 
 return var_B1*var_B2; 
} 
int func_A(int arg_A1, int arg_A2) 
{ 
 int var_A; 
 var_A = func_B(arg_A1,arg_A2) + arg_A1 ; 
 return var_A; 
} 
int main(int argc, char **argv, char **envp) 
{ 
 int var_main; 
 var_main=func_A(4,3);
 return var_main; 
}

上面的代码有指针的知识

【学习笔记】0day安全
CPU取指轨迹图

别问,问就是麻了

CPU在各个函数的代码区跳转,这一切都是与系统栈配合实现的,当函数被调用时,系统栈会为这个函数开辟一个新的栈帧,并把它压入栈中。这个栈帧中的内存空间被它所属的函数独占,正常情况下是不会和别的函数共享的。当函数返回时,系统栈会弹出该函数所对应的栈帧,流程如下:

【学习笔记】0day安全

已经疯了

在实际运行中,main函数并不是第一个被调用的函数,程序被写入内存前还有些其他操作

寄存器与函数栈

win32系统提供两个特殊的寄存器用于标识位于系统栈顶端的栈帧

(1)ESP:栈指针寄存器,其内存放着一个指针,改指针永远指向系统栈最上面一个栈帧的栈顶

(2)EBP:基址指针寄存器,其内存放着一个指针。,改指针永远指向系统最上面一个栈帧的底部

(3)EIP:其内存放着一个指针,该指针永远指向下一条等待执行的指令地址。(控制了EIP的内容就控制了进程)

注意:栈帧底部和栈底是不同的概念,而ESP所指的栈帧顶部和系统栈的顶部是同一个位置

寄存器对栈帧的标识作用

【学习笔记】0day安全

ESP和EBP之间的内存空间为当前栈帧,EBP标识了当前栈帧的底部,ESP标识了当前栈帧的顶部

函数栈帧的信息

栈帧的大小不固定,与函数局部变量多少有关

局部变量:为函数局部变量开辟的内存空间。(全局变量在数据区)

栈帧状态值:保存前栈帧的顶部和底部(实际上只保存前栈帧的底部,前栈帧的顶部可以通过堆栈平衡计算得到),用于在本帧被弹出后恢复出上一个栈帧。

函数返回地址:保存当前函数调用前的“断点”信息,也就是函数调用前的指令位置,以便在函数返回时能够恢复到函数被调用前的代码区中继续执行指令。

函数栈帧的大小并不固定,一般与其对应的局部变量多少有关,函数在运行过程中,其栈帧大小也是在不停变化的。

函数调用约定与相关指令

不同的操作系统、不同的语言、不同的编译器在实现函数调用时的原理基本相同,但具体还是有差别的

【学习笔记】0day安全

如果要明确使用某一种调用约定,只需要在函数前加上调用约定的声明即可,否则默认情况下,vc会使用_stdcall的调用方式。

同一段代码使用不同的编译选项、不同的编译器编译链接后,得到的只执行文件有很多不同

函数调用的步骤:

  • 参数入栈:将参数从右向左依次压入系统栈中
  • 返回地址入栈:将当前代码区调用指令的下一条指令地址压入栈中,供函数返回时继续执行
  • 代码区跳转:处理器从当前代码区跳转到被调用函数的入口处
  • 栈帧调整:具体包括

[/huayang]

FROM:浅浅淡淡[hellohy]

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年12月3日16:30:04
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   【学习笔记】0day安全https://cn-sec.com/archives/1442865.html

发表评论

匿名网友 填写信息