20145231 《信息安全系统设计基础》期中总结
教材学习内容复习
结合课本知识及再次实践加深理解记忆
按照学习时相关重点知识的顺序进行整理归纳
实践内容:重要命令的使用 gdb调试栈帧(再理解) makefile 编译运行代码深入理解局部性
Linux中的重要常用命令
Linux中命令格式为:command [options] [arguments] []表示是可选的,即组成结构为:命令 [选项] [参数]
**man命令**man命令是Linux下的帮助指令,通过man指令可以查看Linux中的指令帮助、配置文件帮助和编程帮助等信息。常用选项:-a:在所有的man帮助手册中搜索-k:根据关键字搜索联机帮助,是一种模糊搜索-f:关键字精确搜索,等价于whatis指令,显示给定关键字的简短描述信息-P:指定内容时使用分页程序-M:指定man手册搜索的路径参数:数字:指定从哪本man手册中搜索帮助关键字:指定要搜索帮助的关键字man -k:常用来搜索,结合管道使用。例句如下:man -k k1 | grep k2 | grep 2
**cheat命令**在linux上,man命令几乎是万能的,但它却不是最高效的。由于它给出的帮助信息很长,在短时间内不好理解,所以在这种情况下,用cheat命令更方便,cheat命令简单来说,就是告诉你一个命令如何使用。它没有提供其他额外多余的信息,只通过使用实例告诉你一个命令如何使用。
**grep命令**grep命令是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹配的行打印出来。grep全称是Global Regular Expression Print,表示全局正则表达式版本,它的使用权限是所有用户。命令格式:grep [options][options]主要参数:-c:只输出匹配行的计数-I:不区分大小写(只适用于单字符)-h:查询多文件时不显示文件名-l:查询多文件时只输出包含匹配字符的文件名-n:显示匹配行及行号-s:不显示不存在或无匹配文本的错误信息-v:显示不包含匹配文本的所有行如果想查找某个宏,我们已知宏保存在include文件夹中,所以可以使用下列语句:grep -nr XXX /usr/include(XXX为所要找的宏)
**find命令**find命令用来在指定目录下查找文件。任何位于参数之前的字符串都将被视为欲查找的目录名。如果使用该命令时,不设置任何参数,则find命令将在当前目录下查找子目录与文件。并且将查找到的子目录和文件全部进行显示。命令格式:find pathname -options [-print -exec -ok ...]参数:pathname:find命令所查找的目录路径。例如用.来表示当前目录,用/来表示系统根目录print:find命令将匹配的文件输出到标准输出exec:find命令对匹配的文件执行该参数所给出的shell命令,相应命令的形式为'command' { } \;,注意{ }和\;之间的空格ok:和-exec的作用相同,只不过以一种更为安全的模式来执行该参数所给出的shell命令,在执行每一个命令之前,都会给出提示,让用户来确定是否执行常用选项:-name:按照文件名查找文件-perm:按照文件权限来查找文件mtime -n +n:按照文件的更改时间来查找文件, - n表示文件更改时间距现在n天以内,+ n表示文件更改时间距现在n天以前-newer file1 ! file2:查找更改时间比文件file1新但比文件file2旧的文件-type:查找某一类型的文件,诸如:b - 块设备文件,d - 目录,c - 字符设备文件,p - 管道文件,l - 符号链接文件,f - 普通文件-size n:[c] 查找文件长度为n块的文件,带有c时表示文件长度以字节计-depth:在查找文件时,首先查找当前目录中的文件,然后再在其子目录中查找。
举例:查找当前目录下大小大于10K的文件
**locate命令**locate命令其实是find -name的另一种写法,但是要比后者快得多,原因在于它不搜索具体目录,而是搜索一个数据库(/var/lib/locatedb),这个数据库中含有本地所有文件信息。Linux系统自动创建这个数据库,并且每天自动更新一次,所以使用locate命令查不到最新变动过的文件。为了避免这种情况,可以在使用locate之前,先使用updatedb命令,手动更新数据库。命令格式:locate [选择参数] [样式]命令参数:-e:将排除在寻找的范围之外-1:如果是1则启动安全模式,在安全模式下,使用者不会看到权限无法看到的档案。这会使速度减慢,因为 locate必须至实际的档案系统中取得档案的权限资料-f:将特定的档案系统排除在外,例如我们没有到必要把proc档案系统中的档案放在资料库中-q:安静模式,不会显示任何错误讯息-n:至多显示 n个输出-r:使用正规运算式 做寻找的条件-o:指定资料库存的名称-d:指定资料库的路径-h:显示辅助讯息-V:显示程式的版本讯息
**whereis命令**whereis命令是定位可执行文件、源代码文件、帮助文件在文件系统中的位置。这些文件的属性应属于原始代码,二进制文件,或是帮助文件。whereis程序还具有搜索源代码、指定备用搜索路径和搜索不寻常项的能力。whereis命令只能用于程序名的搜索,而且只搜索二进制文件(参数-b)、man说明文件(参数-m)和源代码文件(参数-s)。如果省略参数,则返回所有信息。命令格式:whereis [-bmsu] [BMS 目录名 -f ] 文件名主要参数:-b:定位可执行文件-m:定位帮助文件-s:定位源代码文件-u:搜索默认路径下除可执行文件、源代码文件、帮助文件以外的其它文件-B:指定搜索可执行文件的路径-M:指定搜索帮助文件的路径-S:指定搜索源代码文件的路径
**which命令**which指令会在PATH变量指定的路径中,搜索某个系统命令的位置,并且返回第一个搜索结果。which是根据使用者所配置的PATH变量内的目录去搜寻可运行档的,所以,不同的PATH配置内容所找到的命令是不一样的。命令格式:which 可执行文件名称命令参数:-n:指定文件名长度,指定的长度必须大于或等于所有文件中最长的文件名-p:与-n参数相同,但此处的包括了文件的路径-w:指定输出时栏位的宽度-V:显示版本信息
总结find、locate、which、whereis的区别
which (寻找执行档) :这个指令是根据PATH这个环境变量所规范的路径,去搜寻执行档的档名,所以,重点是找出执行档而已,which 后面接的是完整档名
whereis (寻找特定档案):搜寻linux数据库档案中所记录的东西,和locate的主要区别在于后面的参数
locate:搜寻linux数据库档案中所记录的东西,后面直接跟档案的部分名称就行
find:直接搜索整个硬盘
**sort命令**将文本文件内容加以排序。可针对文本文件的内容,以行为单位来排序。参数:m:将几个排序好的文件进行合并。n:依照数值的大小排序Linux Bash中,ls . | sort 命令的功能是(显示当前目录内容并排序)
**du命令**显示目录或文件的大小。du会显示指定的目录或文件所占用的磁盘空间。参数:a:显示目录中个别文件的大小。b:显示目录或文件大小时,以byte为单位。c: 除了显示个别目录或文件的大小外,同时也显示所有目录或文件的总和
**ls命令**显示指定工作目录下之内容(列出目前工作目录所含之档案及子目录)。参数:a:显示所有档案及目录A:同 -a ,但不列出 "." (目前目录) 及 ".." (父目录)t:将档案依建立时间之先后次序列出列出目前工作目录下所有档案及目录;目录于名称后加 "/", 可执行档于名称后加 "*" : ls -AF
Linux Bash中,把ls命令显示当前目录的结果存入ls.txt的命令输出重定向命令是(ls > ls.txt)
vim gcc gdb make 的学习
详细内容见博客:(http://www.cnblogs.com/xzh20145231/p/5907518.html)
Vim常用命令总结
插入:i:在当前光标处进行编辑a:在光标后插入编辑
退出:q!:强制退出,不保存:q:退出:wq!:强制保存并退出:wq:保存并退出:w <文件路径>:另存为
删除:x:删除游标所在的字符dd:删除整行
行间跳转:nG(n Shift+g):光标移动到第n行
复制与粘贴:nyy:复制光标所在及其后的整行共n行p:代表粘贴至光标后
功能设定:
:set autoindent(ai):设置自动缩进:set cindent(cin):设置C语言风格缩进:set nu:以显示行号
GCC编译过程
预处理:`gcc –E hello.c –o hello.i ;gcc –E`调用cpp 产生预处理过的C原始程序编译:`gcc –S hello.i –o hello.s ;gcc –S`调用ccl 产生汇编语言原始程序汇编:`gcc –c hello.s –o hello.o ;gcc -c `调用as 产生目标文件链 接:`gcc hello.o –o hello ;gcc -o` 调用ld 产生可执行文件运行:` ./hello`
GDB调试
进入gdb:gcc -g xxx.c -o xxxgdb xxx查看源码:(gdb) l:进行行号提示(gdb) b n:在第n行设置断点(gdb) r:运行代码,运行至断点处(gdb) n:单步运行(gdb) c:使程序继续往下运行,直到再次遇到断点或程序结束(gdb) q:退出GDB(gdb) watch n:在"n"设置了观察点,观察变量的变化情况四种断点:函数断点:b 函数名 条件表达式行断点:b 行数或函数名 条件表达式条件断点:b 行数或函数名 if表达式临时断点:tbreak 行数或函数名 条件表达式
参照 (http://www.cnblogs.com/lxm20145215----/p/5982554.html) 中具体gdb调试指令对栈帧进行再理解:
使用gcc - g example.c -o example -m32指令在64位的机器上产生32位汇编,然后使用gdb example指令进入gdb调试器:
进入之后先在main函数处设置一个断点,再run一下,使用disassemble指令获取汇编代码,用i(info) r(registers)指令查看各寄存器的值:
可见此时主函数的栈基址为0xffffd068,用x(examine)指令查看内存地址中的值,但目前%esp所指堆栈内容为0,%ebp所指内容也为0
结合display命令和寄存器或pc内部变量,做如下设置:display /i $pc,在每次执行下一条汇编语句时,都会显示出当前执行的语句。再分别查看每一步%esp,%ebp中值的变化情况:
call指令将下一条指令的地址入栈,此时%esp,%ebp和堆栈的值为:
将上一个函数的基址入栈,从当前%esp开始作为新基址:
先为传参做准备:
实参的计算在%eax中进行:
f函数的汇编代码:
实参入栈:
call指令将下一条指令地址入栈:
计算过程:
弾栈(栈顶到%ebp),pop %ebp
,%esp增加4字节:
ret指令将栈顶弹给%eip:
因为函数f修改了%esp,所以用leave指令恢复。leave指令先将%esp对其到%ebp,然后把栈顶弹给%ebp:(LEAVE指令就相当于 mov esp,ebp 和 pop ebp 两条指令的执行效果。)
主函数的汇编代码:
makefile
功能:识别文件代码是否更新,减少编译工作量格式为:目标体:依赖文件[tab键]各目标体运行命令目标体:由make创建,通常是目标文件或可执行文件依赖文件:创建目标体所依赖的文件运行命令:创建每个目标体时需要的运行命令,必须以tab键开头。使用make的格式:make 目标体
计算机系统简介
了解计算机的基本构造及各个部分之间的联系,是对后面章节的一个概括:硬件组成等;
了解编译器如何编译;
了解了操作系统提供的抽象表示:文件是对I/O设备的抽象表示,进程是对处理器、主存和I/O设备的抽象表示。
链接
静态库
静态库是一系列的目标文件(.o文件)的归档文件((lib+name).a文 件);链接阶段,选择静态库,后缀名为“.a”;选择动态库,后缀名为“.so”。
静态链接库的生成:gcc -c
文件名.c ar rcsv libxxx.a xxx.o
静态库的使用:gcc -o
文件名 文件名.c -L. -lxxx//
链接到静态库
注意:
-L:在库文件的搜索路径列表中添加dir目录
-l:在头文件的搜索路径列表中添加dir目录
共享库
共享库的生成:
gcc -fPIC -c xxx.c
gcc -shared -o libxxx.so xxx.o
共享库的使用:gcc -o main main.c -L. -lxxx
注册共享库的方法:将库文件直接复制到/lib或者/usr/lib目录下:cp (lib+name).so /lib
信息的表示和处理
详细内容见博客: (http://www.cnblogs.com/xzh20145231/p/5928371.html)
各种进制之间的转换以及十六进制加减法;
布尔运算求值;
位级运算的掩码运算;
逻辑运算和位级运算的区别;
无符号数编码;
补码编码;
有符号数和无符号数之间的转换;
截断数字的方法;
补码的加法,补码求非;
无符号乘法和有符号乘法;
除以二的幂:无符号:逻辑移位;补码数:算术移位;
浮点数:IEEE浮点标准;
二进制小数;
规格化的值非规格化的值。
程序的机器级表示
用汇编语言理解指令,理解栈帧
详细内容见博客:(http://www.cnblogs.com/xzh20145231/p/5967918.html#3534564)
了解机器级编程,学习了IA32指令集,了解指令集体系结构和虚拟地址这两种抽象在机器级编程中的重要性:
利用object dump
进行反汇编以查看汇编指令;
基本数据格式;
操作数指示符:操作数类型:立即数、寄存器、存储器;相关寻址方式对应的格式;
根据操作数写出对应值;
数据传送指令(与Windows系统下指令有所区别),重点理解压栈和弾栈操作;
加载有效地址指令leal;
控制:条件码的设置、访问方式;跳转指令及其编码;循环结构(机器级代码理解:goto代码);条件传送指令;switch语句;
过程:栈帧结构;转移控制:call指令和ret指令;寄存器使用习惯;使用gdb调试帮助理解栈帧的建立和消亡。
处理器体系结构
详细内容见博客;(http://www.cnblogs.com/xzh20145231/p/5991005.html#3542104)
以Y86为例,指令加硬件实现(HCL语言)
Y86指令及指令编码;(通过指令能写出编码,通过编码能写出指令)
Y86异常:值代表的含义;
体会Y86与IA32代码的区别;
执行popl和pushl指令时处理器行为的不确定性;
组合电路和布尔表达式(HCL语言表示);
ALU算术逻辑单元;
随机访问存储器的读写操作;
Y86的顺序实现:取指、译码、执行、访存、写回、更新PC;(会写每个阶段对应的指令)
SEQ硬件结构、SEQ的时序(对应每个阶段)。
存储器层次结构
详细内容见博客;(http://www.cnblogs.com/xzh20145231/p/6013913.html#3545642)
常见存储技术:RAM、ROM、磁盘、固态硬盘;(区别及应用)
对比SRAM和DRAM的区别及应用;
非易失性存储器和只读存储器;
访问主存的方法:读写事务;
磁盘:磁盘构造;磁盘容量计算;磁盘操作:寻道时间、旋转时间、传送时间;逻辑磁盘块:映射关系、三元组;访问磁盘(连接到I/O设备);
局部性:时间局部性、空间局部性:判断程序好坏;
利用循环体提升程序局部性;
局部性分析:
参考了这篇文章:(http://www.cnblogs.com/dxy1982/p/4194218.html),觉得分析的很好。
存储器层次结构:高速缓存、缓存不命中。
对课程的意见或建议
谢谢老师特意发表git配置教程还有vim使用教程等指导博客,让像我这样动手自学能力不强的同学跟上进度!
代码托管截图
使用find *.|xargs wc -l
查找当前目录以及子目录中的文件行数
托管链接
收获
时间过得很快,周而复始,一个学期却早已过半。在本门课的学习中,我自知不够优秀,对于计算机系统的相关知识很多可能都还是一知半解,实践能力也不算强,每次破解安装或使用新的软件都落于人后,但是我觉得我学习这门课最大的收获就是:实践才有收获。很多时候我们不愿尝试新事物都是因为畏难情绪,但是只要你下定决心认真去做,也一样能做好,空有理论而不实践等于零。
比如:之前忽视了Linux命令学习的重要性,在使用终端时感觉不便,通过本周对Linux命令的再实践,在以后使用虚拟机终端的过程中相信会受益匪浅,再比如:通过上几周使用git托管代码,我发现资料备份以及分类的重要性。还有:看书时不做练习就无法真正理解新知识的核心以及涵义...
学习一门课,不只是掌握其中的相关知识,能够学到一种学习方式、学习习惯才是最大的收获(如老师所说的元知识,某些通用于各种学科的知识),现在也开始慢慢理解,为什么说至少要学习两种编程语言、学习两种操作系统才能找到所谓的不变量...学习之路,道阻且长,且学且珍惜。
不足
在前期的学习中忽略了对基本命令的实践与掌握,所以此次总结特意加强了这部分的实践及记忆,在使用虚拟机终端时,总是不知道对应操作的命令,每次都要去查找,所以对于重要命令的使用一定要熟记于心;在课本学习时,有时会忽略实践的重要性,导致课本知识不能很好的被消化理解,比如:存储其结构体系中的程序的局部性,必须要通过敲代码运行才能直观对比出差距...庆幸自己及时端正了态度,开始每周真正按照老师的要求去做,夯实了所学知识,继续努力。
学习进度条
博客量(新增/累积) | 学习时间(新增/累积) | 重要成长 | |
---|---|---|---|
目标 | 30篇 | 400小时 | |
第一周 | 2/2 | 20/20 | 学习了Linux核心命令 |
第二周 | 2/4 | 21/41 | 学习了vim、gcc、gdb指令 |
第三周 | 2/6 | 20/61 | 学习了信息的表示和处理,了解了二进制在计算机系统中的重要性 |
第五周 | 2/8 | 20/81 | 学习了机器级程序,读懂汇编代码 |
第七周 | 2/12 | 18/118 | 了解了存储器层次结构及存储技术 |
第八周 | 2/14 | 15/133 | 对前几周内容进行复习 |