Heim  >  Artikel  >  Backend-Entwicklung  >  Bringen Sie Ihnen bei, wie Sie die Elf-Struktur mit PHP lesen

Bringen Sie Ihnen bei, wie Sie die Elf-Struktur mit PHP lesen

藏色散人
藏色散人nach vorne
2020-12-21 09:08:113818Durchsuche

Empfohlen: „PHP-Video-Tutorial

Vorausgesetzte Kenntnisse

  1. Ausführbare Dateien des UNIX-Systems liegen alle im ELF-Format vor und die Typen sind in Zieldateien, ausführbare Dateien und gemeinsam genutzte Bibliotheken unterteilt.
  2. Erkundung von ELF Format Drei: Abschnitte
  3. Dieses Beispiel basiert auf einer 64-Bit-Little-Endian-Linux-Maschine

Am Beispiel des Lesens der Zieldatei 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

Die Zieldatei-Elf-Struktur umfasst hauptsächlich:

  1. ELF Der Header befindet sich in der Datei mit 0 bis 64 Bytes und speichert die Beschreibungsinformationen der Datei und die Startposition der Abschnitts-Header-Tabelle
  2. Programm-Header-Tabelle, ausführbare Datei erforderlich, hello.o in diesem Beispiel nicht
  3. Analysieren Sie die Elf-Struktur weiter

Verwenden Sie zuerst den Befehl readelf, um die Elf-Informationen zu lesen: readelf -h hello.o. Die Zusammenfassung lautet wie folgt:

ELF-Header belegt 64 Bytes
  1. N-Abschnitte belegen 6488-64-1472=4952 Bytes
  2. Abschnitts-Header-Tabelle belegt 23*64=1472 Bytes
  3. 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个条目
  4. Lesen Sie den .shstrtab-Abschnitt mit PHP-Inhalt
.shstrtab Abschnitt ist eigentlich der Name aller gespeicherten Abschnitte

<?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);
}

Das obige ist der detaillierte Inhalt vonBringen Sie Ihnen bei, wie Sie die Elf-Struktur mit PHP lesen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:learnku.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen