• Tidak ada hasil yang ditemukan

Example: Listing Section Names

Dalam dokumen Libelf by Example (Halaman 35-44)

Let us now write an example program that prints the names of the sections in an ELF object.

Listing 5.2: Program 4 /*

* P r i n t the n a m e s of ELF s e c t i o n s .

*

* $Id : p r o g 4 . txt 3 687 2019 -02 -22 0 7 : 5 5 : 0 9 Z j k o s h y $

*/

# i n c l u d e < err . h >

# i n c l u d e < f c n t l . h >

# i n c l u d e < g e l f . h >

# i n c l u d e < s t d i o . h >

# i n c l u d e < s t d i n t . h >

# i n c l u d e < s t d l i b . h >

# i n c l u d e < u n i s t d . h >

# i n c l u d e < vis . h >

int

m a i n (int argc , c h a r ** a r g v ) {

int fd ; Elf * e ; E l f _ S c n * scn ; E l f _ D a t a * d a t a ; G E l f _ S h d r s h d r ;

s i z e _ t n , s h s t r n d x , sz ;

c h a r * name , * p , pc [(4 * s i z e o f(c h a r)) + 1];

if ( a r g c != 2)

e r r x ( E X I T _ F A I L U R E , " u s a g e : ␣ % s ␣ file - n a m e " , a r g v [ 0 ] ) ; if ( e l f _ v e r s i o n ( E V _ C U R R E N T ) == E V _ N O N E )

e r r x ( E X I T _ F A I L U R E , " ELF ␣ l i b r a r y ␣ i n i t i a l i z a t i o n ␣ "

" f a i l e d : ␣ % s " , e l f _ e r r m s g ( -1));

e r r x ( E X I T _ F A I L U R E , " % s ␣ is ␣ not ␣ an ␣ ELF ␣ o b j e c t . " , a r g v [ 1 ] ) ;

if ( e l f _ g e t s h d r s t r n d x ( e , & s h s t r n d x ) != 0) 1

e r r x ( E X I T _ F A I L U R E , " e l f _ g e t s h d r s t r n d x () ␣ f a i l e d : ␣ % s . " , e l f _ e r r m s g ( -1));

scn = N U L L ; 2

w h i l e (( scn = e l f _ n e x t s c n ( e , scn )) != N U L L ) { 3 if ( g e l f _ g e t s h d r ( scn , & s h d r ) != & s h d r ) 4

e r r x ( E X I T _ F A I L U R E , " g e t s h d r () ␣ f a i l e d : ␣ % s . " , e l f _ e r r m s g ( -1));

if (( n a m e = e l f _ s t r p t r ( e , s h s t r n d x , s h d r . s h _ n a m e ))

== N U L L ) 5

e r r x ( E X I T _ F A I L U R E , " e l f _ s t r p t r () ␣ f a i l e d : ␣ % s . " , e l f _ e r r m s g ( -1));

(v o i d) p r i n t f ( " S e c t i o n ␣ % -4.4 jd ␣ % s \ n " , ( u i n t m a x _ t ) e l f _ n d x s c n ( scn ) , n a m e );

}

if (( scn = e l f _ g e t s c n ( e , s h s t r n d x )) == N U L L ) 6 e r r x ( E X I T _ F A I L U R E , " g e t s c n () ␣ f a i l e d : ␣ % s . " ,

e l f _ e r r m s g ( -1));

if ( g e l f _ g e t s h d r ( scn , & s h d r ) != & s h d r )

e r r x ( E X I T _ F A I L U R E , " g e t s h d r ( s h s t r n d x ) ␣ f a i l e d : ␣ % s . " , e l f _ e r r m s g ( -1));

(v o i d) p r i n t f ( " . s h s t r a b : ␣ s i z e =% jd \ n " , ( u i n t m a x _ t ) s h d r . s h _ s i z e );

d a t a = N U L L ; n = 0;

w h i l e ( n < s h d r . s h _ s i z e &&

( d a t a = e l f _ g e t d a t a ( scn , d a t a )) != N U L L ) { 7 p = (c h a r *) data - > d _ b u f ;

w h i l e ( p < (c h a r *) data - > d _ b u f + data - > d _ s i z e ) { if ( vis ( pc , * p , V I S _ W H I T E , 0))

p r i n t f ( " % s " , pc );

n ++; p ++;

(v o i d) p u t c h a r (( n % 16) ? ’ ␣ ’ : ’ \ n ’ );

} }

(v o i d) p u t c h a r ( ’ \ n ’ );

(v o i d) e l f _ e n d ( e );

(v o i d) c l o s e ( fd );

e x i t ( E X I T _ S U C C E S S );

}

www.dbooks.org

40 CHAPTER 5. LOOKING AT SECTIONS 1 The functionelf getshdrstrndxretrieves the section index of the section name string table. Using this function allows our program to work cor- rectly when the object being examined uses extended numbering.

2 The function elf nextscn has the useful property that it will return the pointer to theElf Scndescriptor for section number 1 if a NULL pointer is passed in to it. Section number 0 is always of typeSHT NULL, and is not for use by applications.

3 Thiswhileloop iterates through the sections in the ELF object. Function elf nextscn will return NULL after the last section has been traversed, giving us a convenient way to exit the loop.

4 The functiongelf getshdrretrieves the section header table entry for an Elf Scndescriptor. The sh namemember of the returned section header table entry holds the byte offset of the section’s name inside the section name string table.

5 Theelf strptr function converts the byte offset in the sh namemember to a char *pointer. The pointed-to C string can then be printed using printf.

6 Next, the contents of the section name string table itself are printed out.

The call to elf getscn returns the Elf Scn descriptor for the section name string table itself.

7 This code cycles through theElf Datadescriptors for the section, printing out the characters in eachElf Databuffer for the section.

Save the program in listing5.2 on page 38to fileprog4.cand then compile and run it as shown in listing 5.3.

Listing 5.3: Compiling and Running prog4

% cc - o p r o g 4 p r o g 4 . c - l e l f 1

% ./ p r o g 4 p r o g 4 2 S e c t i o n 0 0 0 1 . i n t e r p

S e c t i o n 0 0 0 2 . n o t e . ABI - tag S e c t i o n 0 0 0 3 . h a s h

S e c t i o n 0 0 0 4 . d y n s y m S e c t i o n 0 0 0 5 . d y n s t r

S e c t i o n 0 0 1 5 . c t o r s S e c t i o n 0 0 1 6 . d t o r s S e c t i o n 0 0 1 7 . jcr S e c t i o n 0 0 1 8 . got S e c t i o n 0 0 1 9 . bss S e c t i o n 0 0 2 0 . c o m m e n t S e c t i o n 0 0 2 1 . s h s t r t a b 3 S e c t i o n 0 0 2 2 . s y m t a b S e c t i o n 0 0 2 3 . s t r t a b . s h s t r a b : s i z e = 2 8 7 4

\ˆ@ . s y m t a b \ˆ@ . s t r t a b

\ˆ@ . s h s t r t a b \ˆ@ . i n t e r p \ˆ@ . h a s h \ˆ@ . d y n s y m ...etc...

1 Compile and link the program in the standard way.

2 The program is invoked on itself, to print the names of its own sections.

3 The section name string table is called.shstrtabby convention.

4 This is the content of the section name string table in this object.

www.dbooks.org

Chapter 6

Creating New ELF Objects

This chapter shows how to use thelibelflibrary to create new ELF objects.

6.1 Example: Creating an ELF Object

The example program in listing6.1creates an ELF file with the following con- tent:

• A section named “.foo” containing data in the form of 32-bit words that may need byte-swapping. We had discussed libelf’s handling of data needing byte-swapping in section3.5 on page 19.

• A section named “.shstrtab” containing the section name string table for our ELF object. We covered string tables in section5.3 on page 37.

• AProgram Header Tablewith a singleProgram Header Table Entrycovering the program header table itself. We studied the ELFProgram Header Table in chapter4.

The new ELF object will be marked as a 32-bit PowerPCTMexecutable, and will use big-endian data ordering.

Listing 6.1: Program 5 /*

* C r e a t e an ELF o b j e c t .

*

* $Id : p r o g 5 . txt 2133 2011 -11 -10 0 8 : 2 8 : 2 2 Z j k o s h y $

*/

# i n c l u d e < err . h >

# i n c l u d e < f c n t l . h >

# i n c l u d e < l i b e l f . h > 1

# i n c l u d e < s t d i o . h >

# i n c l u d e < s t d l i b . h >

# i n c l u d e < u n i s t d . h >

u i n t 3 2 _ t h a s h _ w o r d s [] = { 2

0 x 0 1 2 3 4 5 6 7 , 0 x 8 9 a b c d e f , 0 x d e a d c 0 d e };

c h a r s t r i n g _ t a b l e [] = { 3 /* O f f s e t 0 */ ’ \0 ’ ,

/* O f f s e t 1 */ ’ . ’ , ’ f ’ , ’ o ’ , ’ o ’ , ’ \0 ’ , /* O f f s e t 6 */ ’ . ’ , ’ s ’ , ’ h ’ , ’ s ’ , ’ t ’ ,

’ r ’ , ’ t ’ , ’ a ’ , ’ b ’ , ’ \0 ’ };

int

m a i n (int argc , c h a r ** a r g v ) {

int fd ; Elf * e ; E l f _ S c n * scn ; E l f _ D a t a * d a t a ; E l f 3 2 _ E h d r * e h d r ; E l f 3 2 _ P h d r * p h d r ; E l f 3 2 _ S h d r * s h d r ; if ( a r g c != 2)

e r r x ( E X I T _ F A I L U R E , " u s a g e : ␣ % s ␣ file - n a m e " , a r g v [ 0 ] ) ; if ( e l f _ v e r s i o n ( E V _ C U R R E N T ) == E V _ N O N E )

e r r x ( E X I T _ F A I L U R E , " ELF ␣ l i b r a r y ␣ i n i t i a l i z a t i o n ␣ "

" f a i l e d : ␣ % s " , e l f _ e r r m s g ( -1));

if (( fd = o p e n ( a r g v [1] , O _ W R O N L Y | O_CREAT , 0 7 7 7 ) ) < 0) 4 err ( E X I T _ F A I L U R E , " o p e n ␣ \% s \" ␣ f a i l e d " , a r g v [ 1 ] ) ;

if (( e = e l f _ b e g i n ( fd , E L F _ C _ W R I T E , N U L L )) == N U L L ) 5 e r r x ( E X I T _ F A I L U R E , " e l f _ b e g i n () ␣ f a i l e d : ␣ % s . " ,

e l f _ e r r m s g ( -1));

if (( e h d r = e l f 3 2 _ n e w e h d r ( e )) == N U L L ) 6

e r r x ( E X I T _ F A I L U R E , " e l f 3 2 _ n e w e h d r () ␣ f a i l e d : ␣ % s . " , e l f _ e r r m s g ( -1));

ehdr - > e _ i d e n t [ E I _ D A T A ] = E L F D A T A 2 M S B ;

ehdr - > e _ m a c h i n e = E M _ P P C ; /* 32 - bit P o w e r P C o b j e c t */

ehdr - > e _ t y p e = E T _ E X E C ;

if (( p h d r = e l f 3 2 _ n e w p h d r ( e , 1)) == N U L L ) 7

e r r x ( E X I T _ F A I L U R E , " e l f 3 2 _ n e w p h d r () ␣ f a i l e d : ␣ % s . " , e l f _ e r r m s g ( -1));

if (( scn = e l f _ n e w s c n ( e )) == N U L L ) 8

6.1. EXAMPLE: CREATING AN ELF OBJECT 45 e r r x ( E X I T _ F A I L U R E , " e l f _ n e w s c n () ␣ f a i l e d : ␣ % s . " ,

e l f _ e r r m s g ( -1));

if (( d a t a = e l f _ n e w d a t a ( scn )) == N U L L )

e r r x ( E X I T _ F A I L U R E , " e l f _ n e w d a t a () ␣ f a i l e d : ␣ % s . " , e l f _ e r r m s g ( -1));

data - > d _ a l i g n = 4;

data - > d _ o f f = 0 LL ;

data - > d _ b u f = h a s h _ w o r d s ; data - > d _ t y p e = E L F _ T _ W O R D ;

data - > d _ s i z e = s i z e o f( h a s h _ w o r d s );

data - > d _ v e r s i o n = E V _ C U R R E N T ;

if (( s h d r = e l f 3 2 _ g e t s h d r ( scn )) == N U L L )

e r r x ( E X I T _ F A I L U R E , " e l f 3 2 _ g e t s h d r () ␣ f a i l e d : ␣ % s . " , e l f _ e r r m s g ( -1));

shdr - > s h _ n a m e = 1;

shdr - > s h _ t y p e = S H T _ H A S H ; shdr - > s h _ f l a g s = S H F _ A L L O C ; shdr - > s h _ e n t s i z e = 0;

if (( scn = e l f _ n e w s c n ( e )) == N U L L ) 9

e r r x ( E X I T _ F A I L U R E , " e l f _ n e w s c n () ␣ f a i l e d : ␣ % s . " , e l f _ e r r m s g ( -1));

if (( d a t a = e l f _ n e w d a t a ( scn )) == N U L L )

e r r x ( E X I T _ F A I L U R E , " e l f _ n e w d a t a () ␣ f a i l e d : ␣ % s . " , e l f _ e r r m s g ( -1));

data - > d _ a l i g n = 1;

data - > d _ b u f = s t r i n g _ t a b l e ; data - > d _ o f f = 0 LL ;

data - > d _ s i z e = s i z e o f( s t r i n g _ t a b l e );

data - > d _ t y p e = E L F _ T _ B Y T E ; data - > d _ v e r s i o n = E V _ C U R R E N T ;

if (( s h d r = e l f 3 2 _ g e t s h d r ( scn )) == N U L L )

e r r x ( E X I T _ F A I L U R E , " e l f 3 2 _ g e t s h d r () ␣ f a i l e d : ␣ % s . " , e l f _ e r r m s g ( -1));

shdr - > s h _ n a m e = 6;

shdr - > s h _ t y p e = S H T _ S T R T A B ;

shdr - > s h _ f l a g s = S H F _ S T R I N G S | S H F _ A L L O C ; shdr - > s h _ e n t s i z e = 0;

e l f _ s e t s h s t r n d x ( e , e l f _ n d x s c n ( scn )); 10

if ( e l f _ u p d a t e ( e , E L F _ C _ N U L L ) < 0) 11

e r r x ( E X I T _ F A I L U R E , " e l f _ u p d a t e ( N U L L ) ␣ f a i l e d : ␣ % s . " , e l f _ e r r m s g ( -1));

phdr - > p _ t y p e = P T _ P H D R ;

phdr - > p _ o f f s e t = ehdr - > e _ p h o f f ;

phdr - > p _ f i l e s z = e l f 3 2 _ f s i z e ( E L F _ T _ P H D R , 1 , E V _ C U R R E N T );

(v o i d) e l f _ f l a g p h d r ( e , E L F _ C _ S E T , E L F _ F _ D I R T Y );

if ( e l f _ u p d a t e ( e , E L F _ C _ W R I T E ) < 0) 12

e r r x ( E X I T _ F A I L U R E , " e l f _ u p d a t e () ␣ f a i l e d : ␣ % s . " , e l f _ e r r m s g ( -1));

(v o i d) e l f _ e n d ( e );

(v o i d) c l o s e ( fd );

e x i t ( E X I T _ S U C C E S S );

}

1 The header filelibelf.hbrings in function prototypes forlibelf’s func- tions.

2 The hash wordsarray holds 32-bit words. The values in the array would need to be written using big-endian byte ordering when the section is written to file.

3 Thestring tablearray holds a pre-fabricated string table containing the names of our two sections, “.foo” and “.shstrtab”.

4 The first step in creating a new ELF object is to obtain a file descriptor opened for writing.

5 The call to function elf begin allocates an Elf handle. The parameter ELF C WRITE informs libelf of our intent to create a brand new ELF object.

6 The functionelf32 newehdrallocates an ELFExecutable Header. AnExe- cutable Headeris always needed for an ELF object.

The next few lines populate the executable header:

1. TheEI DATAbyte in thee identmember is set to the desired endi- anness (big-endian in our case).

2. The machine type is set to the constant EM PPC, for the PowerPCTM architecture.

3. The object is marked as an ELF executable.

The new ELF object will be a 32-bit object, since its Executable Header had been allocated using the 32-bitelf32 newehdrfunction.

7 The call toelf newphdrallocates an ELFProgram Header Tablecontaining a single entry. This entry is meant to cover the Program Header Table itself.

6.1. EXAMPLE: CREATING AN ELF OBJECT 47 At this point in our program we do not know the file offset at which the ELFProgram Header Tablewill be placed inside our new ELF object. This offset would only be known after the object is laid out. We need to defer filling in our program header table entry until libelf has computed an object layout for us (please see step 11 below).

8 The call toelf newscnallocates anElf Scndescriptor for the ELF section that will hold the values in thehash words array.

To actually associate data with our new section we allocate an Elf Data descriptor and set its fields to map thehash wordsarray.

A call toelf32 getshdrthen returns the Section Header Table Entry for the new section.

1. The type of the new section is set toSHT HASH. Thelibelf library knows how to byte-swap sections of this type.

2. The section is marked as containing content in the file by setting its sh flagsfield to the constantSHF ALLOC.

9 The next call to elf newscn allocates another section descriptor; this de- scriptor will be used for the section name string table. The code then allocates anElf Datadescriptor for this section, and sets its members to map the pre-fabricated string table in the arraystring table.

The call to elf32 getshdr retrieves the Section Header Table Entry for this section. The members of this section header table entry are set as follows:

1. The type of the section is set to SHT STRTAB, the section type for string tables.

2. The section flags are set to indicate that the section contains data in the file, and that it containsNUL-terminated strings.

10 The function elf ndxscn retrieves the section index for the string table section. The call to functionelf setshstrndxthen sets the section name string table index field in the ELFExecutable Header.

11 The call of the function elf update with the parameter ELF C NULL re- quests thelibelflibrary to compute a layout for an ELF object without writing the object out..

After the call toelf updatereturns, the code examines the ELF object’s Executable Header to determine where libelf had placed the object’s Program Header Table. It then updates the Program Header Table Entry created in step 7 to cover the program header table’s file location.

The call to function elf flagdata marks the Program Header Table as having been modified.

12 Finally, the functionelf updateis called with parameterELF C WRITEin order to write the ELF object out to file.

If this example program is run on a little-endian host the libelflibrary will byte-swap the sections that need byte-swapping when the ELF object is written out to file.

Save the program in listing6.1 on page 43to fileprog5.cand then compile and run it as shown in listing 6.2.

Listing 6.2: Compiling and Running prog5

% cc - o p r o g 5 p r o g 5 . c - l e l f 1

% ./ p r o g 5 foo

% f i l e foo 2

foo : ELF 32 - bit MSB e x e c u t a b l e , P o w e r P C or c i s c o 4500 , \ v e r s i o n 1 ( S Y S V ) , s t a t i c a l l y linked , s t r i p p e d

% r e a d e l f - a foo 3 ELF H e a d e r :

M a g i c : 7 f 45 4 c 46 01 02 01 00 00 00 00 00 00 00 00 00

C l a s s : E L F 3 2

D a t a : 2 ’ s c o m p l e m e n t , big e n d i a n

V e r s i o n : 1 ( c u r r e n t )

OS / ABI : U N I X - S y s t e m V

ABI V e r s i o n : 0

T y p e : E X E C ( E x e c u t a b l e f i l e )

M a c h i n e : P o w e r P C

V e r s i o n : 0 x1

E n t r y p o i n t a d d r e s s : 0 x0

S t a r t of p r o g r a m h e a d e r s : 52 ( b y t e s i n t o f i l e ) S t a r t of s e c t i o n h e a d e r s : 112 ( b y t e s i n t o f i l e )

F l a g s : 0 x0

S i z e of t h i s h e a d e r : 52 ( b y t e s )

S i z e of p r o g r a m h e a d e r s : 32 ( b y t e s ) N u m b e r of p r o g r a m h e a d e r s : 1

S i z e of s e c t i o n h e a d e r s : 40 ( b y t e s ) N u m b e r of s e c t i o n h e a d e r s : 3

S e c t i o n h e a d e r s t r i n g t a b l e i n d e x : 2 ...etc...

1 Compile, link and run the program as in our previous examples.

2 3 We can use the fileandreadelf programs to examine the object that we have created.

Dalam dokumen Libelf by Example (Halaman 35-44)

Dokumen terkait