-
MIPS二进制指令集格式参考
2012-12-26 09:23:40MIPS二进制指令集格式参考。里面详细列举了MIPS指令集的各条指令,以及对应的二进制格式。 -
用户态直接执行仅包含二进制指令的文件
2019-04-27 12:31:46经理的皮鞋湿了,但是却没有变胖,所以经理的皮鞋是...展示了一个直接执行二进制指令文件的基本方案,基于Linux内核来执行。 值得一提的是,这不是什么特别有技术含量的东西,这只是一个基本功,我在2006年的长春...经理的皮鞋湿了,但是却没有变胖,所以经理的皮鞋是人造革的。
刚刚写了一篇文章:
不依赖OS编译器,不依赖库,用汇编/机器码直接编程: https://blog.csdn.net/dog250/article/details/89500153展示了一个直接执行二进制指令文件的基本方案,基于Linux内核来执行。
值得一提的是,这不是什么特别有技术含量的东西,这只是一个基本功,我在2006年的长春吉林大学边上租住的房子里就玩过此法。那时是用VC 6。
大公司的程序员不会屑于写我这些淫巧,即便他们也不一定会,也不一定懂,他们只是太关注业务,也许是真的没时间,也许真的就是不屑,觉得这太简单。但是,我的意思就是,这些东西真的太简单,如果你不懂,那真的不是一个合格的程序员。
本文写一个 解释器 ,载入一个仅包含二进制指令的文件,然后执行,这非常简单。
有两种方法可以简单的改变程序的执行流:
- 通过替换函数调用的返回地址。
这是call指令提供的功能,call指令执行时,会将下一条指令压栈,我们只需要在栈里找到这个位置,将其替换为自己的指令即可。 - 直接通过内联汇编调用jmp指令执行自己的指令。
这个非常直接,超级简单。
首先看第一个方法,代码如下:
#include <stdio.h> #include <stdlib.h> #include <sys/mman.h> // 我们想直接执行这段指令,当然,它保存于某个文件,可以从文件里读出到code内存空间。 // char nop[] = {0x48, 0xc7, 0xc0, 0x3c, 0x00, 0x00, 0x00, 0x48, 0x31, 0xff, 0x0f, 0x05}; unsigned char *code; void exec() { unsigned long a, *p; // 替换返回地址,使得exec返回的时候,跳转到我们的代码。 p = (void*)((long)&a + 24); *p = (unsigned long)code; } int main(int argc, char **argv) { FILE *fp = NULL; fp = fopen(argv[1], "r"); // 映射地址空间 code = (unsigned char*)mmap(0, 1024, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_PRIVATE, 0, 0); //memcpy(code, nop, sizeof(nop)); // 将指令文件内容读取到code指示的地址空间。 fread(code, 1024, 1, fp); // 执行之 exec(); printf("end\n"); }
接下来看看直接jmp的方式,依然是一个很简单的代码:
#include <stdio.h> #include <stdlib.h> #include <sys/mman.h> // 我们想直接执行这段指令,当然,它保存于某个文件,可以从文件里读出到code内存空间。 //char nop[] = {0x48, 0xc7, 0xc0, 0x3c, 0x00, 0x00, 0x00, 0x48, 0x31, 0xff, 0x0f, 0x05}; unsigned char *code; int main(int argc, char **argv) { FILE *fp = NULL; fp = fopen(argv[1], "r"); code = (unsigned char*)mmap(0, 1024, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_PRIVATE, 0, 0); // memcpy(code, nop, sizeof(nop)); fread(code, 1024, 1, fp); asm ( "jmp %0" : :"r"(code) :); printf("end\n"); }
将上述的代码编译成一个比如a.out的程序,将一个二进制指令文件作为参数执行之,就会看到效果了。
我来准备一个二进制指令文件,以fork炸弹为例:
.global _start _start: mov $57, %rax # fork 炸弹 syscall jmp _start
照常编译:
[root@localhost ~]# as --64 -o forkbomb.o forkbomb.s [root@localhost myflat]# ld -melf_x86_64 -o forkbomb forkbomb.o --oformat=binary
然后将这个forkbomb作为参数执行a.out,试试看。
值得注意的是,以上的例子中,我没有为指令文件里的指令分配独立的stack空间,而是借用了a.out主进程的stack空间,所有的pop,push等指令,都会操作a.out主进程的stack。
其实,更优雅的方案是,单独分配一个新的stack空间,切过去,皮鞋就干了。
有人会说这样做没有内核方案直接。确实是的,毕竟我们无法直接在bash的命令提示符里输入forkbomb那般执行,但是想达到这个效果,这也不难啊。
你在命令提示符里输入的任何程序都是通过bash来执行的,我们把上述的a.out整个儿给塞进bash中不就OK了吗?在bash开始fork/exec新进程的时候,自己完成mmap,memcpy的事情,然后要么通过替换函数返回地址后主动return,要么直接内联汇编里jmp,不就OK了么。
非常简单!
请注意,埃里克.雷蒙德有枪!
皮鞋湿,不会胖!但是经理的皮鞋除外。埃里克.雷蒙德也不懂皮鞋,毕竟,第一次穿。 - 通过替换函数调用的返回地址。
-
Java二进制指令代码解析
2014-01-22 10:06:56小注:去年在看《深入解析JVM》书的时候做的一些记录,同时参考了《Java虚拟机规范》。只是对指令的一些列举,...Java二进制指令代码解析 Java源码在运行之前都要编译成为字节码格式(如.class文件),然后由C转自:http://www.blogjava.net/DLevin/archive/2011/09/13/358497.html
小注:去年在看《深入解析JVM》书的时候做的一些记录,同时参考了《Java虚拟机规范》。只是对指令的一些列举,加入了一些自己的理解。可以用来查询。
Java二进制指令代码解析
Java源码在运行之前都要编译成为字节码格式(如.class文件),然后由ClassLoader将字节码载入运行。在字节码文件中,指令代码只是其中的一部分,里面还记录了字节码文件的编译版本、常量池、访问权限、所有成员变量和成员方法等信息(详见Java字节码格式详解)。本文主要简单介绍不同Java指令的功能以及在代码中如何解析二进制指令。
Java指令是基于栈的体系结构,大部分的指令默认的操作数在栈中。映像中ARM是基于寄存器的操作指令,而x86好像是混合寄存器和存储器的,发现基于栈的操作指令确实简单,学起来很快。不过不知道这种操作的效率怎么样,以我自己的推测应该是不太好的。对这方面不太了解,随便扯几句。
Java总共有200多条指令,不过很多都是重复的。我的理解,网络是Java一个非常重要的特性,而且Java在设计之初就认为字节码是要在网络中传输的,为了减少网络传输流量,字节码就要尽量设计精简、紧凑。因而Java增加了很多重复指令,比如尽量减少操作数,因而我们会发现Java的很多指令都是没有操作数的;并且指令中的操作数基本上都是当无法将值放到栈中的数据,比如局部变量的索引号和常量池中的索引号。
还有一点需要注意的是,在运行过程中,所有boolean、byte、char、short都是以int类型值存在,因而对这些类型的指令操作很少。然而好像sun实现的虚拟机中。这些类型的数组据说不是以int类型的形式保存的,这个很奇怪。我的理解,以字对齐方式的操作效率会比较高,因而做了这种转换,以空间换时间。
Java指令集(按功能分类)
常量入栈指令
操作码(助记符)
操作数
描述(栈指操作数栈)
aconst_null
null值入栈。
iconst_m1
-1(int)值入栈。
iconst_0
0(int)值入栈。
iconst_1
1(int)值入栈。
iconst_2
2(int)值入栈。
iconst_3
3(int)值入栈。
iconst_4
4(int)值入栈。
iconst_5
5(int)值入栈。
lconst_0
0(long)值入栈。
lconst_1
1(long)值入栈。
fconst_0
0(float)值入栈。
fconst_1
1(float)值入栈。
fconst_2
2(float)值入栈。
dconst_0
0(double)值入栈。
dconst_1
1(double)值入栈。
bipush
valuebyte
valuebyte值带符号扩展成int值入栈。
sipush
valuebyte1
valuebyte2
(valuebyte1 << 8) | valuebyte2 值带符号扩展成int值入栈。
ldc
indexbyte1
常量池中的常量值(int, float, string reference, object reference)入栈。
ldc_w
indexbyte1
indexbyte2
常量池中常量(int, float, string reference, object reference)入栈。
ldc2_w
indexbyte1
indexbyte2
常量池中常量(long, double)入栈。
局部变量值转载到栈中指令
操作码(助记符)
操作数
描述(栈指操作数栈)
(wide)aload
indexbyte
从局部变量indexbyte中装载引用类型值入栈。
aload_0
从局部变量0中装载引用类型值入栈。
aload_1
从局部变量1中装载引用类型值入栈。
aload_2
从局部变量2中装载引用类型值入栈。
aload_3
从局部变量3中装载引用类型值入栈。
(wide)iload
indexbyte
从局部变量indexbyte中装载int类型值入栈。
iload_0
从局部变量0中装载int类型值入栈。
iload_1
从局部变量1中装载int类型值入栈。
iload_2
从局部变量2中装载int类型值入栈。
iload_3
从局部变量3中装载int类型值入栈。
(wide)lload
indexbyte
从局部变量indexbyte中装载long类型值入栈。
lload_0
从局部变量0中装载int类型值入栈。
lload_1
从局部变量1中装载int类型值入栈。
lload_2
从局部变量2中装载int类型值入栈。
lload_3
从局部变量3中装载int类型值入栈。
(wide)fload
indexbyte
从局部变量indexbyte中装载float类型值入栈。
fload_0
从局部变量0中装载float类型值入栈。
fload_1
从局部变量1中装载float类型值入栈。
fload_2
从局部变量2中装载float类型值入栈。
fload_3
从局部变量3中装载float类型值入栈。
(wide)dload
indexbyte
从局部变量indexbyte中装载double类型值入栈。
dload_0
从局部变量0中装载double类型值入栈。
dload_1
从局部变量1中装载double类型值入栈。
dload_2
从局部变量2中装载double类型值入栈。
dload_3
从局部变量3中装载double类型值入栈。
aaload
从引用类型数组中装载指定项的值。
iaload
从int类型数组中装载指定项的值。
laload
从long类型数组中装载指定项的值。
faload
从float类型数组中装载指定项的值。
daload
从double类型数组中装载指定项的值。
baload
从boolean类型数组或byte类型数组中装载指定项的值(先转换为int类型值,后压栈)。
caload
从char类型数组中装载指定项的值(先转换为int类型值,后压栈)。
saload
从short类型数组中装载指定项的值(先转换为int类型值,后压栈)。
将栈顶值保存到局部变量中指令
操作码(助记符)
操作数
描述(栈指操作数栈)
(wide)astore
indexbyte
将栈顶引用类型值保存到局部变量indexbyte中。
astroe_0
将栈顶引用类型值保存到局部变量0中。
astore_1
将栈顶引用类型值保存到局部变量1中。
astore_2
将栈顶引用类型值保存到局部变量2中。
astore_3
将栈顶引用类型值保存到局部变量3中。
(wide)istore
indexbyte
将栈顶int类型值保存到局部变量indexbyte中。
istore_0
将栈顶int类型值保存到局部变量0中。
istore_1
将栈顶int类型值保存到局部变量1中。
istore_2
将栈顶int类型值保存到局部变量2中。
istore_3
将栈顶int类型值保存到局部变量3中。
(wide)lstore
indexbyte
将栈顶long类型值保存到局部变量indexbyte中。
lstore_0
将栈顶long类型值保存到局部变量0中。
lstore_1
将栈顶long类型值保存到局部变量1中。
lstore_2
将栈顶long类型值保存到局部变量2中。
lstroe_3
将栈顶long类型值保存到局部变量3中。
(wide)fstore
indexbyte
将栈顶float类型值保存到局部变量indexbyte中。
fstore_0
将栈顶float类型值保存到局部变量0中。
fstore_1
将栈顶float类型值保存到局部变量1中。
fstore_2
将栈顶float类型值保存到局部变量2中。
fstore_3
将栈顶float类型值保存到局部变量3中。
(wide)dstore
indexbyte
将栈顶double类型值保存到局部变量indexbyte中。
dstore_0
将栈顶double类型值保存到局部变量0中。
dstore_1
将栈顶double类型值保存到局部变量1中。
dstore_2
将栈顶double类型值保存到局部变量2中。
dstore_3
将栈顶double类型值保存到局部变量3中。
aastore
将栈顶引用类型值保存到指定引用类型数组的指定项。
iastore
将栈顶int类型值保存到指定int类型数组的指定项。
lastore
将栈顶long类型值保存到指定long类型数组的指定项。
fastore
将栈顶float类型值保存到指定float类型数组的指定项。
dastore
将栈顶double类型值保存到指定double类型数组的指定项。
bastroe
将栈顶boolean类型值或byte类型值保存到指定boolean类型数组或byte类型数组的指定项。
castore
将栈顶char类型值保存到指定char类型数组的指定项。
sastore
将栈顶short类型值保存到指定short类型数组的指定项。
wide指令
操作码(助记符)
操作数
描述(栈指操作数栈)
wide
使用附加字节扩展局部变量索引(iinc指令特殊)。
通用(无类型)栈操作指令
操作码(助记符)
操作数
描述(栈指操作数栈)
nop
空操作。
pop
从栈顶弹出一个字长的数据。
pop2
从栈顶弹出两个字长的数据。
dup
复制栈顶一个字长的数据,将复制后的数据压栈。
dup_x1
复制栈顶一个字长的数据,弹出栈顶两个字长数据,先将复制后的数据压栈,再将弹出的两个字长数据压栈。
dup_x2
复制栈顶一个字长的数据,弹出栈顶三个字长的数据,将复制后的数据压栈,再将弹出的三个字长的数据压栈。
dup2
复制栈顶两个字长的数据,将复制后的两个字长的数据压栈。
dup2_x1
复制栈顶两个字长的数据,弹出栈顶三个字长的数据,将复制后的两个字长的数据压栈,再将弹出的三个字长的数据压栈。
dup2_x2
复制栈顶两个字长的数据,弹出栈顶四个字长的数据,将复制后的两个字长的数据压栈,再将弹出的四个字长的数据压栈。
swap
交换栈顶两个字长的数据的位置。Java指令中没有提供以两个字长为单位的交换指令。
类型转换指令
操作码(助记符)
操作数
描述(栈指操作数栈)
i2f
将栈顶int类型值转换为float类型值。
i2l
将栈顶int类型值转换为long类型值。
i2d
将栈顶int类型值转换为double类型值。
f2i
将栈顶float类型值转换为int类型值。
f2l
将栈顶float类型值转换为long类型值。
f2d
将栈顶float类型值转换为double类型值。
l2i
将栈顶long类型值转换为int类型值。
l2f
将栈顶long类型值转换为float类型值。
l2d
将栈顶long类型值转换double类型值。
d2i
将栈顶double类型值转换为int类型值。
d2f
将栈顶double类型值转换为float类型值。
d2l
将栈顶double类型值转换为long类型值。
i2b
将栈顶int类型值截断成byte类型,后带符号扩展成int类型值入栈。
i2c
将栈顶int类型值截断成char类型值,后带符号扩展成int类型值入栈。
i2s
将栈顶int类型值截断成short类型值,后带符号扩展成int类型值入栈。
整数运算
操作码(助记符)
操作数
描述(栈指操作数栈)
iadd
将栈顶两int类型数相加,结果入栈。
isub
将栈顶两int类型数相减,结果入栈。
imul
将栈顶两int类型数相乘,结果入栈。
idiv
将栈顶两int类型数相除,结果入栈。
irem
将栈顶两int类型数取模,结果入栈。
ineg
将栈顶int类型值取负,结果入栈。
ladd
将栈顶两long类型数相加,结果入栈。
lsub
将栈顶两long类型数相减,结果入栈。
lmul
将栈顶两long类型数相乘,结果入栈。
ldiv
将栈顶两long类型数相除,结果入栈。
lrem
将栈顶两long类型数取模,结果入栈。
lneg
将栈顶long类型值取负,结果入栈。
(wide)iinc
indexbyte
constbyte
将整数值constbyte加到indexbyte指定的int类型的局部变量中。
浮点运算
操作码(助记符)
操作数
描述(栈指操作数栈)
fadd
将栈顶两float类型数相加,结果入栈。
fsub
将栈顶两float类型数相减,结果入栈。
fmul
将栈顶两float类型数相乘,结果入栈。
fdiv
将栈顶两float类型数相除,结果入栈。
frem
将栈顶两float类型数取模,结果入栈。
fneg
将栈顶float类型值取反,结果入栈。
dadd
将栈顶两double类型数相加,结果入栈。
dsub
将栈顶两double类型数相减,结果入栈。
dmul
将栈顶两double类型数相乘,结果入栈。
ddiv
将栈顶两double类型数相除,结果入栈。
drem
将栈顶两double类型数取模,结果入栈。
dneg
将栈顶double类型值取负,结果入栈。
逻辑运算——移位运算
操作码(助记符)
操作数
描述(栈指操作数栈)
ishl
左移int类型值。
lshl
左移long类型值。
ishr
算术右移int类型值。
lshr
算术右移long类型值。
iushr
逻辑右移int类型值。
lushr
逻辑右移long类型值。
逻辑运算——按位布尔运算
操作码(助记符)
操作数
描述(栈指操作数栈)
iand
对int类型按位与运算。
land
对long类型的按位与运算。
ior
对int类型的按位或运算。
lor
对long类型的按位或运算。
ixor
对int类型的按位异或运算。
lxor
对long类型的按位异或运算。
控制流指令——条件跳转指令
操作码(助记符)
操作数
描述(栈指操作数栈)
ifeq
branchbyte1
branchbyte2
若栈顶int类型值为0则跳转。
ifne
branchbyte1
branchbyte2
若栈顶int类型值不为0则跳转。
iflt
branchbyte1
branchbyte2
若栈顶int类型值小于0则跳转。
ifle
branchbyte1
branchbyte2
若栈顶int类型值小于等于0则跳转。
ifgt
branchbyte1
branchbyte2
若栈顶int类型值大于0则跳转。
ifge
branchbyte1
branchbyte2
若栈顶int类型值大于等于0则跳转。
if_icmpeq
branchbyte1
branchbyte2
若栈顶两int类型值相等则跳转。
if_icmpne
branchbyte1
branchbyte2
若栈顶两int类型值不相等则跳转。
if_icmplt
branchbyte1
branchbyte2
若栈顶两int类型值前小于后则跳转。
if_icmple
branchbyte1
branchbyte2
若栈顶两int类型值前小于等于后则跳转。
if_icmpgt
branchbyte1
branchbyte2
若栈顶两int类型值前大于后则跳转。
if_icmpge
branchbyte1
branchbyte2
若栈顶两int类型值前大于等于后则跳转。
ifnull
branchbyte1
branchbyte2
若栈顶引用值为null则跳转。
ifnonnull
branchbyte1
branchbyte2
若栈顶引用值不为null则跳转。
if_acmpeq
branchbyte1
branchbyte2
若栈顶两引用类型值相等则跳转。
if_acmpne
branchbyte1
branchbyte2
若栈顶两引用类型值不相等则跳转。
控制流指令——比较指令
操作码(助记符)
操作数
描述(栈指操作数栈)
lcmp
比较栈顶两long类型值,前者大,1入栈;相等,0入栈;后者大,-1入栈。
fcmpl
比较栈顶两float类型值,前者大,1入栈;相等,0入栈;后者大,-1入栈;有NaN存在,-1入栈。
fcmpg
比较栈顶两float类型值,前者大,1入栈;相等,0入栈;后者大,-1入栈;有NaN存在,-1入栈。
dcmpl
比较栈顶两double类型值,前者大,1入栈;相等,0入栈;后者大,-1入栈;有NaN存在,-1入栈。
dcmpg
比较栈顶两double类型值,前者大,1入栈;相等,0入栈;后者大,-1入栈;有NaN存在,-1入栈。
控制流指令——无条件跳转指令
操作码(助记符)
操作数
描述(栈指操作数栈)
goto
branchbyte1
branchbyte2
无条件跳转到指定位置。
goto_w
branchbyte1
branchbyte2
branchbyte3
branchbyte4
无条件跳转到指定位置(宽索引)。
控制流指令——表跳转指令
操作码(助记符)
操作数
描述(栈指操作数栈)
tableswitch
<0-3bytepad>
defaultbyte1
defaultbyte2
defaultbyte3
defaultbyte4
lowbyte1
lowbyte2
lowbyte3
lowbyte4
highbyte1
highbyte2
highbyte3
highbyte4
jump offsets...
通过索引访问跳转表,并跳转。
lookupswitch
<0-3bytepad>
defaultbyte1
defaultbyte2
defaultbyte3
defaultbyte4
npairs1
npairs2
npairs3
npairs4
match offsets
通过键值访问跳转表,并跳转。
控制流指令——异常和finally
操作码(助记符)
操作数
描述(栈指操作数栈)
athrow
抛出异常。
jsr
branchbyte1
branchbyte2
跳转到子例程序。
jsr_w
branchbyte1
branchbyte2
branchbyte3
branchbyte4
跳转到子例程序(宽索引)。
(wide)ret
indexbyte
返回子例程序。
对象操作指令
操作码(助记符)
操作数
描述(栈指操作数栈)
new
indexbyte1
indexbyte2
创建新的对象实例。
checkcast
indexbyte1
indexbyte
类型强转。
instanceof
indexbyte1
indexbyte2
判断类型。
getfield
indexbyte1
indexbyte2
获取对象字段的值。
putfield
indexbyte1
indexbyte2
给对象字段赋值。
getstatic
indexbyte1
indexbyte2
获取静态字段的值。
putstatic
indexbyte1
indexbyte2
给静态字段赋值。
数组操作指令
操作码(助记符)
操作数
描述(栈指操作数栈)
newarray
atype
创建type类型的数组。
anewarray
indexbyte1
indexbyte2
创建引用类型的数组。
arraylength
获取一维数组的长度。
multianewarray
indexbyte1
indexbyte2
dimension
创建dimension维度的数组。
方法调用指令
操作码(助记符)
操作数
描述(栈指操作数栈)
invokespecial
indexbyte1
indexbyte2
编译时方法绑定调用方法。
invokevirtual
indexbyte1
indexbyte2
运行时方法绑定调用方法。
invokestatic
indexbyte1
indexbyte2
调用静态方法。
invokeinterface
indexbyte1
indexbyte2
count
0
调用接口方法。
方法返回指令
操作码(助记符)
操作数
描述(栈指操作数栈)
ireturn
返回int类型值。
lreturn
返回long类型值。
freturn
返回float类型值。
dreturn
返回double类型值。
areturn
返回引用类型值。
return
void函数返回。
线程同步指令
操作码(助记符)
操作数
描述(栈指操作数栈)
monitorenter
进入并获得对象监视器。
monitorexit
释放并退出对象监视器。
参考《深入解析JVM》 2010年10月6日
-
Java二进制指令代码大全
2019-02-26 22:03:45Java指令集(按功能分类) 常量入栈指令 操作码(助记符) 操作数 描述(栈指操作数栈) aconst_null null值入栈。 iconst_m1 ...Java指令集(按功能分类)
常量入栈指令
操作码(助记符)
操作数
描述(栈指操作数栈)
aconst_null
null值入栈。
iconst_m1
-1(int)值入栈。
iconst_0
0(int)值入栈。
iconst_1
1(int)值入栈。
iconst_2
2(int)值入栈。
iconst_3
3(int)值入栈。
iconst_4
4(int)值入栈。
iconst_5
5(int)值入栈。
lconst_0
0(long)值入栈。
lconst_1
1(long)值入栈。
fconst_0
0(float)值入栈。
fconst_1
1(float)值入栈。
fconst_2
2(float)值入栈。
dconst_0
0(double)值入栈。
dconst_1
1(double)值入栈。
bipush
valuebyte
valuebyte值带符号扩展成int值入栈。
sipush
valuebyte1
valuebyte2
(valuebyte1 << 8) | valuebyte2 值带符号扩展成int值入栈。
ldc
indexbyte1
常量池中的常量值(int, float, string reference, object reference)入栈。
ldc_w
indexbyte1
indexbyte2
常量池中常量(int, float, string reference, object reference)入栈。
ldc2_w
indexbyte1
indexbyte2
常量池中常量(long, double)入栈。
局部变量值转载到栈中指令
操作码(助记符)
操作数
描述(栈指操作数栈)
(wide)aload
indexbyte
从局部变量indexbyte中装载引用类型值入栈。
aload_0
从局部变量0中装载引用类型值入栈。
aload_1
从局部变量1中装载引用类型值入栈。
aload_2
从局部变量2中装载引用类型值入栈。
aload_3
从局部变量3中装载引用类型值入栈。
(wide)iload
indexbyte
从局部变量indexbyte中装载int类型值入栈。
iload_0
从局部变量0中装载int类型值入栈。
iload_1
从局部变量1中装载int类型值入栈。
iload_2
从局部变量2中装载int类型值入栈。
iload_3
从局部变量3中装载int类型值入栈。
(wide)lload
indexbyte
从局部变量indexbyte中装载long类型值入栈。
lload_0
从局部变量0中装载int类型值入栈。
lload_1
从局部变量1中装载int类型值入栈。
lload_2
从局部变量2中装载int类型值入栈。
lload_3
从局部变量3中装载int类型值入栈。
(wide)fload
indexbyte
从局部变量indexbyte中装载float类型值入栈。
fload_0
从局部变量0中装载float类型值入栈。
fload_1
从局部变量1中装载float类型值入栈。
fload_2
从局部变量2中装载float类型值入栈。
fload_3
从局部变量3中装载float类型值入栈。
(wide)dload
indexbyte
从局部变量indexbyte中装载double类型值入栈。
dload_0
从局部变量0中装载double类型值入栈。
dload_1
从局部变量1中装载double类型值入栈。
dload_2
从局部变量2中装载double类型值入栈。
dload_3
从局部变量3中装载double类型值入栈。
aaload
从引用类型数组中装载指定项的值。
iaload
从int类型数组中装载指定项的值。
laload
从long类型数组中装载指定项的值。
faload
从float类型数组中装载指定项的值。
daload
从double类型数组中装载指定项的值。
baload
从boolean类型数组或byte类型数组中装载指定项的值(先转换为int类型值,后压栈)。
caload
从char类型数组中装载指定项的值(先转换为int类型值,后压栈)。
saload
从short类型数组中装载指定项的值(先转换为int类型值,后压栈)。
将栈顶值保存到局部变量中指令
操作码(助记符)
操作数
描述(栈指操作数栈)
(wide)astore
indexbyte
将栈顶引用类型值保存到局部变量indexbyte中。
astroe_0
将栈顶引用类型值保存到局部变量0中。
astore_1
将栈顶引用类型值保存到局部变量1中。
astore_2
将栈顶引用类型值保存到局部变量2中。
astore_3
将栈顶引用类型值保存到局部变量3中。
(wide)istore
indexbyte
将栈顶int类型值保存到局部变量indexbyte中。
istore_0
将栈顶int类型值保存到局部变量0中。
istore_1
将栈顶int类型值保存到局部变量1中。
istore_2
将栈顶int类型值保存到局部变量2中。
istore_3
将栈顶int类型值保存到局部变量3中。
(wide)lstore
indexbyte
将栈顶long类型值保存到局部变量indexbyte中。
lstore_0
将栈顶long类型值保存到局部变量0中。
lstore_1
将栈顶long类型值保存到局部变量1中。
lstore_2
将栈顶long类型值保存到局部变量2中。
lstroe_3
将栈顶long类型值保存到局部变量3中。
(wide)fstore
indexbyte
将栈顶float类型值保存到局部变量indexbyte中。
fstore_0
将栈顶float类型值保存到局部变量0中。
fstore_1
将栈顶float类型值保存到局部变量1中。
fstore_2
将栈顶float类型值保存到局部变量2中。
fstore_3
将栈顶float类型值保存到局部变量3中。
(wide)dstore
indexbyte
将栈顶double类型值保存到局部变量indexbyte中。
dstore_0
将栈顶double类型值保存到局部变量0中。
dstore_1
将栈顶double类型值保存到局部变量1中。
dstore_2
将栈顶double类型值保存到局部变量2中。
dstore_3
将栈顶double类型值保存到局部变量3中。
aastore
将栈顶引用类型值保存到指定引用类型数组的指定项。
iastore
将栈顶int类型值保存到指定int类型数组的指定项。
lastore
将栈顶long类型值保存到指定long类型数组的指定项。
fastore
将栈顶float类型值保存到指定float类型数组的指定项。
dastore
将栈顶double类型值保存到指定double类型数组的指定项。
bastroe
将栈顶boolean类型值或byte类型值保存到指定boolean类型数组或byte类型数组的指定项。
castore
将栈顶char类型值保存到指定char类型数组的指定项。
sastore
将栈顶short类型值保存到指定short类型数组的指定项。
wide指令
操作码(助记符)
操作数
描述(栈指操作数栈)
wide
使用附加字节扩展局部变量索引(iinc指令特殊)。
通用(无类型)栈操作指令
操作码(助记符)
操作数
描述(栈指操作数栈)
nop
空操作。
pop
从栈顶弹出一个字长的数据。
pop2
从栈顶弹出两个字长的数据。
dup
复制栈顶一个字长的数据,将复制后的数据压栈。
dup_x1
复制栈顶一个字长的数据,弹出栈顶两个字长数据,先将复制后的数据压栈,再将弹出的两个字长数据压栈。
dup_x2
复制栈顶一个字长的数据,弹出栈顶三个字长的数据,将复制后的数据压栈,再将弹出的三个字长的数据压栈。
dup2
复制栈顶两个字长的数据,将复制后的两个字长的数据压栈。
dup2_x1
复制栈顶两个字长的数据,弹出栈顶三个字长的数据,将复制后的两个字长的数据压栈,再将弹出的三个字长的数据压栈。
dup2_x2
复制栈顶两个字长的数据,弹出栈顶四个字长的数据,将复制后的两个字长的数据压栈,再将弹出的四个字长的数据压栈。
swap
交换栈顶两个字长的数据的位置。Java指令中没有提供以两个字长为单位的交换指令。
类型转换指令
操作码(助记符)
操作数
描述(栈指操作数栈)
i2f
将栈顶int类型值转换为float类型值。
i2l
将栈顶int类型值转换为long类型值。
i2d
将栈顶int类型值转换为double类型值。
f2i
将栈顶float类型值转换为int类型值。
f2l
将栈顶float类型值转换为long类型值。
f2d
将栈顶float类型值转换为double类型值。
l2i
将栈顶long类型值转换为int类型值。
l2f
将栈顶long类型值转换为float类型值。
l2d
将栈顶long类型值转换double类型值。
d2i
将栈顶double类型值转换为int类型值。
d2f
将栈顶double类型值转换为float类型值。
d2l
将栈顶double类型值转换为long类型值。
i2b
将栈顶int类型值截断成byte类型,后带符号扩展成int类型值入栈。
i2c
将栈顶int类型值截断成char类型值,后带符号扩展成int类型值入栈。
i2s
将栈顶int类型值截断成short类型值,后带符号扩展成int类型值入栈。
整数运算
操作码(助记符)
操作数
描述(栈指操作数栈)
iadd
将栈顶两int类型数相加,结果入栈。
isub
将栈顶两int类型数相减,结果入栈。
imul
将栈顶两int类型数相乘,结果入栈。
idiv
将栈顶两int类型数相除,结果入栈。
irem
将栈顶两int类型数取模,结果入栈。
ineg
将栈顶int类型值取负,结果入栈。
ladd
将栈顶两long类型数相加,结果入栈。
lsub
将栈顶两long类型数相减,结果入栈。
lmul
将栈顶两long类型数相乘,结果入栈。
ldiv
将栈顶两long类型数相除,结果入栈。
lrem
将栈顶两long类型数取模,结果入栈。
lneg
将栈顶long类型值取负,结果入栈。
(wide)iinc
indexbyte
constbyte
将整数值constbyte加到indexbyte指定的int类型的局部变量中。
浮点运算
操作码(助记符)
操作数
描述(栈指操作数栈)
fadd
将栈顶两float类型数相加,结果入栈。
fsub
将栈顶两float类型数相减,结果入栈。
fmul
将栈顶两float类型数相乘,结果入栈。
fdiv
将栈顶两float类型数相除,结果入栈。
frem
将栈顶两float类型数取模,结果入栈。
fneg
将栈顶float类型值取反,结果入栈。
dadd
将栈顶两double类型数相加,结果入栈。
dsub
将栈顶两double类型数相减,结果入栈。
dmul
将栈顶两double类型数相乘,结果入栈。
ddiv
将栈顶两double类型数相除,结果入栈。
drem
将栈顶两double类型数取模,结果入栈。
dneg
将栈顶double类型值取负,结果入栈。
逻辑运算——移位运算
操作码(助记符)
操作数
描述(栈指操作数栈)
ishl
左移int类型值。
lshl
左移long类型值。
ishr
算术右移int类型值。
lshr
算术右移long类型值。
iushr
逻辑右移int类型值。
lushr
逻辑右移long类型值。
逻辑运算——按位布尔运算
操作码(助记符)
操作数
描述(栈指操作数栈)
iand
对int类型按位与运算。
land
对long类型的按位与运算。
ior
对int类型的按位或运算。
lor
对long类型的按位或运算。
ixor
对int类型的按位异或运算。
lxor
对long类型的按位异或运算。
控制流指令——条件跳转指令
操作码(助记符)
操作数
描述(栈指操作数栈)
ifeq
branchbyte1
branchbyte2
若栈顶int类型值为0则跳转。
ifne
branchbyte1
branchbyte2
若栈顶int类型值不为0则跳转。
iflt
branchbyte1
branchbyte2
若栈顶int类型值小于0则跳转。
ifle
branchbyte1
branchbyte2
若栈顶int类型值小于等于0则跳转。
ifgt
branchbyte1
branchbyte2
若栈顶int类型值大于0则跳转。
ifge
branchbyte1
branchbyte2
若栈顶int类型值大于等于0则跳转。
if_icmpeq
branchbyte1
branchbyte2
若栈顶两int类型值相等则跳转。
if_icmpne
branchbyte1
branchbyte2
若栈顶两int类型值不相等则跳转。
if_icmplt
branchbyte1
branchbyte2
若栈顶两int类型值前小于后则跳转。
if_icmple
branchbyte1
branchbyte2
若栈顶两int类型值前小于等于后则跳转。
if_icmpgt
branchbyte1
branchbyte2
若栈顶两int类型值前大于后则跳转。
if_icmpge
branchbyte1
branchbyte2
若栈顶两int类型值前大于等于后则跳转。
ifnull
branchbyte1
branchbyte2
若栈顶引用值为null则跳转。
ifnonnull
branchbyte1
branchbyte2
若栈顶引用值不为null则跳转。
if_acmpeq
branchbyte1
branchbyte2
若栈顶两引用类型值相等则跳转。
if_acmpne
branchbyte1
branchbyte2
若栈顶两引用类型值不相等则跳转。
控制流指令——比较指令
操作码(助记符)
操作数
描述(栈指操作数栈)
lcmp
比较栈顶两long类型值,前者大,1入栈;相等,0入栈;后者大,-1入栈。
fcmpl
比较栈顶两float类型值,前者大,1入栈;相等,0入栈;后者大,-1入栈;有NaN存在,-1入栈。
fcmpg
比较栈顶两float类型值,前者大,1入栈;相等,0入栈;后者大,-1入栈;有NaN存在,-1入栈。
dcmpl
比较栈顶两double类型值,前者大,1入栈;相等,0入栈;后者大,-1入栈;有NaN存在,-1入栈。
dcmpg
比较栈顶两double类型值,前者大,1入栈;相等,0入栈;后者大,-1入栈;有NaN存在,-1入栈。
控制流指令——无条件跳转指令
操作码(助记符)
操作数
描述(栈指操作数栈)
goto
branchbyte1
branchbyte2
无条件跳转到指定位置。
goto_w
branchbyte1
branchbyte2
branchbyte3
branchbyte4
无条件跳转到指定位置(宽索引)。
控制流指令——表跳转指令
操作码(助记符)
操作数
描述(栈指操作数栈)
tableswitch
<0-3bytepad>
defaultbyte1
defaultbyte2
defaultbyte3
defaultbyte4
lowbyte1
lowbyte2
lowbyte3
lowbyte4
highbyte1
highbyte2
highbyte3
highbyte4
jump offsets...
通过索引访问跳转表,并跳转。
lookupswitch
<0-3bytepad>
defaultbyte1
defaultbyte2
defaultbyte3
defaultbyte4
npairs1
npairs2
npairs3
npairs4
match offsets
通过键值访问跳转表,并跳转。
控制流指令——异常和finally
操作码(助记符)
操作数
描述(栈指操作数栈)
athrow
抛出异常。
jsr
branchbyte1
branchbyte2
跳转到子例程序。
jsr_w
branchbyte1
branchbyte2
branchbyte3
branchbyte4
跳转到子例程序(宽索引)。
(wide)ret
indexbyte
返回子例程序。
对象操作指令
操作码(助记符)
操作数
描述(栈指操作数栈)
new
indexbyte1
indexbyte2
创建新的对象实例。
checkcast
indexbyte1
indexbyte
类型强转。
instanceof
indexbyte1
indexbyte2
判断类型。
getfield
indexbyte1
indexbyte2
获取对象字段的值。
putfield
indexbyte1
indexbyte2
给对象字段赋值。
getstatic
indexbyte1
indexbyte2
获取静态字段的值。
putstatic
indexbyte1
indexbyte2
给静态字段赋值。
数组操作指令
操作码(助记符)
操作数
描述(栈指操作数栈)
newarray
atype
创建type类型的数组。
anewarray
indexbyte1
indexbyte2
创建引用类型的数组。
arraylength
获取一维数组的长度。
multianewarray
indexbyte1
indexbyte2
dimension
创建dimension维度的数组。
方法调用指令
操作码(助记符)
操作数
描述(栈指操作数栈)
invokespecial
indexbyte1
indexbyte2
编译时方法绑定调用方法。
invokevirtual
indexbyte1
indexbyte2
运行时方法绑定调用方法。
invokestatic
indexbyte1
indexbyte2
调用静态方法。
invokeinterface
indexbyte1
indexbyte2
count
0
调用接口方法。
方法返回指令
操作码(助记符)
操作数
描述(栈指操作数栈)
ireturn
返回int类型值。
lreturn
返回long类型值。
freturn
返回float类型值。
dreturn
返回double类型值。
areturn
返回引用类型值。
return
void函数返回。
线程同步指令
操作码(助记符)
操作数
描述(栈指操作数栈)
monitorenter
进入并获得对象监视器。
monitorexit
释放并退出对象监视器。
原文链接:http://www.blogjava.net/DLevin/archive/2011/09/13/358497.html
-
JMP CALL 二进制指令计算公式
2017-10-12 08:21:52偏移量计算的公式二: 目标偏移-CALL指令的起始偏移-CALL指令的大小 ;示例二 CALL [内存地址] ;===================================== 1 [bits 32] 2 3 00000000 90 nop 4 00000001 90 nop 5 ...;示例一 CALL立即数 CALL后面跟一个32位立即数
;===================================
1 [bits 32]
2 test:
3 00000000 90 nop
4 00000001 90 nop
5 00000002 90 nop
6 00000003 E8F8FFFFFF call test
7 00000008 90 nop
8 00000009 90 nop
9 0000000A 90 nop
;===================================
CALL后面跟一个立即数,也就是32位偏移量时,机器码为 0XE8 后面的32位立即数是偏移量.
偏移量的计算: 目标偏移地址 减 CALL 指令后的下一条指令的地址 在当前的例子中,test是目标偏移地址,地址是0 CALL指令后的地址为 08 , 0-08=FFFFFFF8 注意,在内存中,低字在前,高字在后,所以是 0XE8 F8 FF FF FF偏移量计算的公式二: 目标偏移-CALL指令的起始偏移-CALL指令的大小
;示例二 CALL [内存地址]
;=====================================
1 [bits 32]
2
3 00000000 90 nop
4 00000001 90 nop
5 00000002 90 nop
6 00000003 FF15[0B000000] call [test]
7 00000009 90 nop
8 0000000A 90 nop
9 test:
10 0000000B 90 nop
;======================================
机器码是0XFF15 后面跟的是内存地址. test的内存地址是 0B ,所以后面跟的是0B 同样是低字在前,高字在后示例三 call far [内存地址]
;=======================================
1 [bits 32]
2
3 00000000 90 nop
4 00000001 90 nop
5 00000002 90 nop
6 00000003 FF1D[0B000000] call far [test]
7 00000009 90 nop
8 0000000A 90 nop
9 test:
10 0000000B 90 nop
;=======================================
CALL FAR 内存地址,机器码是 0XFF1D 后面内存地址的表示是相同的,但执行不同. 会同时改变CS 与 IP.;示例四 JMP 立数数
;=======================================
1 [bits 32]
2
3 00000000 90 nop
4 00000001 90 nop
5 00000002 90 nop
6 00000003 E902000000 jmp test
7 00000008 90 nop
8 00000009 90 nop
9 test:
10 0000000A 90 nop
;=======================================
JMP 立即数,机器码是 E9 ,后面跟一个偏移量. 偏移量计算与上面CALL相同. test 地址是 0A,JMP指令后下一条指令地址是 08 ,0A-08=2;JMP 内存地址
;=======================================
1 [bits 32]
2
3 00000000 90 nop
4 00000001 90 nop
5 00000002 90 nop
6 00000003 FF25[0B000000] jmp [test]
7 00000009 90 nop
8 0000000A 90 nop
9 test:
10 0000000B 90 nop
;=======================================
JMP 内存地址,机器码是 0XFF25 后面跟的是内存地址. 注意,是从后面的内存地址取出目标数值来改变EIP.;JMP FAR 内存地址
;========================================
1 [bits 32]
2
3 00000000 90 nop
4 00000001 90 nop
5 00000002 90 nop
6 00000003 FF2D[0B000000] jmp far [test]
7 00000009 90 nop
8 0000000A 90 nop
9 test:
10 0000000B 90 nop
;========================================
JMP FAR 机器地址是 0XFF2D 后面同样是内存地址.;============================================================
直接远跳转与直接远调用
;============================================================
1 [bits 32]
2 00000000 EA007C00000800 jmp 0x8:0x7c00
3 00000007 9A007C00000800 call 0x8:0x7c00
JMP直接远跳,机器码是0XEA 32位的偏移在前,16位的段选择子在后.
CALL直接远跳,机器码是0X9A 32位的偏移在前,16位的段选择子在后. -
为Linux内核函数插入二进制指令并且校准偏移的手艺
2020-03-27 10:34:10前面写了两篇关于杂耍把戏的手艺方面的文章: ...并不是很过瘾,因为当我将一个函数完整搬移到另一处的时候,我有意避开了采用相对地址寻址指令偏移校准 核心问题 ,还美其名曰为了简单。 失去... -
用GNU工具集产生一个无格式的二进制指令文件
2019-09-24 17:50:10只需要下面几个步骤,就可以生成一个只有代码的纯二进制指令文件gas.bin: as -o gas.o gas.s objcopy -O binary gas.o gas.bin 转载于:... -
python机器语言直接用二进制代码表达指令_什么是一种二进制语言,它直接使用二进制代码表达指令?...
2020-12-09 13:30:03机器语言是一种二进制语言,它直接使用二进制代码表达指令。机器语言是用二进制代码表示的计算机能直接识别和执行的一种机器指令的集合;一条指令就是机器语言的一个语句,它是一组有意义的二进制代码。机器语言是一... -
python机器语言直接用二进制代码表达指令_Python入门(1)
2020-12-09 13:29:401.编程语言机器语言:直接用计算机能听懂的二进制指令去编写程序,需要了解硬件的细节汇编语言:用英文标签取代二进制指令去编写程序,同样需要了解硬件的细节高级语言:直接用人类能理解的表达方式去编写程序,不... -
Intel 64/x86_64/IA-32/x86处理器 - 通用指令(2) - 二进制算术指令/十进制算术指令
2019-01-17 10:35:04二进制算术指令执行基本的二进制整型计算,操作数可以是字节,单字和双字整型数,位于存储器中,和/或通用寄存器中。 指令 描述 ADCX 带进位的无符号整数加法 ADOX ... -
python机器语言直接用二进制代码表达指令_python是机器语言吗
2020-12-09 13:30:00机器语言是机器能直接识别的程序语言或指令代码,勿需经过翻译,每一操作码在计算机内部都有相应的电路来完成它,或指不经翻译即可为机器直接理解...机器语言:直接编写二进制指令的编程方式机器语言(machine langua... -
汇编指令与二进制代码对照表
2018-10-25 16:19:38汇编指令与二进制代码对照表汇编指令与二进制代码对照表 -
自动生成二进制系统指令
2015-05-03 18:36:00不过可惜的是,经过我测试,如果在使用二进制指令的同时,如果运行时间过长,还是能在系统进程中查看到此指令的具体内容。 ps -axf | grep hello 还是仍然可以显示转换前脚本的内容。不管你是用的shc转码... -
比较二进制_FANUC PMC功能指令详解(06):比较指令二
2020-12-28 00:20:25PMC比较指令如下:序号指令名称功能号功能1EQB2001字节二进制比较(=)2EQW2012字节二进制比较(=)3EQD2024字节二进制比较(=)4NEB2031字节二进制比较(≠)5NEW2042字节二进制比较(≠)6NED2054字节二进制比较(≠)7GTB... -
汇编指令与二进制对应手册
2016-05-16 13:24:52汇编指令与二进制对应手册,从此再也不会觉得00010101010神秘了。 -
硬件设计测试中,MIPS汇编指令翻译成二进制编码的Python实现
2011-04-18 23:43:00用Python实现一些 MIPS 汇编指令翻译成二进制指令的功能。 -
初识二进制2:指令系统
2013-03-19 00:06:00二进制最基本的单位是“位(bit)”,指令与数据均以二进制的形式存在与内存之中,对于机器而言数据和指令并无二致。二进制的数据好理解,先看看指令。 1.CPU智商极低却以速度取胜 大量短小而重复的指令有机结合便... -
反汇编二进制代码
2020-05-22 17:40:51最近又做了一些内核hook的工作,繁琐的地方在于二进制指令的可读性上,下面简要记录dump出指令二进制,之后利用binutils来转成可读的汇编代码. hook的主要流程参考之前的linux内核态hook模块-splice,主要就是构建一个...
-
从Docker到Kubernetes之技术实战.pdf
-
linux中type 、file、stat三者的区别
-
Liunx 优化思路与实操步骤
-
2021年中国新跨境出口B2B电商行业研究报告.pdf
-
计算机复试英语准备.pdf
-
C++ STL(十六):常用算术生成算法(accumulate、fill)
-
应广105G雾化片驱动.rar
-
Samba 服务配置与管理
-
一天学完MySQL数据库
-
EaUS Video Editor(视频剪辑软件)官方中文版V1.6.8.53
-
零基础极简以太坊智能合约开发环境搭建并开发部署
-
泰坦尼克号建模分析-你能活下来吗?
-
303. 区域和检索 - 数组不可变(前缀和)
-
牛牛量化策略交易
-
mysql-8.0.11-winx64.zip
-
MaxScale 实现 MySQL 读写分离与负载均衡
-
jdk8u281.zip
-
vscode 通知: Error loading workspace: err: exit status 1: stderr: build flag -mod=readonly only valid
-
GC如何判断对象可以被回收
-
基于Hypervisor虚拟化技术的Hadoop云平台管理方案的研究.docx