Trouble using Libelf/Elfio libraries : ELF not executable anymore - add

I'm using Libelf and Elfio to try and add a new section to ELF files. I would like it to be executable, just like .text.
This is my problem : with Libelf, as soon as I load (elf_begin()), update (elf_update()) and release (elf_end()) my ELF, it stops to be executable (seg fault when launching). readelf -S displays the sections but returns also the error :
readelf: Warning: the .dynamic section is not contained within the dynamic segment
I didn't find any function in Libelf to "add" the .dynamic section to the DYNAMIC segment.
But I can do that with Elfio (with the segment->add_section_index() function), but then I have to manually add every other section to every other segment, as Elfio seems to overwrite them when loading the ELF.
Has anyone any experience with those libraries ?
My final goal is to be able to create a new executable section in the ELF, and modify its entry point to jump and execute directly that new section, in order to create a packer.

Libelf does not manage the segments (i. e. the program header entries) of an executable ELF file. It does, however, by default re-layout the sections when you call elf_update().
After the re-layout, the program header entries will most probably contain obsolete offsets.
The loader will then try (or refuse) to load sections from file offsets that were only correct before the edit.
Thus the error message: the .dynamic section is now at another offset in the file, and the loader notices that it is not in the DYNAMIC segment anymore.
You can tell Libelf that you are responsible for the section layout by calling elf_flagelf(elf, ELF_C_SET, ELF_F_LAYOUT).
But then again, adding a new section will not be so easy anymore...

Related

Modifying contents of data section in ELF

I have a program that initializes an array to 0. I have pointed the value of that array to a custom section using: __attribute__((section(".mysection")))
struct my_struct my_array[1] __attribute__((section(".mysection"))) = {
{0, 0},
};
The above is only so that we have a default and the linker marks the section as loadable and also includes it in the appropriate section list.
Now I wish to edit the generated ELF and modify the contents of that struct as I choose. I already have a binary file which contains the contents that I wish to have for that section.
I tried using --remove-section and --add-section but could not force the new section to be part of the sections.
Not sure if --update-section would help here, but the microcontroller I have doesn't have --update-section in objcopy and when I try the public version of it, that says that it doesnt support the bfd target.
FWIW, the ELF doesnt use any relocatable addresses etc. All addresses are physical addresses in memory.
Is there a way to achieve this? I just need to replace the contents of the section and modify its length.
In case other, more simple ways, are not suitable, you may implement such functionality by using ELFIO library.

Linux ELF shared library issue

Currently I am working with ELF files and trying to deal with loading SO files. I am trying to "forcibly" link a new (a fake one, without actual calls to the code) SO dependency into executable file. To do that, I modified the .dynstr section contents (created a new section, filled it with the new contents, and resolved all sh_link fileds of Elf64_Shdr entries). Also I modified the .dynamic section (it has more than one null entry, so I modified one) to have DT_NEEDED type with linkage to the needed third-party SO name.
My small test app, being analyzed, appears to be fine (as readelf with -d option, or objdump -p, show). Nevertheless, when trying to run the application, it tells:
error while loading shared libraries: ��oU: cannot open shared object file: No such file or directory
Every time running, the name is different. This makes me think some addresses in the ELF loaded are invalid.
I understand that this way of patching is highly error-prone, but I am interested anyway. So, my question is: are there any ELF tools (like gdb or strace), which can debug image loading process (i.e. which can tell one what is wrong before entry point is hit)? Or are there any switches or options, which can help with this situation?
I have tried things like strace -d, but it would not tell anything interesting.
You do not mention patching DT_STRTAB and DT_STRSZ. These tags control how the dynamic loader locates the dynamic string table. The section headers are only used by the link editor, not at run time.
First of all, I did not manage to find any possibility to deal with sane debugging. My solution came in just because of hard-way raw ELF file hex bytes manual analysis.
My conception in general was right (forgot to mention the DT_STRTAB and DT_STRSZ modification though, thanks to Florian Weimer for reminding of it). The patchelf util (see in the postscriptum below) made me sure I am generally right.
The thing is: when you add a new section to the end, make sure you put data to the PLT right way. To add a new ".dynstr" section, I had to overwrite an auxiliary note segment (Elf**_Phdr::p_type == PT_NOTE) with a new segment, right for the new ".dynstr" section data. Not yet sure if such overwriting might cause some error.
It turned out that I put a raw ELF file ('offline') offset, but had to put this data RVA in the running image (after loading ELF into memory by the system loader, 'online'). Once I fixed it, the ELF started to work properly.
P.S. found a somewhat similar question: How can I change the filename of a shared library after building a program that depends on it? (a useful util for the same purpose I need, patchelf, is mentioned there; patchelf is available under Debian via APT, it is a nice tool for the stated purpose)

GNU linker script: Selective Run address(VMA) allocation

Iam writing a GNU linker script file and need a nudge in the right direction for the following problem.
The device for which the linker script is being created has flash for hosting text and rodata. It has also SRAM for hosting Data and BSS.
I have created variants of linker script which has:
- CODE and RODATA loaded into flash while DATA and BSS are in SRAM
- CODE, RODATA, DATA and BSS in SRAM
These work fine.
I must now create a variant of the linker script which has a majority of TEXT in flash. But certain routines with names ending with a well known suffix are to be loaded into SRAM.
For example, I would like Func1IRAMCode() and Func2__IRAMCode() to be loaded into SRAM section while every other function that does not have a IRAMCode suffix must be loaded into flash.
For portability reasons, I wont attach attribute(section) to these SRAM functions.
Here is where am stumbling.
The text section has the following rule:
.text :
{
*(.text .text.* .gnu.linkonce.t.*);
} > FLASH
.Misc :
{
* (.text.*IRAMCode);
} > SRAM
.data and .bss sections are defined seperately.
Problem is that *IRAMCode() are getting assigned flash addresses.
What is the syntax to exclude *IRAMCode from text section?
How have you solved this problem in your projects?
A way to do this, is to put your functions in another section (for example .sram.text ), to do this, use the section attribute of gcc for each specific function ( ex : __attribute__ (( section ".sram.text")) .
Thus, it will be very easy to wildcard the desired section to the SRAM.

dlopen() .so fails to find symbols in a stripped executable

I have an executable in linux - exe
This executable has some functions in it, that are used throughout the code:
sendMsg
debugPrint
I then want to dynamically load a .so that provides extra functionality to my executable.
In this shared library I include the headers for sendMsg and debugPrint.
I load this shared library with dlopen() and create an API with dlsym().
However, at dlopen() I use RTLD_NOW to resolve all symbols at load time.
It fails stating that it cannot find sendMsg symbol.
This symbol must be in the executable as the sendMsg.c is compiled in there.
However, my executable is stripped by the make process. As such, it would make sense that dlopen cannot find the symbol.
How can i solve this situation?
I could build the shared functions into a static library and link that static library into both exe and the .so. This would increase code size :(
I could remove the stripping of the exe so the symbols can be found
Do some compile time linking magic that I don't know about so the .so knows where the symbols are in exe
man ld:
-E
--export-dynamic
--no-export-dynamic
When creating a dynamically linked executable, using the -E option or the --export-dynamic option causes the linker to add all symbols to the dynamic symbol table. The
dynamic symbol table is the set of symbols which are visible from dynamic objects at run time.
If you do not use either of these options (or use the --no-export-dynamic option to restore the default behavior), the dynamic symbol table will normally contain only those
symbols which are referenced by some dynamic object mentioned in the link.
If you use "dlopen" to load a dynamic object which needs to refer back to the symbols defined by the program, rather than some other dynamic object, then you will probably
need to use this option when linking the program itself.
You can also use the dynamic list to control what symbols should be added to the dynamic symbol table if the output format supports it. See the description of
--dynamic-list.
Note that this option is specific to ELF targeted ports. PE targets support a similar function to export all symbols from a DLL or EXE; see the description of
--export-all-symbols below.
You can also pass the -rdynamic option to gcc/g++ (as noted int the comment). Depending on how you setup your make script, this will be convenient

sprof "PLTREL not found error"

I'm trying to profile our shared library, but whenever I have the environmental variable LD_PROFILE set, I get "PLTREL not found in object ". What gives? Is there some sort of linker flag I'm missing or what? There seems to be no information about this on the internets. The man page for sprof is about 10 words long.
According to an unanswered question on Google Groups, it looks like you aren't the very first person with this problem.
I think pltrel means plt-relative; in some ELF design notes,
There is a .plt section created in the code segment, which is an array of function stubs used to handle the run-time resolution of library calls.
And here's yet a little more:
The next section I want to mention is the .plt section. This contains the jump table that is used when we call functions in the shared library. By default the .plt entries are all initialized by the linker not to point to the correct target functions, but instead to point to the dynamic loader itself. Thus, the first time you call any given function, the dynamic loader looks up the function and fixes the target of the .plt so that the next time this .plt slot is used we call the correct function. After making this change, the dynamic loader calls the function itself.
Sounds to me like there's an issue with how the shared library was compiled or assembled. Hopefully a few more searches to elf PLT section gets you on the right track.
Found this that may be relevante for you:
Known issues with LD_AUDIT
➢ LD_AUDIT does not work with Shared Libraries with no code in them.
➢ Example ICU-4.0 “libicudata.so”
➢ Error: “no PLTREL found in object /usr/lib/libicudata.so.40”
➢ Recompile after patching libicudata by sed'ing -nostdlib etc away sed -i --
"s/-nodefaultlibs -nostdlib//" config/mh-linux
It seems the same applies for LD_PROFILE

Resources