Linux Hook技术(三)

转载自:https://blog.csdn.net/yyttiao/article/details/7358578
今天主要讲述的是ELF 文件的另一个大块叫节头(Section Headers),那么什么叫节头呢.节头里面分散着不同的段,有.bss .text .init .data .got .shstrtab 等等.节头表主要是在连接的角度看待ELF的.每一个节都保存着该节特有的数据,由于节中数据的用途不同,节被分为不同的类型,每种类型都又自己组织数据的方式.有的节储存着一些字符串,例如前面提过的.shstrtab 这个节,就专门储存节对应名词的字符串.今天这一节内容,我们就用使用这个节,获取节的名字.

下面按照我们每一次的惯例,先看一下结构体说明,然后再逐一介绍每一个成员,在前面几节中,我们主要是对ELF进行一个全面的了解,为以后进行HOOK做充分的准备.因为那部分得在ELF文件的基础上去实施的,好了.加油吧~~~

详细说明请参阅 elf.h

/* Section header.  */
typedef struct
{
  Elf32_Word    sh_name;     /* Section name (string tbl index) */
  Elf32_Word    sh_type;     /* Section type */
  Elf32_Word    sh_flags;    /* Section flags */
  Elf32_Addr    sh_addr;     /* Section virtual addr at execution */
  Elf32_Off sh_offset;   /* Section file offset */
  Elf32_Word    sh_size;     /* Section size in bytes */
  Elf32_Word    sh_link;     /* Link to another section */
  Elf32_Word    sh_info;     /* Additional section information */
  Elf32_Word    sh_addralign;    /* Section alignment */
  Elf32_Word    sh_entsize;  /* Entry size if section holds table */
} Elf32_Shdr;

sh_name: 该成员是字符串表中的一个索引

通过该索引就可以获取这个节所对应的节的名字.通常同节的类型(sh_type)来判断当前是属于什么节.

sh_type: 节的类型

这个成员可以告诉我们这个节里面存放的到底是什么数据,对于不同的数据,我们再通过不同的数据结构去获取数据

sh_flags: 节的属性

这个成员指定该节的内容是否可读可写等属性,具体定义如下:

#define SHF_WRITE        (1 << 0)
/* Writable */
#define SHF_ALLOC        (1 << 1)
/* Occupies memory during execution */
#define SHF_EXECINSTR    (1 << 2)
/* Executable */
#define SHF_MERGE        (1 << 4)
/* Might be merged */
#define SHF_STRINGS  (1 << 5)
/* Contains nul-terminated strings */
#define SHF_INFO_LINK    (1 << 6)
/* `sh_info' contains SHT index */
#define SHF_LINK_ORDER(1 << 7)
/* Preserve order after combining */
#define SHF_OS_NONCONFORMING (1 << 8)
/* Non-standard OS specific handling required */

sh_addr: 指向进程空间内的虚拟地址

如果这个节需要被加载到进程中,那么该字段就指向内存中的虚拟地址

sh_offset: 指向文件空间内的绝对偏移(相对整个文件的起始地址的)

该地址可以获取到很多关于节内容的信息.

sh_size: 节的内容大小

如果此节在文件中占用一定的字节,那么这个字段给出了该节所占用的字节大小,

如果此节不存在于文件却在内存中,那么这个字段给出了该节在内存中的字节大小

sh_link: 如果这个节于别的节相连,那么这个字段给出了相关的节在节头中的索引

sh_info: 额外的信息

对于部分节来说,还有一些额外的信息.

sh_addralign: 地址对齐

对于双字节等数据格式,很多时候必须对数据进行必要的对齐,来保证数据的准确存储,这个数是2的整数次幂,对齐只能有2字节对齐,4字节对齐,8字节对齐等,如果是0或者1表示这个节不用对齐.

sh_entsize: 指定节内部数据的大小

这个字段代表字节大小的数,对于某些字节才有意义,例如动态符号节来说,这个字段就给出动态符号表中每一个符号结构的字节大小.

上面说到,要获取节的名字要怎么做呢.sh_name字段只是保存了一个值,并不是字符串地址,那要怎么才能获取字符串呢.在前面讲述的第一个ELF Head的时候有这样一个字段e_shstrndx这个成员就是指向字符串表的索引,就可以知道找到节点中的字符串节表了.

同样在遍历节头的时候,如果字段类型等于SHT_STRTAB,那么对应的也就是字符串表.但是为了方便,在ELF Head中已经指出了他所对应的索引了.在字符串表中是以一系列的'\0'结尾的字符串,在这个节的第一个字节也是0,为什么第一个字节会是0呢,其实这就是空字符串.在这个节的最后一个字节也是0. 因为字符串的最后一个都市'\0'.

既然找到了字符串表,那怎么获取他里面的名字呢,其实可以把字符串表当成一个很大的char型数组sh_name就是所需要的字符串的首字符,通过字符串表首地址加上相对的偏移量就是对应的字符串的名字了.

下面我们就来通过代码来加深印象..

示例代码:

#include "readShdr.h"
SectionType secTyoe[] = {
    {0, "NULL"},
    {1, "SHT_PROGBITS"},
    {2, "SHT_SYMTAB"},
    {3, "SHT_STRTAB"},
    {4, "SHT_RELA"},
    {5, "SHT_HASH"},
    {6, "SHT_DYNAMIC"},
    {7, "SHT_NOTE"},
    {8, "SHT_NOBITS"},
    {9, "SHT_REL"},
    {10, "SHT_SHLIB"},
    {11, "SHT_DYNSYM"},
    {14, "SHT_INIT_ARRAY"},
    {15, "SHT_FINI_ARRAY"},
    {16, "SHT_PREINIT_ARRAY"},
    {17, "SHT_GROUP"},
    {18, "SHT_SYMTAB_SHNDX"},
    {19, "SHT_NUM"},
    {0x60000000, "SHT_LOOS"},
    {0x6ffffff6, "SHT_GNU_HASH"},
    {0x6ffffff7, "SHT_GNU_LIBLIST"},
    {0x6ffffff8, "SHT_CHECKSUM"},
    {0x6ffffffa, "SHT_LOSUNW"},
    {0x6ffffffb, "SHT_SUNW_move"},
    {0x6ffffffc, "SHT_SUNW_COMDAT"},
    {0x6ffffffd, "SHT_SUNW_syminfo"},
    {0x6ffffffe, "SHT_GNU_verdef"},
    {0x6fffffff, "SHT_GNU_verneed"},
    {0x70000000, "SHT_LOPROC"},
    {0x7fffffff, "SHT_HIPROC"},
    {0x80000000, "SHT_LOUSER"},
    {0x8fffffff, "SHT_HIUSER"},
};
char *findSecTypeName(unsigned int type)
{
    int i = 0;
    for (i = 0; i < sizeof(secTyoe) / sizeof(SectionType); i++)
    {
        if (secTyoe[i].type == type)
        {
            return secTyoe[i].typeName;
            break;
        }
    }
    return secTyoe[0].typeName;
}
void displayShdr(Elf32_Ehdr *ehdr, Elf32_Shdr *shdr)
{
    int py = ehdr->e_shstrndx * sizeof(Elf32_Shdr);
    Elf32_Shdr *symtab = (Elf32_Shdr *)((char *)shdr + py);
    printf("symtab 0x%x\n", symtab);
    char *szShdrName = (char *)(symtab->sh_offset + (char *)ehdr);
    printf("e_shstrndx=%dsizeof(Elf32_Shdr)=%dshdr=x%x\n", ehdr->e_shstrndx, sizeof(Elf32_Shdr), shdr);
    printf("Section Headers: 0x%x\n", szShdrName);
    int i = 0;
    printf("[Nr] %-20s%-20s%-5s%-8s%-6s%-6s%-6s%-4s%-4s%-2s\n",
           "Name", "Type",
           "Flg", "Addr", "Off", "Size", "Lk", "Inf", "Al", "ES");
    for (i = 0; i < ehdr->e_shnum; i++)
    {
        printf("[%-2d] %-20s", i, szShdrName + shdr->sh_name);
        printf("%-20s", findSecTypeName(shdr->sh_type));
        printf("%-5x", shdr->sh_flags);
        printf("%-08x", shdr->sh_addr);
        printf("%-06x", shdr->sh_offset);
        printf("%-06x", shdr->sh_size);
        printf("%-4x", shdr->sh_link);
        printf("%-4x", shdr->sh_info);
        printf("%-4x", shdr->sh_addralign);
        printf("%-02x\n", shdr->sh_entsize);
        shdr++;
    }
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,425评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,058评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,186评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,848评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,249评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,554评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,830评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,536评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,239评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,505评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,004评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,346评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,999评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,060评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,821评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,574评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,480评论 2 267

推荐阅读更多精彩内容

  • 上一篇介绍了编译连接的过程,提到了目标文件是通过汇编过程生成的,最终链接生成可执行文件,这篇介绍一下目标文件里面到...
    纸简书生阅读 1,111评论 0 4
  • [toc] 网址 深入理解程序构造 LMA与VMA总结 ELF文件解析和加载(附代码) Linux及安全实践四——...
    余带盐阅读 481评论 0 0
  • 1. 背景 在我们的日常工作中经常会遇到一些BUG,而且这些BUG发生在native层,也就是在我们的so共...
    2baf611355d8阅读 16,786评论 3 41
  • 本文借鉴了网上大多数文章,相当于一边学习一边整合。主要借鉴https://blog.csdn.net/yyttia...
    Sma11_Tim3阅读 1,318评论 0 1
  • 好久都没进菜市场了,偶有路过,看着卖肉的铺子挂满了色彩鲜艳的大块大块肥瘦相见,白里透红的肉。刀工了得,每块看起来都...
    坐看雲起听风吟阅读 467评论 0 1