여러 부분으로 구성된 복합 파일을 디스어셈블하려고 합니다. 그 중 하나는 여러 다른 파일 사이에 끼어 있는 압축되지 않은 커널입니다. 커널 섹션의 정확한 길이를 찾으려고 노력했지만 이것이 어려웠습니다.
vmlinux 헤더에 부트로더가 실행되기 전에 읽어야 하는 데이터의 양이 표시되어 있습니까? 아니면 부트로더가 전환될 때 vmlinux 파일의 전체 내용이 로드될 것이라고 가정합니까?
답변1
짧은 대답은 "아니요"입니다. 그러나 이것이 ELF 이미지라면 해킹을 통해 커널을 찾을 수 있을 것입니다. readelf
아래 해킹을 참조하세요 .
부트로더는 커널의 형식과 루트 파일 시스템이 있는 모든 파일을 이해하는 역할을 담당합니다. 여기에는 형식에 관계없이 커널 파일의 크기를 아는 것이 포함됩니다. PowePC 및 Blackfin에서 부트로더는 전체 커널(압축된 경우)의 압축을 풀고 이를 RAM의 최종 위치에 쓰는 역할을 합니다. ARM에서 커널은 자동 추출되며 부트로더는 원래 커널 파일을 RAM의 편리한 위치에 복사하고 실행을 시작합니다.
커널이 자동 압축 풀기인 경우 압축된 커널 파일의 크기를 나타내는 기호는 사용된 압축 풀기 알고리즘에 따라 파일 시작 부분의 압축 풀기 코드에 나타날 수도 있고 나타나지 않을 수도 있습니다. 링크는 특정 커널 없이 구축됩니다. 서버 매핑의 경우는 어디에 있습니까? 물론 부트로더는 알 방법이 없습니다.
압축되지 않은 커널 코드 자체는 주소가 커널 자체의 시작과 끝인 두 개의 기호로 둘러싸여 있지만 _stext
initramfs _end
를 포함하는 범위는 제외됩니다(initramfs가 커널 바이너리에 연결된 경우). initramfs의 범위는 링커에 의해 두 개의 커널 기호 __initramfs_start
와 __initramfs_end
. 부트 로더는 일반적으로 커널 기호 테이블(파일에 있음)을 읽는 기능이 없으며 , 이 기능이 없으면 커널 파일에서 및 기호가 어디에 있는지 System.map
알 수 없습니다 . 즉, 기호의 위치는 바이너리 시작 부분의 고정된 오프셋이 아닙니다. 이는 링크 타임에 결정되며 커널 빌드 구성에 따라 달라질 수 있습니다._end
__initrams_end
177 E L F
od -c
ELF 형식의 압축되지 않은 커널의 경우 ELF 헤더(복합 파일의 덤프에서)를 찾아 vmlinux 파일의 시작 부분을 식별 할 수 있습니다 . 그런 다음 이 지점부터 파일의 나머지 부분을 readelf -e
OR하여 objdump -h
가장 높은 파일 오프셋( )이 있는 섹션을 찾을 수 있습니다 .shstrtab
. 이 오프셋에 부분 크기를 추가하면 vmlinux가 종료됩니다. 스트립되지 않은 PPC vmlinux를 사용하여 이 방법을 테스트한 결과 독립 실행형 vnlinux 파일 크기와 정확히 일치하는 크기를 얻었습니다. 커널을 제거한 후 이 방법은 제거된 이미지 크기보다 1283바이트 작은 결과를 제공합니다.
임베디드 시스템은 일반적으로 파일 형식을 사용하여 mkimage
커널, rootfs, 장치 트리 및 기타 구성 요소를 패키지합니다. 예를 들어 U-boot는 mkimage를 인식하므로 mkimage 파일 내에서 커널 바이너리가 시작하고 끝나는 위치를 알고 커널이 압축되었는지 여부와 커널 파일이 기록되는 RAM 주소를 알고 있습니다.