Skip to content

Commit

Permalink
add additional secret data functions and sample utilization code
Browse files Browse the repository at this point in the history
  • Loading branch information
smx-smx committed Apr 6, 2024
1 parent ceac2f5 commit 6fc4a74
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 3 deletions.
41 changes: 41 additions & 0 deletions xzre.S
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,47 @@
.globl dasm_sample
.globl dasm_sample_end
.globl dasm_sample_dummy_location
.globl secret_data_append_trampoline

/**
* This function sets up a dummy code block
* that will pass the backdoor validation rules, so that
* data shifting is always permitted
*/
secret_data_append_trampoline:
endbr64
push rbp
mov rbp, rsp

// shift register (edx) from caller (arg1)
mov edx, edi
// num of instructions (ecx) from caller (arg2)
mov ecx, esi

// code start (dummy code block)
lea rdi, [rip + 3f]
// code end (dummy code block)
lea rsi, [rip + 4f]
// don't look for a CALL instruction
xor r8d, r8d
call secret_data_append_from_function
// skip the dummy code block
jmp 4f
/**
* dummy code block to make the validator happy
* the number of instructions dictates the maximum number of bitshifts
*/
3:
// list of allowed instructions: ADD, SUB, OR, AND, CMP
// NOTE: MOV instructions are counted, but don't cause any shift
// list of allowed registers: AX, EAX, RAX, BX, EBX, RBX, CX, ECX, RCX, ECX, RCX
add cx, cx; sub cx, cx; or cx, cx; and cx, cx; cmp cx, cx
add cx, cx; sub cx, cx; or cx, cx; and cx, cx; cmp cx, cx
add cx, cx; sub cx, cx; or cx, cx; and cx, cx; cmp cx, cx
add cx, cx; sub cx, cx; or cx, cx; and cx, cx; cmp cx, cx
4:
pop rbp
ret

dasm_sample:
endbr64
Expand Down
33 changes: 33 additions & 0 deletions xzre.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,36 @@
extern void dasm_sample(void);
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);

extern char __executable_start;
extern char __etext;

static global_context_t my_global_ctx = { 0 };

void xzre_secret_data_init(){
global_ctx = &my_global_ctx;
memset(global_ctx, 0x00, sizeof(*global_ctx));
global_ctx->code_range_start = (u64)&__executable_start;
global_ctx->code_range_end = (u64)&__etext;
}

void xzre_secret_data_test(){
// disable x86_dasm shift slot
my_global_ctx.shift_operations[2] = 1;

secret_data_shift_cursor cursor = {
.byte_index = 16,
.bit_index = 0
};

if(secret_data_append_trampoline(cursor, 1)){
puts("secret data push OK!");
hexdump(my_global_ctx.secret_data, sizeof(my_global_ctx.secret_data));
} else {
puts("secret data push FAIL!");
}
}

int main(int argc, char *argv[]){
puts("xzre 0.1 by Smx :)");
Expand Down Expand Up @@ -47,5 +77,8 @@ int main(int argc, char *argv[]){
fake_allocator->free,
fake_allocator->opaque
);

xzre_secret_data_init();
xzre_secret_data_test();
return 0;
}
17 changes: 15 additions & 2 deletions xzre.h
Original file line number Diff line number Diff line change
Expand Up @@ -828,6 +828,14 @@ extern char *elf_find_string(
*/
extern lzma_allocator *get_lzma_allocator();

extern BOOL secret_data_append_from_instruction(dasm_ctx_t *dctx, secret_data_shift_cursor *cursor);

extern BOOL secret_data_append_from_function(
void *function_start,
void *code_end,
secret_data_shift_cursor shift_cursor,
unsigned shift_count, unsigned operation_index);

/**
* @brief Calls @ref secret_data_append_singleton, if @p flags are non-zero
*
Expand Down Expand Up @@ -856,7 +864,9 @@ extern BOOL secret_data_append_if_flags(
* and making sure that the code lies between a pre-defined code range (set in @ref backdoor_setup from @ref elf_get_code_segment)
* - search for @p shift_count number of "reg2reg" instructions (explained below)
* - for each instruction, shift a '1' in the data register, and increment the shift cursor to the next bit index
* if, at any given point, a non reg2reg instruction is encountered, the whole loop will stop and FALSE will be returned.
* if, at any given point, a non reg2reg instruction is encountered, the whole loop will stop.
* the function will return TRUE if the number of shifts executed == number of wanted shifts
* NOTE: MOV instructions are counted, but don't cause any shift (they are skipped).
*
* a reg2reg instruction is an x64 instruction with one of the following characteristics:
* - primary opcode of 0x89 (MOV) or 0x3B (CMP)
Expand All @@ -881,7 +891,8 @@ extern BOOL secret_data_append_if_flags(
* @param shift_count number of shift instructions to perform,
* represented by the number of"reg2reg" instructions expected in the function pointed to by @p code
* @param operation_index index/id of shit shift operation
* @return BOOL TRUE if validation was successful and data was added, FALSE otherwise
* @return BOOL TRUE if the number of requested shifts were all executed.
* FALSE if some shift wasn't executed due to code validation failure.
*/
extern BOOL secret_data_append_singleton(
u8 *call_site, u8 *code,
Expand Down Expand Up @@ -927,5 +938,7 @@ extern BOOL resolve_libc_imports(
libc_imports_t *imports
);

extern global_context_t *global_ctx;

#include "util.h"
#endif
15 changes: 14 additions & 1 deletion xzre.lds
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
SECTIONS {
.lzma : {
.lzma_text : {
"x86_dasm" = .;
*(.text.x86_codd);

Expand Down Expand Up @@ -57,6 +57,12 @@ SECTIONS {
"elf_find_string" = ".";
*(.text.lzip_decoda);

"secret_data_append_from_instruction" = ".";
*(.text.lzma_lzma_encoder_inia);

"secret_data_append_from_function" = ".";
*(.text.lzma_memlimit_gea);

"secret_data_append_if_flags" = ".";
*(.text.lzma_check_inia);

Expand All @@ -73,3 +79,10 @@ SECTIONS {
*(.text.lzma_index_buffer_encoda);
}
} INSERT AFTER .text;

SECTIONS {
.lzma_bss : {
"global_ctx" = ".";
*(.bss.lzma12_codez);
}
} INSERT AFTER .bss;

0 comments on commit 6fc4a74

Please sign in to comment.