Hello, My name is Stefan.
Now that we have explored the inner workings of an object file, it's time to venture into the disassembly
of a complete binary.
Now, let's begin with an example binary that contains symbols.
And then we will proceed to examine its stripped counterpart to observe the contrasting disassembly
output.
And it's important to note that disassembly and disassembling an object file differs significantly from
disassembling a binary executable.
So when disassembling an object file, we have the luxury of working with symbols that provide valuable
contextual information.
Symbols acts as a guidepost, enabling us to navigate through the code with greater ease.
However, the disassembly of a binary executable presents a unique challenge.
Without the presence of symbols or other symbolic information, we must rely solely on the structure
and patterns with the binary itself.
So this requires a deeper understanding of assembly language and the ability to decipher the code's
logic based on its instructions and data.
Disassembling a binary executable without symbols demands a more meticulous and intricate approach.
We must carefully analyze the code, identify known functions or recognizable patterns, and reconstruct
the program's logic through careful observation.
It requires a keen eye and a solid grasp of assembly language concepts, while disassembling a stripped
binary may be more arduous, it serves as an excellent exercise in honing up reverse engineering skills
and gaining deeper understanding of the code's inner workings.
And here, before explaining further, we will use the objdump to disassemble an executable here.
So objdump uppercase m Intel d a dot out here.
And this is our output here.
The first.
Firstly, we have.
The that's what this assembling section in it.
Right.
So.
Here.
You can see that the binary has a lot more code than the object file.
So it's no longer just the main function or even just a single code section.
There are multiple sections now.
The names like the init.
Pee pee pee.
Here.
This is a pre init.
PLT.
And text.
Here we have the three main sections that we are interested in.
So these sections all contain codes serving different functions such as programming, initialization
or stubs for calling shared libraries.
So the text sections here, let's actually copy this and.
Let's actually copy this into Notepad and we'll see that better.
And here.
What are we going to do is.
Let's go to the next section.
Assembly of a section text.
So the text section is the main code section.
So and it contains the main function as well as you as you saw here.
So as you can see, this is a main function and it also contains a number of other functions such as
the Start that are responsible for tasks such as setting up the command line arguments and runtime environment
for main and cleaning up after Main.
And these extra functions are standard functions present in any Elf binary produced by GCC.
You can also see that the previously incomplete code and data references have now been resolved by the
linker.
For instance, the call paths here.
Let me find that call.
Here.
But this one.
This one here?
Yeah.
The call here in our main function.
Now points to the proper setup in the PLT.
Set in the PLT here.
Paths at PLT.
Here.
And for this.
Points to a proper setup for the shared library that contains paths itself.
So I will explain the workings of pit stops in next lectures.
Again.
So.
So that the full binary executable contains significantly more code and data that I haven't showed it
for now.
And then the corresponding object file.
So.
But so far the output isn't much more difficult to interpret, right?
So the changes to the binary is stripped, which uses the objdump to disassemble the stripped version
of an example binary.
We're going to use that now let's clear that.
Let's close the backgrounds here.
Come.
And here.
Objdump.
And Intel here and a or.
My app.
My app dot.
Sexually.
I think we had this.
My apt out of.
A dot out.
And here again, have this.
By.
Copy this again.
The new mousepad.
And here the main takeaway of this output is that while the different sections are still clearly distinguishable
like the init, the init the.
Light.
They also have the text here.
Uh, but the functions are not.
Instead, all functions have been merged into one big blob of code.
So the start functions here start.
Start functions begins at here.
And the register or the register here?
The register functions.
The register team clones begins after the start.
Those.
So the main functions start at somewhere bottom here.
Here the main function starts here.
And ends at here.
So but in all of these cases, there's nothing special to indicate that the instructions at these markers
represent function starts.
So the only exceptions are the functions in the PLT sections here, the assembly of section PLT.
And.
And which these sections have their names, as we saw before.
Uh, the before output.
And other than that, you are on your own to try make sense of this disassembly output.
Even in this simple example, things are really confusing.
Imagine trying to make sense of a larger binary containing hundreds of different functions all fused
together.
This is exactly why accurate automated function detection is so important in many areas of reverse engineering,
malware analysis or binary analysis, which you will learn in next lectures.