2009-08-28 4 views
19

리눅스에서 간단한 사용자 공간 ELF 로더를 쓰고 있습니다 (왜? for 'fun'). 현재 나의 로더는 아주 간단하며 위치 독립적 코드가 포함 된 정적으로 링크 된 ELF 파일 만로드하도록 설계되었습니다.로딩 시간 ELF 재배치

일반적으로 프로그램이 커널의 ELF 로더에 의해로드되면 해당 주소 공간에로드됩니다. 따라서 데이터 세그먼트 및 코드 세그먼트는 ELF 세그먼트에 지정된 올바른 가상 주소로로드 될 수 있습니다.

그러나 제 경우에는 mmap을 통해 커널 주소를 요청하고 ELF 세그먼트에서 요청 된 주소를 얻거나받지 못할 수 있습니다. 이것은 위치 독립적이기 때문에 코드 세그먼트에는 문제가되지 않습니다. 그러나 데이터 세그먼트가 예상 주소에로드되지 않으면 코드가 데이터 세그먼트에 저장된 내용을 제대로 참조 할 수 없습니다.

사실, 로더는 데이터가 포함되지 않은 간단한 어셈블리 실행 파일로 제대로 작동하는 것으로 보입니다. 그러나 데이터 세그먼트를 추가하고 참조하는 즉시 실행 파일이 올바르게 실행되지 않거나 SEGFAULT가 실행되지 않습니다.

가능한 경우 데이터 세그먼트에 대한 참조가 올바른 위치를 가리 키도록 수정하는 방법은 무엇입니까? 이 목적을 위해 (정적) ELF 파일에 재배치 섹션이 저장되어 있습니까?

+1

mmap() 호출 프로세스가 요청 된 주소를 제공 할 때 mmap()이 실패하는 이유는 이미 해당 주소 공간에 페이지가 할당되어 있기 때문입니다. –

+0

예, 이것이 이유 일 수 있습니다. 내 코드/데이터를 어딘가에 배치하는'ld'에 대해 생각해 보았습니다. 그러나 제네릭 솔루션이 먼저 가능했는지 궁금합니다. 여기서 내가 어떤 반응을 얻지 못한다면 나는 그것을 시도하고 그것을 시도 할 것입니다. –

답변

8

.got 섹션에서 사용할 수있는 절대 주소 (전역 오프셋 표)를 수정하면 프로그램이 작동해야합니다. .text와 .data 사이의 새로운 거리를 맞추기 위해 절대 주소 계산을 수정해야합니다. 아키텍처에 대해이 정보의 출처를 파악해야합니다. Global Offset Table (Processor-Specific)

행운을 빕니다 :

이를 참조하십시오.

+0

새 거리를 계산해서는 안됩니다. 일부 명령어는 상대 주소 지정을 사용하여 데이터 세그먼트의 내용을 참조 할 수 있으며 세그먼트를 멀리 이동하면 단순히 중단됩니다. 세그먼트를 올바르게 맵핑하려면'MAP_FIXED'를 사용해야한다. 그래서 필요한 영역을 사용할 수 없다면'mmap' 콜이 실패하고, 두 세그먼트 모두 큰 영역을 원자 적으로 맵핑 한 다음, 그 부분을 맵핑 해제하고 개별 세그먼트를 맵핑한다. 구멍의. –

4

커널 제공 가상 주소 공간을 완전히 에뮬레이트하고 해당 가상 공간에서 코드를 실행하지 않는 한 어떤 방법으로도 표시되지 않습니다. 파일에서 데이터 섹션을 mmap 할 때 ELF 인터프리터의 가상 주소 공간의 알려지지 않은 주소로 본질적으로이 섹션을 옮기면 코드가 어떤 방식 으로든이를 참조 할 수 없게됩니다.

입증 된 것이 기쁘다. 여기서 배울 점이 매우 좋습니다.

+0

다른 프로세스에서 대상 ELF 및 로더 기능을 갖고 있으며, 이상한 주소의 대상 프로세스에 있어야하는 최소한의 부분이 있습니다. 이렇게하면 대부분의 로더에 표준 도구와 절차를 사용할 수 있습니다. –