20145330 第5周《信息安全系统设计基础》
20145330 第5周《信息安全系统设计基础》
本章学习内容是汇编语言,现在直接写汇编的机会不多了,但一定要能读懂,信息安全的核心思维方式“逆向”在这有很好很直接的体现,反汇编就是直接的****。
教材学习内容总结
- 寻址方式经历三代:
- DOS时代的平坦模式,不区分用户空间和内核空间,很不安全
- 8086的分段模式
- IA32的带保护模式的平坦模式
- 机器级编程的两种抽象
- 指令集结构ISA是机器级程序的格式和行为,定义了处理器状态、指令的格式,以及每条指令对状态的影响
- 机器级程序使用的存储器地址是虚拟地址,提供的储存器看上去是一个非常大的字节数组,实际上是将多个硬件存储器和操作系统软件组合起来
- 代码编译
- 编译产生汇编代码:gcc –s xxx.c 得到.s文件
- 编译产生目标代码文件:gcc -o1 xxx.c 得到.o文件
- 反汇编命令:objdump –d xxx
- 直接编译64位处理器得到32代码的命令:gcc –S –o xxx.s xxx.c -m32
- 二进制文件可以用od 命令查看,也可以用gdb的x命令查看。
- 有些输出内容过多,我们可以使用 more或less命令结合管道查看,也可以使用输出重定向来查看
- od code.o | more
- od code.o > code.txt
- gcc -S 产生的汇编中可以把 以”.“开始的语句都删除了再阅读
- 几个寄存器要深入理解,知道它们的用处
- esi edi可以用来操纵数组
- esp ebp用来操纵栈帧
- 对于寄存器,特别是通用寄存器中的eax,ebx,ecx,edx,大家要理解32位的eax,16位的ax,8位的ah,al都是独立的
- 深入理解各种寻址方式
- 理解操作数的三种类型
- 立即数:常数值,表示为$c标准表示的整数
- 寄存器:表示某个寄存器的内容
- 存储器:根据计算出来的地址访问某个存储器位置
- 掌握有效地址的计算方式
- MOV相当于C语言的赋值”=“,注意ATT格式中的方向, 另外注意不能从内存地址直接MOV到另一个内存地址,要用寄存器中转一下。
- 区分MOV,MOVS,MOVZ
- 栈的特点
- 后进先出的原则
- push压栈,pop出栈
- 栈顶:总是从这端插入和删除元素
- 栈顶元素的地址是最低的
- 栈指针%esp保存着栈顶元素的地址
- 指针就是地址;局部变量保存在寄存器中
- 四组操作
- 加载有效地址:将有效地址写入目的操作数,目的操作数必须是寄存器
- 一元操作:只有一个操作数,既是源又是目的
- 二元操作:源操作数是第一个,可以是立即数、寄存器、存储器,目的操作数是第二个,可以是寄存器、存储器,但两个不能同时为存储器
- 移位:第一个是移位量,用单个字节编码且只允许0-31位的移位,可以是立即数或者放在单字节寄存器%cl中(算术右移SAR,填上符号位/逻辑右移SHR,填上0)目的操作数可以是一个寄存器或存储器
- SET指令根据t=a-b的结果设置条件码
- if-else 的汇编结构
- 联系习题3.16体会
- do-while
- while
- 联系习题3.22
- for
- 联系习题3.23
- 条件传送指令
- 当条件满足时,程序沿着一条路径进行,而当条件不满足时,就走另一条路径。
- comvl指令
- 习题3.27
- switch
- 根据一个整数索引值进行多重分支
- 习题3.29
- IA32通过栈来实现过程调用。掌握栈帧结构,注意函数参数的压栈顺序.
- 线帧结构
- 最顶端的栈帧以两个指针界定,寄存器%ebp为帧指针,而寄存器%esp为栈指针
- call 过程调用
- leave 为返回过程栈
-
ret 从过程调用中返回
gdb
- 使用流程
- 进入GDB #gdb test
- test是要调试的程序,由gcc test.c -g -o test生成。进入后提示符变为(gdb)
- 查看源码 (gdb) l
- 设置断点 (gdb) b 6
- 这样会在运行到源码第6行时停止,可以查看变量的值、堆栈情况等;这个行号是gdb的行号。
- 查看断点处情况 (gdb) info b
- 可以键入"info b"来查看断点处情况,可以设置多个断点;
- 运行代码 (gdb) r
- 显示变量值 (gdb) p n
- 在程序暂停时,键入"p 变量名"(print)即可;
- 在程序暂停时,键入"p 变量名"(print)即可;
- 单步运行 (gdb) n
- 程序继续运行 (gdb) c
-
退出GDB (gdb) q
教材学习中的问题和解决过程
- 进入GDB #gdb test
- 3.1
- 题目:将值存放在指明的存储器地址和寄存器中
- 9(%eax,%edx)
- 解决方法:根据操作数格式操作数值来计算:ox[9+100+03]=ox10C,地址ox10C对应值为ox11
- 3.9
- 题目:基于汇编代码,填写C语言代码缺失的部分
- 解决方法:熟练掌握整数算术操作,了解每条语句的意思,这样更好的助于理解
- 3.15
- 题目:mov指令的地址是多少
- XXXXXXX: 72 12 je 8048391
- XXXXXXX: b8 00 00 00 00 mov $0x0,%eax
- 解决方法:根据反汇编器产生的注释,跳转目标是绝对地址ox8048391,得到mov指令地址ox8048391-ox12=ox804837f
- 出错原因为16进制换算掌握不牢固,应多加练习
- 3,22
- 题目:while循环中基于汇编语言,填写 C语言空缺
- 解决方法:先一步步将汇编语言读懂,在不熟练的情况下查之前的表格,知道testl为测试;je跳转条件为等于零或相等;shrl为右移;or为异或;jne为跳转条件不等于零
了解执行过程后,就很好去填写C语言中缺失的部分了。
- 这个代码计算参数x的奇偶性。如果x中有奇数个1,就返回1,;如果有偶数个1,就返回0
查看汇编文件:
- 3.23
- 题目:for循环中基于汇编语言,填写 C语言空缺
解决方法:这个循环比上一个更为复杂,应该根据for循环的特性慢慢分析,口令已基本熟悉
- 这段代码把x中的位反过来,创造一个镜像。实现的方法是:将x的位从左往右移,然后再填入这些位,就像是把val从右往左移。
查看汇编文件:
- 3.29
- 题目:switch中基于汇编语言,填写 C语言空缺
- 解决方法:关键是将来自汇编代码和跳转表的信息结合起来,理清不同情况
代码调试中的问题和解决过程
实验楼实验
- 第一题:删除gcc产生代码代码中以“.”开头的编译器指令
使用VIM编写代码
查看汇编文件
修改汇编代码并另存
第二题:使用gdb的bt/frame/up/down指令动态查看调用线帧的情况
本周代码托管截图
-
托管链接:http://git.oschina.net/20145330swx/Linux
感悟与思考
-
本周的内容是循序渐进的,要从第一节看到第七节才能比较好的掌握知识,每天学习一点点是良好的学习方法,而且汇编知识上学期也学过,所以比较可以理解内容形式,希望老师每周布置的学习任务都正好是我们充分能掌握的学量,只要时间安排得好就真的可以很好的学习完成。
学习进度条
代码行数(新增/累积) | 博客量(新增/累积) | 学习时间(新增/累积) | 重要成长 | |
---|---|---|---|---|
目标 | 5000行 | 30篇 | 400小时 | |
第一周 | 200/200 | 2/2 | 20/20 | |
第二周 | 300/500 | 2/4 | 18/38 | |
第三周 | 500/1000 | 3/7 | 22/60 | |
第四周 | 000/1000 | 2/9 | 30/90 | |
第五周 | 200/1200 | 1/10 | 30/120 |