2017-10-11 56 views
0

런타임시 공유 라이브러리가 현재 프로세스의 전역 심볼 네임 스페이스에로드되었는지 확인할 수 있습니까? 나는 주로 RTLD_GLOBAL 플래그를 사용하는 dlopen() 호출 결과로드 된 모든 것에 관심이 있습니다.dlopen (RTLD_GLOBAL)을 통해로드 된 공유 라이브러리 열거

감사 용도로이 작업을 수행하고 싶습니다. 동적으로로드되는 공유 라이브러리는 타사 코드와 충돌하지 않도록 가능하면 dlopenRTLD_LOCAL으로로드됩니다. 전역 심볼 네임 스페이스에로드 된 모든 것을 엄격하게 제어해야합니다.

나는 dl_iterate_phdr() API를 보았지만이 정보는 포함되지 않은 것 같습니다.

+0

글쎄, 당신이 null가 반환, RTLD_NOLOAD로한다면 dlopen 예를 들어 사용 (이 목록이있는 경우) 확인하실 수 있습니다 또는 이미로드되었는지 여부에 따라 처리 할 수 ​​있습니다. 아마 당신을 도울 수있는 것은/proc/PID/maps 구문 분석/분석 일 것입니다. 또한 도움이 될 수 있습니다. [https://stackoverflow.com/questions/5103443/how-to-check-what-shared-libraries-are-loaded-at-run-time-for-a-given-process) –

답변

1

당신은 LD_PRELOAD=dlo.so를 추가하고 여기에 당신이가는 gcc -shared -fPIC dlo.c -o dlo.so -ldl 를 사용하여 컴파일

#define _GNU_SOURCE 
#include <dlfcn.h> 

typedef void *(*orig_dl)(const char *file, int mode); 
void *dlopen(const char *file, int mode) 
{ 
    orig_dl o_dlopen; 
    o_dlopen = (orig_dl)dlsym(RTLD_NEXT, "dlopen"); 
    return o_dlopen(file, mode); 
} 

으로 시도 할 수 있습니다. 당신은 종속 dlopen() 그런 식으로로드 라이브러리의을 잡을 것이다 - 당신은 내가 제안이 dlopen()은 단지 부분적인 해결책을 LD_PRELOAD를 사용하여 교체 할 생각 특정 모드

0

으로 추적/인쇄/어떤 dlopen을 사용하여 로그인 할 수 있습니다.

결국 동적 링커 자체의 내부 상태를 긁지 않고이 작업을 수행 할 수있는 방법이 없습니다. 정보가있는 ld.so에서 내 보낸 _rtld_global 기호가 있음을 알았지 만,이를 해석하기 위해 개인 Glibc 헤더를 사용해야합니다.

다음은 전역 네임 스페이스의 모든 공유 라이브러리를 검색 순서대로 인쇄하는 Python 스 니펫입니다 (Glibc 소스를 올바르게 읽은 것으로 가정). RTLD_LOCAL이로드 된 라이브러리는 인쇄되지 않습니다.

Glibc의 구현 세부 사항에 의존한다는 사실은이 접근법이 위험을 안고 있음을 의미하지만 내 테스트/감사 목적을 위해서는 잘 수행 할 것이라고 생각합니다.

내 CentOS는에
import ctypes 

# Abridged type declarations pillaged from Glibc. See: 
# - https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/generic/ldsodefs.h 
# - https://sourceware.org/git/?p=glibc.git;a=blob;f=include/link.h 

class link_map(ctypes.Structure): 
    _fields_ = [ 
     ("l_addr", ctypes.c_size_t), 
     ("l_name", ctypes.c_char_p), 
    ] 


class r_scope_elem(ctypes.Structure): 
    _fields_ = [ 
     ("r_list", ctypes.POINTER(ctypes.POINTER(link_map))), 
     ("r_nlist", ctypes.c_uint), 
    ] 


class rtld_global(ctypes.Structure): 
    _fields_ = [ 
     ("_ns_loaded", ctypes.POINTER(link_map)), 
     ("_ns_nloaded", ctypes.c_uint), 
     ("_ns_main_searchlist", ctypes.POINTER(r_scope_elem)), 
    ] 

_rtld_global = rtld_global.in_dll(ctypes.CDLL(None), "_rtld_global") 
searchlist = _rtld_global._ns_main_searchlist[0] 

print [searchlist.r_list[n][0].l_name for n in xrange(searchlist.r_nlist)] 

7 시스템이 인쇄 : 라이브러리가 이미로드되어있는 경우

['', '/lib64/libpython2.7.so.1.0', '/lib64/libpthread.so.0', '/lib64/libdl.so.2', 
'/lib64/libutil.so.1', '/lib64/libm.so.6', '/lib64/libc.so.6', 
'/lib64/ld-linux-x86-64.so.2']