2016-08-14 23 views
0

바이너리에 대한 정보를 얻기 위해 otool을 사용하고 있습니다. vmaddr 0x0000000100000000otool을 사용하여 이진 파일의 크기를 얻으려면 어떻게해야합니까?

문제에

우리는 그 command 1 segname __TEXT 시작으로 여기에서 볼 수 있습니다
Load command 0 
     cmd LC_SEGMENT_64 
    cmdsize 72 
    segname __PAGEZERO 
    vmaddr 0x0000000000000000 
    vmsize 0x0000000100000000 
    fileoff 0 
filesize 0 
    maxprot 0x00000000 
initprot 0x00000000 
    nsects 0 
    flags 0x0 
Load command 1 
     cmd LC_SEGMENT_64 
    cmdsize 952 
    segname __TEXT 
    vmaddr 0x0000000100000000 
    vmsize 0x0000000000268000 
    fileoff 0 
filesize 2523136 
    maxprot 0x00000005 
initprot 0x00000005 
    nsects 11 
    flags 0x0 

바이너리 크기가 2.3MB이고 0x0000000100000000 4 2GB입니다 것입니다 : 여기에서는 출력의 일부입니다!

주소 중간에 "1"은 64 비트 아키텍처와 관련이 있고 0x0000000100000000은 실제로 주소가 0x00 인 것으로 가정합니다. 그것에 관한 정보를 찾고 있었지만 유용하다고 생각하지 못했습니다. 누구나 내 가정을 확인하고 정확하게 작동하는지 설명 할 수 있습니까?

답변

1

이상한 것은 없습니다.

먼저 "유효하지 않은 세그먼트"는 주소 공간의 하위 4GB에 예약되어 있습니다. 이것은 유효하지 않은 4KB 또는 32 비트 프로세스에서 NULL 포인터 디 레퍼런스 크래시를 만들기 위해 보관 된 것이거나 더 커야합니다 (예 : 포인터로 잘못 캐스팅 된 32 비트 정수). 결국, 왜 안돼? 가상 메모리, 무료입니다. Some more details here.

그런 다음 실행 가능한 텍스트가 4GB 경계에로드됩니다. 나쁜 것은 아닙니다. 낮은 4GB는 실제 메모리로 구워지지 않으며 예약 된 것으로 표시됩니다.

일반적으로 64 비트 주소 공간의 "높은"주소에 물건을로드하는 것이 이상한 일은 아닙니다. 예를 들어 스택은 일반적으로 48 비트 경계 바로 아래 영역에 있습니다. 시스템이 실제로 모든 메모리를 중간에 제공하는 것과 달리 가상 메모리는 실제 메모리 (RAM 또는 스왑 공간)를 소비하는 페이지 만 포함하도록합니다. (실제로는 페이지 데이터 구조 회계에 약간의 비용이 있지만 일반적으로 무시할 수 있음)

VM 크기 필드와 파일 크기 필드 (0x268000 = 2523136 ≈ 2.4MB) 모두에서 이진 크기가보고됩니다. .

+0

내 응용 프로그램이 RAM에로드 될 때 하위 비트가 올바르게 표시됩니다. RAM에서 memmory를 덤프하려면 0x00과 0x268000 사이에있는 메모리를 찾아야합니다. – Sayaki

+1

아니요! 바이너리는 주소가 0x0000000100000000, 즉 4GB 경계 바로 위의 'otool'출력에 쓰여진 것과 똑같이 가상 메모리에 매핑됩니다. 그 아래의 모든 공간은 누군가가 액세스하려고 할 때마다 세그 폴트하는 "유효하지 않은"페이지를 위해 예약되어 있습니다. 실제 RAM에있는 곳은 어디에도 관계가 없습니다 (운영 체제의 변덕에 따라 달라질 수 있습니다. 예를 들어 바꿔 넣을 경우 투명하게 이동할 수 있습니다). –

+0

좋아, 이제 모든 걸 얻는다. 도움을위한 THX :) – Sayaki