前言

ModR/M字段是用来进行内存寻址的,可当地址形如DS:[EAX + ECX*2 + 12345678]时,仅仅靠ModR/M字段,是描述不出来的。

这时就在ModR/M后面增加一个SIB字节,与ModR/M字段共同描述。

上一节说到opcode决定了是否有ModR/M字段,而opcode和ModR/M字段一起决定了SIB字段

可以看到再ModR/M后面,SIB这个值是否有取决于ModR/M的具体取值,其实就是上一节说的esp那个位置,ModR/M是空出来

SIB结构

首字母命名Scale Index Base   SIB

SIB的描述方式为

Base + Index*2**Scale (Scale描述2Scale,所以只能为 *1 *2 *4 *8)

SIB图表

1、当Index = 100 时,Index被0替代,此时只有Base有效

2、当Base = 101 时,Base被0替代,此时只用Index有效

具体解析

0x89 2C 14

先看opcode 0x89

说明基本格式是MOV Ev, Gv : Gv与我当前的x32dedug决定了是32位的通用寄存器,具体是哪一个通用寄存器还要看ModR/M的3,4,5部分

ModR/M字段展开

00 101 100

5号寄存器

现在可以确定是 mov dword ptr ds:[xxxx],EBP

然后Mod R/M是00 100 决定了改指令有SIB字段

看SIB字段

00 010 100

对应的是S I B

用Base + Index*2**Scale这个公式

B:100   对应的是ESP

I:010 以及B:00  对应是EDX

整个下来是mov dword ptr ss:[ESP+EDX],EBP

这里为什么没有偏移呢,这个值还是由ModR/M字段说明,可以看到Mod为00,没有偏移,如果Mod为01或者10 ,后面依旧要更上1个字节的偏移或4个字节的偏移,这里不明白可以看上一节ModR/M的那张表

0x 89 AC 15

先看opcode 0x89

说明基本格式是MOV Ev, Gv : Gv与我当前的x32dedug决定了是32位的通用寄存器,具体是哪一个通用寄存器还要看ModR/M的3,4,5部分

ModR/M字段展开

10 101 100

5号寄存器

现在可以确定是 mov dword ptr ds:[xxxx],EBP

然后Mod R/M是10 100 决定了改指令有SIB字段

看SIB字段

00 010 101

对应的是S I B

用Base + Index*2**Scale这个公式

B:100   对应的是EBP

I:010 以及B:00  对应是EDX

整个下来是mov dword ptr ss:[EBP+EDX+一个dword偏移],EBP

这里为什么又有偏移:

经典变长指令SIB的更多相关文章

  1. 经典变长指令ModR/M

    变长指令 不是所有的指令都是,看到opcode就知道有多长(定长指令),当指令中出现内存操作对象的时候,就需要在操作码后面附加一个字节来进行补充说明,这个字节被称为ModR/M. 该字节的8个位被分成 ...

  2. 经典变长指令-ModRM

    一.如何计算ModRM 0X88 MOV Eb,Gb G:通用寄存器 0X89 MOV Ev,Gv E:寄存器/内存 0X8A MOV Gb,Eb b:字节 0X8B MOV Gv,Ev v:Word ...

  3. 经典变长指令-RegOpcode

    一.回顾Mod/M结构 Intel 64 and IA-32 Architectures Instruction Format ModR/M结构图 Mod与R/M共同描述E的意义(内存或者通用寄存器) ...

  4. 经典定长指令-修改EIP

    1.0x70~0x7F EIP无法像通用寄存器那样用mov来修改,只能通过类似于jz,JNB,JNE JBE,call等的跳转指令来进行修改 条件跳转,后跟一个字节立即数的偏移(有符号),共两个字节. ...

  5. C++中的变长参数

    新参与的项目中,为了使用共享内存和自定义内存池,我们自己定义了MemNew函数,且在函数内部对于非pod类型自动执行构造函数.在需要的地方调用自定义的MemNew函数.这样就带来一个问题,使用stl的 ...

  6. C++内存分配及变长数组的动态分配

    //------------------------------------------------------------------------------------------------ 第 ...

  7. (一)预定义宏、__func__、_Pragma、变长参数宏定义以及__VA_ARGS__

    作为第一篇,首先要说一下C++11与C99的兼容性. C++11将 对以下这些C99特性的支持 都纳入新标准中: 1) C99中的预定义宏 2) __func__预定义标识符 3) _Pragma操作 ...

  8. CSAPP阅读笔记-变长栈帧,缓冲区溢出攻击-来自第三章3.10的笔记-P192-P204

    一.几个关于指针的小知识点: 1.  malloc是在堆上动态分配内存,返回的是void *,使用时会配合显式/隐式类型转换,用完后需要用free手动释放. alloca是标准库函数,可以在栈上分配任 ...

  9. Scala 变长参数

    如果Scala定义变长参数 def sum(i Int*), 那么调用sum时,可以直接输入sum(1,2,3,4,5) 但是不可以sum(1 to 5) 必须要将1 to 5 强制为seq sum( ...

随机推荐

  1. py pandas

    import pandas as pd class Main(): def __init__(self): # 读取excel self.df = pd.read_excel("C:\\Us ...

  2. js 检测浏览器开发者控制台是否被打开

    var element = new Image(); Object.defineProperty(element, "id", { get: function () { debug ...

  3. dynamic creat svg in js

    dynamic creat svg in js SVG title https://developer.mozilla.org/en-US/docs/Web/SVG/Element/title < ...

  4. ffmpeg concat设置绝对路径

    https://superuser.com/questions/718027/ffmpeg-concat-doesnt-work-with-absolute-path/1551017#1551017 ...

  5. C++算法代码——统计数字

    题目来自:http://218.5.5.242:9018/JudgeOnline/problem.php?id=1109 题目描述 某次科研调查时得到了n个自然数,每个数均不超过1500000000( ...

  6. uni-app小白入门自学笔记(二)

    码文不易啊,转载请带上本文链接呀,感谢感谢 https://www.cnblogs.com/echoyya/p/14429616.html 目录 码文不易啊,转载请带上本文链接呀,感谢感谢 https ...

  7. net面试总结的题目

    准备的面试题目. 1.private.protected.public.internal的访问权限? private : 私有成员,在类的内部才可以访问. protected :保护成员,该类内部和继 ...

  8. eclipse从接口快速跳转到实现类

    1.只跳转到实现类上 按住Ctrl键,把鼠标的光标放在要跳转的接口上面,选择第二个 2.直接跳转大实现的方法上 按住Ctrl键,把鼠标的光标放在要跳转的方法上面,选择第二个 对比可以发现,操作都是一样 ...

  9. 换人!golang面试官:连怎么避免内存逃逸都不知道?

    问题 怎么避免内存逃逸? 怎么答 在runtime/stubs.go:133有个函数叫noescape.noescape可以在逃逸分析中隐藏一个指针.让这个指针在逃逸分析中不会被检测为逃逸. // n ...

  10. Python爬虫系统学习(1)

    Python爬虫系统化学习(1) 前言:爬虫的学习对生活中很多事情都很有帮助,比如买房的时候爬取房价,爬取影评之类的,学习爬虫也是在提升对Python的掌握,所以我准备用2-3周的晚上时间,提升自己对 ...