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

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

    教材学习内容

    x86寻址方式
    • DOS时代的平坦模式,不区分用户空间和内核空间,很不安全
    • 8086的分段模式
    • IA32的带保护模式的平坦模式
    机器级编程的两种抽象

    -ISA(Instruction set architecture)。ISA简单来说就是指令集体系结构。定义了处理机状态,指令格式以及指令对状态的影响。
    -机器级使用的存储器地址是虚拟地址。

    机器代码中的处理机状态
    • 程序计数器(PC)表示将要执行的下一条指令在存储器中的地址。
    • 整数寄存器文件。存储32位的值。存储程序状态或用来保存临时数据。
    • 条件码寄存器
    • 浮点寄存器
    Gcc编译代码

    1.产生汇编代码文件:gcc -01 -S xxx.c生成xxx.s文件
    2.产生目标代码文件:gcc -01 -c xxx.c生成xxx.o文件
    3.查看目标代码文件的内容:objdump -d xxx.o

    不同数据汇编代码后缀
    • movb(传送字节)
    • movw(传送字)
    • movl(传送双字)注意:汇编代码中后缀l可以表示4自己整数和8字节双精度浮点数。
    操作数指示符寻址
    • 立即数:$0xff.
    • 寄存器中的内容:%eax(32位),%ax(16位),%al(4位)。
    • 存储器:根据计算出来的地址访问存储器
      学会多种寻址方式寻址。错误的寻址方式:1. 存储器间接寻址错误使用寄存器:movb $0xf,(%bl).2.二元操作如sub,mov中两个操作数不能同时是存储器位置 。
    数据传送指令
    • MOVS和MOVZ指令比较:MOVS符号位扩展,MOVZ零扩展(高位0填充)
    • pushl数据压栈,popl数据出栈。采用先进后出的原则。栈顶地址小,栈底地址大。IA32栈向低地址方向增长。所以push指令减小栈指针。
    • 4个整数操作指令
      addl、subl、andl、xorl
    • 7个跳转指令(jXX)
      jmp、jle、jl、je、jne、jge、jg
    • 有6个条件传送指令(cmovXX)
      只有当条件码满足所需要的约束时,才会更新目的寄存器的值。
      cmovle、cmovl、cmove、cmovne、cmovge、cmovg
    桢栈结构

    为单个过程分配的那部分栈称为栈帧(stack frame)。寄存器%ebp为帧指针,而寄存器%esp为栈指针。栈帧结构(栈用来传递参数、存储返回信息、保存寄存器,以及本地存储)

    转移控制

    支持过程调用和返回的指令:

    指令 描述

    -call Label 过程调用

    -call *Operand 过程调用

    -leave 为返回准备栈

    -ret 从过程调用中返回

    call指令的效果是将返回地址入栈,并跳转到被调用过程的起始处。返回地址是在程序中紧跟在call后面的那条指令地址。

    寄存器使用惯例

    程序寄存器组是唯一能被所有过程共享的资源。虽然在给定时刻只能有一个过程是活动的,但是我们必须保证当一个过程(调用者)调用另一个过程(被调用者)时,被调用者不会覆盖某个调用者稍后会使用的寄存器的值。根据惯例,寄存器%eax、%edx和%ecx被划分为调用者保存寄存器。当过程P调用Q时,Q可以覆盖这些寄存器,而不会破任何P所需要的数据。另一方面,寄存器%ebx、%esi和%edi被划分为被调用者保存寄存器。这意味着Q必须在覆盖这些寄存器之前,先把它们保存到栈中,并在返回前恢复它们。

    数据格式
      • C语言数据类型在IA32中的大小:
      • IA32不支持64位整数运算
      • 大多数GCC生成的汇编代码指令都有一个字符后缀,表明操作数的大小。

    课后习题解答

    3.54

    int decode2(int x ,int y, int z)  
    {  
        int a = z - y;  
        int b = (a << 15) >> 15;  
        return (x ^ a) * b;  
    }  

    3.55

    typedef long long ll_t;
    
    
    void store_prod(ll_t *dest, ll_t x, int y){
    *dest = x*y;
    }
    
    // dest at %ebp+8, x at %ebp + 12, y at %ebp + 20  
    movl   12(%ebp), %esi        //将x的低位存到%esi  
    movl   20(%ebp), %eax       //将y存到%eax  
    movl   %eax, %edx     
    sarl   $31, %edx                  //将(y >> 31)存到%edx  
    movl   %edx, %ecx  
    imull   %esi, %ecx             //计算x_low * (y >> 31)存到%ecx  
    movl   16(%ebp), %ebx    //将x的高位存到%ebp  
    imull   %eax, %ebx           //计算x_high * y  
    addl   %ebx, %ecx           //计算 x_high * y + x_low * (y >> 31) 存到%ecx  
    mull   %esi                       //计算y * x_low 的无符号64位乘积  
    leal   (%ecx, %edx), %edx    //将64位乘积的高位与x_high * y + x_low * (y >> 31)得到最终结果的高位  
    movl   8(%ebp), %ecx  
    movl   %eax, (%ecx)  
    movl   %edx, 4(%ecx)          //将结果写入目的内存地址  
    
    说明:
    该汇编代码其实是y扩展至64位再进行两个64位数的乘积然后进行截断得到的。
    
    事实上有:
    
    y *{signed} x =
    (y_high * 2^32 + y_low) *{signed} (x_high * 2^32 + x_low) =
    y_high *{signed} x_high * 2^64 +
    y_high *{signed} x_low * 2^32 +
    y_low *{signed} x_high * 2^32 +
    y_low *{signed} x_low(有符号的x_low与无符号的x_low相等,故可用mull指令)
    
    而y_high *{signed} x_high由于乘以2^64,所以对结果不会产生影响。

    3.56写出loop函数原型

    int loop(int x, int n)  
    {  
        int result = 0x55555555;  
        int mask;  
        for(mask = 0x80000000;mask !=0; mask = (unsigned)mask >> (n & 0xFF))  
        {  
            result ^= x & mask;  
        }  
        return result;  
    }  

    3.57用条件传送指令写函数cread_alt

    movl    20(%esp), %eax  
    movl    $0, 12(%esp)  
    leal    12(%esp), %edx  
    testl   %eax, %eax  
    cmove   %edx, %eax  
    movl    (%eax), %eax  
    addl    $16, %esp  
    .cfi_def_cfa_offset 4  
     ret  

    3.58

    int switch3(int *p1,int *p2,mode_t action)  
    {  
        int result = 0;  
        switch(action){  
            case MODE_A:  
                result = *p1;  
                *p1 = *p2;  
                break;  
            case MODE_B:  
                result = *p1 + *p2;  
                *p2 = result;  
                break;  
            case MODE_C:  
                *p2 = 15;  
                result = *p1;  
                break;  
            case MODE_D:  
                *p2 = *p1;  
                result = 17;  
                break;  
            case MODE_E:  
                result = 17;  
                break;  
            default:  
                result = -1;  
                break;    
        }  
        return result;  
    }  
    

    本周代码托管

    学习进度条

     代码行数(新增/累积)博客量(新增/累积)学习时间(新增/累积)重要成长
    目标 5000行 30篇 400小时  
    第一周 0/0 1/2 10/10  
    第二周 300/300 1/3 20/30  
    第三周 300/600 2/5 16/46  
    第五周 300/900 1/6 15/61  

    参考资料

  • 相关阅读:
    二进制安全(学习笔记)
    rsa
    bugku 隐写 笔记
    dvwa随学笔记
    实验吧 密码学 writeup
    实验吧 隐写 writeup
    实验吧 web题weiteup
    Java数据结构和算法 第二版 课后习题第三章
    自动化测试入门指南(3)-- 入门demo
    自动化测试入门指南(2)-- 环境搭建
  • 原文地址:https://www.cnblogs.com/dwc929210354/p/5968125.html
Copyright © 2011-2022 走看看