zoukankan      html  css  js  c++  java
  • 20135213-信息安全系统设计基础第四周学习总结

    第五周(10.05-10.11):

    学习计时:共xxx小时

    读书:参考资料:课本

    代码:

    作业:

    博客:参考博客:闫佳歆(特此声明)  

    一、学习目标

    1. 理解逆向的概念以及
    2. 掌握X86汇编基础,能够阅读(反)汇编代码
    3. 了解ISA(指令集体系结构)
    4. 理解函数调用栈帧的概念,并能用GDB进行调试

    二、学习资源

    1. 教材:第三章《程序的机器级表示》,详细学习指导见:重点是3.7,3.11

    2. 课程资料:https://www.shiyanlou.com/courses/413 实验四,课程邀请码:W7FQKW4Y

    3. 教材中代码运行、思考一下,读代码的学习方法见

    三、学习方法

    1. 进度很重要:必须跟上每周的进度,阅读,练习,问答,项目。我会认真对待每一位同学,请你不要因为困难半途而废。

    2. 问答很重要:遇到知识难点请多多提问,这是你的权利更是您对自己负责的义务。问答到博客园讨论小组:http://group.cnblogs.com/103791/
    3. 实践很重要:解决书中习题,实践书中实例,完成每周项目,才算真的消化了这本好书。通过实验楼环境或自己安装的虚拟机在实践中进行学习
    4. 实验报告很重要:详细记录你完成项目任务的思路,获得老师点评和帮助自己复习。学习完成后在博客园中(http://www.cnblogs.com/)把学习过程通过博客发表,博客标题“学号-信息安全系统设计基础第五周学习总结”

    四、学习任务

    1. 阅读教材,完成课后练习(书中有参考答案)

    3.1-3.7中练习,重点:3.1,3.3,3.5,3.6,3.9,3.14,3.15,3.16,3.22,3.23,3.27,3.29,3.30,3.33,3.34

    2. 考核:练习题把数据变换一下

    3. 实验:需要动手的到实验楼中练习一下

    4. 深化、实践题目,额外加分

    、后续学习预告(可选):

    第四章《处理器体系结构》

    、学习过程

    第三章 程序的机器级表示

    一、教材导读

    本章学习内容是汇编语言,现在直接写汇编的机会不多了,但一定要能读懂,信息安全的核心思维方式“逆向”在这有很好很直接的体现,反汇编就是直接的逆向工程。

    本章重点是3.7,但没有3.1-3.6的基础也是不行,如果想真正的提高动手能力,3.11如何用GDB调试汇编要好好练习一下,不过大多GDB技巧大家都会了。

    3.1-3.7中练习,重点:3.1,3.3,3.5,3.6,3.9,3.14,3.15,3.16,3.22,3.23,3.27,3.29,3.30,3.33,3.34

    练习:

    x的高32位为xh,低32位为xl

    y的符号位扩展成32位之后为ysys0或者-1)。

    dest_h = (xl*ys)_l + (xh*y)_l + (xl*y)_h

    dest_l = (xl*y)_l

    注意,所有的乘法都是unsigned*unsigned

    也就是说对于 1*(-1),如果存入两个寄存器中,那么高32位是0,低32位是-1 

    相当于 1*(UNSIGNED_MAX)

    p104, p105: X86 寻址方式经历三代:

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

    p106: ISA的定义,ISA需要大家能总结规律,举一反三,比如能对比学习ARM的ISA;PC寄存器要好好理解;

    p107: gcc -S xxx.c -o xxx.s 获得汇编代码,也可以用objdump -d xxx 反汇编; 注意函数前两条和后两条汇编代码,所有函数都有,建立函数调用栈帧,应该理解、熟记。

    注意:  64位机器上想要得到32代码:gcc -m32 -S xxx.c
           MAC OS中没有objdump, 有个基本等价的命令otool 
           Ubuntu中 gcc -S code.c (不带-O1) 产生的代码更接近教材中代码(删除"."开头的语句)
    

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

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

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

    p110: 了解Linux和Windows的汇编格式有点区别:ATT格式和Intel格式

    p111: 表中不同数据的汇编代码后缀

    p112: 这几个寄存器要深入理解,知道它们的用处。esi edi可以用来操纵数组,esp ebp用来操纵栈帧。 对于寄存器,特别是通用寄存器中的eax,ebx,ecx,edx,大家要理解32位的eax,16位的ax,8位的ah,al都是独立的,我们通过下面例子说明:

        假定当前是32位x86机器,eax寄存器的值为0x8226,执行完addw $0x8266, %ax指令后eax的值是多少? 
    解析:0x8226+0x826=0x1044c, ax是16位寄存器,出现溢出,最高位的1会丢掉,剩下0x44c,不要以为eax是32位的不会发生溢出.
    

    p113: 结合表,深入理解各种 寻址方式;理解操作数的三种类型:立即数、寄存器、存储器;

    掌握有效地址的计算方式 Imm(Eb,Ei,s) = Imm + R[Eb] + R[Ei]*s

    p114: MOV相当于C语言的赋值”=“,注意ATT格式中的方向,

    另外注意不能从内存地址直接MOV到另一个内存地址,要用寄存器中转一下。能区分MOV,MOVS,MOVZ,掌握push,pop

    p115/p116: 栈帧与push pop; 注意栈顶元素的地址是所有栈中元素地址中最低的。

    p117: 指针就是地址;局部变量保存在寄存器中。

    p119: 结合表理解一下算术和逻辑运算, 注意目的操作数都是什么类型 特别注意一下减法是谁减去谁 注意移位操作移位量可以是立即数或%cl中的数

    p123: 结合C语言理解一下控制部分,也就是分支(if/switch),循环语句(while, for)如何实现的。考验大家举一反三的学习能力。控制中最核心的是跳转语句:有条件跳转p128(实现if,switch,while,for),无条件跳转jmp(实现goto)

    p124: 有条件跳转的条件看状态寄存器(教材上叫条件码寄存器) 注意leal不改变条件码寄存器 思考一下:CMP和SUB用在什么地方 p125: SET指令根据t=a-b的结果设置条件码

    p127: 跳转与标号

    p130/p131: if-else 的汇编结构

    p132/p133: do-while

    p134/p135: while

    p137/p138: for

    p144/p145: switch

    p149: IA32通过栈来实现过程调用。掌握栈帧结构,注意函数参数的压栈顺序.

    p150/p151: call/ret; 函数返回值存在%eax中

    p174: bt/frame/up/down :关于栈帧的gdb命令

     

    1.数据格式

    · 由于是从16位体系结构扩展成32位,intel用术语字(word)表示16位数据类型,因此32位为双字(double words),64位数为4字(quad words)。

    ·  以下是比较容易模糊的数据类型大小:

              32位机上:float 4    long int 4   double 8    longlong 8    char* 4   unsigned long 4

              64位机上:float 4    long int 8   double 8    longlong 8    char* 8   unsigned long 8

              另外,GCC long double表示扩展精度(10字节),出于存储器性能考虑,会被存储为12字节

     

    2.访问信息

    · 一个IA32 CPU包含一组8个存储32位值的寄存器,用以存整数数据和指针:eax,ecx,edx,ebx,esi,edi     esp,ebp

    大多数情况下前六个都用作通用寄存器,eax,ecx,edx的存储和恢复惯例不同于ebx,edi,esi(前三者为被调用者保存,后三者为调用者保存,详见3.7.3);

    最后两个用于存储指针,由于在过处理中非常重要,分别指向栈帧的顶部和底部,必须保持。

     

     

    3.计算机machine-level programming重要的两类抽象

    一个重要抽象,是将format and behavior of a machine-level program抽象形成instruction set architecture,即ISA(指令集体系结构)

    对于ISA,要有以下基本观念:IA32的ISA和x86-64的ISA,以及其他大多数ISA,在抽象时都将指令按顺序执行抽象。

    但是处理器的硬件可以并发地执行许多指令,并且采用了一些safeguards来确保并行执行之后的结果和一条一条顺序执行的结果一样。

    第二个重要抽象,是将整个计算机中的memory system用虚拟地址来抽象,使得memory system就好像一个“连续”的字节块。

     

     4.反汇编

    通常,编写程序是利用高级语言如C,Pascal等语言进行编程的,后再经过编译程序生成可以 被计算机系统 直接执行的执行文件。
    反汇编即是指将这些执行文件反编译还原成 汇编语言或其他 高级语言。但通常反编译出来的程序与原程序会存在许多不同,虽然执行效果相同,但程序代码 会发生很大的变化,非编程高手很难读懂。
    另外,有许多程序也可以 进行逆向操作即 反编译 以求修改,例如Flash的文件生成的SWF文件,也可以被反汇编成Flash原码,但会发现与原程序有很大变化。

    5.操作数指示符

    操作数:指示出执行一个操作中要引用的源数据值,以及放置结果的目标位置。

    操作数的三种类型:立即数、寄存器、存储器

    结果存放的两种可能:寄存器中、存储器中

     

    6.寻址方式:

    (1)立即数寻址方式

    格式:$后加用标准c表示法表示的整数,如$0xAFF

    (2)寄存器寻址方式

    %eax,与汇编中学过的AX寄存器类比。

     (3)存储器寻址方式

    • 直接寻址方式
    • 寄存器间接寻址方式
    • 寄存器相对寻址方式
    • 基址变址寻址方式
    • 相对基址变址寻址方式

    7.算术和逻辑操作

           这类操作符大致分为四个小类:

               1、加载有交地址(leal),通常用来执行简单算术操作,目前还不太懂这个与mov的区别

               2、一元或二元操作:incl  decl  negl  notl  addl  subl  imull  xorl  orl  andl

               3、移位操作 :sall==shll(填0)  sarl(算术右移,填符号位)  shrl(逻辑右移,填0

               4、特殊算术操作:imull(有符号64位乘法)  mull(无符号64位乘法)  cltd(转换为四字)

                    idivl(有符号除法)   divl(无符号除法)

     

    8.gcc编译器编译流程:

    ·C预处理器扩展源代码;

    ·编译器产生两个源代码的汇编代码 p1.s p2.s

    ·汇编器将汇编代码转换成二进制目标代码文件 p1.o p2.o

    ·链接器将两个目标代码文件与实现库函数的代码合并,并产生可执行代码p

     

    9.push&pop

    1)堆栈

    需要注意两点:

    1.后进先出

    2.栈指针指向栈顶元素

    3.栈朝低地址方向增长

    2)压栈push

    指令格式——PUSH r16/m16/seg

    指令功能

    第一步:SPSP-2  ;堆栈指针SP上移

    第二步:(SS):(SP)r16/m16/seg  ;字操作数存入堆栈顶部

    注意 堆栈操作必须至少以字为单位,这时栈顶指针-2

    如果压入的是双字,栈顶指针-4

    3)出栈pop

    指令格式——POP r16/m16/seg
    指令功能

    第一步:r16/m16/seg← (SS):(SP) ;栈顶的一个字传送到指定的目的操作数

    第二步:SPSP2   ;堆栈指针SP下移,指向新的栈顶

    栈顶指针变化同压栈。

    10.循环

    ·do-while

    一般形式如下:
    do
    语句;
    while(表达式);
     

    ·while

    一般形式如下:
    while(表达式)
     

    ·for

    for语句是循环控制结构中使用最广泛的一种循环控制语句,特别适合已知循环次数的情况。
    一般形式如下:
    for ( [表达式 1]; [表达式 2 ]; [表达式3] )

    七、遇到的问题及解决

    1.抽象的概念理解的不是很清晰。比如这句:将整个计算机中的memory system用虚拟地址来抽象,使得memory system就好像一个“连续”的字节块。

     2.如何快速读懂反汇编的汇编代码?

    链接:http://www.zhihu.com/question/22299883

    八、其他

    1指针其实是地址,间接引用指针就是将该指针放在一个寄存器中 ,然后在间接存储器引用中引用这个寄存器

    2、局部变量通常保存在寄存器中,而不是存储器

  • 相关阅读:
    待测试
    js中substring和substr的用法
    JavaScript lastIndexOf() 方法
    CSS3 :nth-child() 选择器
    jQuery :has() 选择器
    jquery tr:even,tr:eq(),tr:nth-child()区别
    JS模块化工具requirejs教程(二):基本知识
    JS模块化工具requirejs教程(一):初识requirejs
    HTML基础js操作
    HTML基础dom操作
  • 原文地址:https://www.cnblogs.com/20135213lhj/p/4869853.html
Copyright © 2011-2022 走看看