前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >高级静态分析技能基础:X86汇编语言运算指令说明

高级静态分析技能基础:X86汇编语言运算指令说明

作者头像
望月从良
发布2020-10-09 10:55:31
9610
发布2020-10-09 10:55:31
举报
文章被收录于专栏:Coding迪斯尼Coding迪斯尼

本节我们看看X86指令集以及X86的硬件体系架构。在汇编语言中最常见的指令就是mov,他将数据从一个地方转移到指定位置,该指令能将数据转移到特定位置的内存或是给定寄存器。mov指令的格式为(mov 目的,源头),源头指的是要被挪到的数据,目的是数据被挪动的目的地, 我们看几个具体例子: mov eax, ebx (把寄存器ebx中的数据拷贝到eax寄存器) mov eax, 0x42 (把数值0x42赋值给eax寄存器) mov eax, [0x4037c4](把地址为0x4037c4的4字节数据拷贝到eax寄存器] mov eax, [ebx] (先从寄存器ebx中获取数值,然后找到该数值对应的内存地址,接着再把地址所在处4字节数据赋值给寄存器eax) mov eax, [ebx + esi*4] (取出ebx中的数值,取出esi寄存器中的数值,将后者乘以4后加上前者,所得结果作为内存地址,并把给定地址的4字节数据拷贝到eax寄存器)

另一个跟mov指令很像的是指令lea,lea eax, [ebx+8],其作用为把ebx寄存器的值加上8后所得结果放入eax,这里需要注意区别,利润mov eax, [ebx+8]是把ebx的值加上8,所得结果作为内存地址,然后将地址所在处的4字节数据转移到eax寄存器,因此指令lea eax, [ebx+8]等价于mov eax, ebx+8,这是一个容易混淆之处,我们看下图会更清楚一些:

左边是寄存器的数值,右边是对应内存地址的数值。对于指令lea ebx, [eax5+5],它会计算0x00000005+5=5,然后把结果5放到寄存器ebx。lea指令主要用于加快计算速度,要不然我们完成给定计算需要使用很多条指令,例如先使用mul 5将eax里面的数值乘以5,然后add eax, 5,将5加到eax,然后mov ebx, eax,将eax中存储的数值挪动到ebx,因此不使用lea指令的话,我们需要使用4到5条指令才能达到相同效果。

x86指令集中有不少专门用于进行数值运算。从加减乘除到各种二进制操作,指令add用于执行加法操作,它的格式为:add destination, value 也就是把value对应的数值家到destination对应的数值上,后者可以是内存,也可以是特定寄存器。同理sub指令用于进行减法操作,特别要注意的是,该指令会修改两个重要的标志位寄存器,分别为ZF和CF,如果做减法后所得结果为0,ZF寄存器就好设置为1,如果sub destination ,value这条指令执行时,destination对应的数值小于value,那么CF寄存器就会设置为1,我们看几条运算指令的例子: sub eax, 0x10 把eax寄存器里面的数值减去0x10 add eax, ebx 把ebx寄存器里面的数值添加到eax寄存器 inc edx,将edx寄存器里面的数值增加1 dec ecx 将ecx寄存器里面的数值减少1

乘除法指令分别为mul, div,这两条指令的特点是指对应一个操作数,例如mul 5是指将eax寄存器中的数值乘以5,注意eax没有出现在指令中,对mul指令而言,它默认就是讲eax的数值乘以给定数值。所以在执行mul指令前,我们必须预先存储好eax指令中的数值。mul指令执行后所得结果会被当成一个64位数值分别存储在两个寄存器中,他们分别为edx和eax,edx存储高32位,eax存储低32位,假设执行mul指令后,所得结果为5,000,000,000,该数值早已超过32位,因此必须使用两个32位的寄存器共同存储,其存储结果如下:

div指令使用与mul一样,只是结果的存储正好相反。做完除法后所得结果为64位,那么除法的结果存储在eax,除法所得余数存储在edx,因此在执行mul或div指令时,需要预先存储好两个寄存器的数值,要不然指令执行后原来存储的数值会被冲刷掉。在高级语言编程中我们计算余数时,例如x = x%b,那么底层就好使用div指令,然后把寄存器edx中的数值转移到x变量对应的地址。

除了运算指令外,二进制操作指令也经常用到,例如or, and 和xor等。这些指令的用法与add,sub类似,xor指令在汇编中经常使用,它常用于清零,例如xor eax, eax就是把eax寄存器的数值设置为0,当然我们也可以使用mov eax, 0来清零,但是前者转换为机器码时只有2字节,后者需要5字节。

指令shr,shl用于进行挪位操作,例如shr destination, count把destination对应的数值向右移动count位,shl destination, count 把destination的值向左边挪动count位,挪动后空出来的比特位用0来补齐。例如 shr 1000, 1,执行后数值变为0100。指令ror和rol也用来挪动二进制比特位,于shr,shl不同的是,他们不是用0弥补而是把被挪走的比特位放到前面,例如ror 10101, 1执行后所得结果为11010.挪位指令通常对应对应高级语言的>>和<<操作符。在进行反汇编分析是时,如果我们看到一系列shr, shl, ror,rol等指令,这意味着代码极有可能在进行加解密操作。

最后一条操作符指令就是NOP,它什么都不做,这条指令经常用于进行缓冲区溢出攻击,这条指令的作用在后续章节中会详细讲解。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-09-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Coding迪斯尼 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
对象存储
对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档