0x90
= NOP
= 1个字节0xE9
= JMP
= 5个字节0x8B
= MOV
= 2个字节0x55
= PUSH
= 1个字节0x6A
= PUSH
= 2个字节0x68
= PUSH
= 5个字节不确定它们是否正确。
我一直在使用这个很棒的列表来浏览指令及其操作码,但是它不包含每个操作码的完整长度/字节大小。在一开始就提到“一字节操作码”和“两字节操作码”。虽然
JMP
命令为5个字节(JMP
命令为1个字节,跳转距离为4个字节)。编辑
我本身并不需要一个列表。总的来说,我只是在寻找一种推断指令长度的方法。
#1 楼
除了使用列表之外,使用小型且可移植的长度反汇编程序(例如https://github.com/greenbender/lend)可能会更加有效。评论
现在这是我要追求的,因为它足够小以满足我的需要。
–瓦伦丁
16年4月16日在8:12
注意反汇编程序在GPLv3下,这使其在FLOSS领域之外的许多用途上显得笨拙。
– 0xC0000022L♦
16年4月16日在18:31
也只有x86 ...
–混杂
18年4月26日在13:53
#2 楼
毫无疑问,可以在英特尔手册中找到这些处理器的最终列表。这些可从英特尔网站免费下载。您最想或最想得到的是操作码映射。这一点非常重要,因此通常(如果不是始终)通常是《软件开发人员手册》,《程序员参考手册》中的附录A。操作码映射按第一个字节排序,并为您总结指令的继续方式。例如,在这里您会发现0x8B不仅是一个MOV,而且具体来说是一个字或dword(取决于操作数大小属性)从有效地址到通用寄存器的MOV,因此该操作数可以具有一个范围格式(其编码详细信息在另一个附录中),以使整个指令至少为2个字节,但可能长达7个字节(为mod r / m字节,可选的sib字节和可选的位移)。
至于一字节和两字节的操作码-如今甚至更长-这些仅指指令开始时必需的字节,这对于开始指令是必不可少的,但是对于操作数。最初,只有一个字节的操作码(除非我们将转义符计算为协处理器)。映射填满后,选择0x0F作为引入两个字节的操作码。例如,无论其操作数如何,SMSW指令始终从0x0F 0x01开始。 (总会有第三个字节,它将SMSW与其他以0x0F 0x01开头的指令区分开来,但是当您仔细阅读本手册时,我将其理解为练习。)
评论
您是否有该手册的永久链接,包括(可能包括)页码?
–瓦伦丁
16年4月15日在17:36
@Vallentin:这个怎么样?它们曾经以印刷版的形式提供。我还有两套。
– 0xC0000022L♦
16年4月18日在11:15
#3 楼
制作这样的列表是不可能的(取决于像8B这样的字节后面可能要长于2个字节)。我建议您使用反汇编库,因为几乎所有库都会计算长度,您可以从那里访问它。有一些字节以寄存器/数字作为唯一操作数,但是即使在这种情况下,前缀也可以更改其行为。评论
“做这样一个列表是不可能的”,那完全是错误的。如果无法推断出字节,那么我们将无法执行。
–瓦伦丁
16年4月13日在16:29
我的意思是不可能列出“ push is 2 bytes”。我是说您无法查找操作码来找到长度。
–Lupe
16年4月13日在19:16
那仍然是完全伪造的。如果语言不受固定规则约束。这样,将再次无法执行机器代码。
–瓦伦丁
16年4月13日在19:18
您是否认为您始终可以通过操作码确定指令的长度?我知道它受固定规则的约束;我写了一个反汇编程序作为一个项目。我认为您可能不理解我在说什么,或者我不理解他在问什么:我是说,如果您有操作码(例如8B),则无法可靠地确定全长。
–Lupe
16年4月13日在19:25
我大部分时间都使用ref.x86asm.net/coder32.html x64从首页进行链接
– Sigtran
16年4月14日在16:23
评论
有几个jmp操作码。这就是为什么您会有“短”跳转的原因,例如(+/- 127字节,IIRC)。而且这些不是5字节。同样,根据操作码,通常将操作码视为x字节,而不包含操作数。@ 0xC0000022L,但是它们都没有不同的操作码吗?如果不是,您如何区分它们?
确切地说,它们具有不同的二进制表示形式。但是它们都以助记符形式正式称为jmp。另外,您实际上是否需要一个列表,还是只需要一个库/框架即可正确解码操作码?
@ 0xC0000022L啊,是的,但是我正在分解机器代码,需要弄清楚指令的长度。
有可用于该目的的库。您确定需要手动执行此操作并且需要完整的列表吗?当然,拥有列表仍然很方便,但是坦率地说,为什么仍然要手动进行这样的分析。 RCE确实很乏味,不是吗?