Closed elfmaster closed 1 year ago
Finished. We successfully update the relocation record that will patch the indirect xref for us via ld-linux rtld.
Essentially Shiva manipulates the hot-patching behavior of ld-linux.so by updating certain rela.dyn relocation records that are necessary to re-link xrefs to patched variables.
Indirect xrefs are now linked for .bss variables. Closing.
Feature Description
In the original Shiva implementaiton we didn't include proper support for transforming the uninitialized variable data from an ET_REL object into the .bss area setup in memory by the Shiva module loader.
Details
A Shiva patch module can now properly load and store from .bss variables, however the external linking to patch the executable so that it references an interposed .bss variable will fail.
ELF relocatable objects store .bss variables as
STT_OBJECT/STB_GLOBAL
as is common with static data, but it has asymbol->st_shndx
value ofSHN_COMMON
, which means this global symbol is apart of a common block of uninitialized dataFurthermore the
symbol->st_value
, as it pertains to ELF ET_REL files, will not contain the offset of the .bss variable. Instead it contains the size of the variable, which is reduntant sincesymbol->st_size
already gives us the size. The size of each variable is enough for us to calculate the offsets necessary to store them in a memory mapped .bss area within the patch module.Partially fixed as of 12/8/22
ELF program we are patching:
modules/patches/symbol_interposing4/test_function_patch
patch object:modules/patches/symbol_interposing4/fpatch4.o
The patch replaces function
foo()
and writes a different value to theint bss_var;
When
foo()
printsbss_var
the value is 31337. Which is correct, however the XREF frombar()
tobss_var
is not inserted. We don't yet support the external linking code to identify the XREF, thereforebar()
still references the originalbss_var
.Support for indirect XREF's (i.e. via GOT)
We do not support this:
Or the relaxed version of the code.... (i.e. no code relaxation)
R_AARCH64_RELATIVE relocations and linker chaining in PIE executable
The xref instruction sequences above access a given variable, such as one in the .bss, by indirectly accessing it. The address to the variable is stored in a read-only table at the end of the function, within the .text section. At runtime the ld-linux.so applies the symbol value of
bss_var
to the base address of the executabe, and patches the read-only table with this value. This read-only table can be referenced for indirect variable access.The solution, therefore, is for Shiva to modify the
rela.dyn
relocation entries that patches various parts of .the .text section with the address to the variable we are patching and thus re-linking.We search for the
rela.dyn
entry of typeR_AARCH64_RELATIVE
that has anr_addend
value that is equal to the symbol value of the variable we are patching within the executable. i.e. if symbolbss_var
had an address of 0x11014 then we'd search for the relative relocation's who'sr_addend
is that value.We would then modify the to the
r_addend
to be the negative offset frombss_var
value. i.e. ifbss_var
is at 0x6001014, and the base of the executable is 0x8000000. We would compute:At runtime Shiva patches the correct relative relocations as shown in the psuedo-code snippet above. As a result the ld-linux.so RTLD will patch relocation unit with the correct offset to the
bss_var
that exists in the loaded patch.This is a great example of Cross relocation