• 20155322 2017-2018-1《信息安全系统设计》第五周 学习总结


    20155322 2017-2018-1《信息安全系统设计》第五周 学习总结


    [博客目录]


    教材学习内容总结

    教材内容第三章《程序的机器级表示》的自主学习,复习了汇编的相关知识,记录了一些汇编指令以备不时之需:

    参考资料

    数据传送指令

    mov — Move (Opcodes: 88, 89, 8A, 8B, 8C, 8E, ...)

    mov指令将第二个操作数(可以是寄存器的内容、内存中的内容或值)复制到第一个操作数(寄存器或内存)。mov不能用于直接从内存复制到内存,其语法如下所示:

    mov <reg>,<reg>
    mov <reg>,<mem>
    mov <mem>,<reg>
    mov <reg>,<const>
    mov <mem>,<const>
    

    实例:

    mov eax, ebx            //将ebx的值拷贝到eax
    mov byte ptr [var], 5   //将5保存找var指示内存中的一个字节中
    

    push— Push stack (Opcodes: FF, 89, 8A, 8B, 8C, 8E, ...)

    push指令将操作数压入内存的栈中,栈是程序设计中一种非常重要的数据结构,其主要用于函数调用过程中,其中ESP只是栈顶。在压栈前,首先将ESP值减4(X86栈增长方向与内存地址编号增长方向相反),然后将操作数内容压入ESP指示的位置。其语法如下所示:

    push <reg32>
    push <mem>
    push <con32>
    

    实例:

    push eax        //将eax内容压栈
    push [var]      //将var指示的4直接内容压栈
    

    pop— Pop stack

    pop指令与push指令相反,它执行的是出栈的工作。它首先将ESP指示的地址中的内容出栈,然后将ESP值加4. 其语法如下所示:

    pop <reg32>
    pop <mem>
    

    实例:

    pop edi       //pop the top element of the stack into EDI.
    pop [ebx]     //pop the top element of the stack into memory at the four bytes starting at location EBX.
    

    lea— Load effective address

    lea实际上是一个载入有效地址指令,将第二个操作数表示的地址载入到第一个操作数(寄存器)中。其语法如下所示:

    lea <reg32>,<mem>
    

    实例:

    lea eax, [var]          //var指示的地址载入eax中.
    lea edi, [ebx+4*esi]    // ebx+4*esi表示的地址载入到edi中,这实际是上面所说的寻址模式的一种表示方式.
    

    返回目录

    算术和逻辑指令

    add— Integer Addition

    add指令将两个操作数相加,且将相加后的结果保存到第一个操作数中。其语法如下所示:

    add <reg>,<reg>
    add <reg>,<mem>
    add <mem>,<reg>
    add <reg>,<con>
    add <mem>,<con>
    

    实例:

    add eax, 10             //EAX ← EAX + 10
    add BYTE PTR [var], 10  //10与var指示的内存中的一个byte的值相加,并将结果保存在var指示的内存中
    

    sub— Integer Subtraction

    sub指令指示第一个操作数减去第二个操作数,并将相减后的值保存在第一个操作数,其语法如下所示:

    sub <reg>,<reg>
    sub <reg>,<mem>
    sub <mem>,<reg>
    sub <reg>,<con>
    sub <mem>,<con>
    

    实例:

    sub al, ah      // AL ← AL - AH
    sub eax, 216    //eax中的值减26,并将计算值保存在eax中
    

    inc, dec— Increment, Decrement

    inc,dec分别表示将操作数自加1,自减1,其语法如下所示:

    inc <reg>
    inc <mem>
    dec <reg>
    dec <mem>
    

    实例:

    dec eax             //eax中的值自减1.
    inc DWORD PTR [var] //var指示内存中的一个4-byte值自加1
    

    imul— Integer Multiplication

    整数相乘指令,它有两种指令格式,一种为两个操作数,将两个操作数的值相乘,并将结果保存在第一个操作数中,第一个操作数必须为寄存器;第二种格式为三个操作数,其语义为:将第二个和第三个操作数相乘,并将结果保存在第一个操作数中,第一个操作数必须为寄存器。其语法如下所示:

    imul <reg32>,<reg32>
    imul <reg32>,<mem>
    imul <reg32>,<reg32>,<con>
    imul <reg32>,<mem>,<con>
    

    实例:

    imul eax, [var]     //eax→ eax * [var]
    imul esi, edi, 25   // ESI → EDI * 25
    

    idiv— Integer Division

    idiv指令完成整数除法操作,idiv只有一个操作数,此操作数为除数,而被除数则为EDX:EAX中的内容(一个64位的整数),操作的结果有两部分:商和余数,其中商放在eax寄存器中,而余数则放在edx寄存器中。其语法如下所示:

    idiv <reg32>
    idiv <mem>
    

    实例:

    idiv ebx
    idiv DWORD PTR [var]
     and, or, xor— Bitwise logical and, or and exclusive or
    

    逻辑与、逻辑或、逻辑异或操作指令

    用于操作数的位操作,操作结果放在第一个操作数中。其语法如下所示:

    and <reg>,<reg>
    and <reg>,<mem>
    and <mem>,<reg>
    and <reg>,<con>
    and <mem>,<con>
    or <reg>,<reg>
    or <reg>,<mem>
    or <mem>,<reg>
    or <reg>,<con>
    or <mem>,<con>
    xor <reg>,<reg>
    xor <reg>,<mem>
    xor <mem>,<reg>
    xor <reg>,<con>
    xor <mem>,<con>
    

    实例:

    and eax, 0fH //将eax中的钱28位全部置为0,最后4位保持不变.
    xor edx, edx //设置edx中的内容为0.
    

    not— Bitwise Logical Not
    位翻转指令,将操作数中的每一位翻转,即0->1, 1->0。其语法如下所示:

    not <reg>
    not <mem>
    

    实例:

    not BYTE PTR [var] — 将var指示的一个字节中的所有位翻转.
    

    neg— Negate
    取负指令。语法为:

    neg <reg>
    neg <mem>
    

    实例:

    neg eax // EAX → - EAX
    

    shl, shr— Shift Left, Shift Right
    位移指令,有两个操作数,第一个操作数表示被操作数,第二个操作数指示位移的数量。其语法如下所示:

    shl <reg>,<con8>
    shl <mem>,<con8>
    shl <reg>,<cl>
    shl <mem>,<cl>
    shr <reg>,<con8>
    shr <mem>,<con8>
    shr <reg>,<cl>
    shr <mem>,<cl>
    

    实例:

    shl eax, 1      // Multiply the value of EAX by 2 (if the most significant bit is 0),左移1位,相当于乘以2
    shr ebx, cl     //Store in EBX the floor of result of dividing the value of EBX by 2n where n is the value in CL.
    

    返回目录

    控制转移指令

    X86处理器维持着一个指示当前执行指令的指令指针(IP),当一条指令执行后,此指针自动指向下一条指令。IP寄存器不能直接操作,但是可以用控制流指令更新。
    一般用标签(label)指示程序中的指令地址,在X86汇编代码中,可以在任何指令前加入标签。如:

           mov esi, [ebp+8]
    begin: xor ecx, ecx
           mov eax, [esi]
    

    如第二条指令用begin指示,这种标签的方法在某种程度上简化了汇编程序设计,控制流指令通过标签实现程序指令跳转。

    jmp — Jump

    控制转移到label所指示的地址,(从label中取出执行执行),如下所示:

    jmp <label>
    

    实例:

    jmp begin   //Jump to the instruction labeled begin.
    

    jcondition— Conditional Jump
    条件转移指令,条件转移指令依据机器状态字中的一些列条件状态转移。机器状态字中包括指示最后一个算数运算结果是否为0,运算结果是否为负数等。机器状态字具体解释请见微机原理、计算机组成等课程。语法如下所示:

    je <label> (jump when equal)
    jne <label> (jump when not equal)
    jz <label> (jump when last result was zero)
    jg <label> (jump when greater than)
    jge <label> (jump when greater than or equal to)
    jl <label> (jump when less than)
    jle <label>(jump when less than or equal to)
    

    实例:

    cmp eax, ebx
    jle done        //如果eax中的值小于ebx中的值,跳转到done指示的区域执行,否则,执行下一条指令。
    

    cmp— Compare
    cmp指令比较两个操作数的值,并根据比较结果设置机器状态字中的条件码。此指令与sub指令类似,但是cmp不用将计算结果保存在操作数中。其语法如下所示:

    cmp <reg>,<reg>
    cmp <reg>,<mem>
    cmp <mem>,<reg>
    cmp <reg>,<con>
    

    实例:

    cmp DWORD PTR [var], 10
    jeq loop,
    

    比较var指示的4字节内容是否为10,如果不是,则继续执行下一条指令,否则,跳转到loop指示的指令开始执行

    call, ret— Subroutine call and return
    这两条指令实现子程序(过程、函数等意思)的调用及返回。call指令首先将当前执行指令地址入栈,然后无条件转移到由标签指示的指令。与其它简单的跳转指令不同,call指令保存调用之前的地址信息(当call指令结束后,返回到调用之前的地址)。
    ret指令实现子程序的返回机制,ret指令弹出栈中保存的指令地址,然后无条件转移到保存的指令地址执行。
    call,ret是函数调用中最关键的两条指令。具体细节见下面一部分的讲解。语法为:

    call <label>
    ret
    

    返回目录

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

    • 问题:如何理解逆向?
    • 解决:通过在百度搜索,我在百度百科中找到了答案:逆向工程(又称逆向技术),是一种产品设计技术再现过程,即对一项目标产品进行逆向分析及研究,从而演绎并得出该产品的处理流程、组织结构、功能特性及技术规格等设计要素,以制作出功能相近,但又不完全一样的产品。逆向工程源于商业及军事领域中的硬件分析。其主要目的是在不能轻易获得必要的生产信息的情况下,直接从成品分析,推导出产品的设计原理。软件逆向工程有多种实现方法,主要有三:
      • 1.分析通过信息交换所得的观察。
        最常用于协议逆向工程,涉及使用总线分析器和数据包嗅探器。在接入计算机总线或网络的连接,并成功截取通信数据后,可以对总线或网络行为进行分析,以制造出拥有相同行为的通信实现。此法特别适用于设备驱动程序的逆向工程。有时,由硬件制造商特意所做的工具,如JTAG端口或各种调试工具,也有助于嵌入式系统的逆向工程。对于微软的Windows系统,受欢迎的底层调试器有SoftICE。
      • 2.反汇编,即使用反汇编器,把程序的原始机器码,翻译成较便于阅读理解的汇编代码。这适用于任何的计算机程序,对不熟悉机器码的人特别有用。流行的相关工具有OllyDebug和IDA。
      • 3.反编译,即使用反编译器,尝试从程序的机器码或字节码,重现高级语言形式的源代码。

    • 问题:指令集体系结构(Instruction-Set Architecture, ISA)
    • 解决:通过阅读CSDN上的博客我找到相关知识辅助我理解:
      一个处理器支持的指令和指令的字节级编码就是这个处理器的ISA,包括很多个部分:
      • 指令集
      • 指令集编码
      • 基本数据类型
      • 一组编程规范
      • 寄存器
      • 寻址模式
      • 存储体系
      • 异常事件处理
      • 中断
      • 外部I/O
    • 作用:ISA在编译器编写者(CPU软件)和处理器设计人员(CPU硬件)之间提供了一个抽象层:
      • 处理器设计者:依据ISA来设计处理器
      • 处理器使用者(如:写编译器的牛*程序员):依据ISA就知道CPU选用的指令集,就知道自己可以使用哪些指令以及遵循哪些规范
      • 定义处理器上的软件如何构建,这是ISA的最重要内涵,现代处理器都是支持高级语言编程、操作系统等等特性,ISA要定义出指令集内的指令是如何支撑起C语言里堆栈、过程调用,操作系统里异常、中断,多媒体平台里数字图像处理、3D加速等等。

    • 问题:在汇编中如何调用函数
    • 解决:如果要调用一个函数,实现将数据和控制代码从一个部分到另一个部分的跳转。我们如何来分配执行函数的变量空间,并在返回的时候释放空间,将返回值返回。下面是一张图,非常便于理解:

    返回目录

    代码调试中的问题和解决过程


    返回目录

    本周结对学习情况

    • 结对学习博客
      20155302
    • 结对学习图片
    • 结对学习内容
      • 教材第三章

    返回目录

    代码托管

    返回目录

    学习进度条

    代码行数(新增/累积) 博客量(新增/累积) 学习时间(新增/累积) 重要成长
    目标 5000行 30篇 400小时
    第一周 0/0 1/1 10/10
    第二周 0/0 0/1 10/20
    第三周 200/200 2/3 10/30
    第四周 100/300 1/4 10/40
    第五周 200/500 2/5 10/50
    • 计划学习时间:10小时
    • 实际学习时间:10小时

    返回目录

    参考资料

    返回目录

  • 相关阅读:
    如何判断某个设备文件是否存在
    shell中export理解误区
    linux命令之tail
    国内较快的gnu镜像:北京交通大学镜像
    Cmake的交叉编译
    linux 命令之grep
    makefile之变量赋值
    makefile之VPATH和vpath的使用
    arm汇编进入C函数分析,C函数压栈,出栈,传参,返回值
    Jlink 软件断点和硬件断点
  • 原文地址:https://www.cnblogs.com/blackay03/p/7712304.html
Copyright © 2020-2023  润新知