爆款云主机2核4G限时秒杀,88元/年起!
查看详情

活动

天翼云最新优惠活动,涵盖免费试用,产品折扣等,助您降本增效!
热门活动
  • 618智算钜惠季 爆款云主机2核4G限时秒杀,88元/年起!
  • 免费体验DeepSeek,上天翼云息壤 NEW 新老用户均可免费体验2500万Tokens,限时两周
  • 云上钜惠 HOT 爆款云主机全场特惠,更有万元锦鲤券等你来领!
  • 算力套餐 HOT 让算力触手可及
  • 天翼云脑AOne NEW 连接、保护、办公,All-in-One!
  • 中小企业应用上云专场 产品组合下单即享折上9折起,助力企业快速上云
  • 息壤高校钜惠活动 NEW 天翼云息壤杯高校AI大赛,数款产品享受线上订购超值特惠
  • 天翼云电脑专场 HOT 移动办公新选择,爆款4核8G畅享1年3.5折起,快来抢购!
  • 天翼云奖励推广计划 加入成为云推官,推荐新用户注册下单得现金奖励
免费活动
  • 免费试用中心 HOT 多款云产品免费试用,快来开启云上之旅
  • 天翼云用户体验官 NEW 您的洞察,重塑科技边界

智算服务

打造统一的产品能力,实现算网调度、训练推理、技术架构、资源管理一体化智算服务
智算云(DeepSeek专区)
科研助手
  • 算力商城
  • 应用商城
  • 开发机
  • 并行计算
算力互联调度平台
  • 应用市场
  • 算力市场
  • 算力调度推荐
一站式智算服务平台
  • 模型广场
  • 体验中心
  • 服务接入
智算一体机
  • 智算一体机
大模型
  • DeepSeek-R1-昇腾版(671B)
  • DeepSeek-R1-英伟达版(671B)
  • DeepSeek-V3-昇腾版(671B)
  • DeepSeek-R1-Distill-Llama-70B
  • DeepSeek-R1-Distill-Qwen-32B
  • Qwen2-72B-Instruct
  • StableDiffusion-V2.1
  • TeleChat-12B

应用商城

天翼云精选行业优秀合作伙伴及千余款商品,提供一站式云上应用服务
进入甄选商城进入云市场创新解决方案
办公协同
  • WPS云文档
  • 安全邮箱
  • EMM手机管家
  • 智能商业平台
财务管理
  • 工资条
  • 税务风控云
企业应用
  • 翼信息化运维服务
  • 翼视频云归档解决方案
工业能源
  • 智慧工厂_生产流程管理解决方案
  • 智慧工地
建站工具
  • SSL证书
  • 新域名服务
网络工具
  • 翼云加速
灾备迁移
  • 云管家2.0
  • 翼备份
资源管理
  • 全栈混合云敏捷版(软件)
  • 全栈混合云敏捷版(一体机)
行业应用
  • 翼电子教室
  • 翼智慧显示一体化解决方案

合作伙伴

天翼云携手合作伙伴,共创云上生态,合作共赢
天翼云生态合作中心
  • 天翼云生态合作中心
天翼云渠道合作伙伴
  • 天翼云代理渠道合作伙伴
天翼云服务合作伙伴
  • 天翼云集成商交付能力认证
天翼云应用合作伙伴
  • 天翼云云市场合作伙伴
  • 天翼云甄选商城合作伙伴
天翼云技术合作伙伴
  • 天翼云OpenAPI中心
  • 天翼云EasyCoding平台
天翼云培训认证
  • 天翼云学堂
  • 天翼云市场商学院
天翼云合作计划
  • 云汇计划
天翼云东升计划
  • 适配中心
  • 东升计划
  • 适配互认证

开发者

开发者相关功能入口汇聚
技术社区
  • 专栏文章
  • 互动问答
  • 技术视频
资源与工具
  • OpenAPI中心
开放能力
  • EasyCoding敏捷开发平台
培训与认证
  • 天翼云学堂
  • 天翼云认证
魔乐社区
  • 魔乐社区

支持与服务

为您提供全方位支持与服务,全流程技术保障,助您轻松上云,安全无忧
文档与工具
  • 文档中心
  • 新手上云
  • 自助服务
  • OpenAPI中心
定价
  • 价格计算器
  • 定价策略
基础服务
  • 售前咨询
  • 在线支持
  • 在线支持
  • 工单服务
  • 建议与反馈
  • 用户体验官
  • 服务保障
  • 客户公告
  • 会员中心
增值服务
  • 红心服务
  • 首保服务
  • 客户支持计划
  • 专家技术服务
  • 备案管家

了解天翼云

天翼云秉承央企使命,致力于成为数字经济主力军,投身科技强国伟大事业,为用户提供安全、普惠云服务
品牌介绍
  • 关于天翼云
  • 智算云
  • 天翼云4.0
  • 新闻资讯
  • 天翼云APP
基础设施
  • 全球基础设施
  • 信任中心
最佳实践
  • 精选案例
  • 超级探访
  • 云杂志
  • 分析师和白皮书
  • 天翼云·创新直播间
市场活动
  • 2025智能云生态大会
  • 2024智算云生态大会
  • 2023云生态大会
  • 2022云生态大会
  • 天翼云中国行
天翼云
  • 活动
  • 智算服务
  • 产品
  • 解决方案
  • 应用商城
  • 合作伙伴
  • 开发者
  • 支持与服务
  • 了解天翼云
      • 文档
      • 控制中心
      • 备案
      • 管理中心

      Windows逆向安全(一)之基础知识(一)

      首页 知识中心 其他 文章详情页

      Windows逆向安全(一)之基础知识(一)

      2023-08-03 06:47:06 阅读次数:454

      windows,安全

      前言

      逆向是一种新型的思维模式也是软件开发领域中极为重要的技术,涵盖各种维度去深挖软件架构的本质和操作系统原理,学习逆向后可以在各领域中发挥至关重要的作用,其中包括黑灰色,安全开发,客户端安全,物联网,车联网,游戏安全,红队免杀等行业中绘制出更高的闪光点。

      C与汇编的关系

      基本语法的学习:

      各种进制的转换和原理

      1. 十进制的定义:由十个符号组成,分别是0 1 2 3 4 5 6 7 8 9 逢十进一
      2. 九进制的定义:由九个符号组成,分别是0 1 2 3 4 5 6 7 8 逢九进一
      3. 十六进制的定义:由十六个符号组成,分别是0 1 2 3 4 5 6 7 8 9 A B C D E F
      4. N进制的定义:由N个符号组成 逢N进一

      Windows逆向安全(一)之基础知识(一)

      Windows逆向安全(一)之基础知识(一)

      Windows逆向安全(一)之基础知识(一)

      Windows逆向安全(一)之基础知识(一)

      数据类型与逻辑运算

      Windows逆向安全(一)之基础知识(一)

      在计算机中,由于硬件的制约,数据是有长度限制的,超过数据宽度的数据会被丢弃

      同一个数据,表示无符号数和有符号数则其含义不同

      1. 无符号数:正数
      2. 有符号数:正数、负数

      例:

      • 当数据宽度为4时,即数据只能存储4位2进制位0000~1111

      无符号数:

      1. 数据:0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
      2. 十六进制:0 1 2 3 4 5 6 7 8 9 A B C D E F
      3. 二进制:0000000100100011010001010110011110001001101010111100110111101111

      有符号数:

      正数:

      1. 数据:0 1 2 3 4 5 6 7
      2. 十六进制:0 1 2 3 4 5 6 7
      3. 二进制:00001001000110100010101100111

      负数:

      1. 数据:-1 -2 -3 -4 -5 -6 -7 -8
        十六进制:F E D C B A 9 8
        二进制: 11111110110111001011101010011000
      2. 可以发现当数据为1011,把数据看作无符号数时,数据表示为B
      3. 把数据看作有符号数时,数据表示为-5
      4. 无符号数的表示范围为0~2^4-1即0~15\\ 有符号数的表示范围为-23~23-1即-8~7

      常见的数据类型(重要):

      • BYTE 字节 8BIT 1字节
      • WORD 字 16BIT 2字节
      • DWORD 双字 32BIT 4字节

      常见的运算符类型(重要):

      或运算(or |):
      两个数只要有一个为1则结果为1

      与运算(and &):
      两个数都是1结果才为1

      异或运算(xor ^):
      两个数相同为0, 不同为1

      非运算(not !):
      两个数取反 1是0, 0是1

      CPU如何计算2+3?

      X:0010

      Y:0011

      先异或

      Windows逆向安全(一)之基础知识(一)

       

      R:0001

      异或完以后要判断是否运算结束

      将两个数进行与运算 然后左移一位

      Windows逆向安全(一)之基础知识(一)

       

      0010<<1 ==0100

      如果结果全为0,结果则为我们所要的结果

      否则,把上面异或得到的值赋值到X

      把左移后的结果赋值到Y

      X:0001

      Y:0100

      重复操作

      先异或

      Windows逆向安全(一)之基础知识(一)

       

      R:0101

      再将两个数进行与运算 然后左移一位

      Windows逆向安全(一)之基础知识(一)

       

      左移完结果全是0,结果则为我们所要的

      最终结果为0101=5

      CPU如何计算2-3?

      X:0010

      Y:1101

      先异或

      Windows逆向安全(一)之基础知识(一)

       

      R:1111

      将两个数进行与运算 然后左移一位

      Windows逆向安全(一)之基础知识(一)

      0000<<1=0000

      如果结果全为0,结果则为我们所要的结果

      最终结果为1111 = -1

      如何取某个值的第N位的数值:

      与操作

      如我们想要查看23h这个十六进制数的第3位则可以进行如下运算:

      先将23h转化为二进制:0010 0011

      Windows逆向安全(一)之基础知识(一)

      最简单的加密算法:

      通过异或加密数据 再次异或后则解密数据

      要加密的数据:2021:0010 0000 0010 0001

      密钥:54:0101 0100

      Windows逆向安全(一)之基础知识(一)

       

      高位:0111 0100 = 74

      Windows逆向安全(一)之基础知识(一)

       

      低位:0111 0101 = 75

      原本的2021加密成了7475

      然后再次进行异或操作进行解密:

      Windows逆向安全(一)之基础知识(一)

      高位:0010 0000 = 20

      Windows逆向安全(一)之基础知识(一)

      低位:0010 0100 = 21

      解密回了原来的数值2021

      通用寄存器和内存读写

      32位通用寄存器的指定用途如下:

      Windows逆向安全(一)之基础知识(一)

      Windows逆向安全(一)之基础知识(一)

      Windows逆向安全(一)之基础知识(一)

      堆栈相关汇编指令:

      Windows逆向安全(一)之基础知识(一)

      MOV指令

      MOV 的语法:

      MOV  r/m8,r8
      MOV  r/m16,r16
      MOV  r/m32,r32
      MOV  r8,r/m8
      MOV  r16,r/m16
      MOV  r32,r/m32
      MOV r8,  imm8
      MOV r16,  imm16
      MOV r32,  imm32

      MOV 目标操作数,源操作数

      作用:拷贝源操作数到目标操作数

      源操作数可以是立即数、通用寄存器、段寄存器、或者内存单元
      目标操作数可以是通用寄存器、段寄存器或者内存单元
      操作数的宽度必须一样
      源操作数和目标操作数不能同时为内存单元

      ADD指令

      ADD 的语法:

      ADD r/m8,  imm8
      ADD  r/m16,imm16
      ADD  r/m32,imm32
      ADD r/m16,  imm8
      ADD r/m32,  imm8
      ADD r/m8,  r8
      ADD r/m16,  r16
      ADD r/m32,  r32
      ADD r8,  r/m8
      ADD r16,  r/m16
      ADD r32,  r/m32

      ADD 目标操作数,源操作数

      作用:将源操作数加到目标操作数上

      SUB指令

      SUB 的语法:

      SUB r/m8, imm8
      SUB r/m16,imm16
      SUB r/m32,imm32
      SUB r/m16, imm8
      SUB r/m32, imm8
      SUB r/m8, r8
      SUB r/m16, r16
      SUB r/m32, r32
      SUB r8, r/m8
      SUB r16, r/m16
      SUB r32, r/m32

      SUB 目标操作数,源操作数

      作用:将源操作数减到目标操作数上

      AND指令

      AND 的语法:

      AND r/m8, imm8
      AND r/m16,imm16
      AND r/m32,imm32
      AND r/m16, imm8
      AND r/m32, imm8
      AND r/m8, r8
      AND r/m16, r16
      AND r/m32, r32
      AND r8, r/m8
      AND r16, r/m16
      AND r32, r/m32

      AND 目标操作数,源操作数

      作用:将源操作数与目标操作数与运算后将结果保存到目标操作数中

      OR指令

      OR 的语法:

      OR r/m8, imm8
      OR r/m16,imm16
      OR r/m32,imm32
      OR r/m16, imm8
      OR r/m8, r8
      OR r/m16, r16
      OR r/m32, r32
      OR r8, r/m8
      OR r16, r/m16
      OR r32, r/m32

      OR 目标操作数,源操作数

      作用:将源操作数与目标操作数或运算后将结果保存到目标操作数中

      XOR指令

      XOR 的语法:

      XOR r/m8, imm8
      XOR r/m16,imm16
      XOR r/m32,imm32
      XOR r/m16, imm8
      XOR r/m8, r8
      XOR r/m32, r32
      XOR r8, r/m8
      XOR r16, r/m16
      XOR r32, r/m32

      XOR 目标操作数,源操作数

      作用:将源操作数与目标操作数异或运算后将结果保存到目标操作数中

      NOT指令

      NOT 的语法:

      NOT r/m8
      
      NOT r/m16
      
      NOT r/m32
      
      NOT 操作数

      作用:取反

      LEA指令

      Windows逆向安全(一)之基础知识(一)

      lea:Load Effective Address,即装入有效地址的意思,它的操作数就是地址

      lea r32,dword ptr ds:[内存编号(地址)]

      将内存地址赋值给32位通用寄存器

      lea是传址,mov是传值,注意区别

      堆栈结构

      Windows逆向安全(一)之基础知识(一)

       

      Windows逆向安全(一)之基础知识(一)

      Windows逆向安全(一)之基础知识(一)

      Windows逆向安全(一)之基础知识(一)

      Windows分配栈时 是从高地址往低地址分配:

      1. MOV EBX,0x13FFDC BASE
      2. MOV EDX,0x13FFDC TOP

      栈底和栈顶可以是两个任意的寄存器(Windows采用的是EBP和ESP)

      刚开始堆栈为空,栈顶和栈底相同

      Windows逆向安全(一)之基础知识(一)

      先将数据压入后再修改栈顶

      数据压入

      MOV DWORD PTR DS:[EDX-4],0xAAAAAAAA
      修改栈顶

      SUB EDX,4
      先修改栈顶后再将数据压入
      修改栈顶

      LEA EDX,DWORD PTR DS:[EDX-4] (和上面的SUB一样)
      数据压入

      MOV DOWRD PTR DS:[EDX],0xAAAAAAAA

      Windows逆向安全(一)之基础知识(一)

       

      栈顶加偏移读取

      MOV ESI,DWORD PTR DS:[EBX-8]
      栈底加偏移读取

      MOV EDI,DWORD PTR DS:[EDX+4]

      Windows逆向安全(一)之基础知识(一)

       

      先取出数据再修改栈顶

      取出数据

      MOV EAX,DOWRD PTR DS:[EDX]
      修改栈顶

      ADD EDX,4
      先修改栈顶再取出数据
      修改栈顶

      LEA EDX,DWORD PTR DS:[EDX+4]
      取出数据

      MOV EAX,DOWRD PTR DS:[EDX-4]

      Windows逆向安全(一)之基础知识(一)

      Windows逆向安全(一)之基础知识(一)

      入栈和出栈操作也有对应的指令:

      上面我们自己模拟的两个用作栈顶和栈底的寄存器在WINDOWS中分别对应ESP和EBP

      并且前面我们自己模拟的入栈和出栈操作也有对应的指令:PUSH 和 POP

      就是封装了压入数据和修改栈顶的操作

      • PUSH 和 POP
      • push xxx将 xxx的数据压入堆栈
      • pop xxx将栈顶的数据存储到xxx中

      PUSH指令:

      PUSH r32

      PUSH r16

      PUSH m16

      PUSH m32

      PUSH imm8/imm16/imm32

      所有的push都是将esp-4?

      压入的数据的数据宽度:

      当push的是立即数将esp-4

      当push r32如push eax时将esp-4

      当push dword ptr ds:[12FFDA]即压入双字内存地址中的数据时将esp-4

      当push word ptr ds:[12FFDA]即压入字内存地址中的数据时将esp-2

      当push ax,即r16 ,16位通用寄存器时,esp-2

      push 不允许压入数据宽度为8的数据 如ah al 和byte ptr ds:[内存编号]

      POP指令

      POP r32

      POP r16

      POP m16

      POP m32

      PUSHAD和POPAD指令

      将所有的32位通用寄存器压入堆栈,方便后面随意使用寄存器,用于保护现场

      与POPAD对应

      PUSHFD和POPFD指令

      然后将32位标志寄存器EFLAGS压入堆栈

      与POPAD对应

      其它相关指令

      pusha:将所有的16位通用寄存器压入堆栈

      popa:将所有的16位通用寄存器取出堆栈

      pushf::将的16位标志寄存器EFLAGS压入堆栈

      popf:将16位标志寄存器EFLAGS取出堆栈

      栈底和栈顶原理:

      1. 控制栈顶和栈底分别为两个固定的寄存器(EBP 基址指针寄存器 和 ESP 堆栈指针寄存器)
      2. 刚开始堆栈为空,栈顶和栈底相同

      标志寄存器

      EFLAGS寄存器

      Windows逆向安全(一)之基础知识(一)

      进位标志CF(Carry Flag)

      如果运算结果的最高位产生了一个进位或借位,那么,其值为1,否则其值为0

      例子:

      MOV AL,0xFF
      
      ADD AL,1
      • 0x80+0x40

      加黑的为最高位

      0x80:0 1000 0000

      0x40:0 0100 0000

      Windows逆向安全(一)之基础知识(一)

       

      结果为1100 0000 最高位并没有发生变化,于是CF位为0

      • 0x80-0x40

        注意这里借位的位是1000 0000中的加黑部分

      而非0 1000 0000这里的最高位

      结果为0100 0000 最高位并没有发生变化,于是CF位为0

      • 0x80-0x81

      0x80:1000 0000

      0x81:1000 0001

      Windows逆向安全(一)之基础知识(一)

       

      结果为1111 1111= -1,最高位被借位,于是CF位为1

      奇偶标志PF(Parity Flag)

      奇偶标志PF用于反映运算结果中最低有效字节中“1”的个数的奇偶性

      如果“1”的个数为偶数,则PF的值为1,否则其值为0。

      指令指令执行后AL的结果PFMOV AL,300111ADD AL,301101ADD AL,210000

      例:

      MOV AX,803
      ADD AX,1

      0x803: 0000 1000 0000 0011

      执行结果

      0x804: 0000 1000 0000 0100 总共2个1 ,PF应为1,但实际运行结果PF为0

      因为PF是根据最低有效字节来看,即804后面04的这部分

      04: 0000 0100 总共1个1,所以PF为0

      辅助进位标志AF(Auxiliary Carry Flag)

      在发生下列情况时,辅助进位标志AF的值被置为1,否则其值为0:

      • 在字操作时,发生低字节向高字节进位或借位时
      • 在字节操作时,发生低4位向高4位进位或借位时

      AF与数据宽度相关

      32位时 FFFF F FFF

      16位时 FF F F

      8位时 F F

      加黑的字体为AF标志位判断的位置,如果该位置要向前进位则AF为1,否则为0,和CF相似,不过判断的位置不同

      32位例:

      MOV EAX,55EEFFFF
      
      ADD EAX,2

      16位例:

      MOV AX,5EFE
      
      ADD AX,2

      8位例:

      MOV AL,4E
      
      ADD AL,2

      零标志ZF(Zero Flag)

      零标志ZF用来反映运算结果是否为0

      如果运算结果为0,则其值为1,否则其值为0

      作用:在判断运算结果是否为0时,可使用此标志位

      例子:

      XOR EAX,EAX

      通过xor将eax清零,会改变zf标志位为1

      MOV EAX,0

      通过MOV将EAX赋值为0,非运算,不改变zf标志位

      符号标志SF(Sign Flag)

      符号标志SF用来反映运算结果的符号位,它与运算结果的最高位相同

      例子:

      MOV AL,7F
      ADD AL,2

      溢出标志OF(Overflow Flag)

      溢出标志OF用于反映有符号数加减运算所得结果是否溢出

      注意与CF区分!!!

      最高位进位与溢出的区别:

      进位标志表示无符号数运算结果是否超出范围.

      溢出标志表示有符号数运算结果是否超出范围.

      溢出主要是给有符号运算使用的,在有符号的运算中,有如下的规律:

      • 正 + 正 = 正 如果结果是负数,则说明有溢出
      • 负 + 负 = 负 如果结果是正数,则说明有溢出
      • 正 + 负 永远都不会有溢出

      无符号、有符号都不溢出例

      MOV AL,8
      ADD AL,8

      AL的数据宽度为8,即

      无符号数范围为0~FF即0~255

      8+8=16在0~255内 不溢出

      有符号数的范围为

      正数:0~7F 即0~127

      负数:80~FF 即 -128~0

      8+8=16 在0~127内 两正数相加结果仍为正数,不溢出

      无符号溢出、有符号不溢出例

      MOV AL,0FF
      ADD AL,2

      无符号数时

      FF+2=255+2=257 在0~255外,溢出

      有符号数时

      FF+2=-1+2=1

      正 + 负 永远都不会有溢出

      无符号不溢出、有符号溢出例

      MOV AL,7F
      ADD AL,2

      无符号数时

      7F+2=127+2=129 在0~255内 不溢出

      有符号数时

      7F+2=0x81在80~FF (负数范围)内,两正数相加结果为负数,溢出

      无符号、有符号都溢出

      MOV AL,0FE
      ADD AL,80

      无符号数时

      FE+2=254+2=256=0x100 在0~255外 溢出

      有符号数时

      FE+2=0x100在0~FF外,溢出

      CPU如何计算OF位

      首先引入两个概念:

      • 符号位有进位
      • 最高有效数值位向符号位产生的进位

      对于一个有符号数:如0x80和0xC0

      符号位有进位

      0x80:1 000 0000

      0xC0:1 100 0000

      最高有效数值位向符号位产生的进位

      0x80:1 0 00 0000

      0xC0:1 1 00 0000

      接下来看一组汇编指令

      MOV AL,80
      ADD AL,0C0

      就是运算0x80+0xc0

      0x80:1 0 00 0000

      0xC0:1 1 00 0000

      符号位1+1有产生进位,于是符号位有进位为1

      最高有效数值位向符号位产生的进位0+1没有产生进位,于是最高有效数值位向符号位产生的进位为0

      OF = 符号位有进位 xor 最高有效数值位向符号位产生的进位

      OF = 1 xor 0 = 1 所以此时OF=1

      方向标志DF(Direction Flag)

      DF:方向标志位

      DF=1时串操作为减地址方式 DF=0为增地址方式

      下面的MOVS指令有说明DF的具体应用

      Windows逆向安全(一)之基础知识(一)

      ADC指令:带进位加法

      格式:ADC R/M,R/M/IMM 两边不能同时为内存 数据宽度要一样

      例:

      mov ax,2
      mov bx,1
      手动修改CF为1
      adc ax,1
      执行后,(ax)=4.adc执行时,相当于计算:(ax)+1+CF=2+1+1=4

      计算结果为4,原本1+2=3,但是现在变成了4,注意与ADD的区别就在于进位

      SBB指令:带借位减法

      格式:SBB R/M,R/M/IMM 两边不能同时为内存 数据宽度要一样

      MOV AL,4
      MOV CL,2
      手动修改CF为1
      SBB AL,CL
      执行后,(al)=1,sbb执行时,相当于计算:(al)-2-CF=4-2-1=1

      计算结果为1,原本4-2=2,但是现在变成了1,注意与SUB的区别就在于进位

      XCHG指令:交换数据

      格式:XCHG R/M,R/M 两边不能同时为内存 数据宽度要一样

      XCHG AL,CL
      XCHG DWORD PTR DS:[12FFC4],EAX
      XCHG BYTE PTR DS:[12FFC4],AL

      例:

      MOV AL,1
      MOV CL,2
      XCHG AL,CL

      执行前:AL=1 CL=2

      执行后:AL=2 CL=1

      MOVS指令:移动数据 内存-内存

      BYTE/WORD/DWORD

      MOVS指令常用于复制字符串

      MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI]        简写为:MOVSB
      MOVS WORD PTR ES:[EDI],WORD PTR DS:[ESI]        简写为:MOVSW
      MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI]        简写为:MOVSD

      例:

      MOV EDI,12FFD8
      MOV ESI,12FFD0
      MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI]

      执行后,EDI内存里的值被修改为ESI内存里的值,且EDI和ESI各加4

      为什么各加4?

      和DOWRD数据宽度相关,如果为WORD 则各加2

      为什么执行完是加而不是减?

      由DF(Direction Flag)方向标志位决定,当DF位为1时为减,当DF位为0时,则为加

      STOS指令
      将Al/AX/EAX的值存储到[EDI]指定的内存单元,和数据宽度相关

      STOS BYTE PTR ES:[EDI]                将AL存储到[EDI]
      STOS WORD PTR ES:[EDI]                将AX存储到[EDI]
      STOS DWORD PTR ES:[EDI]                将EAX存储到[EDI]

      注意这里使用的是ES: 之前写的都是DS:

      当后面为[EDI]时要使用ES: 这和后面要学的段寄存器有关,先记住

      存储完数据后EDI地址的变化方向也受DF标志控制,1减0增

      REP指令

      按计数寄存器 (ECX) 中指定的次数重复执行指令

      MOV ECX,10
      REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI]        也可以写成REP MOVSD

      这里的10为十六进制,也就是0x10=16

      代码将会重复执行16次,会不会往同一个地方覆盖?

      不会,因为每执行一次EDI和ESI都会变化4,变化方向由DF决定

      跳转指令

      JCC指令

      cc 代表 condition code(状态码)

      Jcc不是单个指令,它只是描述了跳转之前检查条件代码的跳转助记符

      例如JNE,在跳转之前检查条件代码

      典型的情况是进行比较(设置CC),然后使用跳转助记符之一

      CMP EAX,0
      
      JNE XXXXX

      条件代码也可以用AND、OR、XOR、加法、减法(当然也可以是CMP)等指令来设置

      JCC指令用于改变EIP(CPU要读取的指令地址)

      JMP指令

      JMP指令:修改EIP的值

      JMP指令只影响了EIP,不影响堆栈和其它通用寄存器

      JMP 寄存器/立即数 相当于 MOV EIP,寄存器/立即数

      CALL指令

      CALL指令和JMP指令都会修改EIP的值

      但CALL指令会将返回地址(CALL指令的下一条指令地址)压入堆栈

      因此也会引起esp的变化

      RET指令

      call调用跳转后执行完相关代码完要返回到call的下一条指令时使用ret指令

      ret指令相当于pop eip

      比较指令

      CMP指令

      指令格式:CMP R/M,R/M/IMM

      CMP指令只改变标志寄存器的值

      该指令是比较两个操作数,实际上,它相当于SUB指令,但是相减的结果并不保存到第一个操作数中

      只是根据相减的结果来改变ZF零标志位的,当两个操作数相等的时候,零标志位置1

      例:

      MOV EAX,100
      MOV EBX,200
      CMP EAX,EBX
      CMP AX,WORD PTR DS:[405000]
      CMP AL,BYTE PTR DS:[405000]
      CMP EAX,DWORD PTR DS:[405000]

      TEST指令

      指令格式:TEST R/M,R/M/IMM

      该指令在一定程度上和CMP指令时类似的,两个数值进行与操作,结果不保存,但是会改变相应标志位

      与的操作表项如下:

      Windows逆向安全(一)之基础知识(一)

      可以看到只要有任一操作数为0时,结果就为0

      常见用法:用这个指令,可以确定某寄存器是否等于0

      只有当eax=0时 eax and eax才会是0

      所以

      TEST EAX,EAX

      观察ZF(零标志位)就可以判断EAX是否为0

      JCC指令表

      首先要明确一点,所有的判断跳转指令都是根据标志位来进行判断的

      JCC指令也只影响EIP

      Windows逆向安全(一)之基础知识(一)

      堆栈图

      首先给定一段反汇编代码,分析该段代码的堆栈的变化情况,并绘制出堆栈图

      函数调用

      00401168  |.  6A 02         push 0x2
      0040116A  |.  6A 01         push 0x1
      0040116C  |.  E8 99FEFFFF   call HelloWor.0040100A
      00401171  |.  83C4 08       add esp,0x8

      CALL内部

      00401040  /> \55            push ebp
      00401041  |.  8BEC          mov ebp,esp
      00401043  |.  83EC 40       sub esp,0x40
      00401046  |.  53            push ebx
      00401047  |.  56            push esi
      00401048  |.  57            push edi
      00401049  |.  8D7D C0       lea edi,dword ptr ss:[ebp-0x40]
      0040104C  |.  B9 10000000   mov ecx,0x10
      00401051  |.  B8 CCCCCCCC   mov eax,0xCCCCCCCC
      00401056  |.  F3:AB         rep stos dword ptr es:[edi]
      00401058  |.  8B45 08       mov eax,dword ptr ss:[ebp+0x8]
      0040105B  |.  0345 0C       add eax,dword ptr ss:[ebp+0xC]
      0040105E  |.  5F            pop edi                                  ;  HelloWor.00401171
      0040105F  |.  5E            pop esi                                  ;  HelloWor.00401171
      00401060  |.  5B            pop ebx                                  ;  HelloWor.00401171
      00401061  |.  8BE5          mov esp,ebp
      00401063  |.  5D            pop ebp                                  ;  HelloWor.00401171
      00401064  \.  C3            retn

      开始分析

      分析流程较为冗长,可能会有些乏味,可以先看最后的流程总结,再来看分析的细节

      我们现在开始逐语句分析堆栈的变化情况:

      Windows逆向安全(一)之基础知识(一)

       

      Windows逆向安全(一)之基础知识(一)

      Windows逆向安全(一)之基础知识(一)

      初始堆栈图

      我们观察堆栈的情况:

      此时ESP:0012FF34 EBP:0012FF80

      结合寄存器和堆栈内容绘出简易堆栈图

      Windows逆向安全(一)之基础知识(一)

      Windows逆向安全(一)之基础知识(一)

       

      压入参数

      00401168  |.  6A 02         push 0x2

      Windows逆向安全(一)之基础知识(一)

      可以看到执行后ESP减少了4=0012FF30 并且0012FF30里的内容为2,这就是所谓的入栈操作

      0040116A  |.  6A 01         push 0x1

      Windows逆向安全(一)之基础知识(一)

       

      可以看到执行后ESP又减少了4=0012FF2C ,并且0012FF2C里的内容为1

      上面的两条push语句是将两个立即数 2和1压入到堆栈中,我们可以画出对应的堆栈图:

      Windows逆向安全(一)之基础知识(一)

       

      CALL指令

      0040116C  |.  E8 99FEFFFF   call HelloWor.0040100A

      F7单步步入

      Windows逆向安全(一)之基础知识(一)

      可以看到CALL之后跳转到了0040100A,并且esp又减少了4=0012FF28

      而且我们可以注意到此时堆栈中0012FF28存放的内容是:00401171正好是我们call指令的下一行指令的地址

      0040116C  |.  E8 99FEFFFF   call HelloWor.0040100A
      00401171  |.  83C4 08       add esp,0x8

      所以应证了前面所学的call指令会将要返回的地址压入栈中来保存现场

      此时的堆栈图为

      Windows逆向安全(一)之基础知识(一)

       

      接着我们就跳转到了call的内部

      CALL内部指令

      Windows逆向安全(一)之基础知识(一)

      00401040  /> \55            push ebp

      Windows逆向安全(一)之基础知识(一)

      Windows逆向安全(一)之基础知识(一)

      EBP被压入到堆栈中,此时堆栈图为

      Windows逆向安全(一)之基础知识(一)

      接着执行

      00401041  |.  8BEC          mov ebp,esp

      ebp赋值为esp,此时堆栈图为

      Windows逆向安全(一)之基础知识(一)

      接着执行

      00401043  |.  83EC 40       sub esp,0x40

      Windows逆向安全(一)之基础知识(一)

       

      Windows逆向安全(一)之基础知识(一)

       

      将esp的值减去0x40=64,我们这里的相差的数据宽度为4即16,64/4=16,因此堆栈图里多了16格(蓝色部分),这种操作常被叫做提升堆栈,此时堆栈图为:

      Windows逆向安全(一)之基础知识(一)

      我们可以发现提升完堆栈以后,堆栈的数据有些★意义不明★,这是因为堆栈中存放的是临时的数据,可能是之前使用时没有清理的垃圾数据

      接着执行

      00401046  |.  53            push ebx
      00401047  |.  56            push esi
      00401048  |.  57            push edi

      将三个通用寄存器压入堆栈,用于保护现场,注意CALL之前和CALL之后,其前后环境要一致,这就是所谓的堆栈平衡

      Windows逆向安全(一)之基础知识(一)

      Windows逆向安全(一)之基础知识(一)

      根据此时的堆栈内容绘制堆栈图

      Windows逆向安全(一)之基础知识(一)

       

      接着执行

      00401049  |.  8D7D C0       lea edi,dword ptr ss:[ebp-0x40]

      Windows逆向安全(一)之基础知识(一)

       

      将ebp-40所指向的内存地址赋给edi

      前面我们执行了sub esp,0x40 所以这里其实就是将那时esp的地址传给了edi(就是push ebx esi edi)之前的的esp

      此时堆栈图并发生没有变化

      接着看下一行

      0040104C  |.  B9 10000000   mov ecx,0x10
      00401051  |.  B8 CCCCCCCC   mov eax,0xCCCCCCCC

      分别给ecx和eax赋值,堆栈图依旧没有发生变化

      Windows逆向安全(一)之基础知识(一)

       

      接着看下一行

      00401056  |.  F3:AB         rep stos dword ptr es:[edi]

      这条语句用到了我们前面所学的逆向基础笔记五 标志寄存器中的内容(如有疑惑可前往查看)

      rep的作用是,重复执行 stos dword ptr es:[edi],每次执行都会使ecx-1,直到ecx为0再执行下一条语句

      前面赋值ecx为0x10=16,正好对应我们堆栈图中蓝色的格子数,所以将会执行16次

      stos dword ptr es:[edi]则是将eax的值赋值给edi所指向的内存地址里的值,并且每执行一次edi都会增加4(D标志位为0所以是增加)

      结合前面edi==esp,这里其实是将我们提升堆栈的那部分内存区域初始化

      此时的堆栈内容为

      Windows逆向安全(一)之基础知识(一)

       

      很明显地看到原本的垃圾数据被我们初始化为了CCCCCCCC

      堆栈图也变成了

      Windows逆向安全(一)之基础知识(一)

       

      实际执行内容

      接着看下面的代码

      00401058  |.  8B45 08       mov eax,dword ptr ss:[ebp+0x8]
      0040105B  |.  0345 0C       add eax,dword ptr ss:[ebp+0xC]

      Windows逆向安全(一)之基础知识(一)

       

      根据堆栈图我们可以很清晰地看出

      [ebp+0x8]正是我们call外部push的参数:1

      [ebp+0xc]正是我们call外部push的参数:2

      这里是将eax赋值为1,然后再给eax+2,最终结果eax=3

      还原现场并返回

      此时堆栈图依旧没有发生变化,接着看下面的语句

      0040105E  |.  5F            pop edi                                  ;  HelloWor.00401171
      0040105F  |.  5E            pop esi                                  ;  HelloWor.00401171
      00401060  |.  5B            pop ebx                                  ;  HelloWor.00401171

      出栈,还原现场,堆栈图

      Windows逆向安全(一)之基础知识(一)

       

      下一条

      Windows逆向安全(一)之基础知识(一)

       

      还原esp,前面mov ebp,esp对应也要还原

      此时堆栈图为:

      Windows逆向安全(一)之基础知识(一)

       

      继续看下一条指令

      00401063  |.  5D            pop ebp                                  ;  HelloWor.00401171

      Windows逆向安全(一)之基础知识(一)

       

      将ebp出栈,恢复现场,此时的堆栈图为

      Windows逆向安全(一)之基础知识(一)

      最后一句

      00401064  \.  C3            retn

      此时栈顶为

      Windows逆向安全(一)之基础知识(一)

      返回,相当于于pop eip

      执行后

      Windows逆向安全(一)之基础知识(一)

       

      执行后的堆栈图为

      Windows逆向安全(一)之基础知识(一)

       

      执行返回后

      此时返回到了

      Windows逆向安全(一)之基础知识(一)

       

      也就是之前call的下一句指

      00401171  |.  83C4 08       add esp,0x8

      Windows逆向安全(一)之基础知识(一)

       

      此时的堆栈图

      Windows逆向安全(一)之基础知识(一)

       

      我们可以发现此时的ESP和EBP又变回到了原本执行前的状态,(寄存器也一样),这就是所谓的堆栈平衡

      总结

      通过上面的分析,我们可以得出这段代码所处理的大致流程

      可分为三个部分:压入参数、调用CALL、CALL返回后

      压入参数

      压入参数部分十分简单,就是将调用CALL所需的参数压入堆栈,方便CALL内部执行时调用

      这里对应的语句为

      00401168  |.  6A 02         push 0x2
      0040116A  |.  6A 01         push 0x1

      即这个CALL得到的参数为2和1

      调用CALL

      调用CALL又可以分为六个部分:

      提升堆栈
      保护现场
      初始化提升的堆栈
      执行实际内容
      恢复现场
      返回

      提升堆栈
      对应语句为

      00401040  /> \55            push ebp
      00401041  |.  8BEC          mov ebp,esp
      00401043  |.  83EC 40       sub esp,0x40

      将堆栈提升了0x40

      保护现场

      对应语句为

      00401046  |.  53            push ebx
      00401047  |.  56            push esi
      00401048  |.  57            push edi

      将ebx、esi、edi三个通用寄存器保存到堆栈中,前面的push ebp其实也属于保护现场

      初始化提升的堆栈

      00401049  |.  8D7D C0       lea edi,dword ptr ss:[ebp-0x40]
      0040104C  |.  B9 10000000   mov ecx,0x10
      00401051  |.  B8 CCCCCCCC   mov eax,0xCCCCCCCC
      00401056  |.  F3:AB         rep stos dword ptr es:[edi]

      这里将我们提升的堆栈中的内容全部初始化为CCCCCCCC

      为什么是初始化为CC?防止缓冲溢出

      CC的硬编码对应的指令为int 3,即断点

      这么做有什么好处呢?当程序执行超过缓冲区时,遇到int 3就会自动停下来

      执行实际的内容

      对应语句为

      00401058  |.  8B45 08       mov eax,dword ptr ss:[ebp+0x8]
      0040105B  |.  0345 0C       add eax,dword ptr ss:[ebp+0xC]

      就是将前面压入的参数2和1进行相加得到3

      恢复现场
      对应语句为

      0040105E  |.  5F            pop edi                                  ;  HelloWor.00401171
      0040105F  |.  5E            pop esi                                  ;  HelloWor.00401171
      00401060  |.  5B            pop ebx                                  ;  HelloWor.00401171
      00401061  |.  8BE5          mov esp,ebp
      00401063  |.  5D            pop ebp                                  ;  HelloWor.00401171

      与前面保护现场相对应

      返回

      对应语句为

      00401064  \.  C3            retn

      CALL返回后
      对应语句为

      00401171  |.  83C4 08       add esp,0x8

      作用为平衡堆栈
      逆推C语言代码
      根据我们前面的分析,我们不难发现这其实就是个简单的加法函数

      int add(int x,int y){
          x=x+y;        //这里的x和y分别对应压入的参数
          return x;        //对应RETN 默认采用eax作为返回值的传递载体
      }

       

      版权声明:本文内容来自第三方投稿或授权转载,原文地址:https://blog.51cto.com/u_16179749/6632433,作者:私ははいしゃ敗者です,版权归原作者所有。本网站转在其作品的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如因作品内容、版权等问题需要同本网站联系,请发邮件至ctyunbbs@chinatelecom.cn沟通。

      上一篇:无线WiFi安全渗透与攻防(四)之kismet的使用

      下一篇:Windows逆向安全(一)之基础知识(二)

      相关文章

      2025-05-06 09:18:38

      【区块链的安全性】区块链的安全隐患与防护措施

      区块链技术以其去中心化、不可篡改和透明的特性被广泛应用于金融、供应链、医疗等多个领域。然而,尽管区块链提供了许多安全优势,它仍面临各种安全隐患和挑战。

      2025-05-06 09:18:38
      区块链 , 安全
      2025-04-09 09:16:00

      30天拿下Rust之unsafe代码

      在Rust语言的设计哲学中,"安全优先" 是其核心原则之一。然而,在追求极致性能或者与底层硬件进行交互等特定场景下,Rust提供了unsafe关键字。

      2025-04-09 09:16:00
      Rust , 代码 , 使用 , 内存 , 安全 , 指针
      2025-04-09 09:14:24

      有效提高java编程安全性的12条黄金法则

      有效提高java编程安全性的12条黄金法则

      2025-04-09 09:14:24
      Java , 代码 , 使用 , 安全 , 序列化 , 应用程序 , 规则
      2025-03-24 08:45:46

      windows中CMD快捷命令

      windows中CMD快捷命令

      2025-03-24 08:45:46
      windows , 打开 , 管理器
      2025-03-18 09:59:07

      Java 21的安全性增强与最佳实践:提升应用安全性的实用指南

      Java 21不仅在语言层面和JVM性能上进行优化,还在安全性方面做了很多增强。

      2025-03-18 09:59:07
      Java , 加密 , 安全 , 密钥 , 开发者 , 权限
      2025-03-10 09:50:08

      【后端开发】JavaEE初阶—线程安全问题与加锁原理(超详解)

      【后端开发】JavaEE初阶—线程安全问题与加锁原理(超详解)

      2025-03-10 09:50:08
      加锁 , 安全 , 小编 , 执行 , 线程
      2025-03-04 09:05:20

      Java中的线程安全的集合类(如果想知道Java中有关线程安全的集合类的知识,那么只看这一篇就足够了!)

      在多线程环境中,集合类的线程安全性是保证数据一致性和避免并发冲突的关键。Java 提供了多种线程安全集合类,它们在不同的并发场景中有着各自的优缺点。

      2025-03-04 09:05:20
      ArrayList , 多线程 , 安全 , 并发 , 线程
      2025-02-28 09:28:01

      Pytorch 学习(9):Python C 扩展( C、C++代码-----C so 代码库------python代码调用)

      Pytorch 学习(9):Python C 扩展( C、C++代码-----C so 代码库------python代码调用)

      2025-02-28 09:28:01
      bin , windows , 代码 , 版本
      2025-01-14 09:17:05

      Java竖线分割字符串问题

      Java竖线分割字符串问题

      2025-01-14 09:17:05
      https , Java , windows , 使用 , 分割 , 字符串 , 转义字符
      2025-01-08 08:39:44

      windows系统环境c++(c) socket编程实例代码(含服务端和客户端)

      本代码是windows系统环境c++(c) socket编程实例。包含客户端和服务端,可以实现客户端发送消息,服务端接收消息并写入日志。 server.cpp为服务端。

      2025-01-08 08:39:44
      client , cpp , server , socket , windows , 代码 , 客户端 , 服务端
      查看更多
      推荐标签

      作者介绍

      天翼云小翼
      天翼云用户

      文章

      33561

      阅读量

      5238432

      查看更多

      最新文章

      【区块链的安全性】区块链的安全隐患与防护措施

      2025-05-06 09:18:38

      windows中CMD快捷命令

      2025-03-24 08:45:46

      远程办公安全:共同守护数字时代的明日

      2024-12-23 09:17:13

      ADAudit Plus:提升企业安全的不可或缺的审计解决方案

      2024-12-23 09:17:13

      Log360,引入全新安全与风险管理功能,助力企业积极抵御网络威胁

      2024-12-20 07:51:29

      云原生学习笔记 - 云原生安全概述

      2024-12-16 09:20:33

      查看更多

      热门文章

      liux安全加固手册

      2024-06-28 06:18:27

      kubernets 【安全】-sysdig

      2023-03-23 06:16:59

      信息安全等级保护

      2023-06-25 07:13:26

      k8s学习笔记-安全认证

      2023-04-13 09:51:35

      windows刷新dns,查看文件md5值

      2023-03-24 10:33:05

      在Win10中、如何把常用的应用添加到高效工作窗口呢?

      2023-04-27 08:03:06

      查看更多

      热门标签

      linux java python javascript 数组 前端 docker Linux vue 函数 shell git 节点 容器 示例
      查看更多

      相关产品

      弹性云主机

      随时自助获取、弹性伸缩的云服务器资源

      天翼云电脑(公众版)

      便捷、安全、高效的云电脑服务

      对象存储

      高品质、低成本的云上存储服务

      云硬盘

      为云上计算资源提供持久性块存储

      查看更多

      随机文章

      windows 脚本 编写

      如何制作Win10启动U盘启动盘iso镜像文件

      Windows逆向安全(一)之基础知识(七)

      【Windows】通过注册表还原Windows 11经典右键菜单

      WPA破解-创建Hash-table加速并用Cowpatty破解

      Windows逆向安全(一)之基础知识(十)

      • 7*24小时售后
      • 无忧退款
      • 免费备案
      • 专家服务
      售前咨询热线
      400-810-9889转1
      关注天翼云
      • 旗舰店
      • 天翼云APP
      • 天翼云微信公众号
      服务与支持
      • 备案中心
      • 售前咨询
      • 智能客服
      • 自助服务
      • 工单管理
      • 客户公告
      • 涉诈举报
      账户管理
      • 管理中心
      • 订单管理
      • 余额管理
      • 发票管理
      • 充值汇款
      • 续费管理
      快速入口
      • 天翼云旗舰店
      • 文档中心
      • 最新活动
      • 免费试用
      • 信任中心
      • 天翼云学堂
      云网生态
      • 甄选商城
      • 渠道合作
      • 云市场合作
      了解天翼云
      • 关于天翼云
      • 天翼云APP
      • 服务案例
      • 新闻资讯
      • 联系我们
      热门产品
      • 云电脑
      • 弹性云主机
      • 云电脑政企版
      • 天翼云手机
      • 云数据库
      • 对象存储
      • 云硬盘
      • Web应用防火墙
      • 服务器安全卫士
      • CDN加速
      热门推荐
      • 云服务备份
      • 边缘安全加速平台
      • 全站加速
      • 安全加速
      • 云服务器
      • 云主机
      • 智能边缘云
      • 应用编排服务
      • 微服务引擎
      • 共享流量包
      更多推荐
      • web应用防火墙
      • 密钥管理
      • 等保咨询
      • 安全专区
      • 应用运维管理
      • 云日志服务
      • 文档数据库服务
      • 云搜索服务
      • 数据湖探索
      • 数据仓库服务
      友情链接
      • 中国电信集团
      • 189邮箱
      • 天翼企业云盘
      • 天翼云盘
      ©2025 天翼云科技有限公司版权所有 增值电信业务经营许可证A2.B1.B2-20090001
      公司地址:北京市东城区青龙胡同甲1号、3号2幢2层205-32室
      • 用户协议
      • 隐私政策
      • 个人信息保护
      • 法律声明
      备案 京公网安备11010802043424号 京ICP备 2021034386号