Android逆向进阶-ELF文件分析(3)
本帖最后由 BubblePig 于 2018-3-5 10:52 编辑# 0x00 前言
这里是[无价之宝](http://blog.csdn.net/qq_36869808/article/details/79367884)
之前的(http://blog.csdn.net/qq_36869808/article/details/79334437)
以及(http://blog.csdn.net/qq_36869808/article/details/79438406)
## 内容
1.Program Headers 程序分析
2.Section 分析
3.字符串表
4.符号表
# 0x01 Program Headers 分析
首先来看一个结构体
```
typedef struct {
Elf32_Word p_type;
Elf32_Off p_offset;
Elf32_Addr p_vaddr;
Elf32_Addr p_paddr;
Elf32_Word p_filesz;
Elf32_Word p_memsz;
Elf32_Word p_flags;
Elf32_Word p_align;
} Elf32_phdr;
```
## p_type
描述段的类型,或者如何解释此数组元素的信息。
![这里写图片描述](http://t1.aixinxi.net/o_1c7ogfkp313tl1s1s10ml1e7m9upa.png-j.jpg)
010 Editor分析
![这里写图片描述](http://t1.aixinxi.net/o_1c7ogkkju1f9o11c8mii1r66icra.png-j.jpg)
使用c语言实现程序编写。
![这里写图片描述](http://t1.aixinxi.net/o_1c7oic3qtstu19qo1sh6hpinp0a.png-j.jpg)
```
printf("--------第%d个Program Headers--------\n",1);
printf("p_type:");
for (i = 0; i < 4; i++)
{
c = fgetc(fp);
j = c;
hex_str = inttohex(j);
h1 = j;
if (j < 9){
printf("0%s ", hex_str);
}
else
{
printf("%s ", hex_str);
}
}
E_type(h1);
```
## p_offset
此成员给出从文件头到该段第一个字节的偏移。
010 editor 分析
![这里写图片描述](http://t1.aixinxi.net/o_1c7oitdhl3rs15vicfs1spv1cf9a.png-j.jpg)
c语言分析
![这里写图片描述](http://t1.aixinxi.net/o_1c7oiv86o1bl147m1qo81uu43tia.png-j.jpg)
```
printf("p_offset:");
for (i = 0; i < 4; i++)
{
c = fgetc(fp);
j = c;
hex_str = inttohex(j);
h1 = j;
if (j < 9){
printf("0%s ", hex_str);
}
else
{
printf("%s ", hex_str);
}
}
printf("(%s H)", inttohex(h1));
```
## p_vaddr
此成员给出段的第一个字节将被放到内存中的虚拟地址。
010 editor 对比分析
![这里写图片描述](http://t1.aixinxi.net/o_1c7oj5nac1bnt1cjq5uf1cs14hqa.png-j.jpg)
c语言分析
![这里写图片描述](http://t1.aixinxi.net/o_1c7ojcc1f6451um11gkgskqkd7a.png-j.jpg)
关键代码
```
printf("p_vaddr:");
for (i = 0; i < 4; i++)
{
c = fgetc(fp);
j = c;
hex_str = inttohex(j);
h1 = j;
if (j < 9){
printf("0%s ", hex_str);
}
else
{
printf("%s ", hex_str);
}
}
printf("(%s H)\n", inttohex(h1));
```
## p_paddr
此成员仅用于与物理地址相关的系统中。因为 System V 忽略所有应用程序的物理地址信息,此字段对与可执行文件和共享目标文件而言具体内容是未指定的。
010 Editor 对比分析
![这里写图片描述](http://t1.aixinxi.net/o_1c7ojiknb3h1n3g1hmshbj1pmma.png-j.jpg)
c语言代码:
和上面一样继续向下读取就可以了。
## p_filesz
此成员给出段在文件映像中所占的字节数。可以为 0
010 editor
![这里写图片描述](http://t1.aixinxi.net/o_1c7ojq5cf3l0l0791o1q7k1lmsa.png-j.jpg)
c语言程序展示。
![这里写图片描述](http://t1.aixinxi.net/o_1c7oko52uta31d68673ncp9lja.png-j.jpg)
关键代码:
```
printf("p_filesz:");
for (i = 0; i < 4; i++)
{
c = fgetc(fp);
j = c;
h1 = j;
hex_str = inttohex(j);
if (j < 9){
if (j >= 0){
printf("0%s ", hex_str);
}
else
{
j = 256 + j;
h1 = j;
if (i == 0)
{
j1 = j;
}
hex_str = inttohex(j);
if (j<9)
printf("0%s ", hex_str);
else
printf("%s ", hex_str);
}
}
else
{
printf("%s ", hex_str);
}
}
hex_str = inttohex(h1);
printf("(");
if (h1 < 9){
if (h1 >= 0){
printf("0%s", hex_str);
}
else
{
h1 = 256 + h1;
hex_str = inttohex(h1);
if (h1<9)
printf("0%s", hex_str);
else
printf("%s", hex_str);
}
}
else
{
printf("%s", hex_str);
}
hex_str = inttohex(h1);
if (h1 < 9){
if (h1 >= 0){
printf("0%s", hex_str);
}
else
{
h1 = 256 + h1;
hex_str = inttohex(h1);
if (h1<9)
printf("0%s", hex_str);
else
printf("%s", hex_str);
}
}
else
{
printf("%s", hex_str);
}
printf(" H)\n");
```
## p_memsz
此成员给出段在内存映像中占用的字节数。可以为 0。
010 editor
![这里写图片描述](http://t1.aixinxi.net/o_1c7oks0qb1p86e421rpe8dq1vhea.png-j.jpg)
c语言核心代码
```
printf("p_memsz:");
for (i = 0; i < 4; i++)
{
c = fgetc(fp);
j = c;
h1 = j;
hex_str = inttohex(j);
if (j < 9){
if (j >= 0){
printf("0%s ", hex_str);
}
else
{
j = 256 + j;
h1 = j;
if (i == 0)
{
j1 = j;
}
hex_str = inttohex(j);
if (j<9)
printf("0%s ", hex_str);
else
printf("%s ", hex_str);
}
}
else
{
printf("%s ", hex_str);
}
}
hex_str = inttohex(h1);
printf("(");
if (h1 < 9){
if (h1 >= 0){
printf("0%s", hex_str);
}
else
{
h1 = 256 + h1;
hex_str = inttohex(h1);
if (h1<9)
printf("0%s", hex_str);
else
printf("%s", hex_str);
}
}
else
{
printf("%s", hex_str);
}
hex_str = inttohex(h1);
if (h1 < 9){
if (h1 >= 0){
printf("0%s", hex_str);
}
else
{
h1 = 256 + h1;
hex_str = inttohex(h1);
if (h1<9)
printf("0%s", hex_str);
else
printf("%s", hex_str);
}
}
else
{
printf("%s", hex_str);
}
printf(" H)\n");
```
## p_flags
此成员给出与段相关的标志。
```
#define PF_X 0x1 /* Executable. */
#define PF_W 0x2 /* Writable. */
#define PF_R 0x4 /* Readable. */
```
010 editor
![这里写图片描述](http://t1.aixinxi.net/o_1c7omljvr1jha1kac1gek1acdn9ia.png-j.jpg)
## p_align
可加载的进程段的 p_vaddr 和 p_offset 取值必须合适,相对于对页面大小的取模而言。此成员给出段在文件中和内存中如何对齐。数值 0 和 1 表示不需要对齐。否则 p_align 应该是个正整数,并且是 2 的幂次数,p_vaddr 和 p_offset 对 p_align取模后应该相等。
![这里写图片描述](http://t1.aixinxi.net/o_1c7omuviojj5dd11hoe1hub1ahka.png-j.jpg)
## 总结
整个Program head 就分析完了。
![这里写图片描述](http://t1.aixinxi.net/o_1c7oneh1tbibdoi180hgcu1ndga.png-j.jpg)
# 0x02 Sections
(1). 目标文件中的每个节区都有对应的节区头部描述它,反过来,有节区头部不意味着有节区。
(2). 每个节区占用文件中一个连续字节区域(这个区域可能长度0)。
(3). 文件中的节区不能重叠,不允许一个字节存在于两个节区中的情况发生。
(4). 目标文件中可能包含非活动空间(INACTIVE SPACE)。这些区域不属于任何头部和节区,其内容未指定。
## 1.Section head
```
typedef struct{
Elf32_Word sh_name;
Elf32_Word sh_type;
Elf32_Word sh_flags;
Elf32_Addr sh_addr;
Elf32_Off sh_offset;
Elf32_Word sh_size;
Elf32_Word sh_link;
Elf32_Word sh_info;
Elf32_Word sh_addralign;
Elf32_Word sh_entsize;
}Elf32_Shdr;
```
这里有具体的说明。
![这里写图片描述](http://t1.aixinxi.net/o_1c7oo9h6u147k1nmd1ecmpp3fsma.png-j.jpg)
![这里写图片描述](http://t1.aixinxi.net/o_1c7ooad1l17fn1vujpkmdgm43oa.png-j.jpg)
### sh_type字段
![这里写图片描述](http://t1.aixinxi.net/o_1c7ooch6s1j2qdj31k5hpd2ekja.png-j.jpg)
![这里写图片描述](http://t1.aixinxi.net/o_1c7ooddvfokv1js3k0qjrk1b3sa.png-j.jpg)
还有一些特殊字节,这里就不再赘述了。有兴趣的可以自己研究一下。
# 0x03 字符串表
字符串表节区包含以 NULL(ASCII 码 0)结尾的字符序列,通常称为字符串。
对字符串的引用通常以字符串在字符串表中的下标给出。
一般,第一个字节(索引为 0)定义为一个空字符串。
允许存在空的字符串表节区,其节区头部的 sh_size 成员应该为 0。
# 0x04 符号表
使用
```
readelf -s 1.so
```
进行查看。
![这里写图片描述](http://t1.aixinxi.net/o_1c7ooolnph3ver3121l1o5q3ua.png-j.jpg)
恩,这个留着以后有时间慢慢来分析。
2018年3月4日23:17:26退水了退水了88
,沙发!!!看看学学 支持,以后学习学习 好资源,分析的很详细了学习了 你微信多少,有问题请教,在的时候麻烦回复下有红包,谢谢 这就比较简介了哈 谢谢,好好学习学习
页:
[1]