IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

x86 32-bits / 64-bits Assembleur Discussion :

[C, asm]executer de binaire en memoire executable


Sujet :

x86 32-bits / 64-bits Assembleur

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Février 2013
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Février 2013
    Messages : 24
    Points : 28
    Points
    28
    Par défaut [C, asm]executer de binaire en memoire executable
    Bonjour,

    je viens vers vous car je suis dans l'impasse sur un projet pédagogique.
    Je cherche à exécuter du binaire à la volée a l'aide d'une mémoire exécutable mmap en C et d'un code Assembleur.
    Le problème est que... je n'ai qu'une boucle infinie O.o... pas même un signal du type SIGSEGV ou une exception...
    J'ai beau lire toutes les docs trouvables du web, je reste bloqué... quelque chose semble m'échapper...

    Le main.c
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
     
    #include <sys/mman.h>
    #include <string.h>
     
    char shellcode[] =
      "\x31\xc0"
      "\x31\xdb"
      "\x31\xc9"
      "\x31\xd2"
      "\xeb\x0f"
      "\xb0\x04"
      "\xb3\x01"
      "\x59"
      "\xb2\x0d"
      "\xcd\x80"
      "\xb0\x01"
      "\x31\xdb"
      "\xcd\x80"
      "\xe8\xec\xff\xff\xff"
      "\x48\x65\x6c\x6c\x6f"
      "\x20\x77\x6f\x72\x6c"
      "\x64\x21\x0a";
     
    char *exec;
     
    int main()
    {
      exec = (char *)mmap(NULL, 1024, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANON, -1, 0);
     
      memcpy(exec, shellcode, strlen(shellcode));
      (*(void(*)())exec)();
     
      return (0);
    }

    Le hello.asm
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
     
    bits 32
            section .text
    	global _start
    _start:
                xor eax, eax
                xor ebx, ebx
                xor ecx, ecx
                xor edx, edx
     
                jmp helloworld_string
     
    helloworld_shellcode_next:
                mov al, 4
                mov bl, 1
                pop ecx
                mov dl, 13
                int 0x80
     
                mov al, 1
                xor ebx, ebx
                int 0x80
     
    helloworld_string:
                call helloworld_shellcode_next
                db `Hello world!\n`
    La compilation :
    gcc -o main main.c
    nasm -f elf64 hello.asm
    ld -s hello.o -o hello
    Le objdump -d hello :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
     
    hello2:     file format elf64-x86-64
     
     
    Disassembly of section .text:
     
    0000000000400080 <.text>:
      400080:	31 c0                	xor    %eax,%eax
      400082:	31 db                	xor    %ebx,%ebx
      400084:	31 c9                	xor    %ecx,%ecx
      400086:	31 d2                	xor    %edx,%edx
      400088:	eb 0f                	jmp    0x400099
      40008a:	b0 04                	mov    $0x4,%al
      40008c:	b3 01                	mov    $0x1,%bl
      40008e:	59                   	pop    %rcx
      40008f:	b2 0d                	mov    $0xd,%dl
      400091:	cd 80                	int    $0x80
      400093:	b0 01                	mov    $0x1,%al
      400095:	31 db                	xor    %ebx,%ebx
      400097:	cd 80                	int    $0x80
      400099:	e8 ec ff ff ff       	callq  0x40008a
      40009e:	48                   	rex.W
      40009f:	65                   	gs
      4000a0:	6c                   	insb   (%dx),%es:(%rdi)
      4000a1:	6c                   	insb   (%dx),%es:(%rdi)
      4000a2:	6f                   	outsl  %ds:(%rsi),(%dx)
      4000a3:	20 77 6f             	and    %dh,0x6f(%rdi)
      4000a6:	72 6c                	jb     0x400114
      4000a8:	64 21 0a             	and    %ecx,%fs:(%rdx)
    Le strace ./main :
    brk(0) = 0x123e000
    access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
    mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fc7b49dc000
    access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
    open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
    fstat(3, {st_mode=S_IFREG|0644, st_size=137143, ...}) = 0
    mmap(NULL, 137143, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fc7b49ba000
    close(3) = 0
    access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
    open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
    read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\320\37\2\0\0\0\0\0"..., 832) = 832
    fstat(3, {st_mode=S_IFREG|0755, st_size=1840928, ...}) = 0
    mmap(NULL, 3949248, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7fc7b43f7000
    mprotect(0x7fc7b45b2000, 2093056, PROT_NONE) = 0
    mmap(0x7fc7b47b1000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1ba000) = 0x7fc7b47b1000
    mmap(0x7fc7b47b7000, 17088, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7fc7b47b7000
    close(3) = 0
    mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fc7b49b9000
    mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fc7b49b7000
    arch_prctl(ARCH_SET_FS, 0x7fc7b49b7740) = 0
    mprotect(0x7fc7b47b1000, 16384, PROT_READ) = 0
    mprotect(0x600000, 4096, PROT_READ) = 0
    mprotect(0x7fc7b49de000, 4096, PROT_READ) = 0
    munmap(0x7fc7b49ba000, 137143) = 0
    mmap(NULL, 1024, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fc7b49db000
    stat("1\3001\3331\3111\322\353\17\260\4\263\1Y\262\r\315\200\260\0011\333\315\200\350\354\377\377\377Hello world!\n", 0x601060) = -1 EFAULT (Bad address)
    syscall_3221225217(0x7fc7b49db000, 0x601060, 0xd, 0, 0, 0) = -1 (errno 38)
    syscall_3221225220(0x7fc7b49db000, 0x601060, 0xd, 0, 0, 0) = -1 (errno 38)
    syscall_3221225217(0x7fc7b49db000, 0x601060, 0xd, 0, 0, 0) = -1 (errno 38)
    syscall_3221225220(0x7fc7b49db000, 0x601060, 0xd, 0, 0, 0) = -1 (errno 38)
    (boucle a l'infini)

  2. #2
    Responsable Systèmes


    Homme Profil pro
    Gestion de parcs informatique
    Inscrit en
    Août 2011
    Messages
    17 724
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Gestion de parcs informatique
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Août 2011
    Messages : 17 724
    Points : 43 829
    Points
    43 829
    Par défaut
    Tu compiles pour du 64 bits alors que ton code asm est adapté au 32 bits, en 64 bits en utilise par int 0x80 pour les appels systèmes mais sysenter et les registres à utiliser sont pas les mêmes.

  3. #3
    Nouveau membre du Club
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Février 2013
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Février 2013
    Messages : 24
    Points : 28
    Points
    28
    Par défaut
    oui c'est vrai mais la retrocompatibillité ne le permet elle pas ?
    rax n'est en soi qu'une extension de eax et syscall une sorte de define de int 0x80
    cependant il est vrai que ld ne fonctionnais pas sans elf64...

    le code asm s'execute parfaitement en lancant le ./hello
    c'est vraiment au moment de l'executer via le code C que cela ne donne aucun resultat autre que la boucle infini avec strace ./main

    cependant j'ai tester plusieurs code asm sans plus de resultat je me dit donc qu'il doit y avoir quelque chose de plus profond qui m'aurais échapper.
    je vais tenter avec une ecriture pour x86-64 et je donnerais des nouvelles.

  4. #4
    Responsable Systèmes


    Homme Profil pro
    Gestion de parcs informatique
    Inscrit en
    Août 2011
    Messages
    17 724
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Gestion de parcs informatique
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Août 2011
    Messages : 17 724
    Points : 43 829
    Points
    43 829
    Par défaut
    Pour la rétro-compatibilité, je pense que ton OS 64 bits peut charger un ELF32 qui va utiliser int 0x80 pour les appels systèmes, tandis qu'un ELF64 utiise ra SYSCALL

    rax n'est en soi qu'une extension de eax et syscall une sorte de define de int 0x80
    Non, SYSCALL et int 0x80, c'est pas la même chose, même si le résultat vu de l’extérieur semble similaire.

    Et on utilise pas les mêmes registres
    en x86, les paramètres sont passés dans cet ordre :
    ebx,ecx, edx,esi, edi, ebp - eax contenant le numéro d'appel.
    en x86_64, c'est :
    rdi, rsi, rdx,r10,r8,r9 - rax contenant le numéro d'appel.

  5. #5
    Nouveau membre du Club
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Février 2013
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Février 2013
    Messages : 24
    Points : 28
    Points
    28
    Par défaut autre version asm
    voici une autre version de code asm pour 64 bit que j'ai aussi test et qui ne fonctionne pas plus.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
     
    global _start
        _start:
        jmp short string
     
        code:
        pop rsi
        xor rax, rax
        mov al, 1
        mov rdi, rax
        mov rdx, rdi
        add rdx, 14
        syscall
     
        xor rax, rax
        add rax, 60
        xor rdi, rdi
        syscall
     
        string:
        call code
        db  'Hello, world!',0x0A
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
     
    (->)objdump -d hello3
     
    hello3:     file format elf64-x86-64
     
     
    Disassembly of section .text:
     
    0000000000400080 <.text>:
      400080:	eb 1e                	jmp    0x4000a0
      400082:	5e                   	pop    %rsi
      400083:	48 31 c0             	xor    %rax,%rax
      400086:	b0 01                	mov    $0x1,%al
      400088:	48 89 c7             	mov    %rax,%rdi
      40008b:	48 89 fa             	mov    %rdi,%rdx
      40008e:	48 83 c2 0e          	add    $0xe,%rdx
      400092:	0f 05                	syscall 
      400094:	48 31 c0             	xor    %rax,%rax
      400097:	48 83 c0 3c          	add    $0x3c,%rax
      40009b:	48 31 ff             	xor    %rdi,%rdi
      40009e:	0f 05                	syscall 
      4000a0:	e8 dd ff ff ff       	callq  0x400082
      4000a5:	48                   	rex.W
      4000a6:	65                   	gs
      4000a7:	6c                   	insb   (%dx),%es:(%rdi)
      4000a8:	6c                   	insb   (%dx),%es:(%rdi)
      4000a9:	6f                   	outsl  %ds:(%rsi),(%dx)
      4000aa:	2c 20                	sub    $0x20,%al
      4000ac:	77 6f                	ja     0x40011d
      4000ae:	72 6c                	jb     0x40011c
      4000b0:	64 21 0a             	and    %ecx,%fs:(%rdx)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
     
    #include <sys/mman.h>
    #include <string.h>
     
    char shellcode[] =
      "\xeb\x1e"
      "\x5e"
      "\x48\x89\xc7"
      "\x48\x89\xfa"
      "\x48\x83\xc2\x0e"
      "\x0f\x05"
      "\x48\x31\xc0"
      "\x48\x83\xc0\x3c"
      "\x48\x31\xff"
      "\x0f\x05"
      "\xe8\xdd\xff\xff\xff"
      "\x48"
      "\x65"
      "\x6c"
      "\x6c"
      "\x6f\x2c\x20\x77\x6f\x72\x6c\x64\x21\x0a";
     
    char *exec;
     
    int main()
    {
      exec = (char *)mmap(NULL, 1024, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANON, -1, 0);
     
      memcpy(exec, shellcode, strlen(shellcode));
      (*(void(*)())exec)();
     
      return (0);
    }

  6. #6
    Responsable Systèmes


    Homme Profil pro
    Gestion de parcs informatique
    Inscrit en
    Août 2011
    Messages
    17 724
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Gestion de parcs informatique
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Août 2011
    Messages : 17 724
    Points : 43 829
    Points
    43 829
    Par défaut
    Ton tableau de char shellcode est considéré comme des données, donc dans le segment de données normalement non exécutable.

    Ce que l'on appelle un shellcode est en général exécutable grâce à une faille système mais ne l'est pas normalement.

    Quel est le but final ? Qu'appeles tu exécution de binaire à la volée ?

Discussions similaires

  1. Réponses: 3
    Dernier message: 15/02/2010, 17h54
  2. execution de binaire et recuperation stderr
    Par oniric dans le forum Langage
    Réponses: 4
    Dernier message: 05/12/2007, 17h00
  3. executer un binaire dans un .jar
    Par yli_ren dans le forum Général Java
    Réponses: 5
    Dernier message: 25/06/2007, 16h20
  4. Cryptor , executer un exe en memoire
    Par Hitchigo dans le forum Delphi
    Réponses: 10
    Dernier message: 02/08/2006, 21h08
  5. [Exécutable]puis je creer un executable a partir de mon code ?
    Par youpileouf dans le forum Général Java
    Réponses: 3
    Dernier message: 17/06/2005, 09h15

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo