0x00 前言
这里是无价之宝
之前的Android逆向进阶-ELF文件分析(1)
以及Android逆向进阶-ELF文件分析(2)(c解析ELF head)
内容
1.Program Headers 程序分析
2.Section 分析
3.字符串表
4.符号表
首先来看一个结构体
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
描述段的类型,或者如何解释此数组元素的信息。
010 Editor分析
使用c语言实现程序编写。
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[i] = j;
if (j < 9){
printf("0%s ", hex_str);
}
else
{
printf("%s ", hex_str);
}
}
E_type(h1[0]);
p_offset
此成员给出从文件头到该段第一个字节的偏移。
010 editor 分析
c语言分析
printf("p_offset:");
for (i = 0; i < 4; i++)
{
c = fgetc(fp);
j = c;
hex_str = inttohex(j);
h1[i] = j;
if (j < 9){
printf("0%s ", hex_str);
}
else
{
printf("%s ", hex_str);
}
}
printf("(%s H)", inttohex(h1[0]));
p_vaddr
此成员给出段的第一个字节将被放到内存中的虚拟地址。
010 editor 对比分析
c语言分析
关键代码
printf("p_vaddr:");
for (i = 0; i < 4; i++)
{
c = fgetc(fp);
j = c;
hex_str = inttohex(j);
h1[i] = j;
if (j < 9){
printf("0%s ", hex_str);
}
else
{
printf("%s ", hex_str);
}
}
printf("(%s H)\n", inttohex(h1[0]));
p_paddr
此成员仅用于与物理地址相关的系统中。因为 System V 忽略所有应用程序的物理地址信息,此字段对与可执行文件和共享目标文件而言具体内容是未指定的。
010 Editor 对比分析
c语言代码:
和上面一样继续向下读取就可以了。
p_filesz
此成员给出段在文件映像中所占的字节数。可以为 0
010 editor
c语言程序展示。
关键代码:
printf("p_filesz:");
for (i = 0; i < 4; i++)
{
c = fgetc(fp);
j = c;
h1[i] = j;
hex_str = inttohex(j);
if (j < 9){
if (j >= 0){
printf("0%s ", hex_str);
}
else
{
j = 256 + j;
h1[i] = 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[1]);
printf("(");
if (h1[1] < 9){
if (h1[1] >= 0){
printf("0%s", hex_str);
}
else
{
h1[1] = 256 + h1[1];
hex_str = inttohex(h1[1]);
if (h1[1]<9)
printf("0%s", hex_str);
else
printf("%s", hex_str);
}
}
else
{
printf("%s", hex_str);
}
hex_str = inttohex(h1[0]);
if (h1[0] < 9){
if (h1[0] >= 0){
printf("0%s", hex_str);
}
else
{
h1[0] = 256 + h1[0];
hex_str = inttohex(h1[0]);
if (h1[0]<9)
printf("0%s", hex_str);
else
printf("%s", hex_str);
}
}
else
{
printf("%s", hex_str);
}
printf(" H)\n");
p_memsz
此成员给出段在内存映像中占用的字节数。可以为 0。
010 editor
c语言核心代码
printf("p_memsz:");
for (i = 0; i < 4; i++)
{
c = fgetc(fp);
j = c;
h1[i] = j;
hex_str = inttohex(j);
if (j < 9){
if (j >= 0){
printf("0%s ", hex_str);
}
else
{
j = 256 + j;
h1[i] = 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[1]);
printf("(");
if (h1[1] < 9){
if (h1[1] >= 0){
printf("0%s", hex_str);
}
else
{
h1[1] = 256 + h1[1];
hex_str = inttohex(h1[1]);
if (h1[1]<9)
printf("0%s", hex_str);
else
printf("%s", hex_str);
}
}
else
{
printf("%s", hex_str);
}
hex_str = inttohex(h1[0]);
if (h1[0] < 9){
if (h1[0] >= 0){
printf("0%s", hex_str);
}
else
{
h1[0] = 256 + h1[0];
hex_str = inttohex(h1[0]);
if (h1[0]<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
p_align
可加载的进程段的 p_vaddr 和 p_offset 取值必须合适,相对于对页面大小的取模而言。此成员给出段在文件中和内存中如何对齐。数值 0 和 1 表示不需要对齐。否则 p_align 应该是个正整数,并且是 2 的幂次数,p_vaddr 和 p_offset 对 p_align取模后应该相等。
总结
整个Program head 就分析完了。
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;
这里有具体的说明。
sh_type字段
还有一些特殊字节,这里就不再赘述了。有兴趣的可以自己研究一下。
0x03 字符串表
字符串表节区包含以 NULL(ASCII 码 0)结尾的字符序列,通常称为字符串。
对字符串的引用通常以字符串在字符串表中的下标给出。
一般,第一个字节(索引为 0)定义为一个空字符串。
允许存在空的字符串表节区,其节区头部的 sh_size 成员应该为 0。
0x04 符号表
使用
readelf -s 1.so
进行查看。
恩,这个留着以后有时间慢慢来分析。
2018年3月4日23:17:26退水了退水了88