J'essaie de lire la pile d'un processus enfant mais sans succès. Je sais qu'il est possible d'utiliser ptrace
, mais ptrace
l'interface de vous permet de lire un seul mot à la fois, et j'essaie de numériser une plus grande partie de la pile.
J'ai également essayé de lire les /proc/$pid/mem
limites de la pile extraites du /proc/$pid/maps
fichier après avoir d'abord utilisé ptrace pour y attacher (comme suggéré ici ) mais la lecture continue d'échouer (même lors de l'exécution en tant que root) bien que le même code réussisse lorsqu'il est essayé lecture de différentes parties du processus (par exemple, tas).
Qu'est-ce que je fais mal? Y a-t-il une autre option?
waitpid
entreptrace(PTRACE_ATTACH,…)
etread
(sinon il existe une condition de concurrence possible)? Quelle erreurread
revient? L'enfant fait-il quelque chose de particulier avec son mappage de mémoire - pouvez-vous essayer votre code avec un enfant simple commesleep
?Réponses:
Eh bien, utilisez simplement une boucle, alors. Honnêtement, je ne vois pas en quoi cela constitue un problème
ptrace
, je l'utilise tout le temps pour accéder à distance aux processus.J'utilise quelque chose comme ça:
la source
Voici une autre stratégie qui pourrait nécessiter des ajustements mais devrait être plus efficace avec de gros morceaux de données. L'idée est d'exécuter des appels système dans le processus distant afin de récupérer le contenu de la pile. Il aura besoin d'un code d'architecture spécifique mais si vous ne ciblez que x86 / x86_64, cela ne devrait pas être trop compliqué.
"/tmp/fifo"
dans votre processus d'appel.PTRACE_SYSCALL
étape,waitpid()
pour attendre etPTRACE_GETREGS
/PTRACE_PEEKTEXT
pour vérifier l'opcode actuellement exécuté.open("/tmp/fifo")
,write()
le contenu de la pile,close()
le descripteur.Il pourrait y avoir des alternatives plus élégantes à la pipe nommée, mais je ne peux pas en penser pour le moment. La raison pour laquelle j'utilise uniquement les appels système est que l'injection de code à distance est assez peu fiable sur les systèmes modernes en raison de diverses protections de sécurité. L'inconvénient est qu'il se bloque jusqu'à ce que le processus distant effectue un appel système (ce qui peut être un problème pour certains programmes qui effectuent principalement des calculs).
Vous pouvez voir du code gratuit implémentant la plupart des travaux dans ce fichier source . Les commentaires sur le code sont les bienvenus!
la source
Une autre suggestion.
Lorsque / s'il est accepté dans l'arborescence principale du noyau Linux, vous pourrez utiliser le patch Cross Memory Attach de Christopher Yeoh . Voir la documentation de process_vm_readv par exemple.
la source
Vous pouvez facilement lire la pile d'un autre processus en utilisant le système de fichiers proc (vous aurez besoin d'un accès root pour cela). Avant de lire arbitrairement le / proc / pid / mem, vous devez consulter le / proc / pid / maps. Une simple lecture dans ce fichier montre beaucoup d'entrées. Nous sommes intéressés par l'entrée marquée comme pile. Une fois que vous obtenez cela, vous devez lire les limites inférieure et supérieure de la pile. Maintenant, ouvrez simplement le fichier / proc / pid / mem, recherchez la limite inférieure de la pile et lisez la taille correcte des données.
la source
mems
et nonmaps
? (Je ne vois aucunemems
entrée sous mon/proc
système de fichiers.) L'OP a déjà mentionné la lecture des limites de la pile/proc/$pid/maps
- de quoi suggérez-vous qu'ils font différemment?Vous pouvez essayer lsstack . Il utilise ptrace, comme tous les autres programmes réussis "lire la pile d'un autre processus". Je n'ai pas pu faire fonctionner un programme utilisant / proc / $ pid / mem. Je crois que vous ne pouvez pas le faire de cette façon, même si, logiquement, vous devriez.
la source