ELF格式解析库之初始化
寻宝要先设计路线图
对一个ELF文件来说,它里边装个一个程序的所有信息。我们想要拿的程序信息就在这个ELF文件的某个地址处。可是我们根本就不知道这个具体的地址是哪个,怎么办?举个较形象的例子来描述我们将要的做的事情。峨眉山的山道上放着一大箱金子,我们想搞到这箱黄金。所以在动手之前,我们应该先搞清楚这箱黄金具体位置在哪条山路上,然后设计出几条可行的路线图,接着才是沿着先前设计好的路线去找宝藏。只不过,在这里我们要找的黄金变成了程序某个部分的信息,而那座峨眉山则变成了一个ELF文件。
所以,寻宝要先设计路线图,初始化库要先初始化数据管理句柄。
按照上两篇文章介绍的,ELF的一级数据管理句柄是 :SEF_ELFHEADER
二级数据管理句柄是:SEF_PROHEADER, SEF_SECHEADER
因此,我们按照顺序依次初始化SEF_ELFHEADER, SEF_PROHEADER, SEF_SECHEADER 三个数据管理句柄(管家婆,哈哈哈)。
初始化ELF header
1: long init_elf(char *PBuffer, int nsize, void** phandle)
2: {
3: int ret = 0;
4: if((PBuffer == NULL) || (nsize < 16) || (phandle == NULL))
5: {
6: ret = -1;
7: goto only_out;
8: }
9: if(is_elf(PBuffer))
10: {
11: ret = -3;
12: goto only_out;
13: }
14: /*create new memory for SEF_HEADSET structure and set value
15: *create new memory for SEF_ELFHEADER structure and set value
16: */
17: SEF_HEADSET *PTemp = (SEF_HEADSET *)malloc(sizeof(SEF_HEADSET));
18: SEF_ELFHEADER *handle = (SEF_ELFHEADER *)malloc(sizeof(SEF_ELFHEADER));
19: if(handle == NULL || PTemp == NULL)
20: {
21: ret = -2;
22: goto only_out;
23: }
24: memset(PTemp, 0, sizeof(SEF_HEADSET));
25: memset(handle, 0, sizeof(SEF_ELFHEADER));
26:
27: /* copy elf header from PBuffer */
28: uint8_t nBit = PBuffer[4];
29: if(nBit == ELFCLASS32)
30: {
31: handle->nFlag_Bits = ELFCLASS32;
32: memcpy(&handle->S_ElfHeader_32, PBuffer, sizeof(SEF_ELFHEADER_32));
33: }
34: if(nBit == ELFCLASS64)
35: {
36: handle->nFlag_Bits= ELFCLASS64;
37: memcpy(&handle->S_ElfHeader_64, PBuffer, sizeof(SEF_ELFHEADER_64));
38: }
39:
40: handle->nFlag_Data = PBuffer[5];
41: if((get_local_endding() != PBuffer[5]))
42: {
43: handle->S_ElfHeader_32.e_type = converu16(handle->S_ElfHeader_32.e_type);
44: handle->S_ElfHeader_32.e_machine = converu16(handle->S_ElfHeader_32.e_machine);
45: handle->S_ElfHeader_32.e_version = converu32(handle->S_ElfHeader_32.e_version);
46: handle->S_ElfHeader_32.e_entry = converu32(handle->S_ElfHeader_32.e_entry );
47: handle->S_ElfHeader_32.e_phoff = converu32(handle->S_ElfHeader_32.e_phoff );
48: handle->S_ElfHeader_32.e_shoff = converu32(handle->S_ElfHeader_32.e_shoff );
49: handle->S_ElfHeader_32.e_flags = converu32(handle->S_ElfHeader_32.e_flags );
50: handle->S_ElfHeader_32.e_ehsize = converu16(handle->S_ElfHeader_32.e_ehsize );
51: handle->S_ElfHeader_32.e_phentsize = converu16(handle->S_ElfHeader_32.e_phentsize);
52: handle->S_ElfHeader_32.e_phnum = converu16(handle->S_ElfHeader_32.e_phnum );
53: handle->S_ElfHeader_64.e_type = converu32(handle->S_ElfHeader_64.e_type);
54: handle->S_ElfHeader_64.e_machine = converu32(handle->S_ElfHeader_64.e_machine);
55: handle->S_ElfHeader_64.e_version = converu64(handle->S_ElfHeader_64.e_version);
56: handle->S_ElfHeader_64.e_entry = converu64(handle->S_ElfHeader_64.e_entry );
57: handle->S_ElfHeader_64.e_phoff = converu64(handle->S_ElfHeader_64.e_phoff );
58: handle->S_ElfHeader_64.e_shoff = converu64(handle->S_ElfHeader_64.e_shoff );
59: handle->S_ElfHeader_64.e_flags = converu64(handle->S_ElfHeader_64.e_flags );
60: handle->S_ElfHeader_64.e_ehsize = converu32(handle->S_ElfHeader_64.e_ehsize );
61: handle->S_ElfHeader_64.e_phentsize = converu32(handle->S_ElfHeader_64.e_phentsize);
62: handle->S_ElfHeader_64.e_phnum = converu32(handle->S_ElfHeader_64.e_phnum );
63: }
64: PTemp->pS_ElfHeader= handle;
65: *phandle = PTemp;
66: only_out:
67: return ret;
68: }
初始化segment header
1: long ByteAdjust_SegTab32(SEF_PROHEADER *handle, int PhNum,int nFlag_Data)
2: {
3: int ret = 0;
4: int i;
5: if((handle == NULL) || (PhNum < 1) ||
6: ((nFlag_Data != ELFDATA2MSB) &&
7: (nFlag_Data != ELFDATA2LSB) &&
8: (nFlag_Data != ELFDATANONE)))
9: {
10: ret = -1;
11: goto GetOut;
12: }
13: if(get_local_endding() != nFlag_Data)
14: {
15: for(i=0; i<PhNum; i++)
16: {
17: handle->pS_ProHeader_32[i].p_type = converu32(handle->pS_ProHeader_32[i].p_type);
18: handle->pS_ProHeader_32[i].p_flags = converu32(handle->pS_ProHeader_32[i].p_flags);
19: handle->pS_ProHeader_32[i].p_offset = converu32(handle->pS_ProHeader_32[i].p_offset);
20: handle->pS_ProHeader_32[i].p_vaddr = converu32(handle->pS_ProHeader_32[i].p_vaddr);
21: handle->pS_ProHeader_32[i].p_paddr = converu32(handle->pS_ProHeader_32[i].p_paddr);
22: handle->pS_ProHeader_32[i].p_filesz = converu32(handle->pS_ProHeader_32[i].p_filesz);
23: handle->pS_ProHeader_32[i].p_memsz = converu32(handle->pS_ProHeader_32[i].p_memsz);
24: handle->pS_ProHeader_32[i].p_align = converu32(handle->pS_ProHeader_32[i].p_align);
25: }
26: }
27: GetOut:
28: return ret;
29: }
30:
31: long ByteAdjust_SegTab64(SEF_PROHEADER *handle, int PhNum,int nFlag_Data)
32: {
33: int ret = 0;
34: int i;
35: if((handle == NULL) || (PhNum < 1) ||
36: ((nFlag_Data != ELFDATA2MSB) &&
37: (nFlag_Data != ELFDATA2LSB) &&
38: (nFlag_Data != ELFDATANONE)))
39: {
40: ret = -1;
41: goto GetOut;
42: }
43: if(get_local_endding() != nFlag_Data)
44: {
45: for(i=0; i<PhNum; i++)
46: {
47: handle->pS_ProHeader_64[i].p_type = converu32(handle->pS_ProHeader_64[i].p_type);
48: handle->pS_ProHeader_64[i].p_flags = converu32(handle->pS_ProHeader_64[i].p_flags);
49: handle->pS_ProHeader_64[i].p_offset = converu32(handle->pS_ProHeader_64[i].p_offset);
50: handle->pS_ProHeader_64[i].p_vaddr = converu32(handle->pS_ProHeader_64[i].p_vaddr);
51: handle->pS_ProHeader_64[i].p_paddr = converu32(handle->pS_ProHeader_64[i].p_paddr);
52: handle->pS_ProHeader_64[i].p_filesz = converu32(handle->pS_ProHeader_64[i].p_filesz);
53: handle->pS_ProHeader_64[i].p_memsz = converu32(handle->pS_ProHeader_64[i].p_memsz);
54: handle->pS_ProHeader_64[i].p_align = converu32(handle->pS_ProHeader_64[i].p_align);
55: }
56: }
57: GetOut:
58: return ret;
59: }
60:
61: long init_segtab(unsigned char *PBuffer,void *Handle)
62: {
63: int ret = 0;
64: SEF_HEADSET *PHandle = (SEF_HEADSET *)Handle;
65: if((Handle == NULL ) && (PHandle->pS_ElfHeader == NULL))
66: {
67: ret = -1;
68: goto GetOut;
69: }
70:
71: int PhNum = 0;
72: int i = 0;
73: SEF_ELFHEADER * p_ElfHeader = PHandle->pS_ElfHeader;
74:
75: if((PhNum = p_ElfHeader->S_ElfHeader_32.e_phnum) < 1)
76: {
77: PHandle->pS_ProHeader = NULL;
78: goto GetOut;
79: }
80:
81: SEF_PROHEADER *p_ProHeader = (SEF_PROHEADER *)malloc(sizeof(SEF_PROHEADER));
82:
83: if(p_ProHeader == NULL)
84: {
85: ret = -3;
86: goto GetOut;
87: }
88:
89: /*start deal 32bits elf file*/
90: if(p_ElfHeader->nFlag_Bits == ELFCLASS32)
91: {
92: SEF_PROHEADER_32 *SArrP_Seg = (SEF_PROHEADER_32 *)malloc(PhNum*sizeof(SEF_PROHEADER_32));
93: if(SArrP_Seg == NULL)
94: {
95: ret = -4;
96: goto GetOut;
97: }
98:
99: memcpy(SArrP_Seg,
100: (PBuffer+p_ElfHeader->S_ElfHeader_32.e_phoff),
101: (PhNum*(p_ElfHeader->S_ElfHeader_32.e_phentsize)));
102: if( ByteAdjust_SegTab32(p_ProHeader, PhNum, p_ElfHeader->nFlag_Data) != 0)
103: {
104: ret = -8;
105: goto GetOut;
106: }
107:
108: p_ProHeader->pS_ProHeader_32 = SArrP_Seg;
109: p_ProHeader->pS_ProHeader_64 = NULL;
110: }
111: /*start deal 64bits elf file*/
112: else if(p_ElfHeader->nFlag_Bits == ELFCLASS64)
113: {
114:
115: SEF_PROHEADER_64 *SArrP_Seg = (SEF_PROHEADER_64 *)malloc(PhNum*sizeof(SEF_PROHEADER_64));
116: if(SArrP_Seg == NULL)
117: {
118: PHandle->pS_ProHeader = NULL;
119: ret = -4;
120: goto GetOut;
121: }
122: /*copy program header table from buffer + offset*/
123: memcpy(SArrP_Seg,
124: PBuffer+p_ElfHeader->S_ElfHeader_64.e_phoff,
125: (PhNum*(p_ElfHeader->S_ElfHeader_64.e_phentsize)));
126:
127: /*adjust byte order for every segment*/
128: if((ret = ByteAdjust_SegTab64(p_ProHeader, PhNum, p_ElfHeader->nFlag_Data)) != 0)
129: {
130: ret = -8;
131: goto GetOut;
132: }
133:
134: p_ProHeader->pS_ProHeader_32 = NULL;
135: p_ProHeader->pS_ProHeader_64 = SArrP_Seg;
136: }
137: else
138: {
139: ret = -10;
140: goto GetOut;
141: }
142:
143: PHandle->pS_ProHeader = p_ProHeader;
144:
145:
146: GetOut:
147: return ret;
148: }
初始化section header
1: long ByteAdjust_SecTab32(SEF_SECHEADER *handle, int ShNum,int nFlag_Data)
2: {
3: int ret = 0;
4: int i;
5: if((handle == NULL) || (ShNum < 1) ||
6: ((nFlag_Data != ELFDATA2MSB) &&(nFlag_Data != ELFDATA2LSB) &&(nFlag_Data != ELFDATANONE)))
7: {
8: ret = -1;
9: goto GetOut;
10: }
11:
12: if(get_local_endding() != nFlag_Data)
13: {
14: for(i=0; i<ShNum; i++)
15: {
16:
17: handle->pS_SecHeader_32[i].sh_name = converu32(handle->pS_SecHeader_32[i].sh_name);
18: handle->pS_SecHeader_32[i].sh_type = converu32(handle->pS_SecHeader_32[i].sh_type);
19: handle->pS_SecHeader_32[i].sh_flags = converu32(handle->pS_SecHeader_32[i].sh_flags);
20: handle->pS_SecHeader_32[i].sh_addr = converu32(handle->pS_SecHeader_32[i].sh_addr);
21: handle->pS_SecHeader_32[i].sh_offset = converu32(handle->pS_SecHeader_32[i].sh_offset);
22: handle->pS_SecHeader_32[i].sh_size = converu32(handle->pS_SecHeader_32[i].sh_size);
23: handle->pS_SecHeader_32[i].sh_link = converu32(handle->pS_SecHeader_32[i].sh_link);
24: handle->pS_SecHeader_32[i].sh_info = converu32(handle->pS_SecHeader_32[i].sh_info);
25: handle->pS_SecHeader_32[i].sh_addralign = converu32(handle->pS_SecHeader_32[i].sh_addralign);
26: handle->pS_SecHeader_32[i].sh_entsize = converu32(handle->pS_SecHeader_32[i].sh_entsize);
27: }
28: }
29: GetOut:
30: return ret;
31: }
32:
33: long ByteAdjust_SecTab64(SEF_SECHEADER *handle, int ShNum,int nFlag_Data)
34: {
35: int ret = 0;
36: int i;
37: if((handle == NULL) || (ShNum < 1) ||
38: ((nFlag_Data != ELFDATA2MSB) &&(nFlag_Data != ELFDATA2LSB) &&(nFlag_Data != ELFDATANONE)))
39: {
40: ret = -1;
41: goto GetOut;
42: }
43:
44: if(get_local_endding() != nFlag_Data)
45: {
46: for(i=0; i<ShNum; i++)
47: {
48: handle->pS_SecHeader_64[i].sh_name = converu32(handle->pS_SecHeader_64[i].sh_name);
49: handle->pS_SecHeader_64[i].sh_type = converu32(handle->pS_SecHeader_64[i].sh_type);
50: handle->pS_SecHeader_64[i].sh_flags = converu32(handle->pS_SecHeader_64[i].sh_flags);
51: handle->pS_SecHeader_64[i].sh_addr = converu32(handle->pS_SecHeader_64[i].sh_addr);
52: handle->pS_SecHeader_64[i].sh_offset = converu32(handle->pS_SecHeader_64[i].sh_offset);
53: handle->pS_SecHeader_64[i].sh_size = converu32(handle->pS_SecHeader_64[i].sh_size);
54: handle->pS_SecHeader_64[i].sh_link = converu32(handle->pS_SecHeader_64[i].sh_link);
55: handle->pS_SecHeader_64[i].sh_info = converu32(handle->pS_SecHeader_64[i].sh_info);
56: handle->pS_SecHeader_64[i].sh_addralign = converu32(handle->pS_SecHeader_64[i].sh_addralign);
57: handle->pS_SecHeader_64[i].sh_entsize = converu32(handle->pS_SecHeader_64[i].sh_entsize);
58: }
59: }
60: GetOut:
61: return ret;
62: }
63:
64: long init_section(unsigned char *pbuffer, void *Handle)
65: {
66: int ret = 0;
67: SEF_HEADSET *pS_HeadSet_Temp = NULL;
68: SEF_ELFHEADER *pS_ElfHeader_Temp = NULL;
69: SEF_SECHEADER *pS_SecHeader_Temp = NULL;
70: unsigned char * StrSec_Buffer = NULL;
71: SEF_SECHEADER_32 *pS_SecHeader_32_Temp = NULL;
72: SEF_SECHEADER_64 *pS_SecHeader_64_Temp = NULL;
73:
74: if((pbuffer == NULL) || (Handle == NULL))
75: {
76: ret = -1;
77: goto GetOut;
78: }
79: pS_HeadSet_Temp = (SEF_HEADSET *) Handle;
80: pS_HeadSet_Temp->pBuffer = pbuffer;
81: if(pS_HeadSet_Temp->pS_ElfHeader == NULL)
82: {
83: ret = -2;
84: goto GetOut;
85: }
86: pS_ElfHeader_Temp = pS_HeadSet_Temp->pS_ElfHeader;
87: pS_SecHeader_Temp = (SEF_SECHEADER *)malloc(sizeof(SEF_SECHEADER));
88: if(pS_SecHeader_Temp == NULL)
89: {
90: ret = -4;
91: goto GetOut;
92: }
93: int nShNum;
94: /*start deal 32bits elf file*/
95: if(pS_ElfHeader_Temp->nFlag_Bits == ELFCLASS32)
96: {
97:
98: if((nShNum = pS_ElfHeader_Temp->S_ElfHeader_32.e_shnum) < 1)
99: {
100: pS_HeadSet_Temp->pS_SecHeader = NULL;
101: goto GetOut;
102: }
103: /*create new memory for the SEF_SECHEADER_32 structure*/
104: pS_SecHeader_32_Temp = (SEF_SECHEADER_32 *)malloc(nShNum * sizeof(SEF_SECHEADER_32));
105: if(pS_SecHeader_32_Temp == NULL)
106: {
107: ret = -3;
108: goto GetOut;
109: }
110: /*copy section header table from buffer + shoffset*/
111: memcpy(pS_SecHeader_32_Temp,
112: (pbuffer+pS_ElfHeader_Temp->S_ElfHeader_32.e_shoff),
113: (nShNum * (pS_ElfHeader_Temp->S_ElfHeader_32.e_shentsize)));
114: if(ByteAdjust_SecTab32(pS_SecHeader_Temp, nShNum, pS_ElfHeader_Temp->nFlag_Data) != 0)
115: {
116: ret = -8;
117: goto GetOut;
118: }
119:
120: }
121:
122: /*start deal 64bits elf file*/
123: else if(pS_ElfHeader_Temp->nFlag_Bits == ELFCLASS64)
124: {
125: if((nShNum = pS_ElfHeader_Temp->S_ElfHeader_64.e_shnum) < 1)
126: {
127: pS_HeadSet_Temp->pS_SecHeader = NULL;
128: goto GetOut;
129: }
130:
131: pS_SecHeader_64_Temp = (SEF_SECHEADER_64 *)malloc(nShNum * sizeof(SEF_SECHEADER_64));
132: if(pS_SecHeader_64_Temp == NULL)
133: {
134: ret = -3;
135: goto GetOut;
136: }
137: /*copy section header table from buffer + shoffset*/
138: memcpy(pS_SecHeader_64_Temp,
139: (pbuffer+pS_ElfHeader_Temp->S_ElfHeader_64.e_shoff),
140: (nShNum * (pS_ElfHeader_Temp->S_ElfHeader_64.e_shentsize)));
141: if(ByteAdjust_SecTab64(pS_SecHeader_Temp, nShNum, pS_ElfHeader_Temp->nFlag_Data) != 0)
142: {
143: ret = -8;
144: goto GetOut;
145: }
146: }
147: pS_SecHeader_Temp->pS_SecHeader_32 = pS_SecHeader_32_Temp;
148: pS_SecHeader_Temp->pS_SecHeader_64 = pS_SecHeader_64_Temp;
149: pS_HeadSet_Temp->pS_SecHeader = pS_SecHeader_Temp;
150: GetOut:
151: return ret;
152: }
最后附上头文件:elf_analysis.h
1: #ifndef _ELF_ANALYSIS_H
2: #define _ELF_ANALYSIS_H
3: #include<stdio.h>
4: #include<stdlib.h>
5: #include<string.h>
6: #include "../../include/elf_type.h"
7: #include "../../include/adt.h"
8:
9: /*
10: function: initialize the handle structer
11: input: the arguments1 pbuffer is a data buffer,and
12: the arguments2 nsize that is the total bytes of the buffer.
13: return: the arguments3 phandle inclued these data that the user care about.
14: and the return long number is the errorcode:
15: -1 invalid argument
16: -2 alloc memory failed
17: -3 the data inside the buffer not is ELF file
18: 0 function operated success
19: readme: no
20: */
21: long init_elf(char * pbuffer, int nsize,void** phandle);
22:
23: long ByteAdjust_SegTab32(SEF_PROHEADER *handle, int PhNum,int nFlag_Data);
24:
25: long ByteAdjust_SegTab64(SEF_PROHEADER *handle, int PhNum,int nFlag_Data);
26:
27: long init_segtab( unsigned char *pBuffer, void *Handle);
28:
29: long ByteAdjust_SecTab32(SEF_SECHEADER *handle, int ShNum,int nFlag_Data);
30:
31: long ByteAdjust_SecTab64(SEF_SECHEADER *handle, int ShNum,int nFlag_Data);
32:
33: long init_section(unsigned char *pbuffer, void *Handle);
34:
35: #endif