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

Linux Discussion :

[C]Redéfinir/capturer un syscall (et pas une fonction)


Sujet :

Linux

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2010
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2010
    Messages : 21
    Points : 35
    Points
    35
    Par défaut [C]Redéfinir/capturer un syscall (et pas une fonction)
    Bien le bonjour,

    Je suis étudiant en informatique, et j'ai un projet dans lequel il faut coder un mini-shell, qui réimplémente "open", pour effectuer divers traitements.
    Pour le codage du shell, OK ça va, pas de problèmes.
    Le chargement et la compilation de la librairie dynamique qui redéfinit "open" avec LD_PRELOAD, ça roule (ça a l'air en tout cas).
    Par contre après avoir testé, rien, le néant, pas de réaction, comme si mon "open" n'existait pas.

    Hélas, je venait de brutalement apprendre qu'il y avait "open" et "open", la libc nous cache des choses...
    D'après ce que j'ai compris, le "open" de la libc n'est qu'une fonction (section 3 du man), une pâle copie du véritable appel système qui lui est codé en asm, mais qui d'après ce que j'ai lu appelle le syscall presque immédiatement, elle effectue juste 2-3 verifications avant ça (merci de me corriger si je me trompe).
    Apparemment on appelle ça un wrapper, pour nous éviter d'avoir à utiliser nous-même "syscall" si j'ai bien compris.

    Et donc là est mon problème : ma fonction "open" sera utilisée lorsqu'une commande fera appel à open(3), mais si cette commande utilise directement le syscall, ben mon beau "open" customisé ne sert à rien, on n'y passe jamais. Et apparemment c'est le cas pour toutes les commandes utiles/interessantes du shell.

    La seule chose que j'ai constatée, c'est que lorsque j'utilise une commande svn (ou man), du style "svn log", là mon "open" est pris, et du coup je vois toutes les ouvertures de fichiers (vu que je "printf" les arguments pour tester mon "open"). Du coup ben super, c'est marrant, je comprends bien que "svn" utilise le open(3) mais ça m'avance pas plus.

    Du coup voila ou j'en suis, je cherche comment faire pour intercepter, ou redéfinir cet appel système...et c'est donc là que j'ai besoin de votre aide ^^

    Bon je ne demande pas une solution toute faite, mais juste une piste, quelque chose pour m'aiguiller.
    En fait, il faut "juste" que la commande passe par mon "open", c'est tout ^^.
    Pour l'instant je regarde du coté de "ptrace", donc suivi de l'exécution d'un processus, et de ce qu'il a en mémoire, mais je patauge quand même...


    Merci d'avance à ceux qui prendront la peine de me lire ! (et de me répondre bien sur ;-)

  2. #2
    Membre à l'essai
    Inscrit en
    Septembre 2010
    Messages
    22
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 22
    Points : 14
    Points
    14
    Par défaut
    Fait un "objdump -T /bin/ta_commande" (ou /usr/bin/tacommande).
    Tu verras les différents appels a la libc que fais ta commande. (rajoute | grep open pour filtrer au besoin).
    Tu verras par exemple que "ls" ne fait pas d'appel à open... (en fait il fait appel à opendir qui fait un appel noyau à open, donc impossible d'intercepter le open).

    Pour ton problème, j'ai eu à peu près la même chose. En fait il y a plusieurs types d'open :
    le open à deux arguments (path, flag) et celui à 3 arguments (path, flag, mode)

    Il y a egalement open64. C'est la même chose que open, mais ce dernier est très souvent utilisé par les diverses commandes. Donc ca peut venir de là.

    Un ptit lien au cas ou : http://stackoverflow.com/questions/6...inux-sys-calls

    Perso en ayant redefini open et open64, j'ai constaté que pour des commandes comme touch,less,cp par exemple, c'était open64 qui était appelé.

    Après, y a certain appel que tu ne peux intercepter. Tel que la commande "passwd" qui fait un appel à open64, mais qui pour des raisons de sécurité t'empeche d'intercepter ce dernier.


    ps : moi j'galère sur le minishell

  3. #3
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2010
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2010
    Messages : 21
    Points : 35
    Points
    35
    Par défaut
    Merci de ta réponse, je commençais un peu à désespérer ^^



    Pas mal le coup du objdump, je connaissais pas. Par contre en ce qui me concerne, touch, ls et cp n'utilisent pas open64, je sais pas pourquoi...mystère mystère...

    Pour les open a 2 ou 3 arguments j'avais réglé ça, mais effectivement, j'avais carrément passé le open64 ! J'avais bien lu le header et les sources de la libc, mais j'étais passé trop vite dessus... en fait j'ai vu openat et tout le reste et je m'étais dit que non c'était pas la peine de s'y intéresser de plus près. Argh l'erreur, on ne m'y reprendra plus.

    Merci aussi pour le lien, c'est toujours instructif !

    A part ça, je voulais essayer de redéfinir la fonction syscall() (on sort l'artillerie lourde) lorsqu'ell est appelée pour open, mais marche pas :-(

    Du coup y'a pas de moyen de réimplémenter complètement open (dans l'exemple du sujet, le prof utilise ls quand même, alors que pour l'instant ls n'utilise pas ma lib).

    Mais merci beaucoup pour ton aide, ça m'a débloqué !

  4. #4
    Membre à l'essai
    Inscrit en
    Septembre 2010
    Messages
    22
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 22
    Points : 14
    Points
    14
    Par défaut
    Oui, j'ai constaté que l'exemple du prof était faux.
    "ls" ne faisant pas d'appel à open via la libc (mais via le noyau)

    A tout hasard, j'ai réimplémenté opendir. Mais ca change rien au probleme.
    Dans le 1er exemple ("ls"), il faut tester si il y a un argument ; Si il y en a pas tu génère un message d'erreur ("pola no access read blabla...").
    Cependant, c'est impossible à faire... tout simplement car le systeme UNIX te mettra automatiquement "." dans ton pathname de opendir.

    Après tu peux le faire statiquement... mais bof quoi

    Bref, pour moi le sujet est bancal :p

  5. #5
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2010
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2010
    Messages : 21
    Points : 35
    Points
    35
    Par défaut
    Ah, je suis pas fou quand même !!!

    Parce que j'ai essayé de voir et de retourner le problème dans tous les sens, mais décidément j'en arrivait aussi toujours à la même conclusion...on peut pas savoir depuis le open si le fichier apparaissait explicitement sur la ligne de commande, et même si c'était le cas, il faudrait distinguer les commandes qui peuvent attendre un argument comme ls, de celles comme id, ou pwd.

    Au pire on pourra toujours faire les controles pour l'accès en écriture, mais pas pour la lecture. Et comme tu dis, il faudrait faire ça statiquement, alors qu'on est sensé le faire dans le open.



    Enfin bon, à l'assaut de la 3ème partie du sujet maintenant ^^ et encore merci !

  6. #6
    Membre émérite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    1 515
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 515
    Points : 2 505
    Points
    2 505
    Par défaut
    Je n'ai pas compris pourquoi tu cherchais à intercepter les appels à open(). Tu es sûr que c'est la bonne façon de faire ?

  7. #7
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2010
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2010
    Messages : 21
    Points : 35
    Points
    35
    Par défaut
    En fait il s'agit d'un projet dans lequel on nous demande de "réimplémenter les appels à open". Le but était de vérifier que les fichiers que le open() ouvrirait sont sur la ligne de commande, et entourés de chevrons, entre autres.

    exemple qui ne doit pas fonctionner : ls
    exemple qui doit fonctionner : ls <.>

    Et on doit utiliser LD_PRELOAD. Enfin on devait, c'est fini maintenant ^^

    Pourquoi, tu vois une autre façon de faire ?

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 2
    Dernier message: 01/12/2009, 08h58
  2. [DOM] Submit n'est pas une fonction ?
    Par dark_vidor dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 28/03/2009, 15h45
  3. Lancer un script (et pas une fonction) avec un callback
    Par braxxe dans le forum Interfaces Graphiques
    Réponses: 4
    Dernier message: 26/03/2009, 12h44
  4. compilateur ne reconnait pas une fonction existante
    Par loutsa dans le forum GTK+ avec C & C++
    Réponses: 2
    Dernier message: 02/11/2008, 11h40
  5. un module qui ne contient pas une fonction qu'il contient :?
    Par duplo dans le forum Général Python
    Réponses: 12
    Dernier message: 15/08/2006, 20h30

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