bahorn / skp

Static Kernel Patching in 2024. A hop, SKP and a jmp to a patched-in module!
GNU General Public License v2.0
0 stars 0 forks source link

Simplify the linking process for `runtime`, moving more to patching time. #2

Open bahorn opened 2 months ago

bahorn commented 2 months ago

src/runtime uses a very adhoc aproach for building the payload:

I think I need to replace badlink with something better, and just compile each stage to ELFs or something and do another step to merge them together in a way that they can be modified at patching time.

The end goal is to be able to merge everything into a single python script / executable.

What we are using scripts for right now:

In src/runtime/stage1-uefi-bootservices-hook/Makefile:

        -D _initcall_offset=`python3 ../../scripts/find_initcall.py $(SYMBOLS)` \
        -D _startup_64=`python3 ../../scripts/find_symbol.py $(SYMBOLS) startup_64` \
        -DLOAD_OFFSET=$(LOAD_OFFSET) \

These are only used in the direct patching approach (avoiding the runtime hook). Unsure if I want to remove direct patching as I like the option in newer kernels to apply it.

In src/runtime/stage2/Makefile:

        -D __efi_call=`python3 ../../scripts/find_symbol.py $(SYMBOLS) __efi_call` \
        -D _stage1_offset=$(LOAD_OFFSET) \
        -D _startup_64_offset=`python3 ../../scripts/find_symbol.py $(SYMBOLS) startup_64` \
        -D runtime_hook_len=`wc -c < ../kshelf-loader/runtime_hook.bin` \
        -D _initcall_offset=`python3 ../../scripts/find_initcall.py $(SYMBOLS)` \
        -D __preempt_count=`python3 ../../scripts/find_preempt_count.py $(SYMBOLS)` \

In src/runtime/kshelf-loader/Makefile:

        -D KALLSYMS_OFFSET=`python3 ../../scripts/find_symbol.py $(SYMBOLS) kallsyms_lookup_name` \

Used to work out the relative offset from .text, which stage2 passes to it via an argument.

In src/skp.sh:

# compile the payload
PAYLOAD=$REAL_PAYLOAD \
    SYMBOLS=$INTERMEDIATE/kallsyms \
    UEFI_DIRECT_PATCH=true \
    LOAD_OFFSET=`python3 ./src/scripts/find_space.py $INTERMEDIATE/curr.elf` \
    make -C ./src/runtime

To use a offset to place the payload.

What is badlink being used for

Badlink kinda sucks and only has 6 character symbol names...

bahorn commented 2 months ago

I merged some partial work where i got stage2 and stage1-uefi-bootservices-hook merged together as two object files that get linked together, and removed the one symbol we needed to pass to the kshelf-loader during build.

The kshelf-loader can't generally be linked in as another .o, but not really a big deal.

Main problem I have now is I want to define all the symbols stage2 and stage1-uefi-bootservices-hook and just search+replace them into the binaries, but that doesn't seem simple to do. Parsing relocations and manually resolving them? Really want to generate a R_X86_64_COPY or something.

You can't just define them in a seperate .o and link against that, as we copy stage2 into various locations.

bahorn commented 2 months ago

This is also a blocker on making the testing script parallel, as a unique runtime needs to be built for each kernel image.