Possible to add executable section/segment to ELF binary? - elf

It's easy to add an empty section with objcopy --add-section.
However, I'd like the added section can be loaded as normal .text section and executable. Which means need modify segment header. Any suggestion?

Possible to add executable section/segment to ELF binary?
It's possible in theory, but not in practice: ELF files have complicated internal structures, which would all need to be rebuilt.
Which means need modify segment header
Modifying Phdr table is quite easy: it's just a fixed table. But you'll have to move other segments, and update all internal offsets that point into them, which is the hard part.

Related

ELF binary make section unaccessible

I'm implementing a prototype stack protection mechanism for a university assignment.
The test binary that I'm trying to "harden" is a statically linked elf binary that has multiple stacks, which are hard coded as elf sections. The different stacks are seperated by guard pages (4096 byte sections).
The guard pages should be unaccesible, similar to what mprotect's PROT_NONE would do. I've tried using objcopy with --set-section-flags on readonly but overflowing one of the stacks still results in data being written to the guard page, which means it's clearly still writeable.
How can I make a section like this unaccesible using only elf section flags (or a similar elf property)?
The closest I've been able to find is using an ELF LOAD program header with FLAGS set to 0.
See the "reserve" PHDR in the Chromium NACL linker script: https://src.chromium.org/native_client/trunk/src/native_client/src/trusted/service_runtime/linux/nacl_bootstrap.x

How do I add a prefix to all symbols in an elf object file but so that debugging still works?

I want to add a prefix to every symbol in an elf object file, how do you do that using Linux (eg debian)?
I need the debug information to still work (ie, gdb can still debug effectively albeit using the new names for all the symbols).
The elf object is relocatable.
A solution for a non-relocatable object would also be welcome.
A solution for which code-coverage stats continues to work would also be welcome but is not necessary.
I don't know of any canned way to do this.
I think it could be done by rewriting the ELF symbol table and the DWARF information as well. This is not trivial, though perhaps you could implement it using the various libraries in elfutils.

How can the --add-section switch of OBJCOPY be used?

There are really two questions that revolve around the use of --add-section. The simple one is in the title. Based on my reading, I haven't been able to figure out how one could execute --add-section.
To use add-section, I have to pass a section name. If I use an existing section name the program responds with "can't add section '.data': File in wrong format." Perhaps I just need to pass another parameter. If I use a new section name, which I would prefer to do, I'm warned that "allocated section '.blob' not in segment."
Now, I have gotten my feature to work as I need it to aside from the "not in segment" warning. I'd like to figure out if there is a legitimate way to put this blob into the executable. I would link it in, but that isn't so easy because the data I'm adding is generated from the contents of the executable itself.
The second question is really what I care about. Is there a way to do the following given that the blob cannot be computed until after the link is complete.
Link ELF file
Generate blob from ELF file and other data
Add blob to ELF file so that it is loaded at run-time to the correct location in memory
objcopy --add-section .blob=blob.o \
--set-section-flags .blob=alloc,contents,load,readonly \
--change-section-address .blob=ADDRESS \
program.elf program.blobbed.elf
I'd be happy to add a section and/or segment to the ELF file as part of the link and insert this blob there. I'm not sure how to do that.
It has occurred to me that I could accomplish this feat with a second link, but objcopy would be cleaner.
Link ELF file
Generate blob from ELF file and other data
Re-link ELF file including new blob.o
UPDATE: This last strategy may be workable as long as the relink doesn't change something in the portion of the program that was produced by the first link. It doesn't on first attempts, but it may be possible to work around it. Hence, the desire to use --add-section to add in this blob instead of going through a second link.
You may add that section, fill it with, say, NULs, and then compute your blob. Then patch that blob into this section. Later, when you check the integrity of the ELF, do as if that section was full of NULs and compute the blob again. Finally, compare both computed blob and blob stored in section.
Not specifically answering your question but one approach I used to use for this sort of thing was to link in a placeholder block and then just patch the correct value in afterwards.
I know this isn't what you want to do, but it is a pretty simple and reliable way to do it. And has the major advantage of being tool chain/platform agnostic.

ELF files - What is a section and why do we need it?

I've been reading ELF standard here. From what I understand, each ELF contains ELF header, program headers (why more than one?) and section headers. Can anyone please explain:
How are ELF files generated? is it the compiler responsibility?
What are sections and why do we need them?
What are program headers and why do we need them?
Inside program headers, what's the meaning of the fields p_vaddr and p_paddr?
Does each section have it's own section header?
Alternatively, does any one have a link to a more friendly documenation of ELF?
How are ELF files generated? is it the compiler responsibility?
They can be generated by a compiler, an assembler, or any other tool that can generate them. Even your own program you wrote for generating ELF files ;) They're just streams of bytes after all, so they can be generated by just writing bytes into a file in binary mode. You can do that too.
What are sections and why do we need them?
ELF files are subdivided into sections. Sections are the smallest continuous regions in the file. You can think of them as pages in an organizer, each with its own name and type that describes what does it contain inside. Linkers use this information to combine different parts of the program coming from different modules into one executable file or a library, by merging sections of the same type (gluing pages together, if you will).
In executable files, sections are optional, but they're usually there to describe what's in the file and where does it begin, and how much bytes does it take.
What are program headers and why do we need them?
They're mostly for making executable files. In order to run a program, sections aren't enough, because you have to specify not only what's there in the file, but also where should it be loaded into memory in the running process. Program headers are just for that purpose: they describe segments, which are regions of memory in the running process, with different access privileges & stuff.
Each program header describes one segment. It tells the loader where should it load a certain region in the file into memory and what permissions should it set for that region (e.g. should it be allowed to execute code from it? should it be writable or just for reading?)
Segments can be further subdivided into sections. For example, if you have to specify that your code segment is further subdivided into code and static read-only strings for the messages the program displays. Or that your data segment is subdivided into funky data and hardcore data :J It's for you to decide.
In executable files, sections are optional, but it's nice to have them, because they describe what's in the file and allow for dumping selected parts of it (e.g. with the objdump tool). Sometimes they are needed, though, for storing dynamic linking information, symbol tables, debugging information, stuff like that.
Inside program headers, what's the meaning of the fields p_vaddr and p_paddr?
Those are the addresses at which the data in the file will be loaded. They map the contents of the file into their corresponding memory locations. The first one is a virtual address, the second one is physical address.
Physical addresses are the "raw" memory addresses. On modern operating systems, those are no longer used in the userland. Instead, userland programs use virtual addresses. The operating system deceives the userland program that it is alone in memory, and that the entire address space is available for it. Under the hood, the operating system maps those virtual addresses to physical ones in the actual memory, and it does it transparently to the program.
Of course, not every address in the virtual address space is available at the same time. There are limitations imposed by the actual physical memory available. So the operating system just maps the memory for the segments the program actually uses (here's where the "segments" part from the ELF file's program headers comes into play). If the process tries to access some unmapped memory, the operating system steps in and says, "sorry, chap, this memory doesn't belong to you". (The program can address it, but it cannot access it.)
Does each section have it's own section header?
Yes. If it doesn't have an entry in the Section Headers Table, it's not a section :q Because they only way to tell if some part of the file is a section, is by looking in to the Section Headers Table which tells you what sections are defined in the file and where you can find them.
You can think of the Section Headers Table as a table of contents in a book. Without the table of contents, there aren't any chapters after all, because they're not listed anywhere. The book may have headings, but the content is not subdivided into logical chapters that can be found through the table of contents. Same goes with sections in ELF files: there can be some regions of data, but you can't tell without the "table of contents" which is the SHT.
This link includes a better explaination.
How are ELF files generated? is it the compiler responsibility?*
It is architecture dependent.
What are sections and why do we need them?
Different section have different information such as code, initialized data, uninitialized data etc. These information will be used by the compiler and linker.
What are program headers and why do we need them?
Program headers are used by the operating system when it loads the executable. These headers contains information about the segments (contiguous memory block with some permissions) such as which parts needs to be loaded, interpreter infor etc.
Inside program headers, what's the meaning of the fields p_vaddr and p_paddr?
In general virtual address and the physical address are same. But could be different depends on the system.
Does each section have it's own section header?
yes. Each section have a section header entry at section header table.
This is the best documentation I've found: http://www.skyfree.org/linux/references/ELF_Format.pdf
Each section has only one section header, but there can be section headers without sections
2 - There are many different sections, ex: relocation section recoeds many infomation for relocation symbol. I use the infomation to load a elf object and run/relocate the object.
Antoher example: debug section records debug information, gdb use the data for showing debug message.
Symbol section records symbol information.
3 - programming header used by loader, loader loads a elf execute file by looking up programming header.

Modifying elf file

I would like to add a new flag to an elf file. This flag should then be available
to the kernel in the process descriptor. My first idea was to use libelf, but unfortunately
there seems to be a bug with it on Ubuntu. Elfedit would have probably been a nice tool but I have not found a version for Linux, in particular Ubuntu.
So, I am wondering if anyone can suggest to me if there is any other useful tool out there
to add a custom flag to an elf file?
Many thanks for your help!
People who are able to modify the kernel to take advantage of the new flag probably wouldn't be asking how to add the flag to the ELF libraries.
So, how do you plan to have the kernel use this new flag? What is the purpose of the flag?
Since you are adding to the standard libelf, can't you fix the bug for Ubuntu and let them know that you've done so (make the fix available to them - though they'll probably need to relay it back up the chain).
Please look at ELFIO library. It contains WriteObj and Writer examples. By using the library, you will be able to create and/or modify ELF binary files.
(although old question but for reference I am writing answer based on my own experience)
I suggest to read elf file in memory struct, make changes to flags and load process memory with your in-memory struct. This method will need less efford as compare to bug correction. To start, check file elf.c for elf, program header, section headers struct. you can read file header in your struct which should have three struct members for elf, program, section. start read in your struct from elf header. then read program header on offset given in elf header (iteratively for all program headers). In same way you can read all sections through section headers.
encapsulating 3 headers struct in your own struct also give you oppertunity to have extra needed data in your other struct member.