ホームページ  >  記事  >  バックエンド開発  >  PHPを使用してelf構造を読み取る方法を教えます

PHPを使用してelf構造を読み取る方法を教えます

藏色散人
藏色散人転載
2020-12-21 09:08:113905ブラウズ

推奨: 「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 構造の

    まず、readelf コマンドを使用して elf 情報を読み取ります: readelf -h hello.o。要約は次のとおりです。
  1. ELF ヘッダーは 64 バイトを占有します
  2. N セクションは 6488-64-1472=4952 バイトを占有します
  3. セクション ヘッダー テーブルは 23*64=1472 ワードを占有しますSection
  4. 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 セクションの内容を読み取ります

    .shstrtab セクションは実際には、保存されているすべてのセクションの名前です
  1. <?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を使用してelf構造を読み取る方法を教えますの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はlearnku.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。