Linux Hook技術(shù)(三)

轉(zhuǎn)載自:https://blog.csdn.net/yyttiao/article/details/7358578
今天主要講述的是ELF 文件的另一個(gè)大塊叫節(jié)頭(Section Headers),那么什么叫節(jié)頭呢.節(jié)頭里面分散著不同的段,有.bss .text .init .data .got .shstrtab 等等.節(jié)頭表主要是在連接的角度看待ELF的.每一個(gè)節(jié)都保存著該節(jié)特有的數(shù)據(jù),由于節(jié)中數(shù)據(jù)的用途不同,節(jié)被分為不同的類(lèi)型,每種類(lèi)型都又自己組織數(shù)據(jù)的方式.有的節(jié)儲(chǔ)存著一些字符串,例如前面提過(guò)的.shstrtab 這個(gè)節(jié),就專(zhuān)門(mén)儲(chǔ)存節(jié)對(duì)應(yīng)名詞的字符串.今天這一節(jié)內(nèi)容,我們就用使用這個(gè)節(jié),獲取節(jié)的名字.

下面按照我們每一次的慣例,先看一下結(jié)構(gòu)體說(shuō)明,然后再逐一介紹每一個(gè)成員,在前面幾節(jié)中,我們主要是對(duì)ELF進(jìn)行一個(gè)全面的了解,為以后進(jìn)行HOOK做充分的準(zhǔn)備.因?yàn)槟遣糠值迷贓LF文件的基礎(chǔ)上去實(shí)施的,好了.加油吧~~~

詳細(xì)說(shuō)明請(qǐng)參閱 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: 該成員是字符串表中的一個(gè)索引

通過(guò)該索引就可以獲取這個(gè)節(jié)所對(duì)應(yīng)的節(jié)的名字.通常同節(jié)的類(lèi)型(sh_type)來(lái)判斷當(dāng)前是屬于什么節(jié).

sh_type: 節(jié)的類(lèi)型

這個(gè)成員可以告訴我們這個(gè)節(jié)里面存放的到底是什么數(shù)據(jù),對(duì)于不同的數(shù)據(jù),我們?cè)偻ㄟ^(guò)不同的數(shù)據(jù)結(jié)構(gòu)去獲取數(shù)據(jù)

sh_flags: 節(jié)的屬性

這個(gè)成員指定該節(jié)的內(nèi)容是否可讀可寫(xiě)等屬性,具體定義如下:

#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: 指向進(jìn)程空間內(nèi)的虛擬地址

如果這個(gè)節(jié)需要被加載到進(jìn)程中,那么該字段就指向內(nèi)存中的虛擬地址

sh_offset: 指向文件空間內(nèi)的絕對(duì)偏移(相對(duì)整個(gè)文件的起始地址的)

該地址可以獲取到很多關(guān)于節(jié)內(nèi)容的信息.

sh_size: 節(jié)的內(nèi)容大小

如果此節(jié)在文件中占用一定的字節(jié),那么這個(gè)字段給出了該節(jié)所占用的字節(jié)大小,

如果此節(jié)不存在于文件卻在內(nèi)存中,那么這個(gè)字段給出了該節(jié)在內(nèi)存中的字節(jié)大小

sh_link: 如果這個(gè)節(jié)于別的節(jié)相連,那么這個(gè)字段給出了相關(guān)的節(jié)在節(jié)頭中的索引

sh_info: 額外的信息

對(duì)于部分節(jié)來(lái)說(shuō),還有一些額外的信息.

sh_addralign: 地址對(duì)齊

對(duì)于雙字節(jié)等數(shù)據(jù)格式,很多時(shí)候必須對(duì)數(shù)據(jù)進(jìn)行必要的對(duì)齊,來(lái)保證數(shù)據(jù)的準(zhǔn)確存儲(chǔ),這個(gè)數(shù)是2的整數(shù)次冪,對(duì)齊只能有2字節(jié)對(duì)齊,4字節(jié)對(duì)齊,8字節(jié)對(duì)齊等,如果是0或者1表示這個(gè)節(jié)不用對(duì)齊.

sh_entsize: 指定節(jié)內(nèi)部數(shù)據(jù)的大小

這個(gè)字段代表字節(jié)大小的數(shù),對(duì)于某些字節(jié)才有意義,例如動(dòng)態(tài)符號(hào)節(jié)來(lái)說(shuō),這個(gè)字段就給出動(dòng)態(tài)符號(hào)表中每一個(gè)符號(hào)結(jié)構(gòu)的字節(jié)大小.

上面說(shuō)到,要獲取節(jié)的名字要怎么做呢.sh_name字段只是保存了一個(gè)值,并不是字符串地址,那要怎么才能獲取字符串呢.在前面講述的第一個(gè)ELF Head的時(shí)候有這樣一個(gè)字段e_shstrndx這個(gè)成員就是指向字符串表的索引,就可以知道找到節(jié)點(diǎn)中的字符串節(jié)表了.

同樣在遍歷節(jié)頭的時(shí)候,如果字段類(lèi)型等于SHT_STRTAB,那么對(duì)應(yīng)的也就是字符串表.但是為了方便,在ELF Head中已經(jīng)指出了他所對(duì)應(yīng)的索引了.在字符串表中是以一系列的'\0'結(jié)尾的字符串,在這個(gè)節(jié)的第一個(gè)字節(jié)也是0,為什么第一個(gè)字節(jié)會(huì)是0呢,其實(shí)這就是空字符串.在這個(gè)節(jié)的最后一個(gè)字節(jié)也是0. 因?yàn)樽址淖詈笠粋€(gè)都市'\0'.

既然找到了字符串表,那怎么獲取他里面的名字呢,其實(shí)可以把字符串表當(dāng)成一個(gè)很大的char型數(shù)組sh_name就是所需要的字符串的首字符,通過(guò)字符串表首地址加上相對(duì)的偏移量就是對(duì)應(yīng)的字符串的名字了.

下面我們就來(lái)通過(guò)代碼來(lái)加深印象..

示例代碼:

#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++;
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市蜓斧,隨后出現(xiàn)的幾起案子樟凄,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,807評(píng)論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡虑粥,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,284評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén)宪哩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)娩贷,“玉大人,你說(shuō)我怎么就攤上這事锁孟”蜃妫” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 169,589評(píng)論 0 363
  • 文/不壞的土叔 我叫張陵品抽,是天一觀的道長(zhǎng)储笑。 經(jīng)常有香客問(wèn)我,道長(zhǎng)圆恤,這世上最難降的妖魔是什么突倍? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 60,188評(píng)論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮盆昙,結(jié)果婚禮上羽历,老公的妹妹穿的比我還像新娘。我一直安慰自己淡喜,他們只是感情好秕磷,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,185評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著炼团,像睡著了一般澎嚣。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上瘟芝,一...
    開(kāi)封第一講書(shū)人閱讀 52,785評(píng)論 1 314
  • 那天易桃,我揣著相機(jī)與錄音,去河邊找鬼模狭。 笑死颈抚,一個(gè)胖子當(dāng)著我的面吹牛踩衩,可吹牛的內(nèi)容都是我干的嚼鹉。 我是一名探鬼主播,決...
    沈念sama閱讀 41,220評(píng)論 3 423
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼驱富,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼锚赤!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起褐鸥,我...
    開(kāi)封第一講書(shū)人閱讀 40,167評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤线脚,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體浑侥,經(jīng)...
    沈念sama閱讀 46,698評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡姊舵,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,767評(píng)論 3 343
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了寓落。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片括丁。...
    茶點(diǎn)故事閱讀 40,912評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖伶选,靈堂內(nèi)的尸體忽然破棺而出史飞,到底是詐尸還是另有隱情,我是刑警寧澤仰税,帶...
    沈念sama閱讀 36,572評(píng)論 5 351
  • 正文 年R本政府宣布构资,位于F島的核電站,受9級(jí)特大地震影響陨簇,放射性物質(zhì)發(fā)生泄漏吐绵。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,254評(píng)論 3 336
  • 文/蒙蒙 一河绽、第九天 我趴在偏房一處隱蔽的房頂上張望拦赠。 院中可真熱鬧,春花似錦葵姥、人聲如沸荷鼠。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,746評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)允乐。三九已至,卻和暖如春削咆,著一層夾襖步出監(jiān)牢的瞬間牍疏,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,859評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工拨齐, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留鳞陨,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,359評(píng)論 3 379
  • 正文 我出身青樓瞻惋,卻偏偏與公主長(zhǎng)得像厦滤,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子歼狼,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,922評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容

  • 上一篇介紹了編譯連接的過(guò)程掏导,提到了目標(biāo)文件是通過(guò)匯編過(guò)程生成的,最終鏈接生成可執(zhí)行文件羽峰,這篇介紹一下目標(biāo)文件里面到...
    紙簡(jiǎn)書(shū)生閱讀 1,181評(píng)論 0 4
  • [toc] 網(wǎng)址 深入理解程序構(gòu)造 LMA與VMA總結(jié) ELF文件解析和加載(附代碼) Linux及安全實(shí)踐四——...
    余帶鹽閱讀 528評(píng)論 0 0
  • 1. 背景 在我們的日常工作中經(jīng)常會(huì)遇到一些BUG趟咆,而且這些BUG發(fā)生在native層添瓷,也就是在我們的so共...
    2baf611355d8閱讀 17,192評(píng)論 3 41
  • 本文借鑒了網(wǎng)上大多數(shù)文章,相當(dāng)于一邊學(xué)習(xí)一邊整合值纱。主要借鑒https://blog.csdn.net/yyttia...
    Sma11_Tim3閱讀 1,467評(píng)論 0 1
  • 好久都沒(méi)進(jìn)菜市場(chǎng)了鳞贷,偶有路過(guò),看著賣(mài)肉的鋪?zhàn)訏鞚M了色彩鮮艷的大塊大塊肥瘦相見(jiàn)虐唠,白里透紅的肉悄晃。刀工了得,每塊看起來(lái)都...
    坐看雲(yún)起聽(tīng)風(fēng)吟閱讀 530評(píng)論 0 1