编译原理课件第17讲

上传人:w****i 文档编号:94461774 上传时间:2019-08-07 格式:PPT 页数:46 大小:1.47MB
返回 下载 相关 举报
编译原理课件第17讲_第1页
第1页 / 共46页
编译原理课件第17讲_第2页
第2页 / 共46页
编译原理课件第17讲_第3页
第3页 / 共46页
编译原理课件第17讲_第4页
第4页 / 共46页
编译原理课件第17讲_第5页
第5页 / 共46页
点击查看更多>>
资源描述

《编译原理课件第17讲》由会员分享,可在线阅读,更多相关《编译原理课件第17讲(46页珍藏版)》请在金锄头文库上搜索。

1、利用活动记录进行的“黑客”行为 缓冲区溢出攻击,6.2 全局存储分配策略,缓冲区溢出攻击,缓冲区溢出攻击:,根据程序在执行函数调用时,函数返回地址与函数的局部缓冲区都位于系统栈(活动栈)这一原理,利用代码中对局部变量的边界条件疏于检查的漏洞,篡改函数返回地址,引起程序异常或者改变程序执行流程,进而获得程序控制权。,缓冲区溢出攻击,缓冲区溢出攻击:,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(help

2、, “%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(“f

3、oo() 函数的地址是 %p n“,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

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

5、ne, “ 1234567891234567x0Ax10x40x00 “); 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

6、43 00 f8 eb fd 7f c0 1f 我是bar()函数,程序的执行流程改变了!,bar的代码段,。,缓冲区溢出攻击,6.3 非局部名字的访问,本节介绍 过程内部如何访问过程外部声明的名字? 静态作用域 无过程嵌套的静态作用域(C语言) 有过程嵌套的静态作用域(Pascal语言) 动态作用域(Lisp语言),C语言采用的是静态作用域,即词法作用域,变量与值的绑定是通过检查程序的正文,在编译时期完成的,而与程序的运行流程无关。它扫描程序正文,选取最近遇到的那个绑定。因此结果是5. 在采用动态作用域的语言里,变量与值的绑定是依赖于程序执行流程的,它是选取在运行的过程中所遇到的最近绑定。象

7、上面的例子,如果C语言采用动态作用域的话,那输出结果将是1。,#include int x= 5; int f() return x; int g() int x = 1; return f(); int main(int argc,char*argv) printf(“%d “,g(); ,6.3 非局部名字的访问,6.3.1 无过程嵌套的静态作用域 过程体中的非局部引用可以直接使用静态确定的地址 局部变量在栈顶的活动记录中,可以通过base_sp指针来访问 无须深入栈中取数据,无须访问链 过程可以作为参数来传递,也可以作为结果来返回,6.3 非局部名字的访问,6.3.2 有过程嵌套的静态作

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

9、活动记录。 访问链的追踪用间接操作就可完成。,sort 1 readarray 2 exchange 2 quicksort 2 partition 3,6.3 非局部名字的访问,访问非局部名字的存储单元,sort 1 readarray 2 exchange 2 quicksort 2 partition 3,6.3 非局部名字的访问,过程p对变量a访问时,a的地址由下面的二元组表示: (np na,a在活动记录中的偏移),由当前的活动记录经过np-na次追踪,就可以得到a所声明的过程,在a所声明的过程中,a是一个局部变量,其地址可以用它在本活动记录中的偏移来表示,6.3 非局部名字的访问,

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

11、p的过程p调用嵌套深度为nx的过程x np nx的情况 sort 1 readarray 2 exchange 2 quicksort 2 partition 3,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 readarray 2 exchange 2 quic

12、ksort 2 partition 3,21/46,s,a, 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

13、small; var r: real; begin r := 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

14、0.250 show; small; writeln; 0.250 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; s

15、mall; writeln end.,6.3 非局部名字的访问,实现动态作用域的方法 深访问 用控制链搜索运行栈,寻找包含该非局部名字的第一个活动记录 浅访问 为每个名字在静态分配的存储空间中保存它的当前值 当过程p的新活动出现时,p的局部名字n使用在静态数据区分配给n的存储单元。n的先前值可以保存在p的活动记录中,当p的活动结束时再恢复,6.4 参 数 传 递,6.4.1 值调用 实参的右值传给被调用过程 值调用可以如下实现 把形参当作所在过程的局部名看待,形参的存储单元在该过程的活动记录中。 调用过程计算实参,并把右值放入形参的存储单元中。,6.4 参 数 传 递,6.4.2 引用调用 实参的左值传给被调用过程 引用调用可以如下实现: 把实参的左值放入形参的存储单元。 在被调用过程的目标代码中,任何对形参的引用都是通过传给该过程的指针来间接引用实参的。,6.4 参 数 传 递,6.4.3 复写-恢复调用 值调用和引用调用的混合 复写-恢复调用可以如下实现: 实参的右值和左值同时传给被调用过程。 在被调用过程中,像值调用那样使用实参的右值。 当控制返回调用过程时,根据传递来的实参的左值,将形参当前的值复写到实参存储单元。,6.4 参 数 传 递,6.4.4 换名调用 用实参表达式对形参进行正文替换。 procedure swap(var x, y: in

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 高等教育 > 大学课件

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号