2016-10-09 10 views
1

두 프로그램에서 libc.so의 "printf"기능의 물리적 주소를 가져오고 두 개의 실제 주소가 다릅니다. 그리고 두 개의 서로 다른 실제 주소를 읽었습니다. 내용은 거의 같습니다. 즉 "printf"함수는 메모리에 두 개의 복사본이 있습니다.공유 라이브러리의 기능이 다른 프로세스에 대해 서로 다른 실제 주소에로드 됨

세부 사항 :

  1. 내 운영 체제가 32 비트 리눅스입니다.

  2. 물리적 주소는 "/ proc/self/pagemap"을 읽어서 계산합니다.

  3. 물리적 주소를 읽고 그 소스 코드 [email protected]에서 FMEM 모듈로 구현됩니다 NateBrune/fmem.git

+0

는 "내용이 거의 동일하다"무엇을 의미합니까? 두 개의'printf()'구현이 다르다면, 물론 그들은 다른 위치에 있어야만합니다. 두 프로그램이 서로 다른 버전의 libc를 사용하고 있을까요? – unwind

+1

"* 실제 주소 *"는 확실합니까? 각 프로세스는 자체 * 가상 * 주소 공간을 사용합니다. – alk

+0

[주소 공간 레이아웃 임의 화] (https://en.wikipedia.org/wiki/Address_space_layout_randomization) 일 수 있습니다. –

답변

1

나는 기능 "의 printf"의 실제 주소를 얻을 수 libc의 .so 두 프로그램에서 두 개의 실제 주소가 다릅니다.

아마 잘못하고있는 것일 수 있습니다. 그러나 추측하기는 어렵습니다. 세부 정보를 제공하지 않았습니다. GDB으로 관찰 할 수있는,

#include <stdio.h> 

int main() 
{ 
    printf("&printf: %p\n", &printf); 
    return 0; 
} 

하지 인쇄 libc.so.6에서 printf의 실제 주소를 수행합니다 : 특히

는 다음과 같은 프로그램이 있습니다

(gdb) start 
Temporary breakpoint 1 at 0x8048426: file pagemap.c, line 5. 
Starting program: /tmp/pagemap 

Temporary breakpoint 1, main() at pagemap.c:5 
5  printf("&printf: %p\n", &printf); 
(gdb) n 
&printf: 0x80482f0 
6  return 0; 

(gdb) info symbol 0x80482f0 
[email protected] in section .plt of /tmp/pagemap 

(gdb) p &printf 
$1 = (<text variable, no debug info> *) 0xf7e5add0 <printf> 

(gdb) info sym 0xf7e5add0 
printf in section .text of /lib32/libc.so.6 

printf @0x80482f0을 그 주 실행 파일에 있고 이 아니고이 아닌 것으로 가정합니다 (동일한 실행 파일 실행 중 여러 인스턴스 간을 제외하고 동시에 이 아닌 인 경우 printf의 코드가 실제로 있습니다.

printf @0xf7e5add0libc.so.6이며, printf에 대한 코드가 실제로 어디 때문입니다. 해당 페이지는 libc.so.6을 사용하는 모든 프로세스에서 공유됩니다.

P. libc.so.6printf실제 주소를 얻으려면 하나 대신에이 프로그램을 사용할 수 있습니다 :

#include <stdio.h> 
#include <dlfcn.h> 

int main() 
{ 
    printf("&printf: %p\n", &printf); 
    printf("&printf: %p\n", dlsym(RTLD_NEXT, "printf")); 
    return 0; 
} 

gcc -g pagemap.c -o pagemap -m32 -ldl -D_GNU_SOURCE 

(gdb) run 
Starting program: /tmp/pagemap 
&printf: 0x80483c0 
&printf: 0xf7e55dd0 

(gdb) info sym 0xf7e55dd0 
printf in section .text of /lib32/libc.so.6 
+0

질문이 있습니다. plt의 심볼 이름이'printf @ plt'라고 생각했습니다. 하지만'dlsym (RTLD_DEFAULT, "printf")'이 plt 항목을 찾는 이유는 무엇입니까? 일반 plt되지 않은 기호 문자열이'gdb '처럼 분명히 실제로 찾지 못하는 이유는 무엇입니까? –

+1

@litb "plt의 심볼 이름이 printf @ plt라고 생각했습니다."- 그렇지 않습니다. 'readelf -Ws' 출력에서 ​​보듯이'printf'입니다. '@ plt '는 GDB가 심볼이 무엇인지 명확하게하기 위해 제조하는 이름입니다. –

+0

@EmployedRussian, 맞습니다. 'printf'의 가상 주소는 실제로 'printf @ plt'입니다. 'printf'의 실제 가상 주소는 'printf'가 바인드 된 후 GOT에 저장됩니다. 마지막으로 내 실험에서 두 프로그램에서 'printf'의 가상 주소 0xb7581590 및 0xb7635590을 얻었고 실제 주소는 모두 0x7bc6b590입니다. –