zoukankan      html  css  js  c++  java
  • 20145238荆玉茗 《信息安全系统设计基础》第5周学习总结

    20145238 《信息安全系统设计基础》第4周学习总结


    第3章 程序的机器级表示

    一、知识点

    3.1 X86寻址方式经历的三代:

    • 1 DOS时代的平坦模式,不区分用户空间和内核空间,很不安全
    • 2 8086的分段模式
    • 3 IA32的带保护模式的平坦模式

    3.2 程序编码

    • 1、ISA 指令集体系结构 定义了处理器状态、指令的格式,以及每条指令对状态的影响
    • 2、处理器状态
      PC 程序计数器(%eip):指示将要执行的下一条指令在存储器中的位置。
      整数寄存器文件:包含8个命名的位置,分别存储32位的值。它们可以存储地址、证书数据,记录程序状态、保存临时数据。
      条件码寄存器:保存最近执行的算术或逻辑指令的状态信息。 浮点寄存器:存放浮点数据

    获得汇编代码:gcc -S xxx.c -o xxx.s
    反汇编:objdump -d xxx
    在MAC OS中没有objdump指令,用等价功能的otool
    64位机器上想要得到32代码:gcc -m32 -S xxx.c

    二进制文件可以用od 命令查看,也可以用gdb的x命令查看。有些输出内容过多,我们可以使用 more或less命令结合管道查看,也可以使用输出重定向来查看:
    od code.o | more
    od code.o > code.txt
    

    3.3 数据格式

    b-字节
    w-字
    l-双字(注意:与之后出现的less(少、小、低)区别,此处是long)
    

    3.4 访问信息
    1、寄存器

    • 1.数据寄存器 32位通用寄存器eax、ebx、ecx和edx。 对低16位数据的存取,不会影响高16位的数据。 可传送数据、暂存数据保存算术逻辑运算结果,而且也可作为指针寄存器 低16位寄存器分别命名为:ax、bx、cx和dx。
      *不能作为基址和变址寄存器来存放存储单元的地址。
    • 2.变址寄存器 32位通用寄存器esi、edi,低16位对应先前CPU中的si和di。
      *用于存放存储单元在段内的偏移量,也可存储算术逻辑运算的操作数和运算结果。
    • 3.指针寄存器 32位通用寄存器ebp和esp,低16位对应先前CPU中的sbp和sp。
      *用于存放堆栈内存储单元的偏移量,也可存储算术逻辑运算的操作数和运算结果。
    • 4.指令指针寄存器 eip、ip
      *存放下次将要执行的指令在代码段的偏移量。

    2、寻址方式

    3、指令

    • 1.数据传送指令 MOV 传送字或字节. MOVS 先符号扩展,再传送. MOVZ 先零扩展,再传送.
      *源操作数:立即数,存储在寄存器中或者在存储器中 目的操作数:寄存器、存储器地址。

      PUSH 把字压入堆栈. POP 把字弹出堆栈. 栈顶-此端插入和删除元素。 栈顶元素的地址是所有栈中元素地址中最低的。
      栈指针%esp保存着栈顶元素的地址。 压栈——指针先减,数据再入 弹栈——数据先出,指针再加

    • 2.目的地址传送指令 leal 加载有效地址。 从存储器读数据到寄存器,将有效地址写入目的操作数。 目的操作数必须是一个寄存器。

    3.算数和逻辑操作

    • CMP 比较.(两操作数作减法,右操作数减左操作数). TEST 测试.(两操作数作与运算).
      *比较和测试仅修改标志位,不回送结果
    • 条件码寄存器不能直接读取,有三种方法:
      set指令:根据条件码,设置一个字节。
      jump指令:根据条件码进行跳转,即控制的条件转移。
      cmov条件传送指令:根据条件码决定是否进行mov操作
      *这些指令判断条件是否满足,是根据条件码的组合决定的。
      *sete (e:equal) setl (l:less与之前的long进行区别)

    4、语句

    • 与C语言中的语句功能相同 if-else do-while while for switch(&—创建一个指向数据值的指针;&&—创建一个指向代码位置的指针;jmp中前缀*—间接跳转)

    5、过程

    • 栈、栈帧 栈帧——为每一个过程分配的内存空间,它包含两个特殊的参数,栈指针和帧指针。一个指向栈顶一个指向栈低。
      栈是向低地址增长的,也就是说,栈的底部在内存的高地址部分。

      帧指针:%ebp,指向栈底。 栈指针:%esp,指向栈顶,栈指针可以移动,来分配或释放空间。
      %esp减小——分配空间
      %esp增大——释放空间

    • 寄存器使用

      调用者——%eax、%edx、%ecx 被调用者——%ebx%esi%edi ·具体过程

      需要明确,向被调用者传递的参数是存储在调用者的栈中的。

      调用者栈的结束边界是在执行call指令的时候将返回地址压入栈中,被调用者栈的起始边界是在保存祯指针%ebp的值之后。

      被调用者的栈的起始点都是调用者%ebp的值,为了以后恢复方便。过程调用期间,会通过栈来分配一些自由的内存空间用于存储一些临时的变量,但是在这种类型的分配方式下,是要遵循分配的空间
      必须是16字节整数倍这样的 一个规定 ,这是X86编程的一个规定。所以你就会看到,在很多时候,明明分配了很多空间,但是都没用到。
      被调用过程在进行的时候,要先将旧的%ebp压入栈中,并且初始化两个栈指针,之后要将一些被调用者保存的寄存器里面的值压入栈中保存,防止在之后的代码中会覆盖这些数据。

    6、GDB中bt、frame、up、down的使用(都会打印出移动到的栈层的信息)

    • bt n n是一个正整数,表示只打印栈顶上n层的栈信息。 bt -n
      -n表一个负整数,表示只打印栈底下n层的栈信息。
    • frame n n是一个从0开始的整数,是栈中的层编号。比如:frame 0,表示栈顶,frame 1,表示栈的第二层。
    • up n 表示向栈的上面移动n层,可以不打n,表示向上移动一层。
    • down n 表示向栈的下面移动n层,可以不打n,表示向下移动一层。
    • 查看当前栈层的信息,你可以用以下GDB命令: frame 或
      f(会打印出这些信息:栈的层编号,当前的函数名,函数参数值,函数所在文件及行号,函数执行到的语句。)

    二、实验楼实践

    1.(以下命令为实验楼64位Linux虚拟机环境下适用,32位Linux环境可能会稍有不同) 使用
    gcc –S –o main.s main.c -m32

    ·编译代码如下
    图片编译代码(更换了函数中的数字)

    ·运行结果

    删除以“.”开头的

    程序f的过程调用了g,所以f先把它的%ebp寄存器压入栈作为帧指针,压入被保存的寄存器、本地变量和临时变量,最上面是参数构造区域。然后再用call调用g,这时又把返回地址压入栈。
    g被调用后,把它的帧指针%ebp压入栈,然后压入寄存器、本地变量、临时变量,最上面是参数构造区域。
    g运算结束前,g会把%ebp弹出栈,然后ret指令弹出并跳转到之前call压入的地址,返回到f过程。
    最后leave,%ebp出栈。

    ·将c语言转化为二进制代码并查看

    教材学习中的问题和解决过程

    1.在实验中遇到了以下的问题,我忘记了之前我们只是需要运行一个可编译的程序即可所以忽略了基本的gcc可执行代码转换的步骤

    那我们再来回顾一下:
    C预处理器——扩展源代码-生成.i文件
    编译器——产生两个源代码的汇编代码-——生成.s文件
    汇编器——将汇编代码转化成二进制目标代码——生成.o文件
    链接器——产生可执行代码文件
    之后按照通过汇编器的步骤生成了汇编文件

    2.课本3.1
    前面小于16的操作数没有问题后面计算操作数9(%eax,%edx)的值出错,之后才明白前面的“9”是二进制数,“%eax,%edx”对应的值100、3都是16进制数,计算时要统一进制,9+256+3=268
    转换为16进制即10c

    3.课本3.3
    movb $0xf,(%bl) :目的操作数只能是一个寄存器或者一个存储器地址。(%bl)表示一个值
    movw (%eax),4(%esp):目的操作数与源操作数不能都是存储器
    movl %eax,$0x123:立即数不能作为目的操作数
    movb %si, 8(%ebp):指令后缀与寄存器地址不匹配

    4.课本3.9
    通过汇编代码补充C语言

    int arith(int x,int y,int z)
    {
    int t1=x^y;
    int t2=t1>>3;
    int t3=~t2;
    int t4=t3-2;
    return t4;
    }
    一开始非常不习惯这种题目,最后参考答案再反复更具一条条汇编指令递推才终于理解,一定要注意目的地址有直接用作下一条语句的源操作数,一定要仔细核对,层层推进。

    本周代码托管截图

    实验楼链接

    其他(感悟、思考等,可选)

    本周学习中感受到虽然汇编语言不能像高级语言一样有很强的植入性,但是能够阅读和理解代码,有助于我们理解编译器的优化能力,分析代码中隐含的低效率,可以使我们最大化代码的性能。
    同时了解反汇编,把机器语言转化为汇编语言在信息安全领域也非常重要,比如说许多病毒正是攻击了系统中的漏洞重写信息,获得了系统的控制权,对于了解漏洞的出现和如何预防,需要我们了解
    程序的机器级表示。拥有很好的汇编及反汇编能力,在编写程序的时候就好像给程序穿上了盔甲,正面可攻击,反面可预防,是非常重要的。
    本周使用了StackEdi在线编辑使页面看起来更整洁,在此为那些无法使用markdown的小伙伴推荐。


    学习进度条

    代码行数(新增/累积) 博客量(新增/累积) 学习时间(新增/累积) 重要成长
    目标 5000行 30篇 400小时
    第一周 200/200 2/2 20/20
    第二周 300/500 2/4 18/38
    第三周 500/1000 3/7 22/60
    第四周 300/1300 2/9 30/90

    参考资料

    • 《深入理解计算机系统V2》学习指导
    • ...
  • 相关阅读:
    SQL语句 分页实现
    PHPexcel入门教程
    json_decode返回null,使用echo json_last_error(); 返回4
    配置mysql可局域网内访问
    thinkphp5.0安装composer安装topthink/think-captcha
    linux下mysql忘记密码怎么办
    centos7 设置mysql账号密码开放3306端口实现远程登陆
    高级数据结构第七章A . 数列(树状数组逆序对)
    高级数据结构第六章E . 苹果树 (dfs+树状数组)
    高级数据结构第六章C . 奶牛狂欢节(两个树状数组)
  • 原文地址:https://www.cnblogs.com/20145238jym/p/5967273.html
Copyright © 2011-2022 走看看