信息安全系统设计基础期中总结

【学习时间:8h】

【学习内容:考试试题及书本重点的复习】

一、书本重点内容

1.信息就是“位+上下文”。

2.三种数字:无符号数、有符号数(2进制补码)、浮点数,信息安全系同学从逆向角度考虑为什么会产生漏洞?

整数运算和浮点数运算会有不同的数学属性是因为他们处理数字表现有限性的方式不同。整数的表示虽然只能编码一个较小的范围,但这种表示是精确的;而浮点数表示的范围相对较大,但是这种表示只是近似的。

3.技巧:如果要使用C99中的“long long”类型,编译时可以通过 gcc -std=c99完成。

4.如何让整数运算溢出?如何避免?

因为机器有的限制,只要两个运算数进行运算的结果超过Umax或者Umin,就会发生溢出。避免溢出,将运算结果控制在-2^(w-1)---2^(w-1)-1中间;或者增加if语句判断运算数的是否合法。

5.Java只支持有符号数;Java中,>>是算术右移,>>>是逻辑右移。

6.反汇编指令

gcc -s xx.c -o xx.s 获得

gcc -m32 -s xx.c 从64位机器上得到32位的代码

otool -d xxx 可从mac os 上进行反汇编

7.数据传送指令

mov传送 movs传送符号扩展的字节 movz传送零扩展的字节 ;

movs和movz将一个较小的源数据复制到一个较大到的位置,符号位扩展,高位用源值最高位填充,零扩展就用0填充高位 ;

不能从一个内存地址直接mov到另一个内存地址,要用寄存器中转 栈顶元素是最近被压入的元素,是所有栈中元素地址中最低的。

8.IA32程序用程序栈来支持过程调用。机器用栈来传递过程参数、存储返回信息、保存寄存器用于本地恢复,以及本地存储。为单个过程分配的那部分栈称为栈帧。

9.栈向低地址方向增长,而栈指针%esp指向栈顶元素。可以利用pushl将数据存入栈中并利用popl指令从栈中取出。

栈的增长方式并不是很“和谐”,初学的时候很容易搞错。

10.过程调用

1)call指令有一个目标,即指明被调用过程起始的指令地址。同跳转一样,调用可以是间接的,也可以是直接的。效果是将返回地址入栈,并跳转到被调用过程的起始处。返回地址是在程序中紧跟在call后的那条指令的地址。这样当被调用过程返回的时候,执行会从此处继续。

2)ret指令从栈中弹出地址,并跳转到这个位置。

11.编译器如何产生管理栈结构的代码?

参数在栈上传递给函数,可以从栈中相对于%ebp的正偏移量来访问它们。可以用push指令或是从栈指针减去偏移量在栈上分配空间。在返回前,函数必须将栈恢复到原始的条件,可以恢复所有的被调用者保存寄存器和%ebp,并且重置%esp使其指向返回地址。

我认为了解这个“最后一步”是理解栈帧很重要的一点。正是通过这种机制,才保证了栈帧重复利用而不发生混乱。

12.存储器:从概念上来说是一个很大的字节数组,保存着程序和数据。

这种方式体现了计算机结构的一致性——可以把复杂的问题简单化。

13.Stat包括四种状态,除了AOK表示正常执行外,其他状态都会导致处理器停止。在更完整的设计中,处理器通常都会调用一个异常处理程序。

14.将处理一条指令的操作组织成某个特殊的、有规则的阶段序列,这样可以设计一个充分利用硬件且可以完成大部分指令的处理器。下面是各个阶段:

取指:从存储器中读取指令字节,地址为PC(程序计数器)的值。 译码:译码阶段从寄存器文件中最多读取出两个操作数,得到valA和/或valB。执行:在执行阶段,ALU执行指令指明的操作或者计算存储器引用的有效地址,或者增加、减少栈指针。 访存:可以将数据写入存储器,或者从存储器中读出数据。 写回:写回阶段最多可以写两个结果到寄存器文件。 更新PC:将PC设置成下条指令的地址

15.SEQ时序控制的一条重要原则:处理器从来不需要为了完成一条指令的执行而去读由该指令更新了的状态。

16..磁盘结构

磁盘有若干盘片组成,密封在容器(磁盘驱动器)内;盘片中心有一个可以旋转的主轴,使磁盘以一定的旋转速率旋转;每个盘片的两个表面都有一组被称为磁道的同心圆;每个同心圆由一些间隙分隔成一组等容量磁道(通常是512字节),间隙中存储的是标识扇区的格式化位。 磁盘连同密封装置共同构成旋转驱动器。注意:固态硬盘(SSD)是没有旋转部分的。 磁盘上可以记录的最大位叫做磁盘容量。决定因素有:记录密度(磁道一英寸的段中可以放入的位数);磁道密度(从盘片中心出发,半径一英寸的段内可以有的磁道数);面密度(前两者乘积)

17.计算机程序倾向于引用邻近于其他最近引用过的数据项的数据或其本身;这种倾向性,被称为局部性原理。包括:时间局部性,空间局部性。有良好局部性的程序比局部性差的程序运行的更快。

18.CPU使用一种称为存储器映射I/O的技术向I/O设备发出命令;在使用它的系统中,地址空间的一部分是为I/O设备通信而保留的;每个这样的地址称为I/O端口。但一个设备连接到总线的时候,它映射到一个或者多个I/O端口。

19.存储器层次结构:寄存器——高速缓存(SRAM)——主存(DRAM)——磁盘

20.缓存命中与不命中

缓存命中:当程序需要第(k+1)层的数据对象d的时候,首先会在第k层找d;如果d刚好缓存在第k层,那么就叫做缓存命中;反之,不命中

如果缓存不命中,那么第k层缓存就从第(k+1)层取出包含该数据的块,有可能会覆盖现有的块。被覆盖的块叫做牺牲块;决定该替换哪个块是由缓存的替换策略来控制的。

21.通用的高速缓存存储器结构

每个存储器地址有m位,形成M=2^m个不同地址。这m位被划分成t个标记位、s个组索引位和b个块偏移位。 这样一个机器的高速缓存被组织成S=2^s个高速缓存组的数组;每个数组包含E个高速缓存行;每行由一个B=2^b字节的数据块、一个有效位(指明这个行是否包含有效信息)、t=m-(b+s)个标记位(唯一标识存储在这个高速缓存行中的块)组成。 一般而言,高速缓存块的结构可以用元组(S,E,B,m)表述。其中,C=SEB代表容量。

22.标记位和索引位合起来唯一标识了高速缓存中的块。

二、Linux系统基础

1.终端(Terminal),Linux 的多用户登陆就是通过不同的 /dev/tty 设备完成的,Linux 默认提供了 6 个纯命令行界面的 “terminal”(准确的说这里应该是 6 个 virtual consoles)来让用户登录,在物理机系统上你可以通过使用[Ctrl]+[Alt]+[F1]~[F6]进行切换。当你切换到其中一个终端后想要切换回图形界面,你可以按下[Ctrl]+[Alt]+[F7]来完成。

2.使用Tab键来进行命令补全,补全目录,补全命令参数都是没问题的;

3.用Ctrl+c键来强行终止当前程序(它并不会使终端退出)

4.*——匹配 0 或多个字符;?——匹配任意一个字符

5.创建用户:这里用到 sudo 这个命令,使用这个命令有两个大前提,一是知道当前登录用户的密码,二是当前用户必须在 sudo 用户组。“$ sudo adduser lilei”指令创建新账户,输入密码界面上看不见,其他信息敲下回车键就表示默认。

6.将用户加入群组,使用 usermod 命令可以为用户添加用户组,同样使用该命令你必需有 root 权限。

格式:sudo usermod [参数] sudo [用户]

7.更改文件权限(对所有者,同一用户组的用户,其他人):chmod [0——7][0——7][0——7] [文件]

8. 绝对路径,简单地说就是以根"/"目录为起点的完整路径,以你所要到的目录为终点,表现形式如: /usr/local/bin,表示根目录下的 usr 目录中的 local 目录中的 bin 目录。

9.相对路径,也就是相对于你当前的目录的路径,相对路径是以当前目录 . 为起点,以你所要到的目录为终点,表现形式如:usr/local/bin 。

10.复制文件,使用cp(copy)命令复制一个文件或目录到指定目录。复制目录,成功复制目录需要加上-r或者-R参数,表示递归复制。

11.查看文件类型,file命令查看文件类型

12.读取变量的值,使用echo命令和$符号($符号可以表示引用一个变量的值)

13.du指令查看目录的容量,-d参数指定查看目录的深度

14.sort指令排序,-t参数用于指定字段的分隔符,这里是以":"作为分隔符;-k 字段号用于指定对哪一个字段进行排序,如果要按照数字排序就要加上-n参数。

15.基本正则表达式

(1)+表示前面的字符必须出现至少一次(1次或多次);?表示前面的字符最多出现一次(0次或1次); (2)*星号代表前面的字符可以不出现,也可以出现一次或者多次; (3)\:将下一个字符标记为一个特殊字符、或一个原义字符。例如,“n”匹配字符“n”。“\n”匹配一个换行符。序列“\”匹配“\”而“(”则匹配“(”。

三、gcc,gdb使用

gcc使用

(1)- gcc -E hello.c -o hello.i
预处理 - gcc -c hello.i -o hello.o
将hello.i编译为目标代码 - gcc hello.o -o hello
gcc连接器将目标文件链接为一个可执行文件,一个大致的编译流程结束

gdb使用

(1)break 6(6即设置断点的行号);info break(查看断点信息);r(运行程序);n(单步运行);p i(打印变量i的值);c(继续运行程序)

三、考试疑难问题分析

1.第一周

(1)查看前天创建的文件,find ~-ctime 2

+2:前天之前
-2:现在到前天
 2:前天

(2)df与du命令不同,df查看磁盘容量,du查看目录的容量

(3)Linux Bash中,source 和 . 命令功能等价。( ok)

二者都是指的根目录。

(4)Linux Bash中,使用grep查找当前目录下*.c中main函数在那个文件中的命令是( grep main *.c )

grep命令可以实现查找功能;*代替任意字符。

(5)col 命令的-h参数可以将Tab换成对等数量的空格建。(x )

col实现的是 空格转换为tab。

2.第二周

(1)指令“man -k search | grep line | grep 3”用来查找C函数线性查找,得到结果为lfind或lsearch

(2)操作系统中最基本的四个抽象:虚拟机,进程,虚拟存储器,文件

(3)查找宏 STDIN_FILENO 的值的命令是(grep -nr XXX /usr/include)

(4)链接器的两个主要任务是(符号解析和重定位)。

3.第三周

(1)vi中查看帮助文档,在正常模式下直接使用快捷键K即可

(2)Linux中显示文件(file )属性(status)的命令是( stat )

可以在Linux环境中进行实际操作。

(3)使用du命令对当前目录下的目录或文件按大小排序 的命令是( du -sk *| sort -rn )

| 是管道,可以将前面的结果作为后面操作的输入。

 

4.第四周

(1)Linux汇编中,形成空调用栈帧的语句是(push %ebp movl %esp %ebp)

5.第五周

(1)实现一个数字系统需要三组成部分(组合逻辑、存储器元素、时钟信号)。

(2)gdb中next和step都可以单步跟踪,根据自顶向下原则应该优先选用step. (X )

因为next和step都是单步执行,所以经常用来比较。然而next是不跳进函数内部执行的,而step会跳入函数内部执行。考虑整体性的话,优先选用前者。

(3)a,b长度都是一个字节,a=1,b=6, a|b = ( 7 or [00000111] )

对比: a||b = ( 1 or true )

|与||在布尔运算中是不一样的。前者是“按位或”,后者只是对两个操作数整体上进行或操作,只有0和1两个结果。

(4)C语言中: -2147483647-1U < -2147483647 ( ok )

左侧的-2147483647-1在转换成无符号数的时候,会转换成(4294967296-2147483648)即2147483648;而-2147483647转换成无符号数字的时候也是加上4294967296,则比左侧大。

第六周

(1)对于机器级编程来说,两种重要的抽象是(ISA,虚拟地址)

ISA即指令集体系结构。

(2) 把内存中地址为0x4050处的字复制到地址为0x405c处的指令是 movw ($0x4050) ,($0x405c) (x)

应该是movw ($0x4050) ,$0x405c

(3)汇编代码不会记录程序值的类型。(ok)

汇编代码是二进制形式的,并不会记录程序值类型。

第七周

(1)mem_write中为什么有IRMMOVL( 寄存器往内存写 )

四、个人总结

通过本次期中总结回顾,我发现自己在之前的自学中其实是遗漏了很多内容的;或者有很多内容没有完全“吃透”。因而在复习的过程中,更是经常有“恍然大悟”的感觉。所以,古人说的“书读百遍,其义自现”是有道理的。同时,我认为自己在对基础知识的理解上还是太粗糙,需要进一步打磨。

五、课程建议

我觉得这门课程相较于其他课程来讲,充分调动了我们的积极性,把“学习”从“期末突击”转变为了“苟日新,日日新”。不过,对于基础中等的同学来讲,其实我觉得现在的任务量也相当充实了;现在这种因人而异的学习任务更适合我们。

posted on 2015-11-01 18:22  20135211李行之  阅读(227)  评论(2编辑  收藏  举报