精华内容
下载资源
问答
  • MIPS二进制指令集格式参考

    热门讨论 2012-12-26 09:23:40
    MIPS二进制指令集格式参考。里面详细列举了MIPS指令集的各条指令,以及对应的二进制格式。
  • 该程序会将大多数RVIMFD64 ISA二进制指令(从二进制或十六进制代码)反汇编成汇编指令。 之所以存在(以及它看起来有些“太原始”而无法发布)的原因是我试图学习指令格式以进行计算机体系结构考试。 长话短说,就...
  • 经理的皮鞋湿了,但是却没有变胖,所以经理的皮鞋是...展示了一个直接执行二进制指令文件的基本方案,基于Linux内核来执行。 值得一提的是,这不是什么特别有技术含量的东西,这只是一个基本功,我在2006年的长春...

    经理的皮鞋湿了,但是却没有变胖,所以经理的皮鞋是人造革的。


    刚刚写了一篇文章:
    不依赖OS编译器,不依赖库,用汇编/机器码直接编程: https://blog.csdn.net/dog250/article/details/89500153

    展示了一个直接执行二进制指令文件的基本方案,基于Linux内核来执行。

    值得一提的是,这不是什么特别有技术含量的东西,这只是一个基本功,我在2006年的长春吉林大学边上租住的房子里就玩过此法。那时是用VC 6。

    大公司的程序员不会屑于写我这些淫巧,即便他们也不一定会,也不一定懂,他们只是太关注业务,也许是真的没时间,也许真的就是不屑,觉得这太简单。但是,我的意思就是,这些东西真的太简单,如果你不懂,那真的不是一个合格的程序员。


    本文写一个 解释器 ,载入一个仅包含二进制指令的文件,然后执行,这非常简单。


    有两种方法可以简单的改变程序的执行流:

    1. 通过替换函数调用的返回地址。
      这是call指令提供的功能,call指令执行时,会将下一条指令压栈,我们只需要在栈里找到这个位置,将其替换为自己的指令即可。
    2. 直接通过内联汇编调用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二进制指令代码解析 Java源码在运行之前都要编译成为字节码格式(如.class文件),然后由ClassLoader将字节码载入运行。在字节码文件中,指令代码只是其中的一部分,里面还记录了字节码文件的编译版本、常量池...
    展开全文
  • 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位的段选择子在后.

    展开全文
  • crash> rd -8 0xffffffffa037403d ffffffffa037403d: e8 . crash> rd -8 0xffffffffa037403e ffffffffa037403e: 1e . crash> rd -8 0xffffffffa037403f ffffffffa037403f: 99 . crash>...
  • 二进制算术指令执行基本的二进制整型计算,操作数可以是字节,单字和双字整型数,位于存储器中,和/或通用寄存器中。 指令 描述 ADCX 带进位的无符号整数加法 ADOX ...

    Binary Arithmetic Instructions

    二进制算术指令执行基本的二进制整型计算,操作数可以是字节,单字和双字整型数,位于存储器中,和/或通用寄存器中。

    指令

    描述

    ADCX

    带进位的无符号整数加法

    ADOX

    带溢出位的无符号整数加法

    Intel C/C++ Compiler Intrinsic Equivalent
    unsigned char _addcarryx_u32 (unsigned char c_in, unsigned int src1, unsigned int src2, unsigned int *sum_out);
     

    unsigned char _addcarryx_u64 (unsigned char c_in, unsigned __int64 src1, unsigned __int64 src2, unsigned __int64 *sum_out);

    ADD

    整数加法

    ADC

    带进位的整数加法

    SUB

    减法

    SBB

    带借位的整数减法

    IMUL

    有符号整数乘法

    MUL

    无符号整数乘法

    IDIV

    有符号整数除法

    DIV

    无符号整数除法

    INC

    加1操作

    DEC

    减1操作

    NEG

    取反操作

    CMP

    比较操作

     

    Decimal Arithmetic Instructions

    十进制算术指令执行十进制整型数算术计算,操作数是BCD码。

    简单的说,BCD码有两种类型:组合的BCD码,与未组合的BCD码。

    组合的BCD码是指将两个十进制数字(即0~9)存放在一个字节中,每个数字占4个比特位。例如两位十进制数12D的组合BCD码表示为0001 0010(参看下图左侧)。

    未组合的BCD码是指将单个十进制数字(即0~9)存放在单个字节中,即每个数字占一个字节,该字节的高4比特位是0000,低4比特位是十进制数字0~9。例如上述的两位十进制数12D的未组合BCD码表示为0000.0001-0000.0010(忽略点号.,这里仅用于分隔二进制比特位,方便阅读) ,低字节表示低位数字,高字节表示高位数字。

    由于处理器是按照二进制执行算术运算,所以这两种BCD码在执行计算后,需要运行调整指令,将计算结果调整为十进制BCD码表示。

    指令

    描述

    DAA

    组合的BCD码,加法计算后,调整结果到组合的BCD码

    DAS

    组合的BCD码,减法计算后,调整结果到组合的BCD码

    AAA

    未组合的BCD码,做加法计算后,调整结果到未组合的BCD码

    AAS

    未组合的BCD码,做减法计算后,调整结果到未组合的BCD码

    AAM

    未组合的BCD码,做乘法计算后,调整结果到一对未组合的BCD码

    AAD

    调整两个未组合的BCD数字(最低有效数字在AL寄存器中,最高有效数字在AH寄存器中),在调整后的结果上做除法,可以得到正确的未组合的BCD值。

    注:AAD指令在执行除法操作前执行调整操作数。其他指令DAA/DAS/AAA/AAS/AAM都是在算术操作之后调整计算结果。

    展开全文
  • 汇编指令二进制对应手册,从此再也不会觉得00010101010神秘了。
  • 这里面是汇编指令二进制代码对应手册,里面有所有你可能遇到的汇编指令和对应的二进制代码,对汇编学习者比较有帮助
  • ROS串口通信(2)以十六进制指令读取IMU数据引言1、下载安装ROS的serial软件包2、通用serial通信代码3、使用ROS serial包实现IMU十六进制指令发送及数据读取编解码保存。 引言 前期准备参考博客 1、下载安装ROS的...
  • 汇编指令二进制代码对照表汇编指令二进制代码对照表
  • 赵泽添摘 要 数据是计算机处理的对象,从不同的处理角度来看,数据有不同的表现形态。从外部形式来看计算机颗处理数值、图、文字、声音、视频以及各种模拟信息量...从计算机指令集体系结构的角度来看,计算机中底层...
  • 1602十六进制指令

    千次阅读 2013-03-29 17:20:41
    1602模块的设定,读写,与光标控制都是通过指令来完成,共有11条指令,如下: 指令 RS RW D7 D6 D5 D4 D3 D2 D1 D0 1 清屏 0...
  • Linux串口编程(向空调发送十六进制指令
  • 汇编指令二进制代码对应手册.xls。
  • 二进制最基本的单位是“位(bit)”,指令与数据均以二进制的形式存在与内存之中,对于机器而言数据和指令并无二致。二进制的数据好理解,先看看指令。 1.CPU智商极低却以速度取胜 大量短小而重复的指令有机结合便...
  • 反汇编二进制代码

    2020-05-22 17:40:51
    最近又做了一些内核hook的工作,繁琐的地方在于二进制指令的可读性上,下面简要记录dump出指令二进制,之后利用binutils来转成可读的汇编代码. hook的主要流程参考之前的linux内核态hook模块-splice,主要就是构建一个...
  • 别名:低级语言,二进制代码语言定义:机器语言是直接用二进制代码指令表达的计算机语言,指令是用0和1组成的一串代码,它们有一定的位数,并分成若干段,各段的编码表示不同的含义,例如某台计算机字长为16位,即有...
  • 基于CoreBluetooth与蓝牙4.0设备通讯非常方便,一句话总结就是中心-设备-服务-特征...可以通过LightBlue查看你的蓝牙设备相关信息,也可以发送简单指令。 CBCentralManager scanForPeripherals时需要注意两点: AP...
  • 三进制计算机跟二进制计算机比,优势在哪里?三进制逻辑电路比二进制逻辑电路速度更快、可靠性更高,而且需要的设备和电能也更少。三进制代码的一个特点是对称,即相反数的一致性,因此它和二进制代码不同,不存在无...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 264,828
精华内容 105,931
关键字:

二进制指令