• 2017-2018-1 20155324 《信息安全系统设计基础》第5周学习总结


    2017-2018-1 20155324 《信息安全系统设计基础》第5周学习总结

    参考教材导读与每周考试重点---不断更新

    信息安全的核心思维方式“逆向”在这有很好很直接的体现,反汇编就是直接的逆向工程。

    反汇编(Disassembly):把目标代码转为汇编代码的过程,也可以说是把机器语言转换为汇编语言代码、低级转高级的意思,常用于软件破解(例如找到它是如何注册的,从而解出它的注册码或者编写注册机)、外挂技术、病毒分析、逆向工程、软件汉化等领域。学习和理解反汇编语言对软件调试、漏洞分析、OS的内核原理及理解高级语言代码都有相当大的帮助,在此过程中我们可以领悟到软件作者的编程思想。总之一句话:软件一切神秘的运行机制全在反汇编代码里面。

    通常,编写程序是利用高级语言如C,C++,Delphi等高级语言进行编程的,然后再经过编译程序生成可以被计算机系统直接执行的文件(机器语言)。反汇编即是指将这些执行文件反编译还原成汇编语言或其他语言。但通常反编译出来的程序与原程序会存在些许不同,虽然执行效果相同,但程序代码会发生很大的变化,要读懂反汇编需要有扎实的高级语言编写功底和汇编功底。

    X86 寻址方式:

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

    ISA的定义

    指令集体系结构(ISA)定义了处理器状态、指令的格式、以及每条指令对状态的影响。大多数ISA包括IA32和x84-64,将程序的行为描述成好像每条指令是按顺序执行的。

    • 汇编命令与反汇编命令

    gcc -S xxx.c -o xxx.s获得汇编代码,用gcc -c code.c产生目标文件code.o(二进制文件,无法直接查看),用objdump -d xxx.o反汇编可以查看目标代码文件内容。

    汇编代码(函数前两条和后两条汇编代码,所有函数都有,建立函数调用栈帧):

    前两条:
    pushl %ebp          将寄存器%ebp的内容压入程序栈
    movl %esp,%ebp      得到新栈低,将当前栈顶赋予栈低
    
    后两条:
    popl %ebp           过程调用结束,恢复旧栈低
    ret                 子程序的返回指令
    64位机器上想要得到32代码:gcc -m32 -S xxx.c
    

    gcc -S 产生的汇编中可以把 以”.“开始的语句都删除了再阅读。

    查看二进制文件

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

    od code.o | more
    od code.o > code.txt
    

    不同数据的汇编代码后缀

    image
    Linux和Windows的汇编格式区别

    1 Intel代码省略了指示大小的后缀。
    2 Intel代码省略了寄存器名字前面的'%'符号。
    3 Intel代码用不同的方式来描述寄存器中位置。
    4 在带有多个操作数的指令情况下,列出操作数的顺序相反。
    

    ATT是GCC、OBJDUMP和其它一些我们使用的工具的默认格式。Microsoft的工具、以及来自Intel的文档,其汇编代码都是Intel格式的。使用gcc -S -masm=intel code.c可以使GCC产生Intel格式的代码。
    寄存器

    esi edi可以用来操纵数组,esp ebp用来操纵栈帧。32位的eax,16位的ax,8位的ah,al都是独立的。

    • 寻址方式

    image
    操作数三种类型

    立即数,即常数值
    寄存器,表示某个寄存器的内容
    存储器,根据计算出来的地址(有效地址)访问某个存储器位置。
    

    有效地址

    计算方式Imm(Eb,Ei,s) = Imm + R[Eb] + R[Ei]*s
    MOV
    
    • MOV

    相当于C语言的赋值“=”,不能从内存地址直接MOV到另一个内存地址,要用寄存器中转一下。

    MOV类中的指令将源操作数的值复制到目的操作数中,源操作数指定的值是一个立即数,存储在寄存器或存储器中,目的操作数指定一个位置,要么是一个寄存器,要么是一个存储器地址。

    • push与pop

    先进后出:push将数据压入栈中,pop弹出,弹出的永远是最近被压入的。用数组实现栈,进行操作的一端为栈顶。栈向下增长,栈顶元素的地址是所有栈中元素地址中最低的。栈指针%esp保存栈顶元素的地址。

    源操作数、目的操作数应为字操作数。

    • 指针

    C语言中“指针”其实就是地址。

    • 局部变量

    局部变量通常是保存在寄存器中。因为,寄存器访问比存储器访问要快得多。

    • 算术和逻辑运算

    image

    1、一元操作:只有一个操作数,既是源又是目的,可以是一个寄存器,或者存储器位置。
    
    2、二元操作:第一个操作数可以是立即数、寄存器或者存储器位置;第二个操作数既是源也是又是目的,可以是寄存器或者存储器位置,但是不能同时是存储器位置。
    
    操作的顺序:第二个操作数 操作符 第一个操作数
    
    3、移位操作:先给出移位量,第二项给出要移位的数值。
    

    源操作数(移位量):立即数或者放在单字节寄存器元素%cl中。目的操作数:一个寄存器或是一个存储器位置。

    • 使用disassemble指令获取汇编代码(因为之前执行的命令中有-m32,所以此处显示的是32位汇编代码)

    image

    • i r指令查看各寄存器的值

    image

    可见此时主函数的栈基址为0xffffd058,用x 0xffffd058指令查看内存地址中的值:

    image

    因此,目前%esp所指堆栈内容为0,%ebp所指内容也为0

    • 使用display /i $pc(结合display命令和寄存器/pc内部变量)指令进行设置
      image

    依次如下指令调试汇编代码,并查看%esp、%ebp和堆栈内容:

    1、使用si指令单步跟踪一条机器指令
    2、使用i r指令查看各寄存器的值(在这里要看%eip、%eax、%esp和%ebp)
    3、使用x/na %esp对应的值指令查看堆栈变化
    之后一直重复执行上述三步,直至结束
    

    有条件跳转的条件看状态寄存器(教材上叫条件码寄存器) 注意leal不改变条件码寄存器。

    1、分支(if/switch)

    C语言if-else 语句:

    if(test-expr)
        then-statement
    else
        else-statement
    
    (注:test-expr    整数表达式[假/真])
    

    汇编实现形式:

    t = test-expr;
    if (!t)
        goto false;
    then-statement
    goto done;
    false: 
        else-statement
    done:
    

    2、循环(while, for)

    C语言do-while循环:

    do
        body-statement
        while(test-expr);
    

    汇编实现形式:

    loop:
        body-statement
        t = test-expr;
        if(t)
            goto loop;
    

    while循环、for循环均需转换成do-while形式在转换

    gdb调试分析汇总表

    指令 %eip %ebp %esp %eax 堆栈
    push $0x13 0x80483f9 0xffffd058 0xffffd058 0xf7fbadbc 0x00000000
    call 0x80483e6 0x80483fb 0xffffd058 0xffffd054 0xf7fbadbc 0x13 0x0
    push %ebp 0x80483e6 0xffffd058 0xffffd050 0xf7fbadbc 0x8048400 0x13 0x0
    mov %esp,%ebp 0x80483e7 0xffffd058 0xffffd04c 0xf7fbadbc 0xffffd058 0x8048400 0x13 0x0
    pushl 0x8(%ebp) 0x80483e9 0xffffd04c 0xffffd04c 0xf7fbadbc 0xffffd058 0x8048400 0x13 0x0
    call 0x80483db 0x80483ec 0xffffd04c 0xffffd048 0xf7fbadbc 0x13 0xffffd058 0x8048400 0x13 0x0
    push %ebp 0x80483db 0xffffd04c 0xffffd044 0xf7fbadbc 0x80483f1 0x13 0xffffd058 0x8048400 0x13 0x0
    mov %esp,%ebp 0x80483dc 0xffffd04c 0xffffd040 0xf7fbadbc 0xffffd04c 0x80483f1 0x13 0xffffd058 0x8048400 0x13 0x0
    mov 0x8(%ebp),%eax 0x80483de 0xffffd040 0xffffd040 0xf7fbadbc 0xffffd04c 0x80483f1 0x13 0xffffd058 0x8048400 0x13 0x0
    add $0x13,%eax 0x80483e1 0xffffd040 0xffffd040 0x13 0xffffd04c 0x80483f1 0x13 0xffffd058 0x8048400 0x13 0x0
    pop %ebp 0x80483e4 0xffffd040 0xffffd040 0x26 0xffffd04c 0x80483f1 0x13 0xffffd058 0x8048400 0x13 0x0
    ret 0x80483e5 0xffffd04c 0xffffd044 0x26 0x80483f1 0x13 0xffffd058 0x8048400 0x13 0x0
    add $0x4,%esp 0x80483f1 0xffffd04c 0xffffd048 0x26
    leave 0x80483f4 0xffffd04c 0xffffd04c 0x26 0xffffd058 0x8048400 0x13 0x0
    ret 0x80483f5 0xffffd058 0xffffd050 0x26 0x8048400 0x13 0x0
    add $0x4,%esp 0x8048400 0xffffd058 0xffffd054 0x26
    add $0x13,%eax 0x8048403 0xffffd058 0xffffd058 0x26
    leave 0x8048406 0xffffd058 0xffffd058 0x39
    ret 0x8048407 0x0 0xffffd05c 0x39

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

    问题:区分MOV,MOVS,MOVZ

    解决方案:

    1.MOV相当于C语言的赋值”=“

    2.MOVS将作了符号扩展的字节传送到字

    3.MOVZ将作了零扩展的字节传送到字

    代码托管

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

    通过本周的学习,C语言代码的汇编和反汇编、C语言代码和汇编代码的转换以及加强阅读汇编代码的能力提高上。

    尝试一下记录「计划学习时间」和「实际学习时间」,到期末看看能不能改进自己的计划能力。这个工作学习中很重要,也很有用。
    耗时估计的公式
    :Y=X+X/N ,Y=X-X/N,训练次数多了,X、Y就接近了。

    参考:软件工程软件的估计为什么这么难软件工程 估计方法

    • 计划学习时间:XX小时

    • 实际学习时间:XX小时

    • 改进情况:

    (有空多看看现代软件工程 课件
    软件工程师能力自我评价表
    )

    参考资料

  • 相关阅读:
    五层原理体系结构的简单分析
    Simple Factory 简单工厂模式(静态工厂)
    css一个图片包含多个图片|网站侧栏导航
    百度地图、高德地图的数据从哪里得到的?
    浏览器开发
    开发一款浏览器内核需要学习哪些方面的知识?
    使用PowerDesigner进行数据库建模入门
    How to create a search engine
    合并两个有序数组
    STL中的algorithm
  • 原文地址:https://www.cnblogs.com/wang5324/p/7711341.html
Copyright © 2020-2023  润新知