After the identity array, we have a series of multi-byte integer fields.
The first of these is called the E type Specifies the type of the binary.
The most common values you will encounter here are the e t indicating a relocatable object file and
e t exec, which is an executable binary.
So and the dynamic so e.
T t y n e dynamic library also called the shared object file.
So in this output, let's actually go here again we can see that it's a dynamic library here.
So position independent executable file, it's actually executable file but in a different way here.
And next we have the machine field.
You can also see that field in here.
This is architecture here.
So which denotes the architecture that the binary is intended to run on.
We and here, as you can see here, Advanced Micro Devices, x86 and 64.
And for this course, this will usually be set to.
A m.
86.
64.
As you can see in this red output, since you will mostly be working on 64 bit x86 binaries.
That's why we are getting this machine output here and other values you are likely to encounter include
the m 386, which is 32 bit on 6086 binaries and a m.
Arm for arm binaries.
And the version here we have here.
As you can see here, this tells the object file version here.
Let's actually do that now here.
So as you can see, it tells the object file version which.
Um, serves the same role as the e I version by in the e ident array.
Specifically, it indicates the version of the elf specification that was used when creating the binary.
As this field is 32 bits wide, you might think there are numerous possible values, but in reality
the only possible value is one to indicate version of the version one of the specification.
And with that way you can see that in our elf output output file we have the 0X1.
So we have the one byte here.
And we also have the entry field.
Let's go back to that.
And here so we see that entry.
It's actually.
Go to that.
And here the entry.
This is an entry point virtual address.
This entry field denotes the entry point of the binary, and this is the virtual address at which execution
should start.
You will see that in the next lecture.
So for the example binary, this execution starts at entry point address.
As you can see here, 1050.
And this is where the interpreter typically ld dash linuxone will transfer control after it finishes
loading the binary into virtual memory.
The entry point is also a useful starting point for recursive disassembly, which you will learn in
next lectures.
And here we have the key of here program header, table file offset and we also have the section header
table file offset.
And as you can see here, Elf binaries contain tables of program headers and section headers, among
other things.
And I will revisit the meaning of this header types after I finish discussing the executable header
in this lecture.
But one thing I can already reveal is that the program header and the section header tables need not
to be located at any particular offset in the binary file.
So the only data structure that can be assumed to be at a fixed location in an Elf binary is the executable
header, which is always at the beginning.
So how can you know where to find the program headers and the section headers For this?
The executable header contains two dedicated fields called a program header offset and a here we can
see the section header table offset that indicates the file offsets to to the beginning of the program
header table and the section header table.
And here, as you can see, we have start of the program headers and start of the section headers.
And we in start of program headers we have 64 bytes into file.
And in the start of the section headers we have this 13,968 bytes into file and respectively these two
lines here are the binary, the and offsets here.
And the offsets can also be set to zero to indicate that the file does not contain a program header
or section header table.
And it's important to keep in mind here that these fields are file offsets, meaning the number of bytes
you should read into the file to get to the headers, right?
So in other words, in contrast to E entry field discussed earlier, the program header of and the section
header offset are not virtual addresses.
And here we also have the flags.
As you can see here, processor specific flags we have here.
Let me check if you can see the screen clearly.
Yes.
Let's increase the font size a little bit.
And here we have the E flex, which is processor specific flex.
So the E flex E flex field provides room for flex specific to the architecture for which the binary
is compiled.
So for instance, arm binaries intended to run on embedded platforms can set specific flags in the E
flags field to indicate additional details about the interface they expect from the embedded operating
system like file format, convention conventions, stack organizations and so on here.
And Flex is typically set to zero and is not of interest here.
And as you can see here in this example, we also our flags is also set to zero.
And we also have the size of this header.
We can turn this into e size, the Elf header size in bytes.
So this field specifies the size of the executable header but in bytes.
So for 64 bit x86 binaries, the executable header size is always 64 bytes as you can see here.
And while it's.
54.
No, it's, uh, 52 bytes for, uh, 32 bit x86 binaries here.
62 for.
32 bits here.
And also we have this.
I'm sorry.
Here.
And we also have the pen size.
And for h num here, this is a program header, table entry size and program header table entry count.
As you now know, the E program header table entry size and a program header.
Table entry of.
Yes.
Program Header.
Table.
No, it's actually this program header table.
File offset and this section header table file offset points to the file offsets where the program header
and section header table begins.
Right.
So but for the linker or loader or any other program handling the elf binary to actually traverse these
tables, additional information is needed.
Specifically, they need to know the size of the individual program or section headers in the tables,
as well as the number of headers in each file.
So this information is provided by the font size and for num.
Fields for the program header table.
And by the we have c h.
E and T size, which is section header table entry size and section header table entry count.
And we also have this P.
Maybe has c h numb here.
And c h size fields.
We have these fields because the section header table to specify that.
And in this example binary here we have this number of programs and here we have section header, table
entry size and.
The name, which is program header table entry count.
You can find this field in the number of program headers and size of program headers here.
And we also have the E section header, string table index, a section header string table index here.
And this field contains the index in this in the section header file of the header associated with a
specific and special string table section called the.
C h.
S.
T.
R.
So this is a dedicated section that contains a table of null terminated Ascii strings which store the
names of all the sections in the binary.
It is used by elf processing tools such as Red Elf, as you can see here.
Um, to correctly chose the names of sections.
And I will describe this here section header String table index 30.
And you will learn that this section.
Table index.
In this lecture, let's try this with radulf x.
R c h s t r tab and a dot out here.
This is output file.
And as you can see here, we have this output here and you can see the section names like tab start
tab.
See HSR, str tab and so on contained in the string table at the right side of our listing.
And now that you are familiar with the format and contents of the Elf executable header, let's move
on to the section headers in next section.