The code, connection information, and annotations in the ELF file are stored in sections (section) and contain a
Header table (section header). For each section, there is a table entry in the section Header table (section Header table entry)
Corresponding to this, the table entry records some information about the section, such as its location information in the file and the section
The byte length information.
I. ELF files and related terminology
The Unix system executable and dynamic library files are stored in ELF format. To make the following narrative
Clear without justification, first briefly introduce the ELF file format, and contract some terminology. About Elf
Please refer to the documentation for details of the file format.
The code, connection information, and annotations in the ELF file are stored in sections (section) and contain a
Header table (section header). For each section, there is a table entry in the section Header table (section Header table entry)
Corresponding to this, the table entry records some information about the section, such as its location information in the file and the section
The byte length information.
When the program runs read into memory, it is read in the program segment. In ELF
There is a Program Header table in the file, and each program segment is in the Program Header table
A table entry (The Program Header table entry) corresponds to which the table entry records information about the program segment, such as the process
The position information of the ordinal segment in the file and the byte length information for the program segment. The contents of a program segment are composed of several sections
Composition, the content of the section is grouped together to form the contents of the program section.
In all of these sections, there is a section that consists of strings that are the names of the sections, called
Section name. This section is referred to as the section name table. In another section, the section is named ". Dynsym" and its contents are
Table, each table item of the symbol table records information about a symbol, such as the code corresponding to the symbol
The address value. In another section, the section is named ". Dynstr", and its contents are composed of strings. Most characters
A string in this section corresponds to the symbol name of the symbol. and each letter
The number corresponds to a symbol, and the function name is the symbol name. The following is a function of the symbol corresponding to a function
No.
Elf file at the beginning of a section called Elf file header. It records the offset of the program Header table in the file,
The number of table entries in the Header table, the byte length of each table entry in the Program Header table, the offset of the Header table in the file,
The number of table entries in the Header table, the byte length of each table entry for the section Header table. It also records the section where the section name table is located
The index number of the.
Second, dynamic library symbol table modification method
The methods and steps for modifying the dynamic library symbol table are as follows:
The first step:
Read ELF file header, remove
(1) The Program Header table in the file offset, get the program Header table in the file position;
(2) The number of table entries in the Program Header table and the byte length of each table item in the Program Header table;
(3) The section Header table in the file offset, get the node Header table in the file position;
(4) The number of table entries in the Header table and the byte length of each table entry in the Header table;
(3) The index number of the section where the section name table is located.
Elf file header in the file is offset to zero, which starts at the beginning of the elf file in the first byte, its
The data structure is:
#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 and other information */
Elf32_half E_type; /* ELF File type */
Elf32_half E_machine; /* Machine Model */
Elf32_word e_version; /* Version */
Elf32_addr E_entry; /* Program Entry virtual Address */
Elf32_off E_phoff; /* Offset of the program Header table in the file */
Elf32_off E_shoff; /* The offset of the Header table in the file */
Elf32_word E_flags; /* Processor Flag */
Elf32_half e_ehsize; /* ELF File Header length */
Elf32_half e_phentsize; /* Program Header table per table item length */
Elf32_half E_phnum; /* Total number of table entries in the Header table */
Elf32_half e_shentsize; /* Section Header table each table item length */
Elf32_half E_shnum; /* Total number of table entries in Header table */
Elf32_half E_shstrndx; /* Table Entry index number of the section where the section name table is located */
} ELF32_EHDR;
Step Two:
Set the section Name table in the section header according to the index number of the section Header table in the File and section name table
The file offset of the corresponding table entry in the table, that is, the position of the table entry in the file. Read the table entry, take
The offset of the section name table in the file and the byte length of the section in the file. The section Header table consists of several table items,
The contents of each table item are organized according to the following data structure:
typedef struct
{
Elf32_word Sh_name; /* Section name index number */
Elf32_word Sh_type; /* Section type */
Elf32_word Sh_flags; /* Section flag */
Elf32_addr sh_addr; /* This section virtual address when executing */
Elf32_off Sh_offset; /* Offset in the file */
Elf32_word sh_size; /* Section length */
Elf32_word Sh_link; /* Connect to other sections */
Elf32_word Sh_info; /* Additional Information */
Elf32_word sh_addralign; /* Alignment */
Elf32_word sh_entsize; /* If the contents are table, the length of each table item */
} ELF32_SHDR;
Step Three:
The section name table is read by the section name table in the file offset and the length of the section, and is cached in a buffer.
Fourth Step:
Based on the offset of the Header table in the file, the total number of table items in the Header table, and the length of each table item in the Header table
The head table of the rope section. For each section Header table entry, read out the section name index number from which the section name index number is cached in the slow
The section name table in the Flushing area gives the name of the section corresponding to the section Header table item. If the name is ". Dynsym", record
The offset and byte length of the section in the file. The content of the section named ". Dynsym" is the symbol table,
In addition to recording its offset and byte length in the file, note the length of each of its table entries. Every
A table entry is the information that is recorded for a symbol, and the data structure of the table entry is:
typedef struct
{
Elf32_word St_name; /* Symbol name index number */
Elf32_addr St_value; /* Symbolic Address value */
Elf32_word st_size; /* code length corresponding to the symbol */
unsigned char st_info; /* Symbol type and bang info */
unsigned char st_other; /* Unused with a value of 0 */
Elf32_section St_shndx; /* Section index number of the section */
} Elf32_sym;
When searching for the section Header table, find the section named ". Dynstr" In addition to the ". Dynsym" section.
Make a note of its offset and byte length in the file. Read by the offset and byte length of the knot in the file
Its contents, and caches it in a buffer.
Fifth Step:
As you get in the fourth step: Dynsym the byte length of the section and the length of the table entry for the symbol table to calculate the symbol table table
The number of items, that is, the number of symbols. Then, according to the symbol table (i.e.. Dynsym section) obtained in step fourth,
The offset in the file hits the file pointer where the symbol table is located, retrieves the symbol table to find the character to be modified
No. The method is to read the value of the symbol name index number (st_name) from the symbol table entry, which is the
The symbol name string for the symbol whose information is recorded by the table entry is offset in the. Dynstr section by this value in the
In the fourth step, in the buffer of the. Dynstr section, remove the symbol name and the symbol name and the symbol you want to find.
Symbol names for comparison.
Sixth step:
The fifth step finds the symbol to be modified and can now be modified. The so-called modified symbols are modified
The symbol is in the table item in the symbol table (. Dynsym section), because the contents of the table entry are related to the letter of the symbol
The record of the interest. The hook should focus on the symbol address value (st_value) and the code length corresponding to the symbol
Degrees (st_size). The code length (st_size) that corresponds to the symbol address value (st_value) and the symbol can be
Modify the corresponding St_value and st_size values for another symbol in the dynamic library. It is usually modified to
function symbol. If it is a function symbol, then when the function is called after the modification, it is actually called the above
The function that corresponds to another symbol whose st_value and st_size values are modified. The ELF can also
A dozens of-byte shellcode or other code added to the file, modifying the symbol table when the
The St_value value of the table entry in the symbol table for the changed symbol points to this paragraph of shellcode or other code,
The value of the st_size is set to the byte length of this code. Then, the program calls the modified symbol corresponding to the
function, the Shellcode or other code is actually called.
Iii. Examples of programs
To explain the above, an example program is given below. It prints out the ELF file's
For information, then hook the dynamic Library's function 1 to function 2 by modifying the symbol table. After doing this,
If a program is compiled with the dynamic library, it calls function 1 o'clock, and the program is actually called when it is run
is the function 2. Function 2 can be a function of the dynamic library itself, or it can be you to the ELF file
Secretly added a dozens of-byte shellcode. This is a way of placing a backdoor into the system,
Not a dynamic library that hooks are often called.
The test made a small dynamic library with only two functions haha () and Huhu ():
________________________________________________________
/* HAHA.C */
#include
void haha (void)
{
printf ("---haha");
Return
}
________________________________________________________
/* HUHU.C */
#include
void Huhu (void)
{
printf ("---huhu");
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
The program M.C calls Huhu () and 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]$
Here is the HOOK_ELF.C program:
________________________________________________________________________________
/*
* 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)
*/
Usage: assigns the address value corresponding to the symbol of SRC to the address value corresponding to the DES symbol
If you want to achieve this effect: the user executes the FUNC1 and actually executes the FUNC2, then this should be done:
Hook_elf <lib***.so> <FUNC1> <FUNC2>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdint.h>
#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;
/* The following data structure definition is taken from the elf.h header file */
/* The ELF file header. This appears at the start of the 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", argv[0]);
Exit (1);
}
if (fd = open (argv[1], o_rdonly) = = =-1) {
fprintf (stderr, "Can ' t Open file%s.", argv[1]);
Exit (1);
}
fprintf (stdout, "Dump content of the ELF file '%s '", argv[1]);
fprintf (stdout, "part i:elf File Header ... ");
/* Read ELF file header */
if (read (FD, BUF, 52)! = 52) {
fprintf (stderr, "read error");
Close (FD); Exit (1);
}
E_hdr_ptr = (MYELF32_EHDR *) buf;
fprintf (stdout, "(Magic number and other info) E_ident:%s",
E_hdr_ptr->e_ident);
fprintf (stdout, "(Object file type) e_type:0x%04x",
E_hdr_ptr->e_type);
fprintf (stdout, "(Architecture) e_machine:0x%04x",
E_hdr_ptr->e_machine);
fprintf (stdout, "(Object file version) e_version:0x%08x",
E_hdr_ptr->e_version);
fprintf (stdout, "(Entry point virtual Address) e_entry:0x%08x",
E_hdr_ptr->e_entry);
fprintf (stdout, "(Program Header table file offset) e_phoff:0x%08x",
E_hdr_ptr->e_phoff);
fprintf (stdout, "(Section Header table file offset) e_shoff:0x%08x",
E_hdr_ptr->e_shoff);
fprintf (stdout, "(Processor-specific flags) e_flags:0x%08x",
E_hdr_ptr->e_flags);
fprintf (stdout, "(ELF header size in bytes) e_ehsize:0x%04x",
E_hdr_ptr->e_ehsize);
fprintf (stdout, "(Program Header table entry size) e_phentsize:0x%04x",
E_hdr_ptr->e_phentsize);
fprintf (stdout, "(Program Header table entry count) e_phnum:0x%04x",
E_hdr_ptr->e_phnum);
fprintf (stdout, "(Section Header table entry size) e_shentsize:0x%04x",
E_hdr_ptr->e_shentsize);
fprintf (stdout, "(Section Header table entry count) e_shnum:0x%04x",
E_hdr_ptr->e_shnum);
fprintf (stdout, "(Section Header string table index) e_shstrndx:0x%04x",
E_HDR_PTR->E_SHSTRNDX);
/* Note The offset of the program Header table in the file, the offset of the Header table in the file,
The index number of the section in which the section name table is located, the length of the Program Header table entry bytes, the number of program Header table entries,
Section Header table Entry byte length, Number of section Header table items. */
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 ... ");
if (Lseek (FD, (off_t) Prohdrfileoffset, seek_set)! = Prohdrfileoffset) {
fprintf (stderr, "Lseek to program header error.");
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");
Close (FD); Exit (1);
}
fprintf (stdout, "program Header Entry for Segment%d:", i + 1);
P_hdr_ptr = (MYELF32_PHDR *) buf;
fprintf (stdout, "(Segment type) p_type:0x%08x",
P_hdr_ptr->p_type);
fprintf (stdout, "(Segment flags) p_flags:0x%08x",
P_hdr_ptr->p_flags);
fprintf (stdout, "(Segment file offset) p_offset:0x%08x",
P_hdr_ptr->p_offset);
fprintf (stdout, "(Segment virtual Address) p_vaddr:0x%08x",
P_HDR_PTR->P_VADDR);
fprintf (stdout, "(Segment Physical Address) p_paddr:0x%08x",
P_HDR_PTR->P_PADDR);
fprintf (stdout, "(Segment size in file) p_filesz:0x%08x",
P_hdr_ptr->p_filesz);
fprintf (stdout, "(Segment size in memory) p_memsz:0x%08x",
P_HDR_PTR->P_MEMSZ);
fprintf (stdout, "(Segment alignment) p_align:0x%08x",
P_hdr_ptr->p_align);
}
fprintf (stdout, "part iii:section Header Table ... ");
/* The section that contains the section name table has a file offset for the corresponding table entry in the section Header table. */
Secnamstrtblfileoffset = Sechdrfileoffset + Namstrsectblindex * 40;
if (Lseek (FD, (off_t) Secnamstrtblfileoffset, seek_set)! =
Secnamstrtblfileoffset | | Secnamstrtblfileoffset = = 0) {
fprintf (stderr,
"Lseek to sections Table Entry for section Name String table error. ");
Close (FD); exit (1);
}
if (Read (FD, buf, (size_t) sechdrtblentrsize)! = (ssize_t) sechdrtblentrsize) {
fprintf (stderr, "read error ");
Close (FD); exit (1);
}
S_hdr_ptr = (MYELF32_SHDR *) buf;
Secnamstrtblfileoffset = (unsigned int) s_hdr_ptr->sh_offset;
/* Reads the section name table and caches it in a buffer. */
if (Lseek (FD, (off_t) Secnamstrtblfileoffset, seek_set)! =
Secnamstrtblfileoffset | | Secnamstrtblfileoffset = = 0) {
fprintf (stderr, "Lseek to section Name String Table error.");
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");
Close (FD); Exit (1);
}
if (Lseek (FD, (off_t) Sechdrfileoffset, seek_set)! = Sechdrfileoffset | |
Sechdrfileoffset = = 0) {
fprintf (stderr, "Lseek to section header error.");
Close (FD); Exit (1);
}
/* Record the offset of the symbol table (that is, the. Dynsym section) in the file, by its byte length and each table item's
The length calculates the number of table entries for the symbol table. Also note the offset and byte length of the. Dynstr section in the file. */
for (i = 0; i < (int) sechdrtblentrnum; i++) {
if (read (FD, buf, (size_t) sechdrtblentrsize)! =
(ssize_t) Sechdrtblentrsize) {
fprintf (stderr, "read error");
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.");
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");
Close (FD); Exit (1);
}
S_hdr_ptr = (MYELF32_SHDR *) buf;
fprintf (stdout, "section%d:", i);
Secnameindex = (unsigned int) s_hdr_ptr->sh_name;
fprintf (stdout, "(section name (String TBL Index) sh_name:0x%08x,%s",
S_hdr_ptr->sh_name, secnamestrtable + secnameindex);
fprintf (stdout, "(section type) sh_type:0x%08x",
S_hdr_ptr->sh_type);
fprintf (stdout, "(section Flags) sh_flags:0x%08x",
S_hdr_ptr->sh_flags);
fprintf (stdout, "(Section virtual addr at execution) sh_addr:0x%08x",
S_HDR_PTR->SH_ADDR);
fprintf (stdout, "(section file offset) sh_offset:0x%08x",
S_hdr_ptr->sh_offset);
fprintf (stdout, "(section size in bytes) sh_size:0x%08x",
S_hdr_ptr->sh_size);
fprintf (stdout, "(Link to another section) sh_link:0x%08x",
S_hdr_ptr->sh_link);
fprintf (stdout, "(Additional section information) sh_info:0x%08x",
S_hdr_ptr->sh_info);
fprintf (stdout, "(section Alignment) sh_addralign:0x%08x",
S_hdr_ptr->sh_addralign);
fprintf (stdout, "(Entry Size if section holds table) sh_entsize:0x%08x",
S_hdr_ptr->sh_entsize);
}