menu DizzyK
汇编入门笔记
71 浏览 | 2020-03-31 | 分类:入门笔记,PWN_Notez,CTF_Notez | 标签:

汇编入门笔记

DizzyK

  1. 进制转换

  2. 容器大小

    1. 字节BIT -- 8位
    2. 字WORD -- 16位
    3. 双字DWORD -- 32位
  3. 逻辑运算

    1. 或(or |)
    2. 与(and &)
    3. 异或(xor ^)
    4. 非(not !)
  4. 寄存器
    寄存器 | 主要用途 | 编号 | 存储数据范围
    --|--|--|--
    EAX | 累加器 | 0 | 0 - 0xFFFFFFFF
    ECX | 计数 | 1 | 0 - 0xFFFFFFFF
    EDX | I/O指针 | 2 | 0 - 0xFFFFFFFF
    EBX | DS段的数据指针 | 3 | 0 - 0xFFFFFFFF
    ESP | 堆栈指针 | 4 | 0 - 0xFFFFFFFF
    EBP | SS段的数据指针 | 5 | 0 - 0xFFFFFFFF
    ESI | 字符串操作的源指针(SS段的数据指针) | 6 | 0 - 0xFFFFFFFF
    EDI | 字符串操作的目标指针(ES段的数据指针) | 7 0 - 0xFFFFFFFF

  5. 趁手的工具OD下载

    1. 快捷键
      1. F2 -- 打断点
      2. F7 -- 进入函数
      3. F8 -- 执行下一行
  6. 汇编常见指令

    1. MOV指令 mov A,B将源操作数复制存入目标操作数A
    2. ADD指令add A,B将源操作数A加入目标操作数B
    3. SUB指令sub A,B将源操作数A减去目标操作数B,并记入A
    4. CMP指令cmp A,B将源操作数A减去目标操作数B,不记入A(可以用来比较)
    5. AND指令and A,B将源操作数A与目标操作数B进行与运算
    6. OR指令or A,B将源操作数A与目标操作数B进行或运算
    7. XOR指令xor A,B将源操作数A与目标操作数B进行异或运算
    8. NOT指令not A将源操作数A取否
    9. ADC指令adc byte ptr A,B带进位的加法
    10. SBB指令sbb byte ptr A,B带借位的减法
    1. 对于8、9
         1. A、B不同时为内存
         2. 宽度一样
    1. XCHG指令xchg dword A,B交换A、B
    2. MOVS指令movs dword 内存A,内存B交换A、B
    3. STOS指令stosb/w/d prt es:[EDI]将AK/AX/EAX的值存入[EDI]中
    4. JMP指令jmp A无条件更改EIP的值(跳转)
    5. CALL指令call A会将返回地址(下一条指令地址)记录至堆栈,更改EIP
    6. RETN指令retn跳转回EIP内地址(等于POP EIP)
    7. PUSH指令push A在当前栈顶出写入A(不允许push8位)
    8. POP指令pop A在当前栈顶处读取值并将栈顶移动(POP不允许8位)
    9. TEST指令test A,A检测A是否是0
1. 对A,B
  1. 源操作数可以是立即数.通用寄存器、段寄存器、或者内存单元
  2. 目标操作数可以是通用寄存器、段寄存器或者内存单元
  3. 操作数的宽度必须一样
  4. 源操作数和目标操作数不能同时为内存单元
  5. 很多函数不允许源操作数和目标操作数都是内存
  1. 内存
    1. 寄存器位于CPU内部,执行速度快,但比较贵
    2. 内存速度相对较慢,但成本较低,所以可以做的很大
    3. 寄存器和内存没有本质区别,都是用于存储数据的容器,都是定宽的
    4. 寄存器常用的有8个: (EAX(累加寄存器)、 ECX(计数寄存器)、 EDX(数据寄存器)、 EBX(基址寄存器))[通用寄存器]、 (ESP(堆栈指针寄存器)、 EBP(基址指针寄存器))[栈寄存器]、ESI、EDI
    5. 内存数量特别庞大,无法为每个内存单元起一个名字,所以用编号代替,计算机每一个字节都有一个编号(即编号的单位是BYTE)
    6. 32位和64位计算器差别:寻址宽度4G和64G(正常状态下),可以通过打补丁改变寻址大小
    7. 常用计量单位
      1. BYTE字节 = 8BIT
      2. WORD字 = 16BIT
      3. DWORD双字 = 32BIT
      4. 1KB = 1024BYTE
      5. 1MB = 1024KB
      6. 1GB = 1024MB
    8. 内存格式
      1. 每个内存单元高度是8
      2. [编号]称为地址
      3. 地址的作用
      4. 寻址公式
        1. MOV EAX,DWARD PTR DS:[A]从内存[A]向EAX寄存器中存入双字大小的立即数(读取内存)
        2. MOV DWARD PTR DS:[A],eax从EAX寄存器向内存[A]中存入双字大小的立即数(写入内存)
        3. LEA EAX,DWORD PTR DS:[A]取出内存[A]的地址放入EAX中(读取地址编号)
        4. 特别的
          1. PTR DS:[A]是基址
          2. A可以是reg(寄存器内数据)
          3. A可以表示为[reg1]+[reg2]*B+C(其中B、C为立即数,B只能为1、2、4、8)
      5. 内存编号
      6. 堆栈基础
        1. 有一个BASE寄存器和一个TOP寄存器,都是32位通用寄存器,用来存储内存单位编号
        2. MOV指令,确定栈顶和栈底(先确定栈底后确定栈顶)
        3. BASE存储起始位置编号TOP记录终止位置编号
        4. 存入时TOP的值减A(A为字节数,默认为4)
        5. 释放时TOP的值加4(A为字节数,默认为4)
        6. 默认从高位向低位存储
        7. 如果要读取中间某值的时候可以通过TOPBASE加上偏移的方式去读取
        8. BASE永远不变
        9. 优点临时存储大量数据,便于查找
        10. 可以先存内存后更改栈顶或者反过来
        11. 写入
          1. 法一
            1. 写入MOV DOWRD PTR DS:[reg],B(立即数)
            2. 更改栈顶SUB [reg],4或者LEA [reg],DWORD PTR DS:[[reg]-4]
          2. 法二
            1. PUSH A在当前栈顶出写入A(不允许push8位)
          3. 法三
            1. PUSHAD将8个通用寄存器的值存入堆栈
        12. 读取
          1. 法一
            1. MOV [reg1],DEORD PTR DS:[reg2](reg是栈底或栈顶)
          2. 法二
            1. POP A在当前栈顶处读取值并将栈顶移动(POP不允许8位)
            2. POPAD保存堆栈,还原堆栈
        13. 堆栈平衡
          1. 调用函数前和调用函数后堆栈一样
          2. 堆栈平衡应由调用的函数来进行
          3. 外平栈
      7. 标志寄存器
        1. 进位标志位CF(Carry Flag)无符号运算时的最高位产生进位或者借位时,其值改为1,否则为0
        2. 奇偶标志位PF(Parity Flag)用于反映运算结果中1的个数的奇偶性(只检查最低有效字节,即最后8位)
        3. 辅助进位标志AF(Auxilizry Carry Flag)发生如下两项之一时,变为1
          1. 在字操作中发生低位向高位进位或者借位
          2. 在字节操作中,发生低四位向高四位进位或者借位
        4. 零标志位ZF(Zero Flag)用于反映运算结果是否为零
        5. 符号标志位SF(Sign Flag)用于运算结果的符号位,最高位是什么值,就存什么值
        6. 溢出标志位OF(Overflow Flag)用于反映有符号所有运算结果是否溢出,溢出则为1,否则是0(检测原理:符号位进位 == 1 XOR 最高有效位进位 == 1 == 1时,OF位 == 1)
        7. 方向标志位DF(Direction Flag)加是0,减是1
  2. JCC
    1. JE/JZ指令je A如果ZF位为1则跳转到A
    2. JNE/JNZ指令jne A0如果ZF位为0则跳转到A
    3. JS指令js A如果SF位为1则跳转到A
    4. JNS指令jns A0如果SF位为0则跳转到A
    5. JP/JPE指令jp A如果PF位为1则跳转到A
    6. JNP/JPO指令jnp A0如果PF位为0则跳转到A
    7. JO指令jo A如果OF位为1则跳转到A
    8. JNO指令jno A如果OF位为0则跳转到A
    9. JB/JNAE指令jb A如果CF位为1(无符号小于)则跳转到A
    10. JNB/JAE指令je A如果CF位为0(无符号大于等于)则跳转到A
    11. JBE/JNA指令jbe A如果CF位为1 or ZF位为1(无符号数小于等于)则跳转到A
    12. JNBE/JA指令jnbe A如果CF位为0 and ZF位为1(无符号数大于)则跳转到A
    13. JL/JNGE指令jl A如果SF位不等于OF位(有符号小于)则跳转到A
    14. JNL/JGE指令jnl A如果SF位等于OF位(有符号大于等于)则跳转到A
    15. JLE/JNG指令jle A如果SF位不等于OF位 or ZF位为1(有符号数小于等于)则跳转到A
    16. JNLE/JG指令jnle A如果SF位等于OF位 and ZF位为0(有符号数大于)则跳转到A
    17. REP指令rep stos dword ptr es:[EDI]用EDI内数据填入栈,重复[ECX]次
  3. 函数(汇编中)
    1. 一段能传入数值并有对应返回值的程序
    2. 一般格式
      1. 外平栈中push参数(可省)
      2. call入函数
      3. 提升堆栈,为函数执行提供空间
      4. 保留现场,函数在执行的时候会用到一些寄存器,这些寄存器很可能以后还会用到,所以先存到内存里
      5. 向分配的空间里填充数据,清除垃圾数据(一般是CC填充,防止栈溢出)
      6. 实现函数功能
      7. 恢复现场,将之前保留的寄存器的值恢复
      8. 降低堆栈
      9. 恢复栈底
      10. 函数执行完毕,retn调用处(可省)
知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议

发表评论

email
web

全部评论 (暂无评论)

info 还没有任何评论,你来说两句呐!