64位和32位在汇编语言中的区别

在linux如何生成32位的程序

在linux下默认生成的是64位的,并且ubuntu中没有安装32位的库,因此如果想要在ubuntu中运行或者生成32位的程序需要安装32位的库。

gcc test.c -m32 生成32位的程序

sun@ubuntu:~/Desktop$ gcc test.c -m32
sun@ubuntu:~/Desktop$ file a.out 
a.out: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-, for GNU/Linux 2.6.32, BuildID[sha1]=bb9a90c1c149ca64c5cf230c05e4ffdf2a0013e4, not stripped
sun@ubuntu:~/Desktop$ 

下面是一段32位的反汇编

gdb-peda$ disassemble
Dump of assembler code for function main:
   0x080484aa <+0>:	lea    ecx,[esp+0x4]
   0x080484ae <+4>:	and    esp,0xfffffff0
   0x080484b1 <+7>:	push   DWORD PTR [ecx-0x4]
   0x080484b4 <+10>:	push   ebp
   0x080484b5 <+11>:	mov    ebp,esp
   0x080484b7 <+13>:	push   ecx
   0x080484b8 <+14>:	sub    esp,0x14
=> 0x080484bb <+17>:	mov    DWORD PTR [ebp-0x14],0x1
   0x080484c2 <+24>:	mov    DWORD PTR [ebp-0x10],0x2
   0x080484c9 <+31>:	sub    esp,0x8
   0x080484cc <+34>:	push   DWORD PTR [ebp-0x10]
   0x080484cf <+37>:	push   DWORD PTR [ebp-0x14]
   0x080484d2 <+40>:	call   0x804846b <add>
   0x080484d7 <+45>:	add    esp,0x10
   0x080484da <+48>:	mov    DWORD PTR [ebp-0xc],eax
   0x080484dd <+51>:	mov    eax,0x0
   0x080484e2 <+56>:	mov    ecx,DWORD PTR [ebp-0x4]
   0x080484e5 <+59>:	leave  
   0x080484e6 <+60>:	lea    esp,[ecx-0x4]
   0x080484e9 <+63>:	ret    
End of assembler dump.
gdb-peda$ 

64位的汇编

gdb-peda$ disassemble
Dump of assembler code for function main:
   0x00000000004005e7 <+0>:	push   rbp
   0x00000000004005e8 <+1>:	mov    rbp,rsp
=> 0x00000000004005eb <+4>:	sub    rsp,0x10
   0x00000000004005ef <+8>:	mov    DWORD PTR [rbp-0xc],0x1
   0x00000000004005f6 <+15>:	mov    DWORD PTR [rbp-0x8],0x2
   0x00000000004005fd <+22>:	mov    edx,DWORD PTR [rbp-0x8]
   0x0000000000400600 <+25>:	mov    eax,DWORD PTR [rbp-0xc]
   0x0000000000400603 <+28>:	mov    esi,edx
   0x0000000000400605 <+30>:	mov    edi,eax
   0x0000000000400607 <+32>:	call   0x400596 <add>
   0x000000000040060c <+37>:	mov    DWORD PTR [rbp-0x4],eax
   0x000000000040060f <+40>:	mov    eax,0x0
   0x0000000000400614 <+45>:	leave  
   0x0000000000400615 <+46>:	ret    
End of assembler dump.
gdb-peda$

区别:
1.在64位程序中每个push和pop指令sp减8,而32位的则减4,入栈的最小单位不同。
2.表示的地址范围不同,64位的使用8字节表示,32位的用4字节表示。
3.call指令和ret指令分别会有入栈和出栈的作用,在64位中call指令相当于push rip,jmp 目的地址,第一个入栈的返回地址是8字节,而32位中相当于push eip,jmp 目的地址,入栈的返回地址是4字节。
4.传递参数的方式不同,32位的将参数入栈来传递参数,64位的使用寄存器进行传递参数,用来传递参数的寄存器为rdi,rsi,rdx,rcx,r8,r9,这六个寄存器分别用来存储第一至第六个参数,如果参数多余6个会先将后面的参数先入栈,前六个参数放在对应的寄存器中,在上面的例子中32位的使用了将参数放入栈中的方式 eg:
0x080484cc <+34>: push DWORD PTR [ebp-0x10]
0x080484cf <+37>: push DWORD PTR [ebp-0x14]
64位的将参数放入rdi和rsi寄存器中eg:
0x0000000000400603 <+28>: mov esi,edx
0x0000000000400605 <+30>: mov edi,eax

下面是一个当参数多于6个的例子:
源代码:

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
int add(int a,int b,int c,int d,int e,int f,int g,int h)
{
        int j=a+b+c+d+e+f+g+h;
        return j;
}
int main()
{
        int a=1,b=2,c=3,d=4,e=5,f=6,g=7,h=8;
        int sum=add(a,b,c,d,e,f,g,h);
        return 0;
}

64位的主函数的汇编代码

b-peda$ disassemble
Dump of assembler code for function main:
   0x000000000040051c <+0>:	push   rbp
   0x000000000040051d <+1>:	mov    rbp,rsp
=> 0x0000000000400520 <+4>:	sub    rsp,0x30
   0x0000000000400524 <+8>:	mov    DWORD PTR [rbp-0x24],0x1
   0x000000000040052b <+15>:	mov    DWORD PTR [rbp-0x20],0x2
   0x0000000000400532 <+22>:	mov    DWORD PTR [rbp-0x1c],0x3
   0x0000000000400539 <+29>:	mov    DWORD PTR [rbp-0x18],0x4
   0x0000000000400540 <+36>:	mov    DWORD PTR [rbp-0x14],0x5
   0x0000000000400547 <+43>:	mov    DWORD PTR [rbp-0x10],0x6
   0x000000000040054e <+50>:	mov    DWORD PTR [rbp-0xc],0x7
   0x0000000000400555 <+57>:	mov    DWORD PTR [rbp-0x8],0x8
   0x000000000040055c <+64>:	mov    r9d,DWORD PTR [rbp-0x10]
   0x0000000000400560 <+68>:	mov    r8d,DWORD PTR [rbp-0x14]
   0x0000000000400564 <+72>:	mov    ecx,DWORD PTR [rbp-0x18]
   0x0000000000400567 <+75>:	mov    edx,DWORD PTR [rbp-0x1c]
   0x000000000040056a <+78>:	mov    esi,DWORD PTR [rbp-0x20]
   0x000000000040056d <+81>:	mov    eax,DWORD PTR [rbp-0x24]
   0x0000000000400570 <+84>:	mov    edi,DWORD PTR [rbp-0x8]
   0x0000000000400573 <+87>:	push   rdi
   0x0000000000400574 <+88>:	mov    edi,DWORD PTR [rbp-0xc]
   0x0000000000400577 <+91>:	push   rdi
   0x0000000000400578 <+92>:	mov    edi,eax
   0x000000000040057a <+94>:	call   0x4004d6 <add>
   0x000000000040057f <+99>:	add    rsp,0x10
   0x0000000000400583 <+103>:	mov    DWORD PTR [rbp-0x4],eax
   0x0000000000400586 <+106>:	mov    eax,0x0
   0x000000000040058b <+111>:	leave  
   0x000000000040058c <+112>:	ret    
End of assembler dump.

32位的主函数的汇编代码

gdb-peda$ disassemble
Dump of assembler code for function main:
   0x0804840f <+0>:	push   ebp
   0x08048410 <+1>:	mov    ebp,esp
   0x08048412 <+3>:	sub    esp,0x30
=> 0x08048415 <+6>:	mov    DWORD PTR [ebp-0x24],0x1
   0x0804841c <+13>:	mov    DWORD PTR [ebp-0x20],0x2
   0x08048423 <+20>:	mov    DWORD PTR [ebp-0x1c],0x3
   0x0804842a <+27>:	mov    DWORD PTR [ebp-0x18],0x4
   0x08048431 <+34>:	mov    DWORD PTR [ebp-0x14],0x5
   0x08048438 <+41>:	mov    DWORD PTR [ebp-0x10],0x6
   0x0804843f <+48>:	mov    DWORD PTR [ebp-0xc],0x7
   0x08048446 <+55>:	mov    DWORD PTR [ebp-0x8],0x8
   0x0804844d <+62>:	push   DWORD PTR [ebp-0x8]
   0x08048450 <+65>:	push   DWORD PTR [ebp-0xc]
   0x08048453 <+68>:	push   DWORD PTR [ebp-0x10]
   0x08048456 <+71>:	push   DWORD PTR [ebp-0x14]
   0x08048459 <+74>:	push   DWORD PTR [ebp-0x18]
   0x0804845c <+77>:	push   DWORD PTR [ebp-0x1c]
   0x0804845f <+80>:	push   DWORD PTR [ebp-0x20]
   0x08048462 <+83>:	push   DWORD PTR [ebp-0x24]
   0x08048465 <+86>:	call   0x80483db <add>
   0x0804846a <+91>:	add    esp,0x20
   0x0804846d <+94>:	mov    DWORD PTR [ebp-0x4],eax
   0x08048470 <+97>:	mov    eax,0x0
   0x08048475 <+102>:	leave  
   0x08048476 <+103>:	ret    
End of assembler dump.

在32位的汇编指令中将全部的参数入栈,进行传参

   0x0804844d <+62>:	push   DWORD PTR [ebp-0x8]
   0x08048450 <+65>:	push   DWORD PTR [ebp-0xc]
   0x08048453 <+68>:	push   DWORD PTR [ebp-0x10]
   0x08048456 <+71>:	push   DWORD PTR [ebp-0x14]
   0x08048459 <+74>:	push   DWORD PTR [ebp-0x18]
   0x0804845c <+77>:	push   DWORD PTR [ebp-0x1c]
   0x0804845f <+80>:	push   DWORD PTR [ebp-0x20]
   0x08048462 <+83>:	push   DWORD PTR [ebp-0x24]

在64位的汇编指令中将前六个参数放入寄存器中,后面两个入栈进行传参

   0x000000000040055c <+64>:	mov    r9d,DWORD PTR [rbp-0x10]
   0x0000000000400560 <+68>:	mov    r8d,DWORD PTR [rbp-0x14]
   0x0000000000400564 <+72>:	mov    ecx,DWORD PTR [rbp-0x18]
   0x0000000000400567 <+75>:	mov    edx,DWORD PTR [rbp-0x1c]
   0x000000000040056a <+78>:	mov    esi,DWORD PTR [rbp-0x20]
   0x000000000040056d <+81>:	mov    eax,DWORD PTR [rbp-0x24]
   0x0000000000400570 <+84>:	mov    edi,DWORD PTR [rbp-0x8]
   0x0000000000400573 <+87>:	push   rdi
   0x0000000000400574 <+88>:	mov    edi,DWORD PTR [rbp-0xc]
   0x0000000000400577 <+91>:	push   rdi

在做pwn题时分清64位和32位的不同是很重要的,这两种分别需要覆盖的返回值的位数是不同的。

  • 8
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值