1

I have written a ELF parser that disassmbles the .text section using capstone

my problem is that i dont know how can i segment the text section based on functions and print the name of the function just like the output of objdump -d

because objdump outputs like this :

0x01000 func1:

0x01000 ..

0x01001 ..

how can i find out the name and start address of every function in .text so i can output something like objdump?

i tried using string to see if the names store somewhere in the binary for example in symbol table, but couldn't find them anywhere in it!

(note that I'm not talking about import functions and such, just the functions inside the actual main code in the .text section)

8
  • 1
    You realize there is the BFD library which really makes it easy to write an ELF parser yourself? All part of the binutils project ...
    – 0xC0000022L
    Commented Apr 11, 2019 at 11:19
  • @0xC0000022L this was for our homework and we had to write the entire parser ourselves and only use capstone to disassemble, so how can i get the function names and their addresses during parsing?
    – John P
    Commented Apr 11, 2019 at 11:32
  • Is the symbol table present in the binary?
    – julian
    Commented Apr 11, 2019 at 15:15
  • @julian yes there is, but still doesnt contain name of functions otherwise string wouldve find them
    – John P
    Commented Apr 11, 2019 at 18:19
  • 1
    It sounds very unlikely that would be true if objdump is finding them. This is likely at a point where you need to post a brief sample exhibiting the problem somewhere. You can also rebuild objdump from source with custom logging to figure out how it is working. Make sure you are running the exact same elf through objdump - a stripped elf would not have internal names, so even objdump wouldn't find them, and it would be too bad if you were wasting time chasing a mixup resulting from having run a different version of the file through the objdump test. Commented Apr 12, 2019 at 15:48

1 Answer 1

2

In order to accomplish that you need some knowledge about ELF files. I'm not going explain every detail about ELF files since is a lot to cover so I'll try to be as precise as I can.

NOTE #01: I will use radare2 to dissect the file but you can do it with any hex editor out there.

NOTE #02: Here is the link to the cpp file that I compile to explain you ELF files. Feel free to take it or make your own.

First, you need to know the structure of headers in ELF files. Here you can see the structures of the headers.

The first thing we want to look for is e_ident that represent the format of the file (32bit or 64bit) since the file header will be different depending of the file format.

e_ident offset=0x04, size=1byte

Go to the 0x04 offset of the file and check one byte. (s means seek)

:> s 0x04
0x00000004  02

e_ident = 0x02 means 64bit format.

Now that we now the file format we need to know the offset of the section header(e_shoff), the size of each entry(e_shentsize), and the number of entries in the section header(e_shnum).

e_shoff offset=0x28 size=8bytes
e_shentsize offset=0x3A size=2bytes
e_shnum offset=0x3C size=2bytes

:> s 0x28
0x00000028  e03b 0000 0000 0000

:> s 0x3A
0x0000003a  4000

:> s 0x3C
0x0000003c  1d00

e_shoff = 0x3be0 This is the offset of the section header.
e_shentsize = 0x40 (64 bytes)
e_shnum = 0x1d (29 entries)

We also going to need the index of the section header that contains the names of each section header. This is store in e_shstrndx

e_shstrndx offset=0x3E size=2bytes

:> s 0x3e
0x0000003e  1c00

e_shstrndx = 0x1c (entry 28)

With the entry number you can get the address of shstrtab:

// e_shoff+(e_shentsize*e_shstrndx)+sh_offset
:> s 0x3be0+(0x40*0x1c)+0x18
0x000042f8  df3a 0000 0000 0000

shstrtab = 0x3adf

Now that you have that information you can run a loop that checks all the section entries:

//pseudocode
for (i=0; i<e_shnum; i++)
    entryN = e_shoff+(e_shentsize*i);

NOTE #03:I'll not print those values here because I have to explain more but that will give you something similar to the command readelf -W -l [program]

Each entry has a structure like the section header. To get the name of each entry add sh_name to shstrtab

I'm only going to show you how I got .text but the idea will be the same for any section entry. In my case .text was the entry 0x0e(14). I'm going to need sh_name, the offset in the file sh_offset, and the size sh_size

sh_name offset=0x00 size=4bytes
sh_offset offset=0x18 size=8bytes
sh_size offset=0x20 size=8bytes

//e_shoff+(e_shentsize*e_shstrndx)+sh_name
:> s 0x3be0+(0x40*0x0e)+0x00
0x00003f60  9d00 0000

// Get the name
:> s 0x3adf+0x9d
0x00003b7c  2e74 6578 7400 2e66 696e 6900 2e72 6f64  .text..fini..rod

//e_shoff+(e_shentsize*e_shstrndx)+sh_offset
:> s 0x3be0+(0x40*0x0e)+0x18
0x00003f78  9010 0000 0000 0000

//e_shoff+(e_shentsize*e_shstrndx)+sh_size
:> s 0x3be0+(0x40*0x0e)+0x20
0x00003f80  3102 0000 0000 0000

entryName = 0x3be0 // .text
sh_offset = 0x1090
sh_size = 0x0231 (561bytes)

If you can't found it this way then your ELF file must be corrupted. You can take the one I compile to follow this explanation. Good luck.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.