BubblePig 发表于 2018-3-4 23:22

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

xi850202 发表于 2018-3-4 23:33

,沙发!!!看看学学

136122qwe 发表于 2018-3-5 00:20

支持,以后学习学习

kk1212 发表于 2018-3-5 10:40

好资源,分析的很详细了学习了

wangshuai 发表于 2018-3-5 14:05

你微信多少,有问题请教,在的时候麻烦回复下有红包,谢谢

榜样小二 发表于 2018-3-5 18:30

这就比较简介了哈

hc010634 发表于 2018-9-27 10:14

谢谢,好好学习学习
页: [1]
查看完整版本: Android逆向进阶-ELF文件分析(3)