2016-06-15 3 views
1

"foo"의 텍스트 세그먼트를로드하는 대신 동적으로 연결된 실행 파일 (execve("foo", "", ""))을 동적으로 실행하려고하면 동적 링커가로드되고 (ld-linux.so.2) 올바르게 실행됩니다. "foo"에서 의 주소를 변경하고 foo로 제어를 전달하려면 프로그램 ("foo")에 필요한 라이브러리를로드해야하지만 어떻게 구현됩니까?동적 링커는 프로세스의 텍스트 세그먼트를 어떻게 변경합니까?

어떻게하고 (그것을 사용 부르는 시스템) 여기서 메모리에 않는 동적 로더로드 라이브러리 "foo는"의 코드와 데이터가 (단순히 의 malloc이나 mmap를 사용하고 그 이후 코드로 점프 할 수없는 그것을 추측하고있다 그것도 불가능합니다. 맞습니까? 실행 파일 (정적으로 링크 된 파일처럼)을 작성하고 다시 exceve를 호출하는 임시 파일을 작성하는 것 같지 않습니다.).

+0

"불가능해야하므로 맞지 않습니까?" 잘못된. –

+1

이상하게도 불가능한 것은 데스크톱과 모바일 컴퓨터를 포함한 다른 컴퓨터에서 잘 작동합니다. 동적 연결에 대한 독자적인 연구와 Linux (및 기타 최신 OS)에서 프로그램을 초기화하는 방법에 대해 조사하고 싶을 수도 있습니다. – Olaf

답변

0

실제 구현은 ELF를 기반으로하기 때문에 상당히 복잡합니다. ELF는 많은 시나리오를 수용하려고 시도하지만 상당히 복잡하지만 개념적으로 매우 간단합니다. (라이브러리 의존성이있는 및 open 에드 후)

은 기본적으로는 mmap에 s의 몇 mprotect는의의, 약간의 수정 (지연 될 수 있습니다) 기호를 결합하여 연결을 구현 한 다음 코드로 이동합니다 .

은 이상적으로는 링크 된 공유 라이브러리는 링커가 라이브러리의 .text 섹션 (= 실행 코드)를 작성하지 않고도 어디서나 프로세스 주소 공간에 배치 할 수 -fpic/-fPIC로 컴파일됩니다. 이러한 라이브러리/실행 파일은 수정 가능한 테이블을 통해 다른 라이브러리의 함수를 호출합니다.이 테이블은 링커가 종속 라이브러리를로드 한 실제 위치를 가리 키도록 (아마도 느슨하게) 수정합니다. 하나의 공유 라이브러리에서 다른 공유 라이브러리로 변수에 액세스하는 방법은 비슷하게 간접적입니다.

수정 라이브러리 데이터/코드를 최대한 제한하면 코드 섹션을 MMU/mprotect 시스템 호출을 통해 읽기 전용으로 표시하고 해당 특정 라이브러리를 사용하는 모든 프로세스에서 공유되는 메모리에 매핑 할 수 있습니다.


가 콜 레벨에서 발생하는 아이디어를 얻으려면, 당신은 예를 들면 시도 할 수 있습니다 :

strace /bin/echo hello world 

을 모든 시스템 콜까지 포함 sbrk 약에 (= 힙/.data 세그먼트를 설정) 동적 링커의 동작이어야합니다. malloc는 C 라이브러리의 기능이 아닌 시스템으로


(malloc 링커에 실제로 사용할 수 없습니다. malloc 성장과 다른 별도의 블록 힙 부분과 잠재적 mmap 핑 (ping)을 관리뿐만 아니라 그 관리에 관한 것입니다 쓰기 가능한 "힙"으로, 동적 링커는 프로세스 이미지의 이러한 섹션, 주로 쓰기 전용 간접 테이블 및 라이브러리를 매핑하는 위치에 대해 신경 쓰지 않습니다.

관련 문제