>  기사  >  백엔드 개발  >  PHP를 사용하여 엘프 구조를 읽는 방법을 가르쳐주세요.

PHP를 사용하여 엘프 구조를 읽는 방법을 가르쳐주세요.

藏色散人
藏色散人앞으로
2020-12-21 09:08:113818검색

추천: "PHP 비디오 튜토리얼"

전제 지식

  1. UNIX 시스템 실행 파일은 모두 ELF 형식이며 유형은 대상 파일, 실행 파일 및 공유 라이브러리로 구분됩니다.
  2. ELF 탐색 형식 3: 섹션
  3. 이 예제는 64비트 리틀 엔디안 Linux 시스템을 기반으로 합니다.

대상 파일 hello.o를 예로 들겠습니다.

#include <stdio.h>
void say_hello(char *who) {
    printf("hello, %s!\n", who);
}
char *my_name = "wb";
int man() {
    say_hello(my_name);
    return 0;
}
// 执行gcc -c hello.c生成hello.o

대상 파일 elf 구조에는 주로 다음이 포함됩니다.

  1. ELF 파일 0~64바이트에 위치한 헤더, 파일의 설명 정보 저장, 섹션 헤더 테이블
  2. N 섹션
  3. 섹션 헤더 테이블의 시작 위치, 각 항목은 섹션 정보에 해당하는 64바이트입니다.
  4. 프로그램 헤더 테이블, 실행 파일 필요, 이 예에서는 hello.o가 필요하지 않습니다.

elf 구조 추가 분석

  1. 먼저 elf 정보를 읽으려면 readelf 명령을 사용하십시오: readelf -h hello.o. 요약하면 다음과 같습니다.
  2. ELF 헤더는 64바이트를 차지합니다.
  3. N 섹션은 6488-64-1472=4952바이트를 차지합니다.
  4. 섹션 헤더 테이블은 23*64=1472바이트를 차지합니다.
readelf -h hello.o
ELF Header:
Class:                             ELF64
Data:                              2&#39;s complement, little endian
OS/ABI:                            UNIX - System V
Type:                              REL (Relocatable file)
Machine:                           Advanced Micro Devices X86-64
Start of program headers:          0 (bytes into file)
Start of section headers:          5016 (bytes into file) //Section header table的起始位置
Size of this header:               64 (bytes) //ELF header的占用大小
Size of program headers:           0 (bytes)  //hello.o没有program header table
Number of program headers:         0          //hello.o没有program header table
Size of section headers:           64 (bytes) //Section header table每个条目占用大小
Number of section headers:         23         //Section header table条目个数
Section header string table index: 22         //.shstrtab Section位于Section header table第22个条目

php 콘텐츠가 포함된 .shstrtab 섹션 읽기

  1. .shstrtab 섹션은 실제로 저장된 모든 섹션의 이름입니다
<?php
$fp = fopen("hello.o", "rb");

fseek($fp, 40, SEEK_SET);
$sh_off = fread($fp, 8);
$sh_off = unpack("P", $sh_off);
var_dump("section header offset in file: ". $sh_off[1]);

fseek($fp, 10, SEEK_CUR);
$sh_ent_size = fread($fp, 2);
$sh_ent_size = unpack("v", $sh_ent_size);
var_dump("section header entry size: ". $sh_ent_size[1]);

$sh_num = fread($fp, 2);
$sh_num = unpack("v", $sh_num);
var_dump("section header number: ". $sh_num[1]);

$sh_strtab_index = fread($fp, 2);
$sh_strtab_index = unpack("v", $sh_strtab_index);
var_dump("section header string table index: ". $sh_strtab_index[1]);

fseek($fp, $sh_off[1] + $sh_strtab_index[1] * $sh_ent_size[1], SEEK_SET);
fseek($fp, 24, SEEK_CUR); //sh_name(4) + sh_type(4) + sh_flags(8) + sh_addr(8) = 24
$str_table_off = fread($fp, 8);
$str_table_off = unpack("P", $str_table_off);
var_dump("section name string table offset: ". $str_table_off[1]);

$str_table_size = fread($fp, 8);
$str_table_size = unpack("P", $str_table_size);
var_dump("section name string table size: ". $str_table_size[1]);

fseek($fp, $str_table_off[1], SEEK_SET);
$str = fread($fp, $str_table_size[1]);
print_r(explode("\x00", trim($str, "\x00")));

// 读取所有Section条目信息
for ($i =0;$i < $sh_num[1]; $i ++) {
    fseek($fp, $sh_off[1] + $i * $sh_ent_size[1], SEEK_SET);
    $sh_name = fread($fp, 4);
    $sh_name = unpack("V", $sh_name);
    fseek($fp, 20, SEEK_CUR); //sh_type(4) + sh_flags(8) + sh_addr(8) = 20
    $sh_offset = fread($fp, 8);
    $sh_offset = unpack("P", $sh_offset);

    $sh_size = fread($fp, 8);
    $sh_size = unpack("P", $sh_size);

    printf("section: %2s name: %-24s offset: %12s size: %12s\n", $i, get_section_name($sh_name[1]), $sh_offset[1], $sh_size[1]);
}

function get_section_name($start) {
    global $str;
    $name = substr($str, $start);
    return strstr($name, "\x00", true);
}

위 내용은 PHP를 사용하여 엘프 구조를 읽는 방법을 가르쳐주세요.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 learnku.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제