So here in this example, we'll be writing, uh, an Elf binary from C code.
So previously we have written an Elf header.
Now what we'll do.
We know section headers are not used during, uh, execution.
We only need a program header.
Right.
So we will only add parameters.
So this, uh we have added elf header.
Uh, okay.
We take that this, uh, from the previous example, the elf and h.
Uh, hello.
Uh, I took this entry point, but I had to reduce this to a different entry point because we have reduced
the program headers.
Then I have added a program header.
So and this should be of type load.
And I'm giving an offset of where this particular uh parameter is present in the memories.
First is the 64 bytes of the header okay.
And then 56 bytes of this particular program header structure.
So after this is where my actual program header content is present, the segment is present.
And they gave a program virtual address of this one and physical address of this one.
And what is the size of this and this.
So what I did is I took the from this.
If I take objdump hyphen s on hello will give me both contents of text section and data section.
Okay.
I took this uh, and I converted it into a object code.
So 48 6566.
This is the hello.
Right.
This is what, 48 20A is the data section.
I'm keeping it the starting of the memory.
Then I have B eight.
Just move command and I have 100 which is a write system call.
So this is and then I have b f and which is move command.
So this is a move command one opcode for move operands.
Opcode operands.
Same thing.
Till here.
And now I am writing opening a binary file.
I am writing the header.
I am writing the program header.
I am writing the object code and I am closing the file.
So what we are doing from this we are writing an elf file which is very simple elf file where I am only
having one Elf header program header and the object code is containing data and text section.
So I will run this elf.
I will create this.
So it will create me a file on us bin which is almost like 164 size.
It is not having executable permissions.
I will give this executable permissions.
Now if I say file on this it is saying it is a statically linked binary.
It is not having section header, it is having invalid version.
That is fine for us.
We will have F and h on this bin is saying.
Would give me 64 bit little endian.
That is, for x86, whatever we gave the entry point address.
Is coming here.
It does not have any section headers because number of section headers are zero.
And we don't have string table index as well.
And uh does not have it has only one parameter.
And it is at this particular offset and size of this parameter.
So I can say readelf hyphen w s.
It does not have any sections.
W ell it has only one program header and this is of the size this much.
Uh, to see if you add this all, it will be like to see.
Okay.
And it is taking the same in this memory.
And this is the virtual address and offset.
And I'm having this offset read.
So I have added this offset uh into the virtual address and the physical address.
And in this I gave the entry point as uh, this 4078.
So I gave the entry point as 407F.
Now if I run this binary I got my executable output.
So yeah.
So this is very simple Elf file right where it is taking only uh, 164 bytes and is getting the same
output what we had from here.
But this was taking like.
117 KB because it is adding a lot of information which is used by linker and loader here because we
wanted to achieve our own functionality, whatever the functionality.
I, uh, we wrote our own Elf file, but this is not this will not work with, uh, any NM command or
Elf or objdump.
405 unless I don't see any content like the previous one, right where it is printing all the contents,
but all the utilities will not work because we wrote very minimal Elf file, which is needed for, uh,
to work.
Make it work.
I can keep this.
I cannot compile this in hyphen g option and add gdb and do all those right, because we have written
directly an opcode.
Uh, and we passed we wrote this opcode, copied it from the previous assembly.
We just took data section and text section.
We kept everything in one segment.
And we loaded this particular segment in the memory.
And then the control is passed to this particular segment.
And it worked.
So very simple example of very minimal size of Elf.
And we got it working with the Linux kernel is accepting this particular binary uh, of this particular
if it has only one parameter.
And this is like it is thinking like this is a statically static binary, it is not a dynamic binary,
it is a statically linked.
So one program header is sufficient and of type load to make your executable work.