我正在尝试学习X86汇编(用于学习逆向工程).我学习了C#和C\C++语言以及IL
可能我的主要问题是英语,因为我是波斯语,而且我也找不到任何有用的文件来学习用波斯语写的X86程序集.所以我决定做我为学习C#和C++所做的事情.我试过阅读X86样本和你好世界,但我失败了因为我无法理解我必须选择哪个注册表以及其他只能通过查看源代码无法解决的问题.
所以我决定改变策略并做一个挑战:写一个X86反汇编程序 我很生气,我知道.但我们不能说这是不可能的.第一个认为我需要理解(但没有记住)的是这些表:http://ref.x86asm.net/coder32.html
我对操作码很好,但我不明白如何计算操作数的大小或者寄存器十六进制字节呢?
对不起,我的英语不好.
PS.我想用C#做它
所以,既然这个话题似乎让你感兴趣,那么让我给你一个概述.x86指令最多包含五个部分,最长为15个字节:
prefixes opcode operand displacement immediate
Run Code Online (Sandbox Code Playgroud)
可以生成长度超过15个字节的编码,但CPU拒绝它们.除操作码之外的所有五个部分都是可选的.你可以找到他们的长度如下:
f0
lock,f2
repne,f3
repe,2e
cs,36
ss,3e
ds,26
es,64
fs,65
gs,66
操作数大小覆盖和67
地址大小覆盖.但是,只有一个的f0
,f2
,f3
只有一个26
,2e
,36
,3e
,64
,并65
在同一时间被认可.如果提供了来自每个组的多个前缀,则CPU的行为会有所不同.VEX和EVEX编码指令可能只有段覆盖和地址大小覆盖传统前缀,因为其他前缀包含在VEX和EVEX前缀下.40
to之一4f
.在其他模式中,这些字节是指令,而不是前缀,您的解码器必须考虑到这一点.与传统前缀一样,VEX或EVEX编码指令不能具有REX前缀.c4
并且c5
可以引入用于编码一些现代指令的VEX前缀.在长模式下,它们总是这样做,但在其他模式下,您必须事后检查字节:将其解释为modr/m字节,如果它对r,r
操作数对进行编码,则它是VEX前缀,否则为les
或者为操作码lds
.开头的VEX前缀c4
是两个字节长,有c5
三个字节.的VEX前缀还编码的0f
,0f 38
并且0f 3a
其以VEX编码的指令操作码省略前缀.请注意,通常,使用VEX前缀不是可选的.例如,pdep
被编码为VEX.NDS.LZ.F2.0F38.W0 F5 /r
(例如,c4 e2 7b f5 c0
用于pdep eax,eax,eax
)但相应的传统指令f2 0f 38 f5 r/m32
(例如,f2 0f 38 f5 c0
用于pdep eax,eax
)是无效的.请注意,相同的操作码可以与VEX前缀一起存在而且没有,这两者可能意味着不同的东西.例如,0f 77
是(emms
但)是.VEX.128.0F.WIG 77
c5 f8 77
vzeroupper
62
引入了EVEX前缀,用于编码AVX512指令.与VEX前缀类似,需要检查接下来的几个字节,以区分EVEX前缀和bound
指令.EVEX前缀总是四个字节长,并且像VEX前缀一样编码操作码的一部分.在前缀之后,操作码如下.最初,操作码总是一个单字节,但接着就跑出空位,所以现在要么单字节或前缀一个字节0f
,0f 38
或0f 3a
.如果指令是VEX编码,则不存在这些前缀.请注意,某些前缀可能会更改编码的指令.例如,操作码0f b8
是jmpe
(回车IA-64模式),但f3 0f b8
不repe jmpe
而是popcnt
.
操作码和前缀决定编码哪条指令.从这里开始,它几乎一帆风顺.根据指令,可能会跟随modr/m字节.根据modr/m字节和地址覆盖前缀,可以跟随一个sib字节和一个,两个或四个位移字节.最后,根据指令,操作数大小覆盖前缀和REX前缀,可以跟随一个,两个,四个,六个或八个立即字节.
这与我在Stack Overflow答案范围内给出的描述差不多.所以TL; DR:它真的很复杂.
归档时间: |
|
查看次数: |
980 次 |
最近记录: |