04_CC++漏洞_栈溢出利用

合集下载

C语言中的漏洞利用与渗透测试技术

C语言中的漏洞利用与渗透测试技术

C语言中的漏洞利用与渗透测试技术C语言作为一种广泛应用于编程领域的高级编程语言,由于其灵活和高效的特点,被广泛使用于各种软件开发项目中。

然而,正是因为其广泛的应用,C语言也存在一些漏洞和安全隐患。

本文将重点探讨C 语言中的漏洞利用与渗透测试技术,以帮助读者了解并提高对C语言程序的安全性。

一、C语言中的常见漏洞在介绍漏洞利用与渗透测试技术前,我们首先需要了解C语言中的一些常见漏洞类型。

以下是几种常见的C语言漏洞:1. 缓冲区溢出:这是一种常见的安全漏洞,在C语言中由于缺乏边界检查导致。

当程序接收用户输入时,如果没有正确验证输入的长度,可能会导致缓冲区溢出,使攻击者能够执行恶意代码或破坏系统。

2. 格式化字符串漏洞:当程序使用不正确的格式化字符串函数,或者没有正确检查格式化字符串的输入时,可能会导致攻击者通过格式化字符串漏洞读取或修改内存中的数据,造成信息泄露或系统崩溃。

3. 整数溢出:在C语言中,整数的溢出可能导致程序出现未定义行为,为攻击者提供了利用的机会。

例如,当执行算术运算或数组索引时,如果没有正确检查整数边界,可能会导致溢出。

二、漏洞利用技术漏洞利用是指攻击者利用系统或应用程序中的漏洞,通过注入恶意代码或执行特定操作来获取权限或控制目标系统。

以下是一些常见的漏洞利用技术:1. Shellcode注入:攻击者可以通过利用缓冲区溢出等漏洞,将恶意代码注入到目标系统的内存中。

一旦成功注入,攻击者就可以通过控制指令来执行恶意操作。

2. Return-Oriented Programming(ROP):ROP是一种高级漏洞利用技术,通过利用程序中的已存在的代码段(Gadget)来执行恶意操作。

攻击者通过构造特定的ROP链,在不添加新代码的情况下,利用程序中的现有代码来完成攻击目标。

3. 格式化字符串攻击:攻击者可以通过构造恶意格式化字符串,利用格式化字符串漏洞来读取或修改内存中的数据。

这种技术通常用于泄露内存中的敏感信息或执行特定操作。

c语言的栈溢出问题以及部分解

c语言的栈溢出问题以及部分解

c语言的栈溢出问题以及部分解C语言中的栈溢出问题指的是在函数调用过程中,栈空间被过多地使用,超出了系统为该函数分配的栈空间的大小。

由于栈是用来存储局部变量、函数参数和函数调用信息的重要数据结构,如果栈溢出发生,可能会导致程序崩溃或者安全漏洞。

栈溢出的原因可以分为以下几种情况:1.递归调用深度过大:在使用递归函数时,如果没有正确地设置递归停止条件,递归调用就会无限循环下去,直到栈空间被耗尽。

2.局部变量过多、过大:如果函数中声明了过多的局部变量,或者某些局部变量占用过大的空间,会导致栈空间不足。

3.函数调用嵌套层次过多:如果函数调用过于深层次嵌套,每次调用都会在栈上压入一些参数和调用信息,如果嵌套层次过多,栈空间会被耗尽。

4.数组越界:在C语言中,数组是用连续的内存空间存储的,如果访问了超出数组界限的元素,就会引发栈溢出问题。

栈溢出的危害性主要表现在以下方面:1.系统崩溃:如果栈空间被耗尽,系统将无法继续正常运行,程序会崩溃。

2.安全漏洞:恶意用户可以通过精心构造的输入数据,触发栈溢出,覆盖栈上的返回地址或者函数调用信息,实现任意代码执行,从而进行非法操作、获取系统权限等。

针对栈溢出问题,可以采取以下方案来解决或者缓解:1.优化递归函数:递归调用函数时,应该明确设置停止条件,避免无限循环。

同时,可以尝试使用尾递归优化,将递归调用转换为循环调用。

2.合理使用局部变量:在函数中合理使用局部变量,尽量避免声明过多、过大的局部变量。

可以考虑使用动态内存分配,将一些较大的数据结构分配在堆上。

3.减少函数调用嵌套层次:合理设计程序的结构,减少函数调用的嵌套层次。

可以通过拆分函数、合并函数等方式,减少函数调用的层次。

4.使用安全的函数:在C语言中,存在一些不安全的函数,比如strcpy、strcat等,它们没有对目标地址进行边界检查,容易导致缓冲区溢出。

可以使用更安全的函数,比如strncpy、strncat等,提供了目标地址的长度参数,避免了缓冲区溢出的风险。

C语言中常见的安全漏洞及防范方法

C语言中常见的安全漏洞及防范方法

C语言中常见的安全漏洞及防范方法C语言作为一种广泛应用于系统开发和嵌入式设备的编程语言,虽然具有高效性和灵活性,但在安全性方面却存在一些常见的漏洞。

本文将介绍C语言中常见的安全漏洞,并提供相应的防范方法。

一、缓冲区溢出漏洞缓冲区溢出是C语言中最常见的安全漏洞之一。

当程序试图向一个已经装满数据的缓冲区写入更多的数据时,就会导致缓冲区溢出。

攻击者可以利用这个漏洞来修改程序的执行流,执行恶意代码或者获取敏感信息。

防范方法:1. 使用安全的函数:应该使用安全的函数,如`strncpy`、`snprintf`等,而不是不安全的函数`strcpy`、`sprintf`等。

安全的函数会检查数据长度,避免发生缓冲区溢出。

2. 输入验证:对于用户输入的数据,应该进行输入验证,确保输入的数据不会超出缓冲区的长度。

3. 使用堆栈保护技术:可以使用堆栈保护技术,如栈溢出检测、堆栈随机化等,在一定程度上提高程序对缓冲区溢出漏洞的防护能力。

二、格式化字符串漏洞格式化字符串漏洞是由于未正确使用格式化字符串函数(如`printf`、`sprintf`等)导致的安全问题。

当攻击者能够控制格式化字符串的参数时,就可能导致信息泄露或者任意代码执行。

防范方法:1. 限制格式化字符串的输入:应该限制用户输入的格式化字符串,确保输入的格式化字符串参数是合法且不含恶意代码。

2. 使用安全的格式化函数:使用安全的格式化函数,如`snprintf`等,这些函数会检查参数的有效性,避免格式化字符串漏洞的发生。

3. 程序审计:对于已经存在的代码,应进行定期的程序审计,识别和修复潜在的格式化字符串漏洞。

三、整数溢出漏洞整数溢出漏洞是由于未对输入数据进行正确的检查和验证,导致整数值超出其数据类型范围,从而引发安全问题。

攻击者可以利用这个漏洞来改变程序的行为,执行未经授权的操作。

防范方法:1. 输入验证:对于用户输入的数据,应该进行输入验证,确保输入的数据范围在合理的范围内。

ctf的pwn的几个知识点

ctf的pwn的几个知识点

ctf的pwn的几个知识点摘要:1.CTF pwn知识点简介2.栈溢出漏洞利用3.格式化字符串漏洞利用4.整数溢出漏洞利用5.代码审计与二进制安全6.总结与展望正文:1.CTF pwn知识点简介CTF(Capture The Flag)是信息安全领域一种流行的竞技类比赛,选手需要在各种题目中寻找安全漏洞并利用它们来获得flag。

pwn是CTF比赛中的一类题目,主要涉及二进制漏洞利用、代码审计等知识点。

本文将介绍几个CTF pwn中的重要知识点。

2.栈溢出漏洞利用栈溢出漏洞是指程序在执行过程中,栈空间被恶意输入的数据破坏,导致程序行为被恶意控制。

利用栈溢出漏洞,攻击者可以实现代码执行,进一步控制程序。

栈溢出利用的关键是找到合适的溢出点,通常需要分析程序的输入输出、栈帧布局等。

3.格式化字符串漏洞利用格式化字符串漏洞是C/C++程序中常见的一种漏洞,由于程序没有对用户输入的格式化字符串进行充分检查,导致恶意输入的数据破坏了程序的内存布局。

利用格式化字符串漏洞,攻击者可以实现代码执行,甚至绕过某些安全机制。

格式化字符串利用的关键是构造合适的格式化字符串,以实现可控的内存破坏。

4.整数溢出漏洞利用整数溢出漏洞是指程序在处理整数时,由于没有进行充分的检查,导致整数溢出,从而破坏程序的内存布局。

整数溢出漏洞可以实现可控的内存破坏,甚至远程代码执行。

利用整数溢出漏洞,通常需要分析程序的整数运算、内存布局等。

5.代码审计与二进制安全代码审计是指对程序源代码进行分析,以发现潜在的安全漏洞。

二进制安全是指在程序编译成二进制代码后,对其进行分析和利用的安全领域。

在CTF pwn中,掌握代码审计和二进制安全知识,可以帮助选手在复杂的情况下找到漏洞,并利用它们。

6.总结与展望CTF pwn题目涉及多种知识点,需要选手具备扎实的编程功底、操作系统知识、二进制安全知识等。

随着CTF比赛的普及,pwn题目越来越多样化,选手需要不断学习新知识,提高自己的技能。

电子科技大学22春“电子信息工程”《信息安全概论》期末考试高频考点版(带答案)试卷号:2

电子科技大学22春“电子信息工程”《信息安全概论》期末考试高频考点版(带答案)试卷号:2

电子科技大学22春“电子信息工程”《信息安全概论》期末考试高频考点版(带答案)一.综合考核(共50题)1.NDIS工作的网络协议层次不包括()A、应用层B、传输层C、网络层D、数据链路层参考答案:A2.网络攻击中权限获取及提升的方法有()。

A、通过网络监听、基于网络账号口令破解、社会工程B、通过网络监听、强制口令破解、网络钓鱼C、通过网络监听、基于网络账号口令破解、通过网络欺骗D、通过网络监听、获取口令文件、社会工程参考答案:C3.网络监听程序一般包含以下步骤:()A.数据包过滤与分解、强制口令破解、数据分析B.数据包捕获、强制口令破解、数据分析C.数据包捕获、数据包过滤与分解、数据分析D.网络欺骗、获取口令文件、数据包过滤与分解参考答案:C4.为防止外界干扰,主动红外探测器发射机所发出的()必须经过调制。

A.声波B.噪音C.激光D.红外辐射5.就信息安全来说,完整性是()。

A.保护组织的声誉B.保护系统资源免遭意外损害C.保护系统信息或过程免遭有意或意外的未经授权的修改D.两个或多个信息系统的成功安全组合参考答案:C6.强制口令破解不包括以下:()A.猜解简单口令B.字典攻击C.窥视输入的口令D.暴力猜解参考答案:C7.从系统结构上来看,入侵检测系统可以不包括()A、数据源B、分析引擎C、审计D、响应参考答案:C8.使用Hash签名时,主要局限是()。

A.发送方不必持有用户密钥的副本B.接收方必须持有用户密钥的副本C.接收方不必持有用户密钥的副本D.A和B参考答案:B下面的加密系统属于公钥密码体制的是()A、一个加密系统的加密密钥和解密密钥相同B、一个加密系统的加密密钥和解密密钥不同C、一个加密系统的加解密密钥中,由其中任意一个可以很容易地推导出另一个D、A和C都是参考答案:B10.下面关于DMZ区的说法错误的是()。

A.通常DMZ包含允许来自互联网的通信可进入的设备,如Web服务器、FTP服务器、SMTP服务器和DNS服务器等B.内部网络可以无限制地访问外部网络以及DMZC.DMZ可以访问内部网络D.有两个DMZ的防火墙环境的典型策略是主防火墙采用NAT方式工作,而内部防火墙采用透明模式工作以减少内部网络结构的复杂程度参考答案:C11.关于网闸的工作原理,下面说法错误的是()A、切断网络之间的通用协议连接B、将数据包进行分解或重组为静态数据;对静态数据进行安全审查,包括网络协议检查和代码扫描等C、网闸工作在OSI模型的二层以上D、任何时刻,网闸两端的网络之间不存在物理连接品参考答案:C12.门禁系统属于()系统中的一种安防系统。

溢出提权原理

溢出提权原理

溢出提权原理溢出提权是一种网络攻击技术,攻击者通过利用软件或操作系统的漏洞,使内存中的数据溢出,以此来运行自己的代码,提升自己的权限,从而获取更高的系统访问权限,控制整个系统。

以下是有关溢出提权原理及其实现的详细解释:一、原理1. 缓冲区溢出缓冲区溢出是溢出提权攻击的关键。

它利用了程序设计错误,使其在接收数据时没有考虑到输入数据的长度问题。

攻击者通过给程序提供一个超出了他预期大小的输入,导致程序直接将多余的数据写入了程序的内存区域,进而导致系统的崩溃。

2. 栈溢出栈(stack)是指存储函数调用信息的一种数据结构,它是由编译器自动分配和释放内存的,用于存储局部变量、函数参数和返回地址等信息。

攻击者通过构造特定的输入,可以改变栈的内容,使程序执行到不该执行的地方,从而提升攻击者的权限。

3. 堆溢出当程序运行的时候,需要动态地分配内存,我们称之为堆内存。

攻击者可以构造恶意数据,通过堆溢出的方式覆盖循环队列,使得程序执行到攻击者事先准备好的代码段,从而达到提权的目的。

二、实现1. 利用漏洞攻击者通过针对具体的软件或操作系统中可能存在的漏洞进行攻击,知道漏洞的存在并可以利用其进行溢出提权。

2. 编写恶意代码攻击者可以编写专门的代码,利用漏洞实现溢出提权,一旦恶意代码被加载到内存中,攻击者就可以完成攻击。

3. 利用第三方工具还有一些第三方工具可以协助攻击者实现溢出提权攻击,例如Metasploit,这些工具使用已知的漏洞进行攻击,从而实现溢出提权。

总之,溢出提权是一种非常危险的攻击技术。

为了防范溢出提权攻击,软件开发人员需要对漏洞进行认真的审查和修复,用户也需要安装最新的补丁和升级以减少系统漏洞的利用。

同时,网络安全人员需要保持密切关注,及时监测和响应溢出提权攻击。

网络安全常见漏洞利用方法

网络安全常见漏洞利用方法

网络安全常见漏洞利用方法网络安全是当今社会中一个重要的话题,随着互联网的普及和应用的广泛,网络安全漏洞的利用也越来越多样化和危险化。

本文将介绍网络安全常见漏洞及其利用方法,以增加大家对网络安全的认识和防范意识。

一、操作系统漏洞的利用方法操作系统漏洞是网络安全中最常见的漏洞之一,黑客利用操作系统的漏洞可以实现远程控制、权限提升等恶意行为。

以下是一些常见的操作系统漏洞利用方法:1.1 缓冲区溢出攻击缓冲区溢出是指黑客向程序输入超过其预留空间的数据,从而覆盖掉相邻空间的内容,进而改变程序的执行流程。

黑客可以通过缓冲区溢出攻击来执行恶意代码、控制系统等。

1.2 代码注入攻击代码注入是指黑客将恶意代码注入到正常的代码流程中,使其被执行。

常见的注入方式有SQL注入、XSS(跨站脚本攻击)等。

黑客可以利用代码注入攻击获取用户敏感信息、劫持会话等。

1.3 拒绝服务攻击拒绝服务攻击是指黑客通过向目标服务器发送大量请求,耗尽其资源或使其服务崩溃,从而使合法用户无法正常访问网站或服务。

黑客可以利用操作系统漏洞实施拒绝服务攻击,造成大规模的停机和数据丢失。

二、应用层漏洞的利用方法除了操作系统漏洞外,应用层漏洞也是黑客经常利用的攻击目标。

应用层漏洞通常存在于网站、应用程序等具体实现中,以下是一些常见的应用层漏洞及其利用方法:2.1 跨站脚本攻击(XSS)跨站脚本攻击是指黑客通过在网页中插入恶意脚本,使用户在浏览网页时执行该脚本,从而获取用户的敏感信息或进行其他恶意操作。

黑客可以利用XSS漏洞窃取用户身份信息、篡改网页内容等。

2.2 SQL注入攻击SQL注入攻击是指黑客通过构造恶意的SQL查询语句,使其被数据库误解和执行,从而获取、篡改或删除数据库中的信息。

黑客可以利用SQL注入漏洞获取用户账号、密码等敏感信息。

2.3 文件上传漏洞文件上传漏洞是指网站或应用程序对用户上传的文件没有进行充分的检验和验证,从而被黑客利用上传恶意文件、执行任意代码等。

堆栈溢出的原因

堆栈溢出的原因

堆栈溢出的原因
堆栈溢出是一种常见的安全漏洞,它的发生原因主要是由于程序在执行过程中,使用了过多的栈空间,导致栈溢出,从而破坏了程序的正常执行流程。

本文将从堆栈溢出的原因、危害以及防范措施等方面进行探讨。

堆栈溢出的原因主要有两个方面:一是程序设计不当,二是攻击者利用漏洞进行攻击。

在程序设计不当的情况下,程序员可能会在函数中使用过多的局部变量,或者使用了过多的递归调用,导致栈空间不足,从而引发堆栈溢出。

而在攻击者利用漏洞进行攻击的情况下,攻击者可能会通过输入过长的数据,或者利用格式化字符串漏洞等方式,来覆盖栈中的返回地址,从而控制程序的执行流程。

堆栈溢出的危害主要表现在以下几个方面:一是程序崩溃,导致数据丢失或者系统崩溃;二是攻击者可以利用堆栈溢出漏洞,执行恶意代码,从而获取系统权限或者窃取敏感信息;三是攻击者可以利用堆栈溢出漏洞,进行拒绝服务攻击,从而使系统无法正常运行。

为了防范堆栈溢出漏洞,我们可以采取以下几个措施:一是在程序设计时,尽量减少使用局部变量和递归调用,从而减少栈空间的使用;二是对输入数据进行有效的检查和过滤,避免输入过长的数据;三是使用编译器提供的安全选项,如-fstack-protector等,来检测和防范堆栈溢出漏洞;四是使用堆栈随机化技术,来增加攻击者的难度,从而提高系统的安全性。

堆栈溢出是一种常见的安全漏洞,它的发生原因主要是由于程序设计不当和攻击者利用漏洞进行攻击。

为了防范堆栈溢出漏洞,我们需要采取有效的措施,从而提高系统的安全性。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

栈的属性
• TOP 栈顶 • BASE 栈底
系统栈:内存的栈区
透明性概念
对于C语言这样的高级语言,系统栈的 PUSH,POP等堆栈平衡细节是透明的。 一般说来,只有在使用汇编语言开发程序 的时候,才需要和它直接打交道。 计算机中透明性概念: 计算机中存在,但对于 开发人员不需要了解的东西.
Company
LOGO
安全性编程方法
天津农学院 计算机科学与信息工程系 软件工程教研室 许晓华 xuxiaohua@
第4讲 栈溢出利用
4.1 系统栈的工作原理
栈与系统栈的区别: 栈:数据结构角度的栈,是一种先进后出的数 据表.
常见操作
• PUSH 进栈 • POP 出栈
栈从高到低扩展 数组,按人类的书写习惯,低 位在前,高位在后 整数,按人类的书写习惯,高 位在前,低位在后
当输入7个q, 7个q大于1234567,所以 authenticated 的值为0x00000001,不能通过 验证。 当输入8个q,“qqqqqqqq”大于1234567, authenticated 的值还是0x00000001,但 “qqqqqqqq”后面的字符串截断符 0x00会溢 出。 这溢出数组的一个字节 0x00 恰好把 authenticated变量改为 0x00000000 。 函数返回时,main函数一看authenticated是 0 ,就会通过密码验证.
跳转:按照函数返回地址跳回母函数中继续执行
函数返回时的指令序列
add xxx , esp //降低栈顶,回收当前的栈帧 pop ebp //将上一个栈帧底部位置恢复到ebp, retn //这条指令有两个功能:
a ) 弹出当前栈顶元素,即弹出栈帧中的返回地址。至 此,栈帧恢复工作完成。 b ) 让处理器跳转到弹出的返回地址,恢复调用前的代 码区
高级语言写出的程序经过编译链接,最终 会变成PE文件。当PE文件被装载运行后, 就成了所谓的进程。 如下图所示:
系统栈与函数调用
#include "stdafx.h" 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 ); printf("var_main is %d\n",var_main); return var_main ; }
4.3 修改函数返回地址
如果在刚才溢出的基础上,多溢出几个字 节,将下面的返回地址覆盖。就可以做到 劫持进程。 要将返回地址覆盖为什么地址呢? 当然是通过验证的地址了,见下图。
然后输入密码. 出于字节对齐、容易辨认的目的,将 “ 4321 ”作为一个输入单元。
buffer [ 8 ] 共需要 2 个这样的单元 第 3 个输入单元将authenticated覆盖 第 4 个输入单元将前栈帧EBP值覆盖 第 5 个输入单元将返回地址覆盖
push ebp ; 保存旧栈帧的底部 mov ebp,esp ; 设置新栈帧的底部(栈帧切换) sub esp,xxx ; 设置新栈帧的顶部(抬高栈顶,为新栈 帧开辟空间)
例题
#include "stdafx.h" void fun(int a,int b) { int c=a+b; }
函数返回的步骤
保存返回值:通常将函数的返回值保存在寄存器 EAX中 弹出当前栈帧,恢复上一个栈帧,具体包括:
在堆栈平衡的基础上,给ESP加上栈帧的大小,降低 栈顶,回收当前栈帧的空间 将当前栈帧底部保存的前栈帧EBP值弹入EBP寄存器, 恢复出上一个栈帧 将函数返回地址弹给EIP寄存器
为什么 01234567 不行? 因为字符串大小的比较是按字典序来的,所以 这个串小于“ 1234567 ” authenticated的值是 - 1 ,在内存里将按照补 码存负数,所以实际存的是 0xffffffff 。 那么字符串截断符 0x00 淹没后,变成 0xffffff00 ,还是非 0 ,所以没有进入正确分 支。
由于地址00401122无法在控制台输入,所 以,我们改造一下代码,将密码获取方式 改为从.txt文件中读取。
从.txt文件中读取密码

main() #include "stdafx.h" { int valid_flag=0; #include "string.h" char password[1024]; #include <stdio.h> FILE * fp; #define PASSWORD "1234567" if(!(fp=fopen("password.txt","rw+"))) int verify_password (char *password) { { exit(0); } int authenticated; fscanf(fp,"%s",password); char buffer[8]; valid_flag = verify_password(password); authenticated=strcmp(password, if(valid_flag) PASSWORD); { strcpy(buffer,password);//over printf("incorrect password!\n"); flowed here! } return authenticated; else { } printf("Congratulations! You have passed the verification!\n"); } fclose(fp); }
栈帧
当函数被调用时,系统栈会为这个函数开 辟一个新的栈帧,并把它压入栈中。 当函数返回时,系统栈会弹出该函数所对 应的栈帧。
调用时栈中的操作
在main函数调用func_A的时候,首先在自己的栈帧中压 入函数返回地址,然后为func_A创建新栈帧并压入系统栈 在func_A调用func_B的时候,同样先在自己的栈帧中压 入函数返回地址,然后为func_B创建新栈帧并压入系统栈 在func_B返回时,func_B的栈帧被弹出系统栈,func_A 栈帧中的返回地址被“露”在栈顶,此时处理器按照这个 返回地址重新跳到func_A代码区中执行 在func_A返回时,func_A的栈帧被弹出系统栈,main函 数栈帧中的返回地址被“露”在栈顶,此时处理器按照这 个返回地址跳到main函数代码区中执行
将上述代码,编译链接生成PE文件 在PE文件同目录的位置创建一个password.txt文 件。内容为43214321432143214321 用UltraEdit打开该文件,点击“切换十六进制模式”
将最后一个4321,改成22114011
将PE文件拖入OD,F9运行
4.4 代码植入
寄存器与函数栈帧
WIN32系统提供两个特殊的寄存器用于标识位 于系统栈栈顶的栈帧:
ESP: ( extended stack pointer ) 栈指针寄存器,指向系统栈最上面一个栈帧的栈顶 EBP: ( extended base pointer ) 基址指针寄存器,指向系统栈最上面一个栈帧的底 部
运行,密码输入qqqqqqq(7个q),不通 过 输入qqqqqqqq(8个q),居然通过了密 码验证 为什么?
先来了解一下大端机与小端机的概念。
大端机与小端机
大端机(big endian)
低地址存放最高有效位(MSB:Most Significant Bit) 例如:Java Virtual Machine
参数入栈:将参数从右向左依次压入系统栈中 返回地址入栈:将当前代码区调用指令的下一条 指令地址压入栈中,供函数返回时继续执行 代码区跳转:处理器从当前代码区跳转到被调用 函数的入口处 栈帧调整:具体包括:
保存当前栈帧状态值,以备后面恢复本栈帧时使用 (EBP入栈) 将当前栈帧切换到新栈帧(将ESP值装入EBP,更新 栈帧底部) 给新栈帧分配空间(把ESP减去所需空间的大小,抬 高栈顶)
ห้องสมุดไป่ตู้
小端机(little endian)
低地址存放最低有效位(LSB: Least Significant Bit) 例如:Intel x86
栈帧布局图
再来看一下,函数调用时的栈帧布局图
buffer[0~3] (ASCII: q q q q)
buffer[4~7] (ASCII: q q q null) authenticated (0x00000001) 前栈帧EBP 返回地址 形参:password ……
#include < stdio . h > #include < windows . h > #define PASSWORD "1234567" int verify_password ( char * password ) { int authenticated ; char buffer [ 44 ]; authenticated = strcmp ( password , PASSWORD ); strcpy ( buffer , password ); //over flowed here! return authenticated ; }
相关文档
最新文档