sys_execve système d'appel de l'Assemblée
asm_execve.s:
.de la section .données file_to_run: .ascii "/bin/sh" .de la section .texte .globl principal principales: pushl %ebp movl %esp, %ebp subl $0x8, %esp # tableau de deux pointeurs. tableau[0] = file_to_run tableau[1] = 0 movl file_to_run, %edi movl %edi, -0x4(%ebp) movl $0, -0x8(%ebp) movl $à 11$, %eax # sys_execve movl file_to_run, %ebx # fichier pour l'exécuter leal -4(%ebp), %ecx # paramètres de ligne de commande movl $0, %edx # bloc d'environnement int $0x80 laisser ret
makefile:
NOM = asm_execve $(NOM) : $(NAME).s gcc-o $(NAME) $(NAME).s
Programme est exécuté, mais sys_execve n'est pas appelé:
alex@alex32:~/projet$ make gcc-o asm_execve asm_execve.s alex@alex32:~/projet$ ./asm_execve alex@alex32:~/projet$
Sortie attendue est:
alex@alex32:~/projet$ ./asm_execve $ exit alex@alex32:~/projet$
Cette Assemblée programme est censé fonctionner comme suivants du code C:
char *data[2]; data[0] = "/bin/sh"; data[1] = NULL; execve(data[0], données, NULL);
Quelque chose de mal dans le système les paramètres d'appel?
Utilisation
strace -e execve
de retracer l'appel execve votre programme en fait, rend.OriginalL'auteur Alex F | 2012-02-18
Vous devez vous connecter pour publier un commentaire.
La
execve
appel système est être appelé, mais vous êtes en effet de passer ce mal de paramètres.(Vous pouvez le voir en cours d'exécution de votre exécutable à l'aide de
strace
.)Il y a trois problèmes:
.ascii
n'0 à la fin de la chaîne. (Vous pourriez avoir de la chance, car il n'y a rien qui le suivent dans votre.data
section dans cet exemple, mais ce n'est pas garanti...) Ajouter un 0, ou de l'utilisation.asciz
(ou.string
) à la place.movl file_to_run, %edi
déplace la valeur souligné par lefile_to_run
symbole dans%edi
, c'est à dire les 4 premiers octets de la chaîne (0x6e69622f
). Le adresse de la chaîne est juste la valeur du symbole lui-même, si vous avez besoin d'utiliser le$
préfixe pour les valeurs littérales:movl $file_to_run, %edi
. De même, vous avez besoin de diremovl $file_to_run, %ebx
quelques lignes plus bas. (Ce qui est une source fréquente de confusion entre AT&T syntaxe et syntaxe Intel!)Les paramètres sont placés sur la pile dans le mauvais ordre:
-0x8(%ebp)
est plus faible que-0x4(%ebp)
. L'adresse de la chaîne de commande doit être écrite à-0x8(%ebp)
, le 0 doit être écrite à-0x4(%ebp)
, et laleal
l'instruction devrait êtreleal -8(%ebp), %ecx
.Code fixe:
argv
ouenvp
à fait NULL (comme vous le faites pour envp), de sortexor %ecx,%ecx
;xor %edx,%edx
. Un moyen plus facile de créerargv[]
sur la pile seraitmov $file_to_run, %ebx
;push $0
(ou une remise à zéro reg);push %ebx
;mov %esp, %ecx
.OriginalL'auteur Matthew Slattery
Vous avez réellement n'avez pas besoin de charger quoi que ce soit dans les autres arguments. Si vous le faites dans le x86 suivantes simple code de travail:
Ce sera, pour l'essentiel ouvrir un terminal après l'invocation de l'appel système.
xor %ecx,%ecx
à zéro des registres. Êtes-vous sûr que le passage de la non-zéro déchet œuvres? Rien d'autre que0
(ou un pointeur valide) devrait rendre le système de retour d'appel de-EFAULT
. Pointeurs NULL pourargv
etenvp
sont spécialement documenté que Linux-comportement spécifique (man7.org/linux/man-pages/man2/execve.2.html), et l'équivalent pour le passage d'un pointeur un pointeur NULL. Mais cela ne veut pas dire que d'autres mauvais conseils de "travail". Qui serait effectivement un bug dans la mise en œuvre, s'il est allé et execed quelque chose au lieu de retourner-EFAULT
avec les non-0 mauvais pointeursOui, vous avez raison. J'en suis désolé. J'ai fondamentalement signifie que vous si vous voulez ouvrir un terminal, vous n'avez pas besoin d'arguments spécifiques et il faudra encore travailler si vous donnez les valeurs null.
Êtes-vous sûr que vous avez testé? Vous avez besoin
$file_to_run
, sinon vous êtes juste de chargement les 4 premiers octets de la chaîne et de le transmettre comme un pointeur. Aussi, vous sauver/restaurerebp
, mais votre code clobbersebx
. Si vous voulez retourner en toute sécurité au lieu de s'écraser quandexecve
renvoie une erreur au lieu de execcing, vous devriezpush/pop
ebx ainsi / au lieu de faire un frame de pile. (Peut-être le CRT code est ok si vous tabasser ebx.) Améliorations facultatives: votre chaîne peut aller dans.rodata
de sorte que vous n'avez pas besoin d'un.data
section. Vous pouvez utiliser.asciiz
pour obtenir un zéro chaîne terminée.OriginalL'auteur Shank