• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
  • 如何修改動態庫符號表[轉]

    發表于:2007-07-04來源:作者:點擊數: 標簽:
    ELF 文件中代碼、連接信息和注釋是以節(section)為單位存放的,并存有一 個節頭表(section header)。對每一節,在節頭表中都有一個表項(節頭表項) 與之對應,表項記錄了該節的一些信息,例如該節在文件中的位置信息和該節 的字節長度信息。 一、ELF 文件和有
    ELF 文件中代碼、連接信息和注釋是以節(section)為單位存放的,并存有一
    個節頭表(section header)。對每一節,在節頭表中都有一個表項(節頭表項)
    與之對應,表項記錄了該節的一些信息,例如該節在文件中的位置信息和該節
    的字節長度信息。

    一、ELF 文件和有關術語

    Unix 系統的可執行文件和動態庫文件是以 ELF 格式存放的。為使下面的敘述
    清晰而沒有伎義,先簡要介紹一下 ELF 文件格式,并約定一些術語。關于ELF
    文件格式的詳細情況請參看有關文獻。

    ELF 文件中代碼、連接信息和注釋是以節(section)為單位存放的,并存有一
    個節頭表(section header)。對每一節,在節頭表中都有一個表項(節頭表項)
    與之對應,表項記錄了該節的一些信息,例如該節在文件中的位置信息和該節
    的字節長度信息。

    程序運行讀入內存時,是以程序段(program segment)為單位讀入的。在 ELF
    文件中有一個程序頭表(program header table),每個程序段在程序頭表中有
    一個表項(程序頭表項)與之對應,表項記錄了該程序段的有關信息,例如該程
    序段在文件中的位置信息和該程序段的字節長度信息。程序段的內容由若干節
    組成,節的內容組合在一起連成一片構成程序段的內容。

    在所有這些節中,有一節的內容由字符串構成,這些字符串是各節的名稱,叫
    節名。下面稱這一節為節名表。另有一節,節名為".dynsym",它的內容為符
    號表,符號表的每一表項記錄了一個符號的有關信息,例如該符號對應的代碼
    的地址值。還有一節,節名為".dynstr",它的內容由字符串構成。大多數符
    號在該節中有一個字符串與之對應,這個字符串是該符號的符號名。而每一函
    數對應一個符號,函數名即為符號名。下面稱被某一函數對應的符號為函數符
    號。

    ELF 文件開始處的一段叫 ELF 文件頭。它記錄了程序頭表在文件中的偏移、
    程序頭表的表項數目、程序頭表每一表項的字節長度、節頭表在文件中的偏移、
    節頭表的表項數目、節頭表每個表項的字節長度。它還記錄了節名表所在的節
    的索引序號。

    二、動態庫符號表修改方法

    修改動態庫符號表的方法和步驟如下:

    第一步:

    讀取 ELF 文件頭,取出

    (1) 程序頭表在文件中的偏移,獲取程序頭表在文件中的位置;
    (2) 程序頭表的表項數目和程序頭表每一表項的字節長度;
    (3) 節頭表在文件中的偏移,獲取節頭表在文件中的位置;
    (4) 節頭表的表項數目和節頭表每個表項的字節長度;
    (3) 節名表所在的節的索引序號。

    ELF 文件頭在文件中的偏移為零,即起始于 ELF 文件開頭的第一字節,它的
    數據結構為:

    #define EI_NIDENT (16)

    typedef uint16_t Elf32_Half;
    typedef uint32_t Elf32_Word;
    typedef uint32_t Elf32_Addr;
    typedef uint32_t Elf32_Off;
    typedef uint16_t Elf32_Section;

    typedef struct
    {
    unsigned char e_ident[EI_NIDENT]; /* Magic number及其他信息 */
    Elf32_Half e_type; /* ELF 文件類型 */
    Elf32_Half e_machine; /* 機器型號 */
    Elf32_Word e_version; /* 版本 */
    Elf32_Addr e_entry; /* 程序入口虛地址 */
    Elf32_Off e_phoff; /* 程序頭表在文件中的偏移 */
    Elf32_Off e_shoff; /* 節頭表在文件中的偏移 */
    Elf32_Word e_flags; /* 處理器標志 */
    Elf32_Half e_ehsize; /* ELF 文件頭長度 */
    Elf32_Half e_phentsize; /* 程序頭表每個表項長度 */
    Elf32_Half e_phnum; /* 程序頭表的表項總數 */
    Elf32_Half e_shentsize; /* 節頭表每個表項長度 */
    Elf32_Half e_shnum; /* 節頭表的表項總數 */
    Elf32_Half e_shstrndx; /* 節名表所在的節的表項索引號 */
    } Elf32_Ehdr;

    第二步:

    依據節頭表在文件中的偏移和節名表所在的節的索引序號,定出節名表在節頭
    表中對應的表項的文件偏移,即定出該表項在文件中的位置。讀取該表項,取
    出節名表在文件中的偏移和該節在文件中的字節長度。節頭表由若干表項組成,
    每個表項的內容按下面的數據結構來組織:

    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; /* alignment */
    Elf32_Word sh_entsize; /* 如內容為表,每個表項的長度 */
    } Elf32_Shdr;

    第三步:

    按節名表在文件中的偏移和該節的長度讀取節名表,并緩存在一個緩沖區中。

    第四步:

    依據節頭表在文件中的偏移、節頭表的表項總數、以及節頭表每個表項長度搜
    索節頭表。對每個節頭表項,讀出節名索引號,由節名索引號從上面緩存在緩
    沖區中節名表得出該節頭表項對應的節的名字。如果名字為".dynsym",記錄
    該節的在文件中的偏移和字節長度。名字為 ".dynsym" 的節的內容是符號表,
    除了記錄它在文件中的偏移和字節長度外,還要記下它的每個表項的長度。每
    個表項即是對一個符號所記錄的信息,表項的數據結構為:

    typedef struct
    {
    Elf32_Word st_name; /* 符號名索引號 */
    Elf32_Addr st_value; /* 符號地址值 */
    Elf32_Word st_size; /* 符號對應的代碼長度 */
    unsigned char st_info; /* 符號類型和梆定信息 */
    unsigned char st_other; /* 未用,值為 0 */
    Elf32_Section st_shndx; /* 所在節的節索引號 */
    } Elf32_Sym;

    在搜索節頭表時,除了找 ".dynsym" 節外,還要找到名字為 ".dynstr" 的節,
    記下它的在文件中的偏移和字節長度。由該結在文件中的偏移和字節長度讀取
    它的內容,并緩存在一個緩沖區中。

    第五步:

    按第四步中得到的 ..dynsym節的字節長度和符號表的表項的長度算出符號表表
    項數目,也即符號的數目。然后依據第四步中得到的符號表(即.dynsym節)在
    文件中的偏移把文件指針打到符號表所在的位置,檢索符號表找到要修改的符
    號。方法是從符號表表項中讀出符號名索引號(st_name)的值,這個值即是該
    表項記錄其信息的符號的符號名字符串在 .dynstr 節中的偏移,由這個值在
    第四步中緩存 .dynstr 節的緩沖區中取出符號名,把符號名和要找的符號的
    符號名進行比較。

    第六步:

    第五步中找到了要修改的符號,現在可以進行修改了。所謂修改符號就是修改
    該符號在符號表(.dynsym 節)中表項,因為表項的內容是對該符號的有關信
    息的記錄。hook 時需要關注的是符號地址值(st_value)和符號對應的代碼長
    度(st_size)??梢园逊柕刂分?st_value)和符號對應的代碼長度(st_size)
    修改為動態庫中另一符號的相應的 st_value 和 st_size 值。通常修改的是
    函數符號。如果是函數符號,那么修改后當調用該函數時,實際調用的是上面
    修改時取其 st_value 和 st_size 值的另一符號所對應的函數。也可以向ELF
    文件中加入的一段幾十字節的 shellcode 或其他代碼,修改符號表時把所修
    改的符號在符號表中的表項的 st_value 值指向這段 shellcode 或其他代碼,
    st_size 的值置為這段代碼的字節長度。那么,程序調用被修改的符號所對應
    的函數時,實際調用的是這段 shellcode 或其他代碼。

    三、示例程序

    為對上面所說的進行解釋,下面的給出一個示例程序。它打印出 ELF 文件的
    有關信息,然后通過修改符號表把動態庫的函數1 hook 到函數2。這樣做以后,
    如果某程序編譯時與該動態庫連接了,它調用函數1時,程序運行時實際調用
    的是函數2。函數2可以是動態庫本身就有的函數,也可以是你向 ELF 文件中
    偷偷加入的一段幾十字節的 shellcode。這是向系統置入后門的一個方法,特
    別是 hook 經常被調用的動態庫。

    測試時做了一個小動態庫,它僅有兩個函數 haha() 和 huhu():
    ________________________________________________________
    /* haha.c */

    #include

    void haha(void)
    {
    printf(" --- haha\n");
    return;
    }
    ________________________________________________________
    /* huhu.c */

    #include

    void huhu(void)
    {
    printf(" --- huhu\n");
    return;
    }
    ________________________________________________________

    [wangdb@redhat62 exploit]$ gcc -c -fPIC -O3 haha.c huhu.c
    [wangdb@redhat62 exploit]$ gcc -shared haha.o huhu.o -o libtst.so.1.0
    [wangdb@redhat62 exploit]$ ln -s libtst.so.1.0 libtst.so

    程序 m.c 調用 huhu() 和 haha():
    ________________________________________________________
    /* m.c */
    int main()
    {
    haha();
    huhu();
    return 0;
    }
    ________________________________________________________

    [wangdb@redhat62 exploit]$ gcc m.c -L. -ltst -o ttt
    [wangdb@redhat62 exploit]$ gcc -O3 hook_elf.c -o elf_hook
    [wangdb@redhat62 exploit]$ ./ttt
    --- haha
    --- huhu
    [wangdb@redhat62 exploit]$ ./elf_hook libtst.so huhu haha
    .
    .
    .
    [wangdb@redhat62 exploit]$ ./ttt
    --- haha
    --- haha
    [wangdb@redhat62 exploit]$

    下面是 hook_elf.c 程序:
    ________________________________________________________________________________
    /*
    * C Program File: hook_elf.c ---
    *
    * Description: This program read and print relevant information of ELF
    * File, then hook function fun1 to fun2. After hooking, when
    * some program call function fun1, actually it is fun2 being
    * called.
    * Usage:
    * hook_elf
    * (Note: when dst_sym == src_sym, ELF file is not changed.)
    *
    * Author: wangdb (wangdb@nsfocus.com)
    */

    #include
    #include
    #include
    #include
    #include
    #include
    #include

    #define EI_NIDENT (16)

    typedef uint16_t Elf32_Half;
    typedef uint32_t Elf32_Word;
    typedef uint32_t Elf32_Addr;
    typedef uint32_t Elf32_Off;
    typedef uint16_t Elf32_Section;

    /* 下面的數據結構定義取自 elf.h 頭文件 */

    /* The ELF file header. This appears at the start of every ELF file. */

    typedef struct
    {
    unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */
    Elf32_Half e_type; /* Object file type */
    Elf32_Half e_machine; /* Architecture */
    Elf32_Word e_version; /* Object file version */
    Elf32_Addr e_entry; /* Entry point virtual address */
    Elf32_Off e_phoff; /* Program header table file offset */
    Elf32_Off e_shoff; /* Section header table file offset */
    Elf32_Word e_flags; /* Processor-specific flags */
    Elf32_Half e_ehsize; /* ELF header size in bytes */
    Elf32_Half e_phentsize; /* Program header table entry size */
    Elf32_Half e_phnum; /* Program header table entry count */
    Elf32_Half e_shentsize; /* Section header table entry size */
    Elf32_Half e_shnum; /* Section header table entry count */
    Elf32_Half e_shstrndx; /* Section header string table index */
    } myElf32_Ehdr;

    /* Program segment header. */

    typedef struct
    {
    Elf32_Word p_type; /* Segment type */
    Elf32_Off p_offset; /* Segment file offset */
    Elf32_Addr p_vaddr; /* Segment virtual address */
    Elf32_Addr p_paddr; /* Segment physical address */
    Elf32_Word p_filesz; /* Segment size in file */
    Elf32_Word p_memsz; /* Segment size in memory */
    Elf32_Word p_flags; /* Segment flags */
    Elf32_Word p_align; /* Segment alignment */
    } myElf32_Phdr;

    /* 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 */
    } myElf32_Shdr;

    /* Symbol table entry. */

    typedef struct
    {
    Elf32_Word st_name; /* Symbol name (string tbl index) */
    Elf32_Addr st_value; /* Symbol value */
    Elf32_Word st_size; /* Symbol size */
    unsigned char st_info; /* Symbol type and binding */
    unsigned char st_other; /* No defined meaning, 0 */
    Elf32_Section st_shndx; /* Section index */
    } myElf32_Sym;

    /* The syminfo section if available contains additional information about
    every dynamic symbol. */

    typedef struct
    {
    Elf32_Half si_boundto; /* Direct bindings, symbol bound to */
    Elf32_Half si_flags; /* Per symbol flags */
    } myElf32_Syminfo;


    /* Main routine */

    int main(int argc, char *argv[])
    {
    myElf32_Ehdr *e_hdr_ptr;
    myElf32_Phdr *p_hdr_ptr;
    myElf32_Shdr *s_hdr_ptr;

    myElf32_Sym *symptr;
    myElf32_Syminfo *HashSymPtr;

    int fd, i;
    unsigned char buf[256];

    unsigned int ProHdrFileOffset;
    unsigned int SecHdrFileOffset;
    unsigned int NamStrSecTblIndex;
    unsigned int ProHdrTblEntrNum;
    unsigned int SecHdrTblEntrNum;
    unsigned int ProHdrTblEntrSize;
    unsigned int SecHdrTblEntrSize;

    unsigned int SecNamStrTblFileOffset = 0;
    char SecNameStrTable[1024];
    unsigned int SecNameIndex = 0;

    unsigned char SymTblEntry[16];

    unsigned int DebugInfoFileOffset = 0;
    int DebugInfoSymTblNum = 0;
    unsigned int DebugInfoStrTblFileOffset = 0;
    char DebugInfoStrTable[4096];
    unsigned int DebugInfoStrTblSize = 0;

    unsigned int SymTblFileOffset = 0;
    int SymTblNum = 0;
    unsigned int SymNamStrTblFileOffset = 0;
    char SymNamStrTable[2048];
    unsigned int SymNamStrTblSize = 0;

    unsigned int HashOffset = 0;
    int HashTblNum = 0;

    unsigned char src_sym[16], dst_sym[16];
    unsigned char tmp_sym_addr[4];
    unsigned char tmp_sym_size[4];
    unsigned int src_sym_tbl = 0, dst_sym_tbl = 0;

    if (argc < 4) {
    fprintf(stderr, "Usage: %s \n", argv[0]);
    exit(1);
    }

    if ( (fd = open(argv[1], O_RDONLY)) == -1 ) {
    fprintf(stderr, "Can't open file \"%s\".\n", argv[1]);
    exit(1);
    }

    fprintf(stdout, "Dump content of the ELF file '%s'\n", argv[1]);

    fprintf(stdout, "Part I: ELF File Header...\n");

    /* 讀取 ELF 文件頭 */
    if ( read(fd, buf, 52) != 52 ) {
    fprintf(stderr, "read error\n");
    close(fd); exit(1);
    }

    e_hdr_ptr = (myElf32_Ehdr *)buf;

    fprintf(stdout, "(Magic number and other info)e_ident: %s\n",
    e_hdr_ptr->e_ident);
    fprintf(stdout, "(Object file type)e_type: 0x%04X\n",
    e_hdr_ptr->e_type);
    fprintf(stdout, "(Architecture)e_machine: 0x%04X\n",
    e_hdr_ptr->e_machine);
    fprintf(stdout, "(Object file version)e_version: 0x%08X\n",
    e_hdr_ptr->e_version);
    fprintf(stdout, "(Entry point virtual address)e_entry: 0x%08X\n",
    e_hdr_ptr->e_entry);
    fprintf(stdout, "(Program header table file offset)e_phoff: 0x%08X\n",
    e_hdr_ptr->e_phoff);
    fprintf(stdout, "(Section header table file offset)e_shoff: 0x%08X\n",
    e_hdr_ptr->e_shoff);
    fprintf(stdout, "(Processor-specific flags)e_flags: 0x%08X\n",
    e_hdr_ptr->e_flags);
    fprintf(stdout, "(ELF header size in bytes)e_ehsize: 0x%04X\n",
    e_hdr_ptr->e_ehsize);
    fprintf(stdout, "(Program header table entry size)e_phentsize: 0x%04X\n",
    e_hdr_ptr->e_phentsize);
    fprintf(stdout, "(Program header table entry count)e_phnum: 0x%04X\n",
    e_hdr_ptr->e_phnum);
    fprintf(stdout, "(Section header table entry size)e_shentsize: 0x%04X\n",
    e_hdr_ptr->e_shentsize);
    fprintf(stdout, "(Section header table entry count)e_shnum: 0x%04X\n",
    e_hdr_ptr->e_shnum);
    fprintf(stdout, "(Section header string table index)e_shstrndx: 0x%04X\n",
    e_hdr_ptr->e_shstrndx);

    /* 記下程序頭表在文件中的偏移、節頭表在文件中的偏移、
    節名表所在的節的索引序號、程序頭表表項字節長度、程序頭表表項數目、
    節頭表表項字節長度、節頭表表項數目。*/
    ProHdrFileOffset = (unsigned int)e_hdr_ptr->e_phoff;
    SecHdrFileOffset = (unsigned int)e_hdr_ptr->e_shoff;
    NamStrSecTblIndex = (unsigned int)e_hdr_ptr->e_shstrndx;
    ProHdrTblEntrNum = (unsigned int)e_hdr_ptr->e_phnum;
    SecHdrTblEntrNum = (unsigned int)e_hdr_ptr->e_shnum;
    ProHdrTblEntrSize = (unsigned int)e_hdr_ptr->e_phentsize;
    SecHdrTblEntrSize = (unsigned int)e_hdr_ptr->e_shentsize;

    fprintf(stdout, "Part II: Program Header Table...\n");

    if ( lseek(fd, (off_t)ProHdrFileOffset, SEEK_SET) != ProHdrFileOffset ) {
    fprintf(stderr, "lseek to program header error.\n");
    close(fd); exit(1);
    }

    for (i = 0; i < (int)ProHdrTblEntrNum; i++) {
    if ( read(fd, buf, (size_t)ProHdrTblEntrSize) !=
    (ssize_t)ProHdrTblEntrSize ) {
    fprintf(stderr, "read error\n");
    close(fd); exit(1);
    }
    fprintf(stdout, "Program Header Entry for Segment %d:\n", i + 1);
    p_hdr_ptr = (myElf32_Phdr *)buf;
    fprintf(stdout, "(Segment type)p_type: 0x%08X\n",
    p_hdr_ptr->p_type);
    fprintf(stdout, "(Segment flags)p_flags: 0x%08X\n",
    p_hdr_ptr->p_flags);
    fprintf(stdout, "(Segment file offset)p_offset: 0x%08X\n",
    p_hdr_ptr->p_offset);
    fprintf(stdout, "(Segment virtual address)p_vaddr: 0x%08X\n",
    p_hdr_ptr->p_vaddr);
    fprintf(stdout, "(Segment physical address)p_paddr: 0x%08X\n",
    p_hdr_ptr->p_paddr);
    fprintf(stdout, "(Segment size in file)p_filesz: 0x%08X\n",
    p_hdr_ptr->p_filesz);
    fprintf(stdout, "(Segment size in memory)p_memsz: 0x%08X\n",
    p_hdr_ptr->p_memsz);
    fprintf(stdout, "(Segment alignment)p_align: 0x%08X\n",
    p_hdr_ptr->p_align);
    }

    fprintf(stdout, "Part III: Section Header Table...\n");

    /* 定出節名表所在的節在節頭表中對應的表項的文件偏移。*/
    SecNamStrTblFileOffset = SecHdrFileOffset + NamStrSecTblIndex * 40;
    if ( lseek(fd, (off_t)SecNamStrTblFileOffset, SEEK_SET) !=
    SecNamStrTblFileOffset || SecNamStrTblFileOffset == 0 ) {
    fprintf(stderr,
    "lseek to Section Table Entry for Section Name String Table error.\n");
    close(fd); exit(1);
    }
    if ( read(fd, buf, (size_t)SecHdrTblEntrSize) != (ssize_t)SecHdrTblEntrSize ) {
    fprintf(stderr, "read error\n");
    close(fd); exit(1);
    }
    s_hdr_ptr = (myElf32_Shdr *)buf;
    SecNamStrTblFileOffset = (unsigned int)s_hdr_ptr->sh_offset;

    /* 讀取節名表,并緩存在一個緩沖區中。*/
    if ( lseek(fd, (off_t)SecNamStrTblFileOffset, SEEK_SET) !=
    SecNamStrTblFileOffset || SecNamStrTblFileOffset == 0 ) {
    fprintf(stderr, "lseek to Section Name String Table error.\n");
    close(fd); exit(1);
    }
    if ( read(fd, SecNameStrTable, (size_t)s_hdr_ptr->sh_size) !=
    (ssize_t)s_hdr_ptr->sh_size ) {
    fprintf(stderr, "read error\n");
    close(fd); exit(1);
    }

    if ( lseek(fd, (off_t)SecHdrFileOffset, SEEK_SET) != SecHdrFileOffset ||
    SecHdrFileOffset == 0 ) {
    fprintf(stderr, "lseek to section header error.\n");
    close(fd); exit(1);
    }

    /* 記錄符號表(即.dynsym節)在文件中的偏移,由它的字節長度和每個表項的
    長度算出符號表的表項數目。同時記下.dynstr節在文件中的偏移和字節長度。*/
    for (i = 0; i < (int)SecHdrTblEntrNum; i++) {
    if ( read(fd, buf, (size_t)SecHdrTblEntrSize) !=
    (ssize_t)SecHdrTblEntrSize ) {
    fprintf(stderr, "read error\n");
    close(fd); exit(1);
    }
    s_hdr_ptr = (myElf32_Shdr *)buf;
    /*if ( s_hdr_ptr->sh_type == 0x3 && s_hdr_ptr->sh_name == 0x11 ) {
    SecNamStrTblFileOffset = (unsigned int)s_hdr_ptr->sh_offset;
    }*/
    if ( strcmp(SecNameStrTable + s_hdr_ptr->sh_name, ".symtab") == 0 ) {
    DebugInfoFileOffset = (unsigned int)s_hdr_ptr->sh_offset;
    DebugInfoSymTblNum = (int)((s_hdr_ptr->sh_size)/(s_hdr_ptr->sh_entsize));
    }
    if ( strcmp(SecNameStrTable + s_hdr_ptr->sh_name, ".strtab") == 0 ) {
    DebugInfoStrTblFileOffset = (unsigned int)s_hdr_ptr->sh_offset;
    DebugInfoStrTblSize = (unsigned int)s_hdr_ptr->sh_size;
    }
    if ( strcmp(SecNameStrTable + s_hdr_ptr->sh_name, ".dynsym") == 0 ) {
    SymTblFileOffset = (unsigned int)s_hdr_ptr->sh_offset;
    SymTblNum = (int)((s_hdr_ptr->sh_size)/(s_hdr_ptr->sh_entsize));
    }
    if ( strcmp(SecNameStrTable + s_hdr_ptr->sh_name, ".dynstr") == 0 ) {
    SymNamStrTblFileOffset = (unsigned int)s_hdr_ptr->sh_offset;
    SymNamStrTblSize = (unsigned int)s_hdr_ptr->sh_size;
    }
    if ( strcmp(SecNameStrTable + s_hdr_ptr->sh_name, ".hash") == 0 ) {
    HashOffset = (unsigned int)s_hdr_ptr->sh_offset;
    HashTblNum = (int)((s_hdr_ptr->sh_size)/(s_hdr_ptr->sh_entsize));
    }
    }

    if ( lseek(fd, (off_t)SecHdrFileOffset, SEEK_SET) != SecHdrFileOffset ) {
    fprintf(stderr, "lseek to section header error.\n");
    close(fd); exit(1);
    }

    for (i = 0; i < (int)SecHdrTblEntrNum; i++) {
    if ( read(fd, buf, (size_t)SecHdrTblEntrSize) !=
    (ssize_t)SecHdrTblEntrSize ) {
    fprintf(stderr, "read error\n");
    close(fd); exit(1);
    }
    s_hdr_ptr = (myElf32_Shdr *)buf;
    fprintf(stdout, "Section %d:\n", i);
    SecNameIndex = (unsigned int)s_hdr_ptr->sh_name;
    fprintf(stdout, "(Section name (string tbl index))sh_name: 0x%08X -> %s\n",
    s_hdr_ptr->sh_name, SecNameStrTable + SecNameIndex);
    fprintf(stdout, "(Section type)sh_type: 0x%08X\n",
    s_hdr_ptr->sh_type);
    fprintf(stdout, "(Section flags)sh_flags: 0x%08X\n",
    s_hdr_ptr->sh_flags);
    fprintf(stdout, "(Section virtual addr at execution)sh_addr: 0x%08X\n",
    s_hdr_ptr->sh_addr);
    fprintf(stdout, "(Section file offset)sh_offset: 0x%08X\n",
    s_hdr_ptr->sh_offset);
    fprintf(stdout, "(Section size in bytes)sh_size: 0x%08X\n",
    s_hdr_ptr->sh_size);
    fprintf(stdout, "(Link to another section)sh_link: 0x%08X\n",
    s_hdr_ptr->sh_link);
    fprintf(stdout, "(Additional section information)sh_info: 0x%08X\n",
    s_hdr_ptr->sh_info);
    fprintf(stdout, "(Section alignment)sh_addralign: 0x%08X\n",
    s_hdr_ptr->sh_addralign);
    fprintf(stdout, "(Entry size if section holds table)sh_entsize: 0x%08X\n",
    s_hdr_ptr->sh_entsize);
    }

    fprintf(stdout,
    "************************************************************************\n");

    if ( lseek(fd, (off_t)DebugInfoStrTblFileOffset, SEEK_SET) !=
    DebugInfoStrTblFileOffset || DebugInfoStrTblFileOffset == 0 ) {
    fprintf(stderr, "lseek to Debug Info String Table error.\n");
    goto next;
    }
    read(fd, DebugInfoStrTable, (size_t)(DebugInfoStrTblSize + 1));

    if ( lseek(fd, (off_t)DebugInfoFileOffset, SEEK_SET) !=
    DebugInfoFileOffset || DebugInfoFileOffset == 0 ) {
    fprintf(stderr, "lseek to Debug Info Symbol Table error.\n");
    goto next;
    }
    for (i = 0; i < DebugInfoSymTblNum; i++) {
    read(fd, SymTblEntry, (size_t)16);
    symptr = (myElf32_Sym *)SymTblEntry;
    fprintf(stdout, "Debug Infomation -> Symbol ID: %d\n", i);
    fprintf(stdout, "Symbol_index_and_name: 0x%08X -> %s\n",
    symptr->st_name, DebugInfoStrTable + symptr->st_name);
    fprintf(stdout, "Symbol_value: 0x%08X\n", symptr->st_value);
    fprintf(stdout, "Symbol_size: 0x%08X\n", symptr->st_size);
    fprintf(stdout, "Symbol_type_and_binding: 0x%02X\n", symptr->st_info);
    fprintf(stdout, "Section_index: 0x%04X\n", symptr->st_shndx);
    fprintf(stdout,
    "--------------------------------------------------------\n");
    }

    fprintf(stdout,
    "************************************************************************\n");

    next:

    /* 讀取 .dynstr 節的內容,并緩存在一個緩沖區中。*/
    if ( lseek(fd, (off_t)SymNamStrTblFileOffset, SEEK_SET) !=
    SymNamStrTblFileOffset || SymNamStrTblFileOffset == 0 ) {
    fprintf(stderr, "lseek to Dynamical symbol name string error.\n");
    close(fd); exit(1);
    }
    read(fd, SymNamStrTable, (size_t)(SymNamStrTblSize + 1));
    if ( lseek(fd, (off_t)SymTblFileOffset, SEEK_SET) != SymTblFileOffset ||
    SymTblFileOffset == 0 ) {
    fprintf(stderr, "lseek to Dynamical symbol Table error.\n");
    close(fd); exit(1);
    }
    for (i = 0; i < SymTblNum; i++) {
    read(fd, SymTblEntry, (size_t)16);
    symptr = (myElf32_Sym *)SymTblEntry;
    fprintf(stdout, "Symbol ID: %d\n", i);
    fprintf(stdout, "Symbol_index_and_name: 0x%08X -> %s\n",
    symptr->st_name, SymNamStrTable + symptr->st_name);
    fprintf(stdout, "Symbol_value: 0x%08X\n", symptr->st_value);
    fprintf(stdout, "Symbol_size: 0x%08X\n", symptr->st_size);
    fprintf(stdout, "Symbol_type_and_binding: 0x%02X\n", symptr->st_info);
    fprintf(stdout, "Section_index: 0x%04X\n", symptr->st_shndx);
    fprintf(stdout,
    "--------------------------------------------------------\n");
    }

    fprintf(stdout,
    "************************************************************************\n");

    if ( lseek(fd, (off_t)HashOffset, SEEK_SET) != HashOffset ||
    HashOffset == 0 ) {
    fprintf(stderr, "lseek to hash table error.\n");
    close(fd); exit(-1);
    }
    for (i = 0; i < HashTblNum; i++) {
    fprintf(stdout, "Hash Table ID: %d\n", i);
    read(fd, SymTblEntry, (size_t)4);
    HashSymPtr = (myElf32_Syminfo *)SymTblEntry;
    fprintf(stdout, "Direct_bindings, symbol_bound_to: 0x%04X\n",
    HashSymPtr->si_boundto);
    fprintf(stdout, "Per_symbol_flags: 0x%04X\n", HashSymPtr->si_flags);
    fprintf(stdout,
    "--------------------------------------------------------\n");
    }

    close(fd); /* End of Printing */

    /* Change symbol value, hook it */

    if ( (fd = open(argv[1], O_RDWR)) < 0 ) {
    fprintf(stderr, "Can't open object file '%s'.\n", argv[1]);
    exit(-1);
    }

    /* 檢索符號表搜索要修改的符號。*/
    if ( lseek(fd, (off_t)SymTblFileOffset, SEEK_SET) != SymTblFileOffset ) {
    fprintf(stderr, "lseek error.\n");
    close(fd); exit(-1);
    }

    for (i = 0; i < SymTblNum; i++) {
    read(fd, SymTblEntry, (size_t)16);
    symptr = (myElf32_Sym *)SymTblEntry;
    if ( strcmp(argv[2], SymNamStrTable + symptr->st_name) == 0 ) {
    memcpy(dst_sym, SymTblEntry, 16);
    dst_sym_tbl = (unsigned int)lseek(fd, (off_t)0, SEEK_CUR) - 16;
    }
    if ( strcmp(argv[3], SymNamStrTable + symptr->st_name) == 0 ) {
    memcpy(src_sym, SymTblEntry, 16);
    src_sym_tbl = (unsigned int)lseek(fd, (off_t)0, SEEK_CUR) - 16;
    }
    }

    /* 修改符號表中要修改的符號所對應的表項的 st_value 和 st_size 值。*/
    symptr = (myElf32_Sym *)src_sym;
    memcpy(tmp_sym_addr, &symptr->st_value, 4);
    memcpy(tmp_sym_size, &symptr->st_size, 4);
    symptr = (myElf32_Sym *)dst_sym;
    memcpy(&symptr->st_value, tmp_sym_addr, 4);
    memcpy(&symptr->st_size, tmp_sym_size, 4);

    if ( dst_sym_tbl == 0 || src_sym_tbl == 0 ||
    lseek(fd, (off_t)dst_sym_tbl, SEEK_SET) != dst_sym_tbl ) {
    fprintf(stderr, "lseek error.\n");
    close(fd); exit(-1);
    }
    if ( write(fd, dst_sym, (size_t)16) != (ssize_t)16 ) {
    fprintf(stderr, "write error\n");
    close(fd); exit(-1);
    }

    close(fd);
    return 0;
    }

    /* EOF */

    原文轉自:http://www.kjueaiud.com

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>