文档库 最新最全的文档下载
当前位置:文档库 › 栈溢出实验报告

栈溢出实验报告

栈溢出实验报告
栈溢出实验报告

华中科技大学计算机学院《信息系统应用安全》实验报告

实验名称团队成员:

注:团队成员贡献百分比之和为1 教师评语:

一.实验环境

? 操作系统:windows xp sp3 ? 编译平台:visual c++ 6.0 ? 调试环境:ollydbg

二.实验目的

1. 掌握缓冲区溢出的原理;

2. 掌握缓冲区溢出漏洞的利用技巧;

3. 理解缓冲区溢出漏洞的防范措施。

三.实验内容及步骤

1. 缓冲区溢出漏洞产生的的基本原理和攻击方法

? 缓冲区溢出模拟程序

由于拷贝字符串时产生缓冲区溢出,用“abcd”字符串的值覆盖了原来eip的值,所以

main函数返回时eip指向44434241,引发访问异常。 ? 运行命令窗口的shellcode 由于把main函数的返回eip地址替换成了jmp esp的地址,main函数

返回的时候就会执行我们的shellcode代码。该shellcode,运行命令窗口。

2. ms06-040 缓冲区溢出漏洞分析和利用

? 溢出点定位

篇二:缓冲区溢出实验报告

院系:计算机与通信工程学院

班级:信息安全10-02班

1. 实验目的

掌握缓冲区溢出的原理

掌握常用的缓冲区溢出方法

理解缓冲区溢出的危害性

掌握防范和避免缓冲区溢出攻击的方法

2. 实验工具

溢出对象:ccproxy 7.2

(1)

(2)调试工具:

使用vmware虚拟机,安装ccproxy7.2进行实验调试。

3. 实验步骤

了解ccproxy 7.2

代理服务器为大家解决了很多问题,比如阻挡黑客攻击和局域网共享上网等。 ? 国内非

常受欢迎的一款代理服务器软件

? 设置简单,使用方便

关于ccproxy6.2缓冲区溢出漏洞说明

ccproxy在代理telnet协议时,可以接受ping命令

ping命令格式:ping hostname\r\n 当hostname的长度大于或者等于1010字节时,ccproxy 6.2会发生缓冲区溢出,导致

程序崩溃

ccproxy 6.2缓冲区溢出漏洞演示

在目标主机运行ccproxy,使用默认设置

运行ccproxy的机器ip是192.168.6.132 使用telnet命令连接ccproxy: telnet 192.168. 6.132 23 返回信息:(如图)

输入ping命令,后接畸形数据:

在ping命令后接10个字符a(ping aaaaaaaaaa),观察返回信息

将字符a的数量变为100个、1000个、2000个,观察返回信息

(注:由于本人安装的是7.2版本,其漏洞已修复,故智能识别252个字符,其后被截

断,所以当出现的畸形字符长度超过252时,就不再被识别,所以会有“host not found”)原理:

如果终端提示“host not found”,说明ccproxy正确地处理了这个畸形数据,仍工作正

如果终端提示“失去了跟主机的连接”,表明ccproxy已经崩溃

ccproxy 6.2缓冲区溢出漏洞利用

如何利用这个漏洞,来实现攻击目的,做一些特别的事情。

我们知道,栈是一个后进先出的结构,函数在入栈时,先将返回地址ret压入栈,接着

是ebp基址寄存器,然后根据局部变量的大小,开辟一定大小的缓冲区,再将局部变量压入。

在将局部变量压入栈的时候,如果压入数据过长,大于事先声明的缓冲区大小,就会覆

盖ebp和ret。

漏洞的利用有5个方面的问题需要考虑。

一是ret的定位,要用我们的地址覆盖ret,就需要先知道ret在哪,也就是我们定好

的这个地址,应该放在字符串的什么位置。

二是要寻找一个跳转指令,将这个指令的地址填充到ret,这样才能在返回时通过跳转

指令转到其它地方执行程序

三是要构造shellcode,也就是完成一些特定的功能。

四是将所构造的shellcode放在跳转指令转向的地方。

最后一个步骤就是根据上面的这些分析过程,将它们整合成攻击程序,运行这个攻击程

序就能直接利用缓冲区溢出漏洞。

函数栈布局,栈顶是内存低地址,栈底是内存高地址篇三:数据结构栈和队列实验报告

一、实验目的和要求

(1)理解栈和队列的特征以及它们之间的差异,知道在何时使用那种数据结构。

(2)重点掌握在顺序栈上和链栈上实现栈的基本运算算法,注意栈满和栈空的条件。

(3)重点掌握在顺序队上和链队上实现队列的基本运算算法,注意循环队队列满和队空的

条件。

(4)灵活运用栈和队列这两种数据结构解决一些综合应用问题。

二、实验环境和方法

实验方法:

(一)综合运用课本所学的知识,用不同的算法实现在不同的程序功能。

(二)结合指导老师的指导,解决程序中的问题,正确解决实际中存在的异常情况,逐

步改善功能。

(三)根据实验内容,编译程序。

实验环境:windows xp visual c++6.0

三、实验内容及过程描述

实验步骤:

①进入visual c++ 6.0集成环境。

②输入自己编好的程序。

③检查一遍已输入的程序是否有错(包括输入时输错的和编程中的错误),如发现有

错,及时改正。

④进行编译和连接。如果在编译和连接过程中发现错误,频幕上会出现“报错信息”,

根据提示找到出错位置和原因,加以改正。再进行编译,如此反复直到不出错为止。⑤

运行程序并分析运行结果是否合理。在运行是要注意当输入不同的数据时所得结果

是否正确,应运行多次,分别检查在不同情况下结果是否正确。

实验内容:编译以下题目的程序并调试运行。

1)、编写一个程序algo3-1.cpp,实现顺

的各种基本运算,并在此基础上设计一

程序并完成如下功能:

(1)初始化栈s;

(2)判断栈s是否非空;序栈个主

(3)依次进栈元素a,b,c,d,e;

(4)判断栈s是否非空;

(5)输出出栈序列;

(6)判断栈s是否非空;

(7)释放栈。图3.1 proj3_1 工程组成

本工程proj3_1的组成结构如图3.1所示。本工程的模块结构如图3.2所示。图中方框

表示函数,方框中指出函数名,箭头方向表示函数间的调用关系。

图3.2 proj3_1工程的程序结构图

其中包含如下函数:

initstack(sqstack *&s) //初始化栈s destroystack(sqstack *&s) //销毁栈s stackempty(sqstack *s) //判断栈空

push(sqstack *&s,elemtype e) //进栈

pop(sqstack *&s,elemtype &e) //出栈

gettop(sqstack *s,elemtype &e) //取栈顶元素

对应的程序如下:

//文件名:algo3-1.cpp

#include <stdio.h>

#include <malloc.h>

#define maxsize 100

typedef char elemtype;

typedef struct

{ elemtype data[maxsize];

int top; //栈顶指针

} sqstack;

void initstack(sqstack *&s) //初始化栈s { s=(sqstack *)malloc(sizeof(sqstack)); s->top=-1; //栈顶指针置为-1 }

void destroystack(sqstack *&s) //销毁栈s {

free(s);

}

bool stackempty(sqstack *s) //判断栈空

{

return(s->top==-1);

}

bool push(sqstack *&s,elemtype e) //进栈

{ if (s->top==maxsize-1) //栈满的情况,即栈上溢出

return false;

s->top++; //栈顶指针增1 s->data[s->top]=e; //元素e放在栈顶指针处

return true;

}

bool pop(sqstack *&s,elemtype &e) //出栈

{ if (s->top==-1) //栈为空的情况,即栈下溢出

return false;

e=s->data[s->top]; //取栈顶指针元素的元素

s->top--; //栈顶指针减1 return true;

}

bool gettop(sqstack *s,elemtype &e) //取栈顶元素

{ if (s->top==-1) //栈为空的情况,即栈下溢出

return false;

e=s->data[s->top]; //取栈顶指针元素的元素

return true;

}

设计exp3-1.cpp程序如下 //文件名:exp3-1.cpp #include <stdio.h>

#include <malloc.h>

#define maxsize 100

typedef char elemtype;

typedef struct

{ elemtype data[maxsize];

int top; //栈顶指针

} sqstack;

extern void initstack(sqstack *&s); extern void destroystack(sqstack *&s); extern bool stackempty(sqstack *s); extern bool push(sqstack *&s,elemtype e); extern bool pop(sqstack *&s,elemtype &e); extern bool gettop(sqstack *s,elemtype &e); void main()

{

elemtype e;

sqstack *s;

printf(栈s的基本运算如下:\n); printf( (1)初始化栈s\n);

initstack(s);

printf( (2)栈为%s\n,(stackempty(s)?空:非空)); printf( (3)依次进栈元素a,b,c,d,e\n); push(s,a);

push(s,b);

push(s,c);

push(s,d);

push(s,e);

printf( (4)栈为%s\n,(stackempty(s)?空:非空)); printf( (5)出栈序列:);

while (!stackempty(s))

{

pop(s,e);

printf(%c ,e);

}

printf(\n);

printf( (6)栈为%s\n,(stackempty(s)?空:非空)); printf( (7)释放栈\n);

destroystack(s);

}

运行结果如下:

2)、编写一个程序algo3-2.cpp,实现链栈的各种基本运算,并在此基础上设计一个主

程序并完成如下功能:

(1)初始化链栈s;

(2)判断链栈s是否非空;

(3)依次进栈a,b,c,d,e;

(4)判断链栈s是否非空;

(5)输出链栈长度;

(6)输出从栈底到栈顶元素;

(7)输出出队序列;

(8)判断链栈s是否非空;图3.3 proj3_2工程组成

(9)释放队列。

本工程proj3_2的组成结构如图3.3所示。本工程的模块结构如图3.4所示。图中方框

表示函数,方框中指出函数名,箭头方向表示函数间的调用关系。

图3.4 proj3_2工程的程序结构图

其中包含如下函数:

initstack(listack *&s) //初始化栈s destroystack(listack *&s) //销毁栈

stackempty(listack *s) //判断栈是否为空

push(listack *&s,elemtype e) //进栈

pop(listack *&s,elemtype &e) //出栈

gettop(listack *s,elemtype &e) //取栈顶元素

对应的程序如下:

//文件名:algo3-2.cpp

#include <stdio.h>

#include <malloc.h>

typedef char elemtype;

typedef struct linknode

{

elemtype data; //数据域篇四:数据结构顺序栈实验报告

一、设计人员相关信息

1. 设计者姓名、学号和班号:12地信李晓婧 12012242983

2. 设计日期:2014.

3. 上机环境:vc++6.0

二、程序设计相关信息

1. 实验题目:编写一个程序,实现顺序栈(假设栈中元素类型为char)的各种基本运

算,并在此基础上设计一个程序,完成如下功能:

(1)初始化栈

(2)判断栈是否为空

(3)依次进栈元素a,b,c,d,e (4)判断栈是否为空

(5)输出栈长度

(6)输出从栈顶到栈底元素

(7)输出出栈序列

(8)判断栈是否为空

(9)释放栈

2. 实验项目组成:栈的初始化、销毁、判断是否为空、进栈、出栈、取栈顶元素。

3. 实验项目的程序结构(程序中的函数调用关系图):

4. 实验项目包含的各个文件中的函数的功能描述:

(1)初始化栈initstack:建立一个新的空栈,实际上将栈顶指针指向-1即可。

(2)销毁栈destroystack:释放栈占用的存储空间

(3)判断栈是否为空stackempty:栈为空的条件是s->op==-1。

(4)进栈push:在栈不满的条件下,先将栈顶指针增1,然后在栈顶指针指向位置插入

元素e。

(5)出栈pop:在栈不为空的条件下,先将栈顶元素赋给e,然后将栈顶指针减1.

(6)取栈顶元素gettop:在栈不为空的条件下,将栈顶元素赋给e。

5. 算法描述或流程图:

#include stdio.h

#include malloc.h

#include<stdlib.h>

#define maxsize 50

typedef char elemtype; typedef struct

{elemtype data[maxsize];

int top; /*栈顶指针*/

}sqstack; //定义顺序栈类型

void initstack(sqstack*&s)/*初始化*/ {

s=(sqstack*)malloc(sizeof(sqstack)); s->top=-1; //栈顶指针置为-1 } void destroystack(sqstack *&s)/*销毁*/ {

free(s); } int stackempty(sqstack*s)/*判断是否为空*/ {

return(s->top==-1);

} int push(sqstack *&s,elemtype a[],int n) { int i; if(s->top==maxsize-1) //栈满的情况,即栈上溢出return 0;

for(i=0;i<n;i++) { s->top++; //栈顶指针增1 s->data[s->top]=a[i]; //元素e放在栈顶指针处

} int pop(sqstack*&s,elemtype &e)/*出栈一个元素*/ { if(s->top==-1) //栈为空的情况,即栈下溢出 return 0; e=s->data[s->top]; //取栈顶元素

s->top--; //栈顶指针减1 return 1;

}

} return 1; int gettop(sqstack *s,elemtype &e)/*取栈顶元素*/ { if(s->top==-1) //栈为空的情况,即栈下溢出 return 0; e=s->data[s->top]; //取栈顶元素

return 1;

} int stacklength(sqstack *s)/*求栈长度*/ {

return(s->top+1);

} void dispstack(sqstack *s) { } void main()

{

int i,j;

elemtype str[5]={a,b,c,d,e}; //定义字符数组 sqstack *st; //定义栈

initstack(st);/*初始化*/

i=stackempty(st); //判断栈是否为空

if(i==0) int i; for(i=s->top;i>=0;i--) printf(%c,s->data[i]);

printf(\n); printf(顺序栈非空\n); else printf(顺序栈为空\n); push(st,str,5); //进栈

j=stackempty(st);

if(j==0) printf(顺序栈非空\n); else printf(顺序栈为空\n); printf(栈长度为:%d\n,stacklength(st)); //输出栈长度

printf(出栈序列:\n);

dispstack(st); //输出栈

stackempty(st);

destroystack(st);

}

6. 实验数据和实验结果:

篇五:栈的操作(实验报告) 实验三栈和队列

3.1实验目的:

(1)熟悉栈的特点(先进后出)及栈的基本操作,如入栈、出栈等,掌握栈的基本操

在栈的顺序存储结构和链式存储结构上的实现;

(2)熟悉队列的特点(先进先出)及队列的基本操作,如入队、出队等,掌握队列的

本操作在队列的顺序存储结构和链式存储结构上的实现。

3.2 实验要求:

(1)复习课本中有关栈和队列的知识;

(2)用c语言完成算法和程序设计并上机调试通过;

(3)撰写实验报告,给出算法思路或流程图和具体实现(源程序)、算法分析结果(包

时间复杂度、空间复杂度以及算法优化设想)、输入数据及程序运行结果(必要时给出多

种可能的输入数据和运行结果)。

3.3 基础实验

[实验1] 栈的顺序表示和实现

实验内容与要求:

编写一个程序实现顺序栈的各种基本运算,并在此基础上设计一个主程序,完成如下功

能:

(1)初始化顺序栈

(2)插入元素

(3)删除栈顶元素

(4)取栈顶元素

(5)遍历顺序栈

(6)置空顺序栈

分析:

栈的顺序存储结构简称为顺序栈,它是运算受限的顺序表。

对于顺序栈,入栈时,首先判断栈是否为满,栈满的条件为:p->top= =maxnum-1,

栈满时,不能入栈; 否则出现空间溢出,引起错误,这种现象称为上溢。

出栈和读栈顶元素操作,先判栈是否为空,为空时不能操作,否则产生错误。通常栈空

作为一种控制转移的条件。

注意:

(1)顺序栈中元素用向量存放

(2)栈底位置是固定不变的,可设置在向量两端的任意一个端点

(3)栈顶位置是随着进栈和退栈操作而变化的,用一个整型量top(通常称top为栈顶

指针)来指示当前栈顶位置

参考程序:

#include<stdio.h>

#include<stdlib.h>

#define maxnum 20 #define elemtype int

/*定义顺序栈的存储结构*/

typedef struct

{ elemtype stack[maxnum];

int top;

}sqstack;

/*初始化顺序栈*/

void initstack(sqstack *p) { if(!p)

printf(eorror);

p->top=-1;

}

/*入栈*/

void push(sqstack *p,elemtype x) { if(p->top<maxnum-1) { p->top=p->top+1;

p->stack[p->top]=x;

}

else

printf(overflow!\n);

}

/*出栈*/

elemtype pop(sqstack *p)

{ elemtype x;

if(p->top!=0)

{ x=p->stack[p->top]; printf(以前的栈顶数据元素%d已经被删除!\n,p->stack[p->top]); p->top=p->top-1;

return(x);

}

else

{ printf(underflow!\n);

return(0);

}

}

/*获取栈顶元素*/

elemtype gettop(sqstack *p) { elemtype x;

if(p->top!=0)

{ x=p->stack[p->top]; return(x);

}

else

{ printf(underflow!\n); return(0);

}

}

/*遍历顺序栈*/

void outstack(sqstack *p)

{ int i;

printf(\n);

if(p->top<0)

printf(这是一个空栈!);

printf(\n);

for(i=p->top;i>=0;i--) printf(第%d个数据元素是:%6d\n,i,p->stack[i]); }

/*置空顺序栈*/

void setempty(sqstack *p)

{

p->top= -1;

}

/*主函数*/

main()

{ sqstack *q;

int y,cord;elemtype a;

do{

printf(\n);

printf(第一次使用必须初始化!\n); printf(\n);

printf(\n 主菜单 \n); printf(\n 1 初始化顺序栈 \n); printf(\n 2 插入一个元素 \n); printf(\n 3 删除栈顶元素 \n); printf(\n 4 取栈顶元素 \n); printf(\n 5 置空顺序栈 \n); printf(\n 6 结束程序运行 \n); printf(\n--------------------------------\n); printf(请输入您的选择( 1, 2, 3, 4, 5,6)); scanf(%d,&cord);

printf(\n);

switch(cord)

{ case 1:

{ q=(sqstack*)malloc(sizeof(sqstack)); initstack(q);

outstack(q);

}break;

case 2: { printf(请输入要插入的数据元素:a=); scanf(%d,&a);

push(q,a);

outstack(q);

}break;

case 3:

{ pop(q);

outstack(q);

}break;

case 4:

{ y=gettop(q);

printf(\n栈顶元素为:%d\n,y); outstack(q);

}break;

case 5:

{ setempty(q);

printf(\n顺序栈被置空!\n); outstack(q);

}break;

case 6:

exit(0);

}

}while (cord<=6);

} [实验2] 栈的链式表示和实现

实验内容与要求:

编写一个程序实现链栈的各种基本运算,并在此基础上设计一个主程序,完成如下功能:

(1)初始化链栈

(2)链栈置空

(3)入栈

(4)出栈

(5)取栈顶元素

(6)遍历链栈

分析:

链栈是没有附加头结点的运算受限的单链表。栈顶指针就是链表的头指针。

注意:

(1)linkstack结构类型的定义可以方便地在函数体中修改top指针本身

(2)若要记录栈中元素个数,可将元素个数属性放在linkstack类型中定义。

(3)链栈中的结点是动态分配的,所以可以不考虑上溢。

参考程序:

#include stdio.h

#include malloc.h

#include stdlib.h

typedef int elemtype;

typedef struct stacknode {

elemtype data;

stacknode * next;

}stacknode;

typedef struct {

stacknode * top; //栈顶指针

}linkstack;

/*初始化链栈*/

void initstack(linkstack * s) { s->top=null;

printf(\n已经初始化链栈!\n); }

/*链栈置空*/

void setempty(linkstack * s) { s->top=null;

printf(\n链栈被置空!\n);

}

/*入栈*/

void pushlstack(linkstack * s, elemtype x) { stacknode * p;

p=(stacknode *)malloc(sizeof(stacknode)); //建立一个节点。 p->data=x; p->next=s->top; //由于是在栈顶pushlstack,所以要指向栈顶。

数据结构-实验报告顺序栈

(封面) 学生实验报告 学院:国际经贸学院 课程名称:数据结构 专业班级: 09电子商务 姓名: 学号: 学生实验报告

(经管类专业用) 一、实验目的及要求: 1、目的 通过实验,实现顺序栈的各种基本运算。 2、内容及要求 编写一个程序,实现顺序栈的各种基本运算,并在此基础上设计一个主程序完成下列功能: (1)初始化栈S。 (2)判断栈S是否非空。 (3)依次进栈元素a,b,c,d,e。 (4)判断栈S是否非空。 (5)输出栈的长度。 (6)输出从栈顶到栈底的元素。 (7)输出出栈序列; (8)判断链栈S是否为空; (9)释放链栈 二、仪器用具: 三、实验方法与步骤:

一、查阅顺序栈等相关资料,熟悉顺序栈基本概念和流程 二、“开展”顺序栈实验流程 三、整理实验数据和文档,总结实验的过程,编写实验报告 四、实验结果与数据处理: 1、顺序栈的代码: #include #include #define MaxSize 100 typedef char ElemT ype; typedef struct { ElemT ype data[MaxSize]; int top; //栈顶指针 } SqStack; void InitStack(SqStack *&s) { s=(SqStack *)malloc(sizeof(SqStack)); s->top=-1; } void ClearStack(SqStack *&s) { free(s); } int StackLength(SqStack *s) { return(s->top+1);

数据结构堆栈与队列实验报告

实验二堆栈和队列 实验目的: 1.熟悉栈这种特殊线性结构的特性; 2.熟练并掌握栈在顺序存储结构和链表存储结构下的基本运算; 3.熟悉队列这种特殊线性结构的特性; 3.熟练掌握队列在链表存储结构下的基本运算。 实验原理: 堆栈顺序存储结构下的基本算法; 堆栈链式存储结构下的基本算法; 队列顺序存储结构下的基本算法; 队列链式存储结构下的基本算法; 实验内容: 第一题链式堆栈设计。要求 (1)用链式堆栈设计实现堆栈,堆栈的操作集合要求包括:初始化StackInitiate(S),非空否StackNotEmpty(S),入栈StackiPush(S,x),出栈StackPop(S,d),取栈顶数据元素StackTop(S,d); (2)设计一个主函数对链式堆栈进行测试。测试方法为:依次把数据元素1,2,3,4,5入栈,然后出栈并在屏幕上显示出栈的数据元素; (3)定义数据元素的数据类型为如下形式的结构体, Typedef struct { char taskName[10]; int taskNo; }DataType; 首先设计一个包含5个数据元素的测试数据,然后设计一个主函数对链式堆栈进行测试,测试方法为:依次吧5个数据元素入栈,然后出栈并在屏幕上显示出栈的数据元素。 第二题对顺序循环队列,常规的设计方法是使用対尾指针和对头指针,对尾指针用于指示当前的対尾位置下标,对头指针用于指示当前的対头位置下标。现要求: (1)设计一个使用对头指针和计数器的顺序循环队列抽象数据类型,其中操作包括:初始化,入队列,出队列,取对头元素和判断队列是否为空; (2)编写主函数进行测试。 程序代码: 第一题: (1)源程序"LinStack.h"如下: #define NULL 0 typedef struct snode { DataType data; struct snode *next; } LSNode; /*(1)初始化StackInitiate(LSNode ** head) */ void StackInitiate(LSNode ** head) /*初始化带头结点链式堆栈*/

顺序栈的基本操作讲解

遼穿紳範大學上机实验报告 学院:计算机与信息技术学院 专 业 : 计算机科学与技术(师 范) 课程名称:数据结构 实验题目:顺序栈的基本操作 班级序号:师范1班 学号:201421012731 学生姓名:邓雪 指导教师:杨红颖 完成时间:2015年12月25号 一、实验目的: 1 ?熟悉掌握栈的定义、结构及性质; 2. 能够实现创建一个顺序栈,熟练实现入栈、出栈等栈的基本操作; 3?了解和掌握栈的应用。 二、实验环境: Microsoft Visual C++ 6.0

三、实验内容及要求: 栈是一种特殊的线性表,逻辑结构和线性表相同,只是其运算规则有更多的限制,故又称为受限的线性表。 建立顺序栈,实现如下功能: 1. 建立一个顺序栈 2. 输出栈 3. 进栈 4. 退栈 5. 取栈顶元素 6. 清空栈 7. 判断栈是否为空 进行栈的基本操作时要注意栈”后进先出”的特性。 四、概要设计: 1、通过循环,由键盘输入一串数据。创建并初始化一个顺序栈。 2、编写实现相关功能函数,完成子函数模块如下。 3、调用子函数,实现菜单调用功能,完成顺序表的相关操作

五、代码: #include #include #define maxsize 64 typedef int datatype; //定义结构体typedef struct { datatype data[maxsize]; int top; }seqstack; //建立顺序栈seqstack *SET(seqstack *s) { int i; s=(seqstack*)malloc(sizeof(seqstack)); s->top=-1; printf(" 请输入顺序栈元素(整型,以scanf("%d",&i); do{ s->top++; s->data[s->top]=i; scanf("%d",&i); 0 结束):"); }while(i!=0); printf(" 顺序栈建立成功\n"); return s; } //清空栈void SETNULL(seqstack *s) { s->top=-1;} //判断栈空 int EMPTY(seqstack *s) { if(s->top>=0) return 0; else return 1;} //进栈 seqstack *PUSH(seqstack *s) { int x; printf(" 你想要插入的数字:"); scanf("%d",&x); if(s->top==maxsize-1) { printf("overflow"); return NULL; } else {

缓冲区溢出攻击实验

HUNAN UNIVERSITY 课程实验报告 题目: Buflab-handout 学生姓名 学生学号 专业班级计科1403 (一)实验环境 联想ThinkPadE540 VM虚拟机ubuntu32位操作系统 (二)实验准备 1.使用tar xvf命令解压文件后,会有3个可执行的二进制文件bufbomb,hex2raw, makecookie。bufbomb运行时会进入getbuf函数,其中通过调用Gets函数读取字符 串。要求在已知缓冲区大小的情况下对输入的字符串进行定制完成特定溢出操作。 从给的PDF文件中我们得知getbuf函数为:

/ /Buffer size for getbuf #define NORMAL_BUFFER_SIZE 32 int getbuf() { char buf[NORMAL_BUFFER_SIZE]; Gets(buf); return 1; } 这个函数的漏洞在于宏定义的缓冲区的大小为32,若输入的字符串长于31(字符串末尾结束符)则会导致数据的覆盖,从而导致一系列损失;在此实验中,我们正是利用这个漏洞来完成实验。 2. hex2raw可执行文件就是将给定的16进制的数转成二进制字节数据。 Makecookie是产生一个userid。输入的相应的用户名产生相应的cookie值。 **我产生的cookie值为0x5eb52e1c,如下图所示: Level0: 实验要求:从英文的PDF文件中的“Your task is to get BUFBOMB to execute the code for smoke when getbuf executes its return statement, rather than returning to test. Note that your exploit string may also corrupt parts of the stack not directlyrelated to this stage, but this will not cause a problem, since smoke causes the program to exit directly.”这句话看出实验让我们在test运行完后,不直接退出,而是跳到smoke函数处执行然后退出,这点很重要!(本人之前一直没有成功就是错在这儿) Test源码: void test() { int val; // Put canary on stack to detect possible corruption volatile int local = uniqueval(); val = getbuf(); // Check for corrupted stack if (local != uniqueval()) { printf("Sabotaged!: the stack has been corrupted\n"); } else if (val == cookie) { printf("Boom!: getbuf returned 0x%x\n", val); validate(3);

栈的操作(实验报告)

实验三栈和队列 3.1实验目的: (1)熟悉栈的特点(先进后出)及栈的基本操作,如入栈、出栈等,掌握栈的基本操作在栈的顺序存储结构和链式存储结构上的实现; (2)熟悉队列的特点(先进先出)及队列的基本操作,如入队、出队等,掌握队列的基本操作在队列的顺序存储结构和链式存储结构上的实现。 3.2实验要求: (1)复习课本中有关栈和队列的知识; (2)用C语言完成算法和程序设计并上机调试通过; (3)撰写实验报告,给出算法思路或流程图和具体实现(源程序)、算法分析结果(包括时间复杂度、空间复杂度以及算法优化设想)、输入数据及程序运行结果(必要时给出多种可能的输入数据和运行结果)。 3.3基础实验 [实验1] 栈的顺序表示和实现 实验内容与要求: 编写一个程序实现顺序栈的各种基本运算,并在此基础上设计一个主程序,完成如下功能:(1)初始化顺序栈 (2)插入元素 (3)删除栈顶元素 (4)取栈顶元素 (5)遍历顺序栈 (6)置空顺序栈 分析: 栈的顺序存储结构简称为顺序栈,它是运算受限的顺序表。 对于顺序栈,入栈时,首先判断栈是否为满,栈满的条件为:p->top= =MAXNUM-1,栈满时,不能入栈; 否则出现空间溢出,引起错误,这种现象称为上溢。 出栈和读栈顶元素操作,先判栈是否为空,为空时不能操作,否则产生错误。通常栈空作为一种控制转移的条件。 注意: (1)顺序栈中元素用向量存放 (2)栈底位置是固定不变的,可设置在向量两端的任意一个端点 (3)栈顶位置是随着进栈和退栈操作而变化的,用一个整型量top(通常称top为栈顶指针)来指示当前栈顶位置 参考程序: #include #include #define MAXNUM 20

SEED信息安全实验系列:缓冲区溢出漏洞实验

缓冲区溢出漏洞实验 一、实验描述 缓冲区溢出是指程序试图向缓冲区写入超出预分配固定长度数据的情况。这一漏洞可以被恶意用户利用来改变程序的流控制,甚至执行代码的任意片段。这一漏洞的出现是由于数据缓冲器和返回地址的暂时关闭,溢出会引起返回地址被重写。 二、实验准备 本次实验为了方便观察汇编语句,我们需要在32位环境下作操作,因此实验之前需要做一些准备。 1、输入命令安装一些用于编译32位C程序的东西: sudo apt-get update sudo apt-get install lib32z1 libc6-dev-i386 sudo apt-get install lib32readline-gplv2-dev 2、输入命令“linux32”进入32位linux环境。此时你会发现,命令行用起来没那么爽了,比如不能tab补全了,所以输入“/bin/bash”使用bash: 三、实验步骤 3.1 初始设置

Ubuntu和其他一些Linux系统中,使用地址空间随机化来随机堆(heap)和栈(stack)的初始地址,这使得猜测准确的内存地址变得十分困难,而猜测内存地址是缓冲区溢出攻击的关键。因此本次实验中,我们使用以下命令关闭这一功能: sudo sysctl -w kernel.randomize_va_space=0 此外,为了进一步防范缓冲区溢出攻击及其它利用shell程序的攻击,许多shell程序在被调用时自动放弃它们的特权。因此,即使你能欺骗一个Set-UID程序调用一个shell,也不能在这个shell中保持root权限,这个防护措施在/bin/bash中实现。 linux系统中,/bin/sh实际是指向/bin/bash或/bin/dash的一个符号链接。为了重现这一防护措施被实现之前的情形,我们使用另一个shell程序(zsh)代替/bin/bash。下面的指令描述了如何设置zsh程序: sudo su cd /bin rm sh ln -s zsh sh exit 3.2 shellcode 一般情况下,缓冲区溢出会造成程序崩溃,在程序中,溢出的数据覆盖了返回地址。而如果覆盖返回地址的数据是另一个地址,那么程序就会跳转到该地址,如果该地址存放的是一段精心设计的代码用于实现其他功能,这段代码就是shellcode。 观察以下代码: #include int main( ) { char *name[2]; name[0] = ‘‘/bin/sh’’; name[1] = NULL; execve(name[0], name, NULL); } 本次实验的shellcode,就是刚才代码的汇编版本: \x31\xc0\x50\x68"//sh"\x68"/bin"\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80 3.3 漏洞程序 把以下代码保存为“stack.c”文件,保存到/tmp 目录下。代码如下: /* stack.c */ /* This program has a buffer overflow vulnerability. */ /* Our task is to exploit this vulnerability */ #include #include #include int bof(char *str) { char buffer[12]; /* The following statement has a buffer overflow problem */strcpy(buffer, str); return 1;

栈的应用的实验报告

班级学号姓名实验组别 试验日期室温报告日期成绩 报告内容:(目的和要求、原理、步骤、数据、计算、小结等) 实验名称:栈的实现与应用 实验目的; 1.掌握栈的定义。 2.掌握栈基本操作的实现,并能用于解决实际问题。 实验环境(硬/软件要求): Windows 2000, Visual C++ 6.0 实验内容: 1.实现栈的如下基本操作:push,pop,isempty,isfull,createstack. 2.利用栈的基本操作实现conversion()函数,该函数能将任意输出的十进制整数转化为二进制形式表示。 实验要求: 1.用顺序存储结构实现栈的基本操作:push,pop,isempty,isfull,createstack. 2.利用栈的基本操作实现conversion()函数 3.编写主函数完成实验内容2. 【C语言源程序】 #include #include #define maxsize 1024 /*栈的最大容量为1024*/ typedef int datatype; typedef struct { datatype elements[maxsize]; int Top; /*栈指针*/ }Stack; void setNull(Stack *S) {S->Top=-1;} int isfull(Stack *S) {if(S->Top>=maxsize-1)return (1); else return (0); } int isempty(Stack *S) { if(S->Top>=0)return (0); else return (1); } /*isempty*/ void push( Stack *S,datatype E) { if(S->Top>=maxsize-1)

实验4 缓冲区溢出攻击实验

深圳大学实验报告课程名称:计算机系统(2) 实验项目名称:缓冲区溢出攻击实验 学院:计算机与软件学院 专业:计算机科学与技术 指导教师:罗秋明 报告人: 实验时间:2016年5月8日 实验报告提交时间:2016年5月22日 教务处制

一、实验目标: 1.理解程序函数调用中参数传递机制; 2.掌握缓冲区溢出攻击方法; 3.进一步熟练掌握GDB调试工具和objdump反汇编工具。 二、实验环境: 1.计算机(Intel CPU) 2.Linux64位操作系统(CentOs) 3.GDB调试工具 4.objdump反汇编工具 三、实验内容 本实验设计为一个黑客利用缓冲区溢出技术进行攻击的游戏。我们仅给黑客(同学)提供一个二进制可执行文件bufbomb和部分函数的C代码,不提供每个关卡的源代码。程序运行中有3个关卡,每个关卡需要用户输入正确的缓冲区内容,否则无法通过管卡! 要求同学查看各关卡的要求,运用GDB调试工具和objdump反汇编工具,通过分析汇编代码和相应的栈帧结构,通过缓冲区溢出办法在执行了getbuf()函数返回时作攻击,使之返回到各关卡要求的指定函数中。第一关只需要返回到指定函数,第二关不仅返回到指定函数还需要为该指定函数准备好参数,最后一关要求在返回到指定函数之前执行一段汇编代码完成全局变量的修改。 实验代码bufbomb和相关工具(sendstring/makecookie)的更详细内容请参考“实验四缓冲区溢出攻击实验.p ptx”。 本实验要求解决关卡1、2、3,给出实验思路,通过截图把实验过程和结果写在实验报告上。

四、实验步骤和结果 步骤1 返回到smoke() 1.1 解题思路 首先弄清楚getbuf()的栈帧结构,知道存放字符数组buf地址的单元和存放getbuf()返回地址的单元之间相差多少个字节。假设两者之间相差x个字节。 然后找到smoke()函数的入口地址。该值为4个字节。 再构造exploit.txt,前x个字节随意填,然后再填入4个字节的smoke()地址,注意是小端方式存储。 这样操作完成,就可以得到预期结果了。 1.2 解题过程 首先进入GDB对bufbomb进行调试,先在调用getbuf()处设置断点,然后运行。 注:此时的输入文件exploit_raw.txt文件中是随便填的,并不影响我调用smoke(),因为我会在gdb中使用set指令直接修改getbuf()的返回地址。 此时查看运行程序的调用栈帧结构,如下所示: 上图说明当getbuf()执行完后,会返回到test()函数中(返回到地址0x08048db2,我们要修改存放这个值的地址单元,改为smoke的入口地址值)。

数据结构栈的基本操作,进栈,出栈

第五次实验报告—— 顺序栈、链栈的插入和删除一需求分析 1、在演示程序中,出现的元素以数字出现定义为int型, 2、演示程序在计算机终端上,用户在键盘上输入演示程序中规定的运算命令,相应的输入数据和运算结果显示在终端上 3、顺序栈的程序执行的命令包括如下: (1)定义结构体 (2)顺序栈的初始化及创建 (3)元素的插入 (4)元素的删除 (5)顺序栈的打印结果 3、链栈的程序执行的命令包括如下: (1)定义结构体 (2)链栈的初始化及创建 (3)元素的插入 (4)元素的删除 (5)链栈的打印结果 二概要设计 1、顺序栈可能需要用到有序表的抽象数据类型定义: ADT List{ 数据对象:D={ai|ai∈ElemL, i=1,2,...,n, n≥0} 数据关系:R1={|ai-1,ai ∈D, i=2,...,n } 基本操作: InitStack(SqStack &S) 操作结果:构造一个空栈 Push(L,e) 操作结果:插入元素e为新的栈顶元素

Status Pop(SqStack &S) 操作结果:删除栈顶元素 }ADT List; 2、链栈可能需要用到有序表的抽象数据类型定义: ADT List{ 数据对象:D={ai|ai∈ElemL, i=1,2,...,n, n≥0} 数据关系:R1={|ai-1,ai ∈D, i=2,...,n } 基本操作: LinkStack(SqStack &S) 操作结果:构造一个空栈 Status Push(L,e) 操作结果:插入元素e为新的栈顶元素 Status Pop(SqStack &S) 操作结果:删除栈顶元素 }ADT List; 3、顺序栈程序包含的主要模块: (1) 已给定的函数库: (2)顺序栈结构体: (3)顺序栈初始化及创建: (4)元素插入 (5)元素删除

栈和队列综合实验报告

栈和队列综合实验报告 一、实验目的 (1)能够利用栈和队列的基本运算进行相关操作。 (2)进一步熟悉文件的应用 (3)加深队列和栈的数据结构理解,逐步培养解决实际问题的编程能力。 二、实验环境 装有Visual C++的计算机。 本次实验共计4学时。 三、实验内容 以下两个实验任选一个。 1、迷宫求解 设计一个迷宫求解程序,要求如下: 以M × N表示长方阵表示迷宫,求出一条从入口到出口的通路,或得出没有通路的结论。 能任意设定的迷宫 (选作)如果有通路,列出所有通路 提示: 以一个二维数组来表示迷宫,0和1分别表示迷宫中的通路和障碍,如下图迷宫数据为:11

01 01 01 01 01 01 01 11 入口位置:1 1 出口位置:8 8 四、重要数据结构 typedef struct{ int j[100]; int top;栈顶指针,一直指向栈顶 }stack;//存放路径的栈 int s[4][2]={{0,0},{0,0},{0,0},{0,0}}; //用于存放最近的四步路径坐标的数组,是即使改变的,即走一步,便将之前的坐标向前移一步,将最早的一步坐标覆盖掉,新的一步放入数组末尾其实功能和队列一样。 其作用是用来判断是否产生了由于本程序算法产生的“田”字方格内的死循环而准备的,用于帮助跳出循环。 五、实现思路分析 if(a[m][n+1]==0&&k!=3){ n++; k=1; o=0; }else if(a[m+1][n]==0&&k!=4){ m++;

k=2; o=0; }else if(a[m][n-1]==0&&k!=1){ n--; k=3; o=0; }else if(a[m-1][n]==0&&k!=2){ m--; k=4; o=0; }else{ o++;} if(o>=2){ k=0; }//向所在方格的四个方向探路,探路顺序为→↓←↑(顺时针),其中if判断条件内的&&k!=n和每个语句块中的对k赋值是为防止其走回头路进入死循环,而最后一个else{}内语句是为了防止进入死路时,不能走回头路而造成的死循环。 push(q,m,n);//没进行一次循环都会讲前进的路径入栈。 if (pushf(&s[0][0],m,n)==0){ k=3;}//用来判断是否产生了由于本程序探路算法产生的“田”字方格内的死循环而准备的,用于帮助跳出田字循环。同时会将路径存入用于下次判断 六、程序调试问题分析 最开始写完时是没有死路回头机制的,然后添加了两步内寻路不回头机制。 第二个是“田”字循环问题,解决方法是加入了一个记录最近四步用的数组和一个判断田字循环的函数pushf。

山东大学信息安全实验报告

山东大学软件学院 信息安全导论课程实验报告 学号:201300301385 姓名:周强班级: 2013级八班 实验题目:缓冲区溢出实验 实验学时:日期: 实验目的: (1)了解缓冲区溢出的原理 (2)利用缓冲区溢出现象构造攻击场景 (3)进一步思考如何防范基于缓冲区溢出的攻击 硬件环境: 软件环境: WindowsXP操作系统 VS2008 实验步骤与内容: (1)了解缓冲区溢出的原理 缓冲区溢出简单来说就是计算机对接收的输入数据没有进行有效的检测(理情况下是程序检测数据长度并不允许输入超过缓冲区长度的字符),向缓冲区内填充数据时超过了缓冲区本身的容量,而导致数据溢出到被分配空间之外的内存空间,使得溢出的数据覆盖了其他内存空间的数据。 看一个代码实例,程序如下: void function(char *str) { char buffer[16]; strcpy(buffer,str); } 上面的strcpy()将直接把str中的内容copy到buffer中。这样只要str的长度大于16,就会造成buffer的溢出,使程序运行出错。

(2)利用缓冲区溢出现象构造攻击场景 首先打开Microsoft Visual C++,新建工程和cpp文件,复制实验指导书的代码进行编译连接: 单击运行按钮,然后第1次输入“zhouqianga”,第2次输入2个“ga”,即可看到输出“correct”。

按F10开始进行逐步调试: 当第一次执行gets()函数之前,内存情况如下图所示

在最新的版本中gets被认为是不安全的,gets从标准输入设备读字符串函数。可以无限读取,不会判断上限,以回车结束读取,所以程序员应该确保buffer的空间足够大,以便在执行读操作时不发生溢出。现在都被要求改为get_s。来防止溢出。 如下图所示。 (3)学习例子程序2:数据被执行 在xp系统下,直接运行Exploit-1.1.exe,如下图所示:

数据结构实验报告 顺序栈

《数据结构与算法》实验报告

一、实验内容 1.栈的实现 2.顺序栈的基本操作 二、实验目的及要求 熟悉栈的基本操作在顺序栈的实现。通过具体应用实例在复习高级编程语言使用方法的基础上初步了解数据结构的应用。 三、设计分析与算法描述 顺序栈的存储结构: typedef struct { int elem[Stack_Size]; int top; }SeqStack; void InitStack(SeqStack *S)//构造一个空栈(初始化) int Push(SeqStack *S,int x)//进栈 int Pop(SeqStack *S,int *x)//出栈 int IsEmpty(SeqStack *S)//判栈是否空 int IsFull(SeqStack *S)//判栈是否满 int GetTop(SeqStack *S,int *x)//读栈顶 四、附件:带注释的源程序 #include"iostream.h" #define Stack_Size 50 #define false 0 #define true 1

typedef struct { int elem[Stack_Size]; int top; }SeqStack; void InitStack(SeqStack *S)//构造一个空栈(初始化) { S->top=-1; } int Push(SeqStack *S,int x)//进栈 { if(S->top==Stack_Size-1)//栈已满 return (false); S->top++; S->elem[S->top]=x; return (true); } int Pop(SeqStack *S,int *x)//出栈 { if(S->top==-1)//栈已空 return (false); else { *x=S->elem[S->top];

栈溢出实验报告

华中科技大学计算机学院《信息系统应用安全》实验报告 实验名称团队成员: 注:团队成员贡献百分比之和为1 教师评语: 一.实验环境 ? 操作系统:windows xp sp3 ? 编译平台:visual c++ 6.0 ? 调试环境:ollydbg 二.实验目的 1. 掌握缓冲区溢出的原理; 2. 掌握缓冲区溢出漏洞的利用技巧; 3. 理解缓冲区溢出漏洞的防范措施。 三.实验内容及步骤 1. 缓冲区溢出漏洞产生的的基本原理和攻击方法 ? 缓冲区溢出模拟程序 由于拷贝字符串时产生缓冲区溢出,用“abcd”字符串的值覆盖了原来eip的值,所以 main函数返回时eip指向44434241,引发访问异常。 ? 运行命令窗口的shellcode 由于把main函数的返回eip地址替换成了jmp esp的地址,main函数 返回的时候就会执行我们的shellcode代码。该shellcode,运行命令窗口。 2. ms06-040 缓冲区溢出漏洞分析和利用 ? 溢出点定位 篇二:缓冲区溢出实验报告 缓 冲 区 溢 出 报 告 院系:计算机与通信工程学院 班级:信息安全10-02班 1. 实验目的 掌握缓冲区溢出的原理 掌握常用的缓冲区溢出方法 理解缓冲区溢出的危害性 掌握防范和避免缓冲区溢出攻击的方法 2. 实验工具 溢出对象:ccproxy 7.2 (1) (2)调试工具: 使用vmware虚拟机,安装ccproxy7.2进行实验调试。 3. 实验步骤 了解ccproxy 7.2 代理服务器为大家解决了很多问题,比如阻挡黑客攻击和局域网共享上网等。 ? 国内非 常受欢迎的一款代理服务器软件 ? 设置简单,使用方便 关于ccproxy6.2缓冲区溢出漏洞说明

华科_计算机系统实验报告

课程实验报告课程名称:计算机系统基础 专业班级: 学号: 姓名: 指导教师: 报告日期:年月日 计算机科学与技术学院

目录 实验1: (1) 实验2: (7) 实验3: (24) 实验总结 (34)

实验1:数据表示 1.1 实验概述 实验目的:更好地熟悉和掌握计算机中整数和浮点数的二进制编码表示。 实验目标:加深对数据二进制编码表示的了解。 实验要求:使用有限类型和数量的运算操作实现一组给定功能的函数。 实验语言:c。 实验环境:linux 1.2 实验内容 需要完成bits.c中下列函数功能,具体分为三大类:位操作、补码运算和浮点数操作。 1)位操作 表1列出了bits.c中一组操作和测试位组的函数。其中,“级别”栏指出各函数的难度等级(对应于该函数的实验分值),“功能”栏给出函数应实现的输出(即功能),“约束条件”栏指出你的函数实现必须满足的编码规则(具体请查看bits.c中相应函数注释),“最多操作符数量”指出你的函数实现中允许使用的操作符的最大数量。 你也可参考tests.c中对应的测试函数来了解所需实现的功能,但是注意这些测试函数并不满足目标函数必须遵循的编码约束条件,只能用做关于目标函数正确行为的参考。 表1 位操作题目列表

2)补码运算 表2列出了bits.c中一组使用整数的补码表示的函数。可参考bits.c中注释说明和tests.c中对应的测试函数了解其更多具体信息。 表2 补码运算题目列表 3)浮点数操作 表3列出了bits.c中一组浮点数二进制表示的操作函数。可参考bits.c中注释说明和tests.c中对应的测试函数了解其更多具体信息。注意float_abs的输入参数和返回结果(以及float_f2i函数的输入参数)均为unsigned int类型,但应作为单精度浮点数解释其32 bit二进制表示对应的值。 表3 浮点数操作题目列表

栈和队列及其应用实验报告

数据结构实验报告 实验名称:栈和队列及其应用 班级:12级电气本2 学号:2012081227 姓名:赵雪磊 指导教师:梁海丽 日期:2013年9月23日 数学与信息技术学院 一、实验目的

1. 掌握栈和队列的概念。 2.掌握栈和队列的基本操作(插入、删除、取栈顶元素、出队、入队等)。 3.理解栈和队列的顺序、链式存储。 二、实验要求 利用顺序栈将任意一个给定的十进制数转换成二进制、八进制、十六进制数并输出。 三、算法描述 #include "stdafx.h" #include "iomanip.h" void D10to2_8_16(int i,char radix) { char m; if(i>=radix) D10to2_8_16(i/radix,radix); if((m=i%radix+'0')>0x39) m+=7; cout << m; } void main(void) { int nDec; cout << "请输入一个十进制正整数...\n" << "nDec="; cin >> nDec; cout << "转换为二进制是:"; D10to2_8_16(nDec,2); cout << endl; cout << "转换为八进制是:0"; D10to2_8_16(nDec,8); cout << endl; cout << "转换为十六进制是:0x"; D10to2_8_16(nDec,16); cout << endl; } 四、程序清单 #include #include #define N 2 //可以控制进制转换 using namespace std; typedef struct{ int *top; int *base; int stacksize; }stack;

栈实验报告

北京建筑大学 理学院《数据结构与算法》课程实验报告 课程名称《数据结构与算法》实验名称栈的创建以及应用实验地点基C-419 日期_2015-4-25 姓名李若万班级信131 学号201307010135 指导教师毕靖成绩 【实验目的】 1.熟悉并写出栈的逻辑结构表示 2.实现栈的存储表示 3.实现线性表的操作 【实验内容】 1.括号匹配 【实验要求】 1.要求:在实验报告中写出栈的ADT表示; 2.在实验报告中给出数据类型定义和核心算法和程序; 3.在实验报告中罗列实验过程中出现的问题和解决的方法; 4.打包上交调试后的完整程序,提交实验报告; 5.实验之前写出实验报告的大概框架,实验过程中填写完整。 6.实验时携带需要上机调试的程序; 7.实验评分:实验之前预习占20%,实验报告书写情况占50%,运行情况30%。 【实验步骤】 实验中出现的问题以及解决方法: 1、代码里面用到getch()报错,后来在前面提前声明头文件#include可以运行。 2、不知道怎么实验括号的匹配检验,通过查资料了解到括号匹配检验的实现需要用 switch,case,break,default等等语句来实现。 3、设定好的小中括号可以正常按代码运行,若遇到其他的大括号和数字等,也可以运行匹配成功,问题 没有得到解决。 【实验结果】 1、ADT表示: ADT Stack{ InitStack(&S)//构造一个空栈S GetTop(S,&e)//取栈顶元素 Push(&S,e)//插入新的栈顶元素 Pop(&S,&e)//删除栈顶元素 DestroyStack(&S)//销毁栈 } 2、数据结构的定义: typedef struct //定义结构体 {selemtype *base; //定义栈底指针 selemtype *top; //定义栈顶指针 int stacksize; //定义栈的大小 } sqstack; //sqstack为结构体类型

缓冲区溢出攻击实验报告

缓冲区溢出攻击实验报告 班级:10网工三班学生姓名:谢昊天学号:46 实验目的和要求: 1、掌握缓冲区溢出的原理; 2、了解缓冲区溢出常见的攻击方法和攻击工具; 实验内容与分析设计: 1、利用RPC漏洞建立超级用户利用工具文件检测RPC漏洞,利用工具软件对进行攻击。攻击的结果将在对方计算机上建立一个具有管理员权限的用户,并终止了对方的RPC服务。 2、利用IIS溢出进行攻击利用软件Snake IIS溢出工具可以让对方的IIS溢出,还可以捆绑执行的命令和在对方计算机上开辟端口。 3、利用WebDav远程溢出使用工具软件和远程溢出。 实验步骤与调试过程: 1.RPC漏洞出。首先调用RPC(Remote Procedure Call)。当系统启动的时候,自动加载RPC服务。可以在服务列表中看到系统的RPC服务。利用RPC漏洞建立超级用户。首先,把文件拷贝到C盘跟目录下,检查地址段到。点击开始>运行>在运行中输入cmd>确定。进入DOs模式、在C盘根目录下输入 -,回车。检查漏洞。 2.检查缓冲区溢出漏洞。利用工具软件对进行攻击。在进入DOC模式、在C盘根目录下输入 ,回车。 3,利用软件Snake IIS溢出工具可以让对方的IIS溢出。进入IIS溢出工具软件的主界面. PORT:80 监听端口为813 单击IDQ溢出。出现攻击成功地提示对话框。 4.利用工具软件连接到该端口。进入DOs模式,在C盘根目录下输入 -vv 813 回车。5.监听本地端口(1)先利用命令监听本地的813端口。进入DOs模式,在C盘根目录下输入nc -l -p 813回车。(2)这个窗口就这样一直保留,启动工具软件snake,本地的IP 地址是,要攻击的计算机的IP地址是,选择溢出选项中的第一项,设置IP为本地IP地址,端口是813.点击按钮“IDQ溢出”。(3)查看nc命令的DOS框,在该界面下,已经执行了设置的DOS命令。将对方计算机的C盘根目录列出来,进入DOC模式,在C盘根目录下输入nc -l -p 813回车。 6.利用WebDav远程溢出使用工具软件和远程溢出。(1)在DOS命令行下执行,进入DOC 模式,在C盘根目录下输入回车。(2)程序入侵对方的计算机进入DOC模式,在C盘根目录下输入nc -vv 7788 回车。 实验结果: 1.成功加载RPC服务。可以在服务列表中看到系统的RPC服务,见结果图。 2.成功利用工具软件对进行攻击。 3.成功利用IIS溢出进行攻击利用软件Snake IIS溢出工具让对方的IIS溢出,从而捆绑

(完整word版)顺序栈基本操作实验报告

数据结构实验三 课程数据结构实验名称顺序栈基本操作第页 专业班级学号 姓名 实验日期:年月日评分 一、实验目的 1.熟悉并能实现栈的定义和基本操作。 2.了解和掌握栈的应用。 二、实验要求 1.进行栈的基本操作时要注意栈"后进先出"的特性。 2.编写完整程序完成下面的实验内容并上机运行。 3.整理并上交实验报告。 三、实验内容 1.编写程序任意输入栈长度和栈中的元素值,构造一个顺序栈,对其进行清空、销毁、入栈、出栈以及取栈顶元素操作。 2.编写程序实现表达式求值,即验证某算术表达式的正确性,若正确,则计算该算术表达式的值。 主要功能描述如下: (1)从键盘上输入表达式。 (2)分析该表达式是否合法: ?a) 是数字,则判断该数字的合法性。若合法,则压入数据到堆栈中。 ?b) 是规定的运算符,则根据规则进行处理。在处理过程中,将计算该表达式的值。 ?c) 若是其它字符,则返回错误信息。 (3)若上述处理过程中没有发现错误,则认为该表达式合法,并打印处理结果。 程序中应主要包含下面几个功能函数: ?l void initstack():初始化堆栈 ?l int Make_str():语法检查并计算

?l int push_operate(int operate):将操作码压入堆栈 ?l int push_num(double num):将操作数压入堆栈 ?l int procede(int operate):处理操作码 ?l int change_opnd(int operate):将字符型操作码转换成优先级 ?l int push_opnd(int operate):将操作码压入堆栈 ?l int pop_opnd():将操作码弹出堆栈 ?l int caculate(int cur_opnd):简单计算+,-,*,/ ?l double pop_num():弹出操作数 四、实验步骤 (描述实验步骤及中间的结果或现象。在实验中做了什么事情,怎么做的,发生的现象和中间结果) 第一题: #include using namespace std; #define STACK_INIT_SIZE 100 //存储空间初始分配量 #define STACKINCREMENT 10 //存储空间分配增量 #define OVERFLOW -1 #define OK 1 #define NO -1 #define NULL 0 typedef int Status; typedef char SElemType; typedef struct { SElemType *base; //在栈构造之前和销毁之后,base的值为NULL SElemType *top; //栈顶指针 int stacksize; //当前已分配的存储空间,以元素为单位 } SqStack; Status Initstack(SqStack &S)//构造一个空栈S { S.base=(SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType)); if(!S.base) exit(OVERFLOW); S.top=S.base; S.stacksize= STACK_INIT_SIZE; return OK; }//InitStack Status StackEmpty(SqStack &S) { if(S.base==S.top)

数据结构栈和队列实验报告.doc

南京信息工程大学实验(实习)报告 实验(实习)名称栈和队列日期2017.11.8 得分指导老师崔萌萌 系计算机系专业软件工程年级2016 班次(1) 姓名学号 一、实验目的 1、学习栈的顺序存储和实现,会进行栈的基本操作 2、掌握递归 3、学习队列的顺序存储、链式存储,会进行队列的基本操作 4、掌握循环队列的表示和基本操作 二、实验内容 1、用栈解决以下问题: (1)对于输入的任意一个非负十进制数,显示输出与其等值的八进制数,写出程序。(2)表达式求值,写出程序。 2、用递归写出以下程序: (1)求n!。 (2)汉诺塔程序,并截图显示3、4、5个盘子的移动步骤,写出移动6个盘子的移动次数。

3、编程实现:(1)创建队列,将asdfghjkl依次入队。(2)将队列asdfghjkl依次出队。 4、编程实现创建一个最多6个元素的循环队列、将ABCDEF依次入队,判断循环队列是否队满。 三、实验步骤 1.栈的使用 1.1 用栈实现进制的转换: 代码如下: #include #include using namespace std; int main() { stack s; //栈s; int n,radix; printf("请输入要转换的十进制非负整数: "); scanf("%d",&n); printf("请输入目标进制: "); scanf("%d",&radix);

printf("转换为%d进制: ",radix); while(n) { s.push(n%radix); n /= radix; } while(!s.empty()) { //非空 printf("%d",s.top()); s.pop(); } printf("\n"); return 0; } 运行结果如下: 2.2 求表达式的值 代码如下: #include #include #include #include #define true 1 #define false 0 #define OPSETSIZE 8 typedef int Status;

相关文档