一步一步走进Linux HOOK API(二)

本文是Linux HOOK API系列的第二篇,主要探讨程序头Program Headers的作用和结构。程序头是一个结构数组,用于在系统加载程序时指导内存布局。内容包括段的类型、文件偏移、虚拟和物理地址、大小、属性以及对齐方式等,这些信息对于程序的执行至关重要。
摘要由CSDN通过智能技术生成

一步一步走进Linux HOOK API(二)

从上一篇的ELF Head之后,想必很多读者已经对ELF文件开始感觉不是遥不可及了,今天这一节,主要是讲程序头(Program Headers),程序头主要是从加载执行的角度来看的,很多人想那里面到底是什么东西呢,其实程序头就是一个结构数组,每一个头保存着对应的不同的数据,有的数据是告诉系统把我放入内存,有的数据时告诉系统我是变量.等等...在系统加载程序的时候就要通过该程序头来加载不同的段.

下面就来看一下程序头的结构体:

typedef struct

{

   Elf32_Word p_type; /* Segment type */

   Elf32_Off p_offset; /* Segment file offset */

   Elf32_Addr p_vaddr; /* Segment virtual address */

   Elf32_Addr p_paddr; /* Segment physical address */

   Elf32_Word p_filesz; /* Segment size in file */

   Elf32_Word p_memsz; /* Segment size in memory */

   Elf32_Word p_flags; /* Segment flags */

   Elf32_Word p_align; /* Segment alignment */

} Elf32_Phdr;

p_type:            段的类型

在elf.h头文件中,有很详细的说明段的类型,比如PT_LOAD 表示加载的程序段

p_offset:        文件偏移

该段在文件中的偏移。这个偏移是相对于整个文件的。

p_vaddr:         加载后的虚拟地址

该段加载后在进程空间中占用的内存起始地址。

p_paddr:        该段的物理地址

这个字段被忽略,因为在多数现代操作系统下物理地址是进程无法触及的。

p_filesz:         该段在文件中占用的字节大小

有些段可能在文件中不存在但却占用一定的内存空间,此时这个字段为0

p_memsz:     该段在内存中占用的字节大小

有些段可能仅存在于文件中而不被加载到内存,此时这个字段为0

p_flags:         段的属性

表示该段的读写执行等属性.elf.h文件中的定义是

#define PF_X (1 << 0) /* Segment is executable */

#define PF_W (1 << 1) /* Segment is writable */

#define PF_R (1 << 2) /* Segment is readable */

#define PF_MASKOS 0x0ff00000 /* OS-specific */

#define PF_MASKPROC 0xf0000000 /* Processor-specific */

p_align:          对齐

现代操作系统都使用虚拟内存为进程序提供更大的空间,分页技术功不可没,页就成了最小的内存分配单位,不足一页的按一页算。所以加载程序数据一般也从一页的起始地址开始,这就属于对齐。

示例代码:

typedef struct _SegmentType_

{

unsigned int type;

char *typeName;

}SegmentType;

SegmentType segTyoe[] = {

{0,"NULL"},{1,"LOAD"},

{2,"DYNAMIC"},{3,"INTERP"},

{4,"NOTE"},{5,"SHLIB"},

{6,"PHDR"},{7,"TLS"},

{8,"NUM"},{0x60000000,"LOOS"}, {0x6474e550,"GNU_EH_FRAME"},{0x6474e551,"PT_GNU_STACK"}, {0x6474e552,"PT_GNU_RELRO"},{0x6ffffffa,"PT_SUNWBSS"}, {0x6ffffffb,"PT_SUNWSTACK"},{0x6fffffff,"PT_HISUNW"},

{0x70000000,"PT_HIOS"},{0x7fffffff,"PT_HIPROC"},

};

char* findSegTypeName(unsigned int type)

{

int i = 0;

for(i = 0;i < sizeof(segTyoe) / sizeof(SegmentType);i++){

if(segTyoe[i].type == type){

return segTyoe[i].typeName;

break;

}

}

return segTyoe[0].typeName;

}

void displayPhdr(Elf32_Ehdr *ehdr,Elf32_Phdr *phdr)

{

printf("Program Headers:\n");

printf("%-20s%-10s%-10s%-10s%-10s%-10s%-10s%-10s\n",

"Type","Offset","VirtAddr","PhysAddr","FileSiz",

"MemSiz","Flg","Align");

int i = 0;

for(i = 0; i < ehdr->e_phnum;i++){

printf("%-20s%-10x%-10x%-10x%-10x%-10x%-10x%-10x\n",

findSegTypeName(phdr->p_type),

phdr->p_offset,

phdr->p_vaddr,

phdr->p_paddr,

phdr->p_filesz,

phdr->p_memsz,

phdr->p_flags,

phdr->p_align

);

if(phdr->p_type == PT_INTERP){

printf("\t[Requesting program interpreter: %s]\n",

(char*)((char*)ehdr + phdr->p_offset));

}

phdr++;

}

}


 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值