Linux에서 현재 rpath를 검사하는 방법이 있습니까?


83

readelf -d <elf> | grep RPATH쉘에서 주어진 바이너리를 검사하는 데 사용할 수 있다는 것을 알고 있지만 프로세스 내에서이 작업을 수행 할 수 있습니까?

(내가 완전히 구성한 시스템 호출) :

  /* get a copy of current rpath into buffer */
  sys_get_current_rpath(&buffer);

코드베이스에서 의심스러운 SO 링크 문제를 진단하려고 시도하고 있으며 가능하면 RPATH를 검사하고 싶습니다 (차라리 외부 스크립트를 생성 할 필요가 없습니다).


1
공유 라이브러리 문제를 진단 할 때 RUNPATH 태그도 검사해야합니다. 따라서 grep PATH대신 해야 합니다. RPATH 또는 RUNPATH의 사용 여부는 링커에 달려 있으며, 둘 사이에는 미묘하지만 중요한 차이점이 있습니다. stackoverflow.com/a/52020177
Nicolas Capens

답변:


54
#include <stdio.h>
#include <elf.h>
#include <link.h>

int main()
{
  const ElfW(Dyn) *dyn = _DYNAMIC;
  const ElfW(Dyn) *rpath = NULL;
  const char *strtab = NULL;
  for (; dyn->d_tag != DT_NULL; ++dyn) {
    if (dyn->d_tag == DT_RPATH) {
      rpath = dyn;
    } else if (dyn->d_tag == DT_STRTAB) {
      strtab = (const char *)dyn->d_un.d_val;
    }
  }

  if (strtab != NULL && rpath != NULL) {
    printf("RPATH: %s\n", strtab + rpath->d_un.d_val);
  }
  return 0;
}

1
훌륭하지만 $ ORIGIN에서는 작동하지 않습니다. $ ORIGIN은 해석되지 않으며 함수에서있는 그대로 반환됩니다. $ ORIGIN 해석을 추가하는 방법이 있습니까?
Jérôme 2014

5
@ Jérôme /proc마운트 된 환경에서 실행하는 경우 확장 $ORIGINreadlink("/proc/self/exe", ...)마지막 슬래시에서 NUL 종료 만큼 간단 합니다.
러시아어 고용

질문이 구체적으로에 관한 것이지만 바이너리가 공유 라이브러리를로드 할 수있는 경로를 알고 싶다면 태그 RPATH를 확인하는 것도 똑같이 중요하다는 점에 주목하고 싶습니다 DT_RUNPATH.
Nicolas Capens

154

기록을 위해 rpath헤더 를 표시하는 몇 가지 명령이 있습니다.

objdump -x binary-or-library |grep RPATH

더 나은 방법은 다음과 같습니다.

readelf -d binary-or-library |head -20

두 번째 명령은 다른 라이브러리에 대한 직접적인 종속성과 rpath.


7
우분투 15.04에서는 다음을 사용해야합니다. objdump -x binary-or-library | grep RUNPATH
Andreas Roth


11
이 답변이없는 것도 요청했다 (되고 질문을 할 포함 된 질문 자체를).
러시아어 고용


1

편의상 쉘 함수로 사용하는 것은 다음과 같습니다.

function getrpath {
    eu-readelf -d "${1:?}" | sed -e '/RUNPATH/{s~.*\[\(.*\)\]~\1~;n};d'
}

이것은 다음 과 같은 eu-readelf출력을 소비 합니다 elfutils.

Type              Value
NEEDED            Shared library: [libpq.so.5]
NEEDED            Shared library: [libc.so.6]
RUNPATH           Library runpath: [/some/path/to/lib]
....

그리고 방출

 /some/path/to/lib

readelfelfutils 대신 binutils에서도 잘 작동합니다 eu-readelf.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.