教你用php读取elf结构

前提知识

  1. UNIX系统的可执行文件都采用ELF格式,类型分为目标文件、可执行文件和共享库
  2. ELF格式探析之三:sections
  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 header,位于文件的0~64字节,存储文件的描述信息,Section header table的起始位置
  2. N个Section
  3. Section header table,每个条目64字节,对应一个Section的信息
  4. Program header table,可执行文件需要,本例的hello.o没有

进一步分析elf结构

  1. 首先用readelf命令读取elf信息:readelf -h hello.o。总结如下:
  2. ELF header占用64字节
  3. N个Section占用6488-64-1472=4952字节
  4. Section header table占用23*64=1472字节
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每个条目占用大小
Number of section headers:         23         //Section header table条目个数
Section header string table index: 22         //.shstrtab Section位于Section header table第22个条目

php读取.shstrtab Section内容

  1. .shstrtab Section其实是存储的所有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);
}

关于教你用php读取elf结构的文章就分享到这,如果对你有帮助欢迎继续关注我们哦

本文来自投稿,不代表科技代码立场,如若转载,请注明出处https://www.cwhello.com/42099.html

如有侵犯您的合法权益请发邮件951076433@qq.com联系删除

(0)
上一篇 2022年6月23日 16:31
下一篇 2022年6月25日 01:24

相关推荐

  • PHP8中的新函数:str_contains()的高效字符串搜索方法。

    随着PHP8的发布,我们又迎来了一个新函数:str_contains()。这个函数的功能是在字符串中高效地搜索指定的子字符串。相比较于之前已有的PHP函数,str_contains()具有更高的效率和更方便的使用方式。在这篇文章中,...

    2023年5月21日
    010
  • 我的php学习第二十一天之php基础篇

    昨日回顾 PHP变量 1)不需要提前定义,使用时直接赋一个值即可。 2)PHP的变量的命名规则,跟JS一样,允许的字符有:大小写英文字母、0-9、_ 3)PHP的变量必须以美元符号$开头;例如:$name=“周更生”; 4)PHP的变...

    2015年12月1日
    0423
  • PHP中str_replace高级使用你知道吗?

    “str_replace高级使用你应该了解一下”在阅读PHP框架ThinkPHP源码的过程中有很多方法的冷门使用,也就是不常用的使用方法。这里咔咔先对str_replace这个方法进行解析,这个方法也就是替换字符串中的一些字符(区分...

    2022年6月25日 PHP自学教程
    0122
  • PHP中如何进行深度强化学习和用户行为分析。

    随着深度学习技术的不断发展,人工智能在各行各业中的应用越来越广泛。在各种编程语言中,PHP作为一种流行的服务器端语言,也可以使用深度强化学习技术进行用户行为分析。深度学习是一种通过对大量数据进行训练,...

    2023年5月30日
    03
  • php基本语法-函数

    函数的主要功能: 代码重复性使用 模块化编程 函数的定义: 定义语法: function 函数名([参数1,参数2,参数n]){        函数体;        [return;] } 调用语法: 函数名([实参1,实参2,实参n]); 函数定义及调用 例1...

    2017年9月26日 PHP自学教程
    0226
  • PHP实现Memcached数据库异地容灾的方法。

    随着互联网应用规模不断扩大,数据容灾成为了一个不可避免的话题。Memcached是一种高效的缓存数据库,但是它的本地存储方式使得它存在单点故障的风险。因此,为了提高Memcached的可靠性,需要在异地进行容灾。本...

    2023年5月21日
    00
  • PHP8.0中的事件处理库:Event

    PHP8.0中的事件处理库:Event随着互联网的不断发展, PHP作为一门流行的后台编程语言,被广泛应用于各种Web应用程序的开发中。在这个过程中,事件驱动机制成为了非常重要的一环。PHP8.0中的事件处理库Event将为我...

    2023年5月19日
    01
  • 字符串的布尔类型:bool, boolean

    bool和boolean用于标识某种只有两个状态值的数据:true,false——吃没吃,去没去,有没有。。。。。 在应用出,我们常常会(需要)直接将一个数据(可能是各种其他类型)当作一个布尔值来进行判断。 那么此时其实...

    2018年3月17日
    0299

联系我们

QQ:951076433

在线咨询:点击这里给我发消息邮件:951076433@qq.com工作时间:周一至周五,9:30-18:30,节假日休息