使用C语言读取ELF文件的数据部分

elf文件的分析,推荐此篇

测试环境: Kali Linux x64

首先生成一个小的elf文件样例:

// demo.c
#include <stdio.h>

int main(int argc, char **argv) 
// 读取demo.txt文件的内容
{
	FILE *fp;
	char buff[256];
	
	fp = fopen("demo.txt", "r");
	// demo.txt可自行创建,并打入一些字符
	fgets(buff, 256, fp);
	printf("\n%s\n", buff);
	fclose(fp);

	return 0;
}

然后运行命令:

gcc -o demo demo.c

之后会得到一个名为demo的可执行文件,elf类型的。
接下来可以尝试读取elf文件中LOAD Segments的数据:

// 此测试中忽略ELF文件类型的判断和错误处理等操作
// ELF文件类型的判断可在elf_head中进行,即确保elf_head.e_ident的前四个字符即可;
// 错误处理包括fread和fseek函数的成功与否。

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

#include "/usr/include/elf.h"  // 引入elf的头文件

int main()
{
	FILE *fp;
	Elf64_Ehdr elf_head;
	fp = fopen("demo", "r");
	
	// 读取elf文件头表
	fread(&elf_head, sizeof(Elf64_Ehdr), 1, fp);
	// 读取elf的程序头表
	Elf64_Phdr *phdr = (Elf64_Phdr*)malloc(sizeof(Elf64_Phdr)*elf_head.e_phnum);
	a = fseek(fp, elf_head.e_phoff, SEEK_SET);
	a = fread(phdr, sizeof(Elf64_Phdr)*elf_head.e_phnum, 1, fp);
	rewind(fp);
	
	int idx;
	for (idx=0; idx<elf_head.e_phnum; idx++)
	{
		/*
		可以打印这些信息再与 readelf -l demo 的结果做对比
		printf("type:   %hx\n", phdr[idx].p_type);
		printf("flags:  %hx\n", phdr[idx].p_flags);
		printf("offest: %hx\n", phdr[idx].p_offset);
		printf("fsize:  %hx\n", phdr[idx].p_filesz);
		printf("memsize:%hx\n", phdr[idx].p_memsz);
		printf("align:  %hx\n", phdr[idx].p_align);
		*/
		
		// LOAD 对应的type值为1
		if (phdr[idx].p_type == 1)
		{
			// 分配 p_filesz 个字节的空间
			// uint8_t为字节类型,也可使用unsigned char
		    uint8_t *code=(uint8_t*)malloc(sizeof(uint8_t)*phdr[idx].p_filesz);
		    // 依据此段在文件中的偏移读取出
			fseek(fp, phdr[idx].p_offset, SEEK_SET);
			fread(code, sizeof(uint8_t)*phdr[idx].p_filesz, 1, fp);
			// 显示读取的内容
			uint8_t *p = code;
			int i = 0;
			for (i=0; i<phdr[idx].p_filesz; i++)
			{
				printf("%x", *p);
				p++;
			}
			printf("\n------\n");
			// 回溯
			rewind(fp);
		}
	}
	
	return 0;
}

运行后即可得到结果:

7f454c46211000000000303e010008010000000400000000f8390000000000400380b04001e01
d0600040004000000004000000004000000006820000006820000008000000030004000a82000
000a82000000a820000001c00000001c000000010000000100040000000000000000000000000
00106000000106000000010000000100050000100000000100000000100000004d20000004d20
00000010000000100040000200000000200000000200000005810000005810000000100000001
0006000e82d000000e83d000000e83d00000060200000068200000001000000020006000f82d0
00000f83d000000f83d000000e01000000e010000008000000040004000c42000000c42000000
c420000004400000004400000004000000050e574644000142000000014200000001420000000
3c00000003c00000004000000051e574646000000000000000000000000000000000000000000
010000000052e574644000e82d000000e83d000000e83d0000001820000001820000001000000
02f6c696236342f6c642d6c696e75782d7838362d36342e736f2e3204000100001000474e5500
0003000200000004000140003000474e550fb6ed3b9ba3ef3aefd8b16c1812735ea92c8372000
90001000600000810000090000000d165ce6d0000000000000000000000000000520002000000
000000000000001e0001200000000000000000001100012000000000000000000034000120000
000000000000000180001200000000000000000006e000200000000000000000000b000120000
0000000000000007d0002000000000000000000002500022000000000000000000006c6962632
e736f2e360666f70656e07072696e746606667657473066636c6f736505f5f6378615f66696e6
16c697a6505f5f6c6962635f73746172745f6d61696e0474c4942435f322e322e3505f49544d5
f64657265676973746572544d436c6f6e655461626c6505f5f676d6f6e5f73746172745f5f05f
49544d5f7265676973746572544d436c6f6e655461626c6500000020202020002000200000101
01000100000000751a6990020460000000e83d000000800000006011000000f03d00000080000
00020110000004040000000800000004040000000d83f0000006000100000000000e03f000000
6000400000000000e83f0000006000600000000000f03f0000006000800000000000f83f00000
06000900000000000184000000070002000000000002040000000700030000000000028400000
00700050000000000030400000007000700000000000
------
4883ec8488b5dd2f004885c0742ffd04883c48c3000000000ff35e22f00ff25e42f00f1f400ff
25e22f00680000e9e0ffffffff25da2f00681000e9d0ffffffff25d22f00682000e9c0fffffff
f25ca2f00683000e9b0ffffffff25822f0066900000000031ed4989d15e4889e24883e4f05054
4c8d5aa100488dd43100488d3dc1000ff15362f00f4f1f4400488d3d912f00488d58a2f004839
f87415488b5e2f004885c0749ffe0f1f800000c3f1f800000488d3d612f00488d355a2f004829
fe48c1fe34889f048c1e83f481c648d1fe7414488b5e52e004885c0748ffe066f1f4400c3f1f8
00000803d212f000752f5548833dc62e0004889e574c488b3d22f00e82dffffffe868ffffffc6
5f92e0015dc3f1f800000c3f1f800000e97bffffff554889e54881ec2010089bdecfeffff4889
b5e0feffff488d3580e00488d3d7be00e8d0feffff488945f8488b55f8488d85f0feffffbe010
04889c7e8a4feffff488d85f0feffff4889c6488d3d52e00b80000e879feffff488b45f84889c
7e85dfeffffb80000c9c366f1f440041574989d741564989f641554189fd41544c8d25f02b005
5488d2df02b00534c29e54883ec8e8f3fdffff48c1fd3741b31dbf1f04c89fa4c89f64489ef41
ff14dc4883c314839dd75ea4883c485b5d415c415d415e415fc3f1f0c30004883ec84883c48c3
------
102072064656d6f2e7478740a2573a011b33b380006000cf0ffff840005cf0ffffac0006cf0ff
ff5400051f1ffffc4000ccf1ffffe40002cf2ffff2c10014000000017a5201781011bc7890171
0140001c00010f0ffff2b0000000000014000000017a5201781011bc7890100240001c00080ef
ffff500000e1046e184afb7788003f1a3b2a33242200001400044000a8efffff8000000000001
c0005c00085f0ffff75000041e1086243d6270c7800440007c000e0f0ffff5d000042e108f245
e188e345e208d445e288c548e3086648e3883747e406ae3841e3041e2842e2042e1842e1042e8
010000c4000f8f0ffff100000000000
------
601100000020110000001000000010000000c0000000010000000d00000004412000000190000
000e83d0000001b0000000800000001a0000000f03d0000001c000000080000000f5feff6f000
0830000005000000020400000060000000303000000a0000000970000000b0000000180000000
15000000000000000300000000400000002000000060000000014000000070000000170000000
b0500000070000000f0400000080000000c0000000090000000180000000fbffff6f000000080
000feffff6f0000d04000000ffffff6f000010000000f0ffff6f0000b84000000f9ffff6f0000
30000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000f83d0000000000000000000000
3610000000461000000056100000006610000000000000004040000000

可见有4个LOAD段,并且每段的内容如上。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值