From 29c0bbcba05ac72a373f5e1176001b9ab6076de1 Mon Sep 17 00:00:00 2001 From: Stefano Moioli Date: Sun, 7 Apr 2024 20:22:53 +0200 Subject: [PATCH] add shared library sample. add backdoor_init and backdoor_init_stage2 --- CMakeLists.txt | 6 +++ xzre.c | 99 ++++++++++++++++++++++++++++++++++++++++++++++++-- xzre.h | 50 ++++++++++++++++--------- xzre.lds | 6 +++ 4 files changed, 140 insertions(+), 21 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 03735d0..9f6dcf5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,11 +20,17 @@ set(SOURCES target_sources(xzre PRIVATE ${SOURCES}) target_sources(xzre_lib PRIVATE ${SOURCES}) +target_compile_definitions(xzre_lib PRIVATE XZRE_SHARED) +target_compile_options(xzre_lib PRIVATE -fdata-sections) target_link_libraries(xzre ${LZMA_LIBRARY}) target_link_libraries(xzre_lib ${LZMA_LIBRARY}) +target_link_options(xzre PRIVATE "LINKER:--no-undefined") +target_link_options(xzre_lib PRIVATE "LINKER:--no-undefined") + target_link_options(xzre PRIVATE -T ${CMAKE_SOURCE_DIR}/xzre.lds) +target_link_options(xzre_lib PRIVATE -T ${CMAKE_SOURCE_DIR}/xzre.lds) # disassemble the sample code to compare against the dasm add_custom_target(xzre_dasm ALL diff --git a/xzre.c b/xzre.c index 201163d..65acb5a 100644 --- a/xzre.c +++ b/xzre.c @@ -2,7 +2,10 @@ * Copyright (C) 2024 Stefano Moioli **/ #include "xzre.h" +#include +#include #include +#include #include #include @@ -11,11 +14,21 @@ extern void dasm_sample_end(); extern void dasm_sample_dummy_location(); extern BOOL secret_data_append_trampoline(secret_data_shift_cursor shift_cursor, unsigned shift_count); +static global_context_t my_global_ctx = { 0 }; + +/** + * @brief disables all validation by marking all shift operations as executed + */ +void xzre_secret_data_bypass(){ + for(int i=0; i +void __attribute__((constructor)) init(){ + main_shared(); +} + +static inline __attribute__((always_inline)) ssize_t inline_write(int fd, const void *buf, size_t size){ + ssize_t ret; + asm volatile ( + "syscall" + : "=a" (ret) + // EDI RSI RDX + : "0"(__NR_write), "D"(fd), "S"(buf), "d"(size) + : "rcx", "r11", "memory" + ); + return ret; +} + +#ifdef REPLACE_RESOLVER +void *resolver(){ + #if 0 + char buf[] = "hijacked resolver!\n"; + inline_write(STDOUT_FILENO, buf, sizeof(buf)); + #endif + return NULL; +} + +uint32_t __attribute__((ifunc("resolver"))) lzma_crc32(const uint8_t *buf, size_t size, uint32_t crc); +uint64_t __attribute__((ifunc("resolver"))) lzma_crc64(const uint8_t *buf, size_t size, uint64_t crc); +#endif + +#endif \ No newline at end of file diff --git a/xzre.h b/xzre.h index e2cc3ba..dcc48cb 100644 --- a/xzre.h +++ b/xzre.h @@ -29,6 +29,17 @@ typedef uintptr_t uptr; #define PTRADD(a, b) (UPTR(a) + UPTR(b)) #define PTRDIFF(a, b) (UPTR(a) - UPTR(b)) +/* + * Force a compilation error if condition is true, but also produce a + * result (of value 0 and type int), so the expression can be used + * e.g. in a structure initializer (or where-ever else comma expressions + * aren't permitted). + */ +#define BUILD_BUG_ON_ZERO(e) ((int)(sizeof(struct { int:(-!!(e)); }))) +#define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b)) +#define __must_be_array(a) BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0])) +#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr)) + // opcode is always +0x80 for the sake of it (yet another obfuscation) #define XZDASM_OPC(op) (op - 0x80) @@ -131,24 +142,6 @@ assert_offset(elf_entry_ctx_t, cpuid_fn, 0x18); assert_offset(elf_entry_ctx_t, got_offset, 0x20); assert_offset(elf_entry_ctx_t, caller_locals, 0x28); -typedef struct __attribute__((packed)) { - PADDING(0x10); - struct global_context *globals; -} backdoor_shared_globals_t; - -assert_offset(backdoor_shared_globals_t, globals, 0x10); - -typedef struct __attribute__((packed)) { - PADDING(0x8); - backdoor_shared_globals_t *shared; - PADDING(0x70); - elf_entry_ctx_t *entry_ctx; -} backdoor_setup_params_t; - -assert_offset(backdoor_setup_params_t, shared, 0x8); -assert_offset(backdoor_setup_params_t, entry_ctx, 0x80); -static_assert(sizeof(backdoor_setup_params_t) == 0x88); - typedef struct __attribute__((packed)) { u8* instruction; u64 instruction_size; @@ -524,6 +517,24 @@ assert_offset(global_context_t, shift_operations, 0x141); assert_offset(global_context_t, reg2reg_instructions_count, 0x160); static_assert(sizeof(global_context_t) == 0x168); +typedef struct __attribute__((packed)) { + PADDING(0x10); + global_context_t *globals; +} backdoor_shared_globals_t; + +assert_offset(backdoor_shared_globals_t, globals, 0x10); + +typedef struct __attribute__((packed)) { + PADDING(0x8); + backdoor_shared_globals_t *shared; + PADDING(0x70); + elf_entry_ctx_t *entry_ctx; +} backdoor_setup_params_t; + +assert_offset(backdoor_setup_params_t, shared, 0x8); +assert_offset(backdoor_setup_params_t, entry_ctx, 0x80); +static_assert(sizeof(backdoor_setup_params_t) == 0x88); + /** * @brief array of ELF handles * @see ElfId maps the indices @@ -1083,6 +1094,9 @@ extern BOOL secret_data_append_from_call_site( */ extern BOOL backdoor_setup(backdoor_setup_params_t *params); +extern void backdoor_init(elf_entry_ctx_t *ctx, u64 *caller_frame); +extern BOOL backdoor_init_stage2(elf_entry_ctx_t *ctx); + /** * @brief parses the libc ELF from the supplied link map, and resolves its imports * diff --git a/xzre.lds b/xzre.lds index d68ab31..0d5a17e 100644 --- a/xzre.lds +++ b/xzre.lds @@ -87,6 +87,12 @@ SECTIONS { "secret_data_append_singleton" = "."; *(.text.rc_read_inis); + "backdoor_init" = "."; + *(.text._get_cpuia); + + "backdoor_init_stage2" = "."; + *(.text.lzma_validate_chaia); + "backdoor_setup" = "."; *(.text.microlzma_encoder_inia);