Estou tentando ler a pilha de um processo filho, mas sem sorte. Eu sei que é possível usar ptrace
, mas ptrace
a interface permite que você leia apenas uma palavra de cada vez, e estou tentando digitalizar partes maiores da pilha.
Também tentei ler os /proc/$pid/mem
limites da pilha como extraídos do /proc/$pid/maps
arquivo depois de usar o ptrace para anexar a ele (como sugerido aqui ), mas a leitura continua falhando (mesmo quando executado como root), embora o mesmo código tenha êxito ao ser tentado leitura de diferentes partes do processo (por exemplo, heap).
O que estou fazendo de errado? Existe alguma outra opção?
waitpid
entreptrace(PTRACE_ATTACH,…)
eread
(caso contrário, há uma possível condição de corrida)? Que erroread
retorna? A criança está fazendo algo peculiar com seu mapeamento de memória - você pode tentar seu código com uma criança simples comosleep
?Respostas:
Bem, basta usar um loop, então. Sinceramente, não vejo como isso constitui um problema
ptrace
; uso-o o tempo todo para acessar processos remotamente.Eu uso algo como isto:
fonte
Aqui está outra estratégia que pode precisar de ajustes, mas deve ser mais eficiente com grandes blocos de dados. A idéia é executar syscalls no processo remoto para recuperar o conteúdo da pilha. Ele precisará de um código de arquitetura específico, mas se você segmentar apenas x86 / x86_64, não deve ser muito complicado.
"/tmp/fifo"
no seu processo de chamada.PTRACE_SYSCALL
para avançar,waitpid()
para aguardar ePTRACE_GETREGS
/PTRACE_PEEKTEXT
para verificar o código de operação atualmente executado.open("/tmp/fifo")
,write()
o conteúdo da pilha,close()
o descritor.Pode haver alternativas mais elegantes para o pipe nomeado, mas não consigo pensar em nenhuma agora. A razão de eu usar somente syscalls é porque a injeção remota de código não é confiável nos sistemas modernos devido a várias proteções de segurança. A desvantagem é que ele travará até que o processo remoto faça uma syscall (o que pode ser um problema para alguns programas que geralmente fazem cálculos).
Você pode ver algum código gratuito implementando a maior parte do trabalho neste arquivo de origem . Comentários sobre o código são bem-vindos!
fonte
Outra sugestão.
Quando / se for aceito na árvore principal do kernel Linux, você poderá usar o patch Cross Memory Attach de Christopher Yeoh . Consulte a documentação de process_vm_readv, por exemplo.
fonte
Você pode ler facilmente a pilha de outro processo usando o sistema de arquivos proc (você precisará de acesso root para isso). Antes de ler arbitrariamente a partir do / proc / pid / mem, você precisa consultar o / proc / pid / maps. Uma simples leitura neste arquivo mostra muitas entradas. Estamos interessados na entrada marcada como pilha. Depois de conseguir isso, você precisa ler os limites inferior e superior da pilha. Agora simplesmente abra o arquivo / proc / pid / mem, procure o limite inferior da pilha e leia o tamanho correto dos dados.
fonte
mems
e nãomaps
? (Não consigo ver nenhumamems
entrada no meu/proc
sistema de arquivos.) O OP já mencionou a leitura dos limites da pilha/proc/$pid/maps
- o que você sugere que eles façam de maneira diferente?Você pode tentar lsstack . Ele usa o ptrace, assim como qualquer outro programa bem-sucedido de "leia a pilha de outro processo". Não consegui obter um programa usando / proc / $ pid / mem reading para funcionar. Acredito que você não pode fazer dessa maneira, embora, logicamente, deva.
fonte