编译原理课程第16讲.ppt_第1页
编译原理课程第16讲.ppt_第2页
编译原理课程第16讲.ppt_第3页
编译原理课程第16讲.ppt_第4页
编译原理课程第16讲.ppt_第5页
已阅读5页,还剩40页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、利用活动记录进行的“黑客”行为 缓冲区溢出攻击,6.2 全局存储分配策略,1/33,缓冲区溢出攻击,缓冲区溢出攻击:,根据程序在执行函数调用时,函数返回地址与函数的局部缓冲区都位于系统栈(活动栈)这一原理,利用代码中对局部变量的边界条件疏于检查的漏洞,篡改函数返回地址,引起程序异常或者改变程序执行流程,进而获得程序控制权。,缓冲区溢出攻击,缓冲区溢出攻击:,char help10; void foo(const char *input) char buf10; int i = 0; for (i = 0; i 30; i+) if (i % 4 =0) printf(n); sprintf(h

2、elp, %08x, bufi); printf( %s, help+6); printf(n);,strcpy(buf, input); printf(%snn, buf); for (i = 0; i 30; i+) if (i % 4 =0) printf(n); sprintf(help, %08x, bufi); printf( %s, help+6); printf(n); ,void bar(void) printf(我是bar()函数,程序的执行流程改变了!n); void main(int argc, char *argv) printf(foo() 函数的地址是 %p n,

3、foo); printf(bar()函数的地址是%p n,bar); foo(argv1); getch(); ,缓冲区溢出攻击,D:bufferoverrunDebugbufferoverrun 12345 foo() 函数的地址是 00401005 bar() 函数的地址是0040100A cc cc cc cc cc cc cc cc cc cc cc cc 80 ff 12 00 58 12 40 00 ba 0e 43 00 a8 44 f9 77 07 00 12345,31 32 33 34 35 00 cc cc cc cc cc cc 80 ff 12 00 58 12 40

4、 00 ba 0e 43 00 a8 44 f9 77 07 00,缓冲区溢出攻击,调用过程main的活动记录地址,foo()调用结束后,应该跳转的代码地址,buf 10,5/33,0 x00401258,0 x0012ff80,0 x0012ff1c,getch()的代码,。,高地址区,低地址区,栈增长方向,缓冲区溢出攻击,#include stdafx.h #include windows.h int main(int argc, char* argv) char cmdline100 = bufferoverrun.exe; strcat(cmdline, 123456789123456

5、7x0Ax10 x40 x00 ); WinExec(cmdline,SW_SHOW); return 0; ,缓冲区溢出攻击,foo() 函数的地址是 00401005 bar()函数的地址是0040100A cc cc cc cc cc cc cc cc cc cc cc cc 80 ff 12 00 58 12 40 00 ae 0e 43 00 f8 eb fd 7f c0 1f 1234567891234567 ,31 32 33 34 35 36 37 38 39 31 32 33 34 35 36 37 0a 10 40 00 ae 0e 43 00 f8 eb fd 7f c0

6、 1f 我是bar()函数,程序的执行流程改变了!,bar的代码段,。,缓冲区溢出攻击,6.3 非局部名字的访问,本节介绍 过程内部如何访问过程外部声明的名字? 静态作用域 无过程嵌套的静态作用域(C语言) 有过程嵌套的静态作用域(Pascal语言) 动态作用域(Lisp语言),6.3 非局部名字的访问,6.3.1 无过程嵌套的静态作用域 过程体中的非局部引用可以直接使用静态确定的地址 局部变量在栈顶的活动记录中,可以通过base_sp指针来访问 无须深入栈中取数据,无须访问链 过程可以作为参数来传递,也可以作为结果来返回,6.3 非局部名字的访问,6.3.2 有过程嵌套的静态作用域 过程嵌套

7、深度 sort1 readarray2 exchange2 quicksort2 partition3 变量的嵌套深度:它的声明所在过程的嵌套深度作为该名字的嵌套深度,6.3 非局部名字的访问,寻找非局部名字存储单元的访问链,访问链总是指向本活动的最近的外围过程的活动记录,sort 1 readarray2 exchange2 quicksort2 partition 3,6.3 非局部名字的访问,1、假定过程p的嵌套深度为np,它引用嵌套深度为na的变量a,na np。如何访问a的存储单元? 从栈顶的活动记录开始,追踪访问链np na次。 到达a的声明所在过程的活动记录。 访问链的追踪用间接

8、操作就可完成。,sort 1 readarray2 exchange2 quicksort2 partition 3,6.3 非局部名字的访问,访问非局部名字的存储单元,sort 1 readarray2 exchange2 quicksort2 partition 3,6.3 非局部名字的访问,过程p对变量a访问时,a的地址由下面的二元组表示: (np na,a在活动记录中的偏移),由当前的活动记录经过np-na次追踪,就可以得到a所声明的过程,在a所声明的过程中,a是一个局部变量,其地址可以用它在本活动记录中的偏移来表示,15/33,6.3 非局部名字的访问,2、建立访问链 假定嵌套深度为

9、np的过程p调用嵌套深度为nx的过程x np nx的情况 x肯定就声明在p中 被调用过程的访问链必须指向调用过程的活动记录的访问链,sort 1 readarray2 exchange2 quicksort2 partition 3,6.3 非局部名字的访问,2、建立访问链,sort 1 readarray2 exchange2 quicksort2 partition 3,s,a, x,q (1, 3),k, v,访问链,q (1, 9),k, v,访问链,p (1, 3),i, j,访问链,6.3 非局部名字的访问,2、建立访问链 假定嵌套深度为np的过程p调用嵌套深度为nx的过程x np

10、 nx的情况 sort1 readarray2 exchange2 quicksort2 partition3,6.3 非局部名字的访问,2、建立访问链 假定嵌套深度为np的过程p调用嵌套深度为nx的过程x np nx的情况 p和x的嵌套深度分别为1,2,nx 1的外围过程肯定相同 追踪访问链np (nx 1)次,到达了静态包围x和p的且离它们最近的那个过程的最新活动记录 所到达的访问链就是x的活动记录中的访问链应该指向的那个访问链,6.3 非局部名字的访问,2、建立访问链,sort 1 readarray2 exchange2 quicksort2 partition 3,20/33,s,a

11、, x,q (1, 3),k, v,访问链,q (1, 9),k, v,访问链,p (1, 3),i, j,访问链,s,6.3 非局部名字的访问,6.3.3 动态作用域 被调用过程的非局部名字a和它在调用过程中引用的是同样的存储单元。 新的绑定仅为被调用过程的局部名字建立,这些名字在被调用过程的活动记录中占用存储单元。,6.3 非局部名字的访问,program dynamic(input, output); var r: real; procedure show; begin write(r: 5: 3) end; procedure small; var r: real; begin r :

12、= 0.125; show end; begin r := 0.25; show; small; writeln; show; small; writeln end.,6.3 非局部名字的访问,program dynamic(input, output); var r: real; procedure show; begin write(r: 5: 3) end; procedure small; var r: real; begin r := 0.125; show end; begin静态作用域 r := 0.25;0.250 0.250 show; small; writeln;0.25

13、0 0.250 show; small; writeln end.,6.3 非局部名字的访问,program dynamic(input, output); var r: real; procedure show; begin write(r: 5: 3) end; procedure small; var r: real; begin r := 0.125; show end; begin动态作用域 r := 0.25;0.250 0.125 show; small; writeln;0.250 0.125 show; small; writeln end.,6.3 非局部名字的访问,实现动

14、态作用域的方法 深访问 用控制链搜索运行栈,寻找包含该非局部名字的第一个活动记录 浅访问 为每个名字在静态分配的存储空间中保存它的当前值 当过程p的新活动出现时,p的局部名字n使用在静态数据区分配给n的存储单元。n的先前值可以保存在p的活动记录中,当p的活动结束时再恢复,6.4 参 数 传 递,6.4.1 值调用 实参的右值传给被调用过程 值调用可以如下实现 把形参当作所在过程的局部名看待,形参的存储单元在该过程的活动记录中。 调用过程计算实参,并把右值放入形参的存储单元中。,6.4 参 数 传 递,6.4.2 引用调用 实参的左值传给被调用过程 引用调用可以如下实现: 把实参的左值放入形参的

15、存储单元。 在被调用过程的目标代码中,任何对形参的引用都是通过传给该过程的指针来间接引用实参的。,6.4 参 数 传 递,6.4.3 复写-恢复调用 值调用和引用调用的混合 复写-恢复调用可以如下实现: 实参的右值和左值同时传给被调用过程。 在被调用过程中,像值调用那样使用实参的右值。 当控制返回调用过程时,根据传递来的实参的左值,将形参当前的值复写到实参存储单元。,6.4 参 数 传 递,6.4.4 换名调用 用实参表达式对形参进行正文替换。 procedure swap(var x, y: integer); var temp: integer; begin temp := x; x :=

16、 y; y := temp end,6.4 参 数 传 递,6.4.4 换名调用 用实参表达式对形参进行正文替换。 procedure swap(var x, y: integer); var temp: integer; begin 调用swap(i, ai) temp := x; x := y; y := temp end,30/33,6.4 参 数 传 递,6.4.4 换名调用 用实参表达式对形参进行正文替换。 procedure swap(var x, y: integer); var temp: integer; begin 调用swap(i, ai) temp := x;temp

17、:= i; x := y;i := ai; y := tempai := temp end,本 章 要 点,影响存储分配策略的语言特征 各种存储分配策略,主要了解静态分配和动态栈式分配 活动记录中各种数据域的作用和安排 非局部数据访问的实现方法 各种参数传递方式及其实现,例 题 1,main() char *cp1, *cp2; cp1 = 12345; cp2 = abcdefghij; strcpy(cp1,cp2); printf(cp1 = %sncp2 = %sn, cp1, cp2); 在某些系统上的运行结果是: cp1 = abcdefghij cp2 = ghij 为什么cp2

18、所指的串被修改了?,例 题 1,因为常量串“12345”和“abcdefghij”连续分配在常数区 执行前: 1 2 3 4 5 0 a b c d e f g h i j 0 cp1 cp2,例 题 1,因为常量串“12345”和“abcdefghij”连续分配在常数区 执行前: 1 2 3 4 5 0 a b c d e f g h i j 0 cp1 cp2 执行后: a b c d e f g h i j 0 f g h i j 0 cp1 cp2,例 题 1,因为常量串“12345”和“abcdefghij”连续分配在常数区 执行前: 1 2 3 4 5 0 a b c d e f

19、g h i j 0 cp1 cp2 执行后: a b c d e f g h i j 0 f g h i j 0 cp1 cp2 现在的编译器大都把程序中的串常量单独存放在只读 数据段中,因此运行时会报错,例 题 2,下面的程序运行时输出3个整数。试从运行环 境和printf的实现来分析,为什么此程序会有3 个整数输出? main() printf(“%d, %d, %dn”); ,例 题 2,当用传统的参数声明方式时,C语言编译器是不做实在参数和形式参数的个数和类型是否一致的检查的,由程序员自己保证它们的一致性。 但是,c语言的实现保证被调用函数能准确地取到第一个实在参数。因此printf的

20、实现首先取到第一个参数格式控制字符串,然后分析它的格式控制要求,根据格式控制中的格式说明,到栈中取第二、第三个参数等等,而不管调用者是否真正提供了这些参数。所以该程序有3个整数输出。,例 题 3,main() func();printf(Return from funcn); func() char s4; strcpy(s,12345678); printf(%sn,s); ,例 题 3,main() func();printf(Return from funcn); func() char s4; strcpy(s,12345678); printf(%sn,s); 在X86/Linux操作系统上的运行结果如下: 12345678 Return from func Segmentation fault (core dumped),例 题 3,main() func();printf(Return from funcn); func() char s4; strcpy(s,12345678); printf(%sn,s); ,例 题 3,main() func();printf(Ret

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论