2017-09-28 17 views
1

je travaille sur un programme écrit en assembleur:Compiler programme d'assemblage binaire forme plat comprend les caractères étrangers « f » qui n'existent pas dans d'autres formats

xor eax, eax  ; make eax equal to 0 
push eax   ; pushes null 
push 0x68732f2f  ; pushes /sh (//) 
push 0x6e69622f  ; pushes /bin 
mov ebx, esp  ; passes the first argument 
push eax   ; empty third argument 
mov edx, esp  ; passes the third argument 
push eax   ; empty second argument 
mov ecx, esp  ; passes the second argument 
mov al, 11   ; execve system call #11 
int 0x80   ; makes an interrupt 

Lorsque compilé en utilisant nasm comme plat -forme binaire, je vois des caractères étrangers f dans la représentation hexadécimale du programme. Je comptais voir

0000000: 31c0 5068 2f2f 7368 682f 6269 6e89 e350 1.Ph//shh/bin..P         
0000010: 89e2 5089 e1b0 0bcd 80     ..P...... 

mais en fait voir:

0000000: 6631 c066 5066 682f 2f73 6866 682f 6269 f1.fPfh//shfh/bi 
0000010: 6e66 89e3 6650 6689 e266 5066 89e1 b00b nf..fPf..fPf.... 
0000020: cd80          .. 

Bizarrement, quand je tente de compiler mon programme en utilisant nasm dans un autre format tel que ELF-32, je vois la représentation hexagonale I je me attends (bien que beaucoup d'autres hex je ne devrais probablement pas inclure dans ma solution):

0000000: 7f45 4c46 0101 0100 0000 0000 0000 0000 .ELF............ 
0000010: 0100 0300 0100 0000 0000 0000 0000 0000 ................ 
0000020: 4000 0000 0000 0000 3400 0000 0000 2800 @.......4.....(. 
0000030: 0500 0200 0000 0000 0000 0000 0000 0000 ................ 
0000040: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 
0000050: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 
0000060: 0000 0000 0000 0000 0100 0000 0100 0000 ................ 
0000070: 0600 0000 0000 0000 1001 0000 1900 0000 ................ 
0000080: 0000 0000 0000 0000 1000 0000 0000 0000 ................ 
0000090: 0700 0000 0300 0000 0000 0000 0000 0000 ................ 
00000a0: 3001 0000 2100 0000 0000 0000 0000 0000 0...!........... 
00000b0: 0100 0000 0000 0000 1100 0000 0200 0000 ................ 
00000c0: 0000 0000 0000 0000 6001 0000 3000 0000 ........`...0... 
00000d0: 0400 0000 0300 0000 0400 0000 1000 0000 ................ 
00000e0: 1900 0000 0300 0000 0000 0000 0000 0000 ................ 
00000f0: 9001 0000 1000 0000 0000 0000 0000 0000 ................ 
0000100: 0100 0000 0000 0000 0000 0000 0000 0000 ................ 
0000110: 31c0 5068 2f2f 7368 682f 6269 6e89 e350 1.Ph//shh/bin..P 
0000120: 89e2 5089 e1b0 0bcd 8000 0000 0000 0000 ..P............. 
0000130: 002e 7465 7874 002e 7368 7374 7274 6162 ..text..shstrtab 
0000140: 002e 7379 6d74 6162 002e 7374 7274 6162 ..symtab..strtab 
0000150: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 
0000160: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 
0000170: 0100 0000 0000 0000 0000 0000 0400 f1ff ................ 
0000180: 0000 0000 0000 0000 0000 0000 0300 0100 ................ 
0000190: 0073 6865 6c6c 7370 6177 6e2e 6173 6d00 .shellspawn.asm. 

pour ce que je suis en train d'accomplir, je pense que je dois utiliser un binaire forme plate.

Ma question: d'où vient ce caractère f et qu'est-ce que cela signifie? comment puis-je l'enlever?

NASM version 2.10.09 compiled on Dec 29 2013

xxd V1.10 27oct98 by Juergen Weigert

+0

Si vous voulez juste passer les pointeurs à NULL comme 2ème et 3ème arguments, pourquoi ne pas les faire pointer vers le premier résultat 'push eax' (qui est aussi le terminateur de chaîne)? c'est-à-dire xor-zero/push/'mov edx, esp' /' mov ecx, esp'. En outre, [la page de manuel] (http://man7.org/linux/man-pages/man2/execve.2.html) indique que vous pouvez réellement passer un argv = NULL et envp = NULL (mais avertit que ce n'est pas portable et n'en dépendez pas). Donc vous pouvez juste 'xor edx, edx' /' pousser edx'/.../'mov ecx, edx' /' lea eax, [edx + 11] '. –

Répondre

2

nasm -f bin définit le mode par défaut à 16 bits. Dans ce mode, les instructions de taille d'opérande de 32 bits (comme xor eax,eax ou push eax) doivent être codées avec un préfixe de taille d'opérande 0x66. Voir this table des modes par rapport aux préfixes pour la taille de l'opérande et la taille de l'adresse. (f est 0x66 en ASCII). Voir aussi les liens vers les manuels x86 dans le wiki tag du . Voir aussi how to disassemble flat binaries en mode 16, 32 ou 64 bits.

-f elf est un synonyme de -felf32, donc son mode de ciblage 32 bits. -felf64 cible le mode 64 bits (push eax ne peut pas être codé). dans le manuel NASM: BITS 32 indique l'assembleur à l'assembleur pour le mode 32 bits, remplaçant la valeur par défaut en fonction du format de fichier de sortie. IDK s'il existe une option de ligne de commande qui crée des binaires plats avec du code 32 bits. Je n'en vois pas dans la page de manuel ou --help.Si, pour une raison ou une autre, vous ne voulez vraiment pas modifier vos sources, vous pouvez utiliser -felf et utiliser ld --oformat binary pour lier les binaires plats. Voir How to generate plain binaries like nasm -f bin with the GNU GAS assembler?

Ah, les docs impliquent que BITS 32 est la seule façon:

Le plus probable raison d'utiliser la directive BITS est d'écrire 32 bits ou code 64 bits dans un fichier binaire plat;


révision du code de votre code actuel:

Si vous voulez juste passer des pointeurs à NULL comme 2ème et 3ème args, pourquoi pas les deux points du premier résultat push eax (qui est aussi le terminateur de chaîne)? c'est-à-dire xor-zero/push/mov edx, esp/mov ecx, esp.

En outre, the man page dit que vous pouvez réellement passer un argv = NULL et envp = NULL (mais avertit que ce n'est pas portable et ne dépend pas de lui). Donc, vous pouvez simplement xor edx,edx/push edx/.../mov ecx,edx/lea eax, [edx+11].

+0

Je suis allé avec 'BITS 32' et maintenant hex représente la façon dont je voudrais. Merci! – jakenberg

0

Je préface ce avec, je ne suis pas certain à 100% de cela, mais ...

Selon This website, il est une taille opérande préfixe de priorité. Je vais deviner que l'assembleur est très prudent, ou peut-être qu'il est configuré pour la sortie de l'assembleur 32 bits et qu'il est amusant d'essayer de s'assurer que vos instructions xor et mov sont de la bonne taille. Il semble que cela n'affecte en fait pas le temps d'exécution, si ce site est correct, alors peut-être juste un habillage supplémentaire.

Je revérifierais les drapeaux passés dans nasm pour être sûr que vous ne lui dites pas accidentellement de faire le mouvement que vous attendez.

Ou l'espoir d'une réponse plus approfondie d'un codeur récent x86 asm mor :)

+0

Merci pour votre réponse utile Michael. Mon utilisation nasm est la suivante: 'nasm shellspawn.asm'. J'ai essayé d'être plus précis que cela mais j'ai les mêmes résultats. Je vais continuer à rechercher cette avenue – jakenberg

+1

Ce n'est pas une question de "plus prudent". En code 32 bits, la taille d'opérande '0x66' signifie une taille d'opérande de 16 bits, donc vous devez obtenir le bon mode. Mais oui, @jakenberg la valeur par défaut pour '-fbin' est le mode 16 bits. Vous pouvez utiliser une directive 'BITS 32'. Je ne suis pas sûr s'il existe une option NASM pour définir le mode à 32 bits tout en faisant un binaire plat. –

+0

Merci Peter. J'ai mis 'BITS 32' en haut de mon fichier' .asm' et je ne vois plus les préfixes d'opérande de taille. J'ai appris quelque chose de vous deux! – jakenberg