WEBVTT

00:00.980 --> 00:05.750
After the identity array, we have a series of multi-byte integer fields.

00:05.870 --> 00:11.810
The first of these is called the E type Specifies the type of the binary.

00:11.840 --> 00:19.340
The most common values you will encounter here are the e t indicating a relocatable object file and

00:19.370 --> 00:23.870
e t exec, which is an executable binary.

00:23.870 --> 00:26.590
So and the dynamic so e.

00:26.600 --> 00:30.980
T t y n e dynamic library also called the shared object file.

00:30.990 --> 00:40.790
So in this output, let's actually go here again we can see that it's a dynamic library here.

00:40.790 --> 00:46.550
So position independent executable file, it's actually executable file but in a different way here.

00:46.550 --> 00:50.330
And next we have the machine field.

00:50.330 --> 00:52.760
You can also see that field in here.

00:52.760 --> 00:54.170
This is architecture here.

00:54.380 --> 01:00.320
So which denotes the architecture that the binary is intended to run on.

01:00.320 --> 01:06.000
We and here, as you can see here, Advanced Micro Devices, x86 and 64.

01:06.660 --> 01:10.620
And for this course, this will usually be set to.

01:11.980 --> 01:13.330
A m.

01:13.690 --> 01:14.620
86.

01:15.220 --> 01:16.160
64.

01:16.180 --> 01:26.140
As you can see in this red output, since you will mostly be working on 64 bit x86 binaries.

01:26.200 --> 01:33.370
That's why we are getting this machine output here and other values you are likely to encounter include

01:33.370 --> 01:44.290
the m 386, which is 32 bit on 6086 binaries and a m.

01:46.150 --> 01:50.390
Arm for arm binaries.

01:51.440 --> 01:54.170
And the version here we have here.

01:55.850 --> 02:00.050
As you can see here, this tells the object file version here.

02:00.780 --> 02:03.120
Let's actually do that now here.

02:03.120 --> 02:08.370
So as you can see, it tells the object file version which.

02:09.820 --> 02:18.640
Um, serves the same role as the e I version by in the e ident array.

02:18.850 --> 02:25.810
Specifically, it indicates the version of the elf specification that was used when creating the binary.

02:25.840 --> 02:32.650
As this field is 32 bits wide, you might think there are numerous possible values, but in reality

02:32.650 --> 02:39.960
the only possible value is one to indicate version of the version one of the specification.

02:39.970 --> 02:48.730
And with that way you can see that in our elf output output file we have the 0X1.

02:48.730 --> 02:50.770
So we have the one byte here.

02:52.830 --> 02:55.860
And we also have the entry field.

02:56.430 --> 02:58.710
Let's go back to that.

02:59.160 --> 03:02.910
And here so we see that entry.

03:03.660 --> 03:04.120
It's actually.

03:05.970 --> 03:06.690
Go to that.

03:15.130 --> 03:17.970
And here the entry.

03:17.980 --> 03:20.110
This is an entry point virtual address.

03:20.110 --> 03:27.910
This entry field denotes the entry point of the binary, and this is the virtual address at which execution

03:27.910 --> 03:29.080
should start.

03:29.470 --> 03:31.870
You will see that in the next lecture.

03:31.870 --> 03:37.930
So for the example binary, this execution starts at entry point address.

03:38.050 --> 03:41.440
As you can see here, 1050.

03:41.890 --> 03:51.250
And this is where the interpreter typically ld dash linuxone will transfer control after it finishes

03:51.250 --> 03:53.710
loading the binary into virtual memory.

03:53.800 --> 04:00.720
The entry point is also a useful starting point for recursive disassembly, which you will learn in

04:00.730 --> 04:01.690
next lectures.

04:01.690 --> 04:10.300
And here we have the key of here program header, table file offset and we also have the section header

04:10.300 --> 04:12.340
table file offset.

04:12.430 --> 04:18.290
And as you can see here, Elf binaries contain tables of program headers and section headers, among

04:18.290 --> 04:19.190
other things.

04:19.190 --> 04:26.000
And I will revisit the meaning of this header types after I finish discussing the executable header

04:26.000 --> 04:26.570
in this lecture.

04:26.570 --> 04:35.150
But one thing I can already reveal is that the program header and the section header tables need not

04:35.150 --> 04:38.240
to be located at any particular offset in the binary file.

04:38.240 --> 04:45.590
So the only data structure that can be assumed to be at a fixed location in an Elf binary is the executable

04:45.620 --> 04:48.680
header, which is always at the beginning.

04:48.680 --> 04:54.350
So how can you know where to find the program headers and the section headers For this?

04:54.350 --> 05:03.380
The executable header contains two dedicated fields called a program header offset and a here we can

05:03.380 --> 05:11.570
see the section header table offset that indicates the file offsets to to the beginning of the program

05:11.570 --> 05:13.940
header table and the section header table.

05:14.060 --> 05:20.600
And here, as you can see, we have start of the program headers and start of the section headers.

05:20.600 --> 05:26.240
And we in start of program headers we have 64 bytes into file.

05:26.240 --> 05:37.040
And in the start of the section headers we have this 13,968 bytes into file and respectively these two

05:37.040 --> 05:43.850
lines here are the binary, the and offsets here.

05:43.850 --> 05:50.210
And the offsets can also be set to zero to indicate that the file does not contain a program header

05:50.210 --> 05:51.860
or section header table.

05:51.860 --> 05:58.250
And it's important to keep in mind here that these fields are file offsets, meaning the number of bytes

05:58.250 --> 06:02.480
you should read into the file to get to the headers, right?

06:02.480 --> 06:13.520
So in other words, in contrast to E entry field discussed earlier, the program header of and the section

06:13.520 --> 06:17.270
header offset are not virtual addresses.

06:17.420 --> 06:20.690
And here we also have the flags.

06:21.370 --> 06:24.580
As you can see here, processor specific flags we have here.

06:24.820 --> 06:28.120
Let me check if you can see the screen clearly.

06:28.120 --> 06:28.720
Yes.

06:28.960 --> 06:30.970
Let's increase the font size a little bit.

06:31.900 --> 06:37.150
And here we have the E flex, which is processor specific flex.

06:37.150 --> 06:45.670
So the E flex E flex field provides room for flex specific to the architecture for which the binary

06:45.670 --> 06:46.360
is compiled.

06:46.360 --> 06:55.310
So for instance, arm binaries intended to run on embedded platforms can set specific flags in the E

06:55.360 --> 07:01.750
flags field to indicate additional details about the interface they expect from the embedded operating

07:01.750 --> 07:08.530
system like file format, convention conventions, stack organizations and so on here.

07:08.530 --> 07:14.980
And Flex is typically set to zero and is not of interest here.

07:14.980 --> 07:22.420
And as you can see here in this example, we also our flags is also set to zero.

07:22.420 --> 07:25.930
And we also have the size of this header.

07:26.410 --> 07:31.670
We can turn this into e size, the Elf header size in bytes.

07:31.670 --> 07:37.430
So this field specifies the size of the executable header but in bytes.

07:37.430 --> 07:48.770
So for 64 bit x86 binaries, the executable header size is always 64 bytes as you can see here.

07:49.620 --> 07:52.950
And while it's.

07:54.340 --> 07:55.320
54.

07:55.540 --> 08:05.050
No, it's, uh, 52 bytes for, uh, 32 bit x86 binaries here.

08:05.110 --> 08:07.150
62 for.

08:07.800 --> 08:10.470
32 bits here.

08:12.560 --> 08:15.980
And also we have this.

08:16.340 --> 08:17.040
I'm sorry.

08:19.510 --> 08:20.020
Here.

08:20.020 --> 08:23.290
And we also have the pen size.

08:23.500 --> 08:30.760
And for h num here, this is a program header, table entry size and program header table entry count.

08:30.760 --> 08:39.640
As you now know, the E program header table entry size and a program header.

08:41.740 --> 08:44.170
Table entry of.

08:44.530 --> 08:45.070
Yes.

08:45.190 --> 08:45.790
Program Header.

08:46.060 --> 08:46.750
Table.

08:47.980 --> 08:51.970
No, it's actually this program header table.

08:53.420 --> 09:00.620
File offset and this section header table file offset points to the file offsets where the program header

09:00.620 --> 09:01.910
and section header table begins.

09:01.910 --> 09:02.420
Right.

09:02.420 --> 09:10.040
So but for the linker or loader or any other program handling the elf binary to actually traverse these

09:10.040 --> 09:12.140
tables, additional information is needed.

09:12.320 --> 09:18.080
Specifically, they need to know the size of the individual program or section headers in the tables,

09:18.080 --> 09:21.200
as well as the number of headers in each file.

09:21.200 --> 09:27.320
So this information is provided by the font size and for num.

09:28.930 --> 09:30.820
Fields for the program header table.

09:30.820 --> 09:35.020
And by the we have c h.

09:36.460 --> 09:43.060
E and T size, which is section header table entry size and section header table entry count.

09:44.050 --> 09:45.960
And we also have this P.

09:47.120 --> 09:50.390
Maybe has c h numb here.

09:52.280 --> 09:55.650
And c h size fields.

09:57.410 --> 10:03.170
We have these fields because the section header table to specify that.

10:03.170 --> 10:10.640
And in this example binary here we have this number of programs and here we have section header, table

10:10.640 --> 10:11.960
entry size and.

10:13.630 --> 10:16.870
The name, which is program header table entry count.

10:17.170 --> 10:24.760
You can find this field in the number of program headers and size of program headers here.

10:26.440 --> 10:36.580
And we also have the E section header, string table index, a section header string table index here.

10:37.360 --> 10:44.620
And this field contains the index in this in the section header file of the header associated with a

10:44.620 --> 10:49.990
specific and special string table section called the.

10:50.770 --> 10:51.770
C h.

10:51.820 --> 10:52.010
S.

10:52.120 --> 10:52.400
T.

10:52.450 --> 10:53.050
R.

10:55.600 --> 11:02.860
So this is a dedicated section that contains a table of null terminated Ascii strings which store the

11:02.860 --> 11:06.120
names of all the sections in the binary.

11:06.130 --> 11:13.630
It is used by elf processing tools such as Red Elf, as you can see here.

11:14.710 --> 11:17.650
Um, to correctly chose the names of sections.

11:17.650 --> 11:22.930
And I will describe this here section header String table index 30.

11:24.100 --> 11:28.270
And you will learn that this section.

11:29.240 --> 11:31.040
Table index.

11:31.720 --> 11:42.590
In this lecture, let's try this with Rudolph x r c h s t r tab and a dot out here.

11:42.620 --> 11:43.400
This is output file.

11:43.400 --> 11:50.870
And as you can see here, we have this output here and you can see the section names like tab start

11:50.870 --> 11:51.500
tab.

11:51.530 --> 12:01.850
See HSR, str tab and so on contained in the string table at the right side of our listing.

12:01.880 --> 12:07.880
And now that you are familiar with the format and contents of the Elf executable header, let's move

12:07.880 --> 12:11.750
on to the section headers in next section.
