硬编码基础二(跳转相关)
今天的指令都是跟eip的变动有关
JCC短跳系列跳转
这一系列是条件跳转指令也都是两字节定长,第一个字节是opcode也是跳转条件后一个字节是有符号的偏移长度,当条件成立时会跳转到当前eip + 2 + 操作数的位置
70~7f是二字节jcc指令
JCC系列跳转
这一系列是6字节定长的跳转指令,与前面的短跳系列不同的地方就是他的操作数是4字节长度这就意味着他的可跳转范围变大了
操作码是0f80~0f8f,是二字节的操作码后面跟着4字节的操作数
loop相关(2字节)
loop指令是循环指令在执行跳转前会执行ecx–,然后根据ecx(可能还有zf标志位)来判断是否跳转,且loop都为短跳转,毕竟一个循环也不太可能超出一个字节的偏移
loop指令包括了:
- loop
- loopne
- loope
loopne : e0 ib
loope : e1 ib
loop :e2 ib
ib的意思是立即数长度为byte
这边loopz和loope是一个意思,其他两个也一样
段内jmp相关
jmp包括了
- jmp,近距离无条件跳转指令
- jecxz/jecxz,顾名思义就是rcx或者ecx为0 的时候跳转
- jmp short ,短距离跳转
jmp:e9 id (5字节)
jecxz:e3 ib (2字节)
jmp short : eb ib(2字节)
段内call/ret
call是调用指令,他会执行push eip然后在跳转(段内跳转的情况下只push eip,出段就会在push个cs)
call的操作码紧跟jmp
call: e8 id
ret指令是返回指令,他会pop eip的方式回退到之前的位置
ret : c3
retn: c2 iw 这是多了一步esp = esp + iw一般是stdcall的调用时候会有这种指令
跨段跳转相关
首先要了解在32位的Intelcpu下段寄存器的主要目的已经不是为了寻址,主要是用来做权限检查也就是保护模式的跨段权限检查
它包括了16位的可见段选择子描述和80位的不可见部分(根据一些书上说的这80位是记录了权限相关内容不过具体的我也不清楚)
八个段寄存器包括(顺序也很重要):
- es
- cs
- ss
- ds
- fs
- gs
- ldtr
- tr
jmp far : ea ap(6字节,2字节的段标识和4字节的偏移)
这里的位置就是段选择子所对应的段描述符的基地址 + 后四个字节的偏移
(段选择子的相关内容可以看我之前的段权限校验测试那篇文章,这里可以认为选择子就是一个表的偏移和rpl也就是请求权限级别的组合)
ret far : cb 这个ret会出栈八个字节其中四个是eip还有四个是字节其中2位是cs还有两位会追加到esp上
retfarn : ca iw