溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

用php讀取elf結(jié)構(gòu)的方法

發(fā)布時(shí)間:2020-12-22 09:58:48 來源:億速云 閱讀:171 作者:小新 欄目:編程語言

這篇文章給大家分享的是有關(guān)用php讀取elf結(jié)構(gòu)的方法的內(nèi)容。小編覺得挺實(shí)用的,因此分享給大家做個(gè)參考。一起跟隨小編過來看看吧。

前提知識(shí)
  1. UNIX系統(tǒng)的可執(zhí)行文件都采用ELF格式,類型分為目標(biāo)文件、可執(zhí)行文件和共享庫

  2. ELF格式探析之三:sections

  3. 本例基于64位的小端序linux機(jī)器

以讀取目標(biāo)文件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;
}
// 執(zhí)行g(shù)cc -c hello.c生成hello.o
目標(biāo)文件elf結(jié)構(gòu)主要有:
  1. ELF header,位于文件的0~64字節(jié),存儲(chǔ)文件的描述信息,Section header table的起始位置

  2. N個(gè)Section

  3. Section header table,每個(gè)條目64字節(jié),對(duì)應(yīng)一個(gè)Section的信息

  4. Program header table,可執(zhí)行文件需要,本例的hello.o沒有

進(jìn)一步分析elf結(jié)構(gòu)
  1. 首先用readelf命令讀取elf信息:readelf -h hello.o??偨Y(jié)如下:

  2. ELF header占用64字節(jié)

  3. N個(gè)Section占用6488-64-1472=4952字節(jié)

  4. Section header table占用23*64=1472字節(jié)

readelf -h hello.o
ELF Header:
Class:                             ELF64
Data:                              2'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每個(gè)條目占用大小
Number of section headers:         23         //Section header table條目個(gè)數(shù)
Section header string table index: 22         //.shstrtab Section位于Section header table第22個(gè)條目
用php讀取.shstrtab Section內(nèi)容
  1. .shstrtab Section其實(shí)是存儲(chǔ)的所有Section的名字

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

感謝各位的閱讀!關(guān)于用php讀取elf結(jié)構(gòu)的方法就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,讓大家可以學(xué)到更多知識(shí)。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到吧!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI