성공하지 못한 채 하위 프로세스의 스택을 읽으려고 합니다. 작동한다는 것을 알고 있지만 ptrace
인터페이스 ptrace
를 사용하면 한 번에 한 단어만 읽을 수 있는 반면, 저는 스택의 더 큰 부분을 스캔하려고 합니다.
/proc/$pid/mem
또한 제안된 대로 ptrace를 사용하여 파일에 처음 첨부한 후 파일에서 추출된 스택 경계에서 읽기를 시도했습니다./proc/$pid/maps
여기) 그러나 프로세스의 다른 부분(예: 힙)에서 읽으려고 시도할 때 동일한 코드가 성공하더라도 읽기는 계속 실패합니다(루트로 실행하는 경우에도).
내가 뭘 잘못했나요? 다른 옵션이 있나요?
답변1
ptrace
인터페이스를 사용하면 한 번에 한 단어만 읽을 수 있지만 저는 스택의 더 많은 부분을 스캔하려고 합니다.
좋습니다. 루프를 사용해 보겠습니다. 솔직히 이것이 어떻게 문제를 일으키는지 모르겠습니다 ptrace
. 저는 항상 프로세스에 원격으로 액세스하는 데 이를 사용해 왔습니다.
나는 다음과 같은 것을 사용합니다 :
static int memcpy_from_target(pid_t pid, char *dest, long src, size_t n)
{
static int const align = sizeof(long) - 1;
while (n)
{
size_t todo = MIN(n, sizeof(long) - (src & align));
long data = ptrace(PTRACE_PEEKTEXT, pid, src - (src & align), 0);
if (errno)
{
perror("ptrace_peektext (memcpy_from_target)");
return -1;
}
memcpy(dest, (char *)&data + (src & align), todo);
dest += todo; src += todo; n -= todo;
}
return 0;
}
답변2
이는 조정이 필요할 수 있는 또 다른 전략이지만 대량의 데이터에 더 효과적입니다. 아이디어는 스택 내용을 검색하기 위해 원격 프로세스에서 시스템 호출을 수행하는 것입니다. 아키텍처별 코드가 필요하지만 x86/x86_64만 대상으로 하는 경우에는 큰 문제가 발생하지 않습니다.
"/tmp/fifo"
예를 들어 호출 프로세스에서 명명된 파이프를 만듭니다 .PTRACE_SYSCALL
단계,waitpid()
대기 및PTRACE_GETREGS
/PTRACE_PEEKTEXT
또는 현재 실행 중인 opcode를 확인 하여 시스템 호출에서 반환될 때까지 추적된 프로세스로 들어갑니다 .- 원격 프로세스의 레지스터와 해당 스택의 작은 영역을 백업합니다.
open("/tmp/fifo")
자신의 데이터( ,write()
스택 내용,close()
설명자) 로 스택을 덮어써서 원격 프로세스에서 시스템 호출을 실행합니다 .- 원격 프로세스의 상태를 복원합니다.
- 호출 프로세스에서 FIFO 데이터를 읽습니다.
명명된 파이프에 대한 더 우아한 대안이 있을 수 있지만 지금은 그것들이 생각나지 않습니다. 내가 시스템 호출만 사용하는 이유는 다양한 보안 보호로 인해 원격 코드 주입이 최신 시스템에서 상당히 신뢰할 수 없기 때문입니다. 단점은 원격 프로세스가 시스템 호출을 수행할 때까지 정지된다는 점입니다(주로 계산을 수행하는 일부 프로그램에서는 문제가 될 수 있음).
다음에서 대부분의 작업을 수행하는 무료 코드를 볼 수 있습니다.이 소스 파일. 코드에 대한 피드백을 환영합니다!
답변3
또 다른 제안.
메인 Linux 커널 트리에 승인되면 Christopher Yeoh의크로스 메모리 연결수리하다. 문서 보기process_vm_readv예를 들어.
답변4
당신은 시도 할 수 있습니다스택. 다른 모든 성공적인 "다른 프로세스의 스택 읽기" 프로그램과 마찬가지로 ptrace를 사용합니다. /proc/$pid/mem 읽기를 사용하여 프로그램을 작동시킬 수 없습니다. 논리적으로는 그렇게 해야 하지만 나는 그렇게 할 수 없다고 믿습니다.