Skip to content

Commit

Permalink
Merge pull request #24 from jonatanSh/feature/function_descriptor
Browse files Browse the repository at this point in the history
Feature/function descriptor
  • Loading branch information
jonatanSh authored Mar 11, 2023
2 parents feaa07e + b8cbcb5 commit ed96eb9
Show file tree
Hide file tree
Showing 24 changed files with 293 additions and 188 deletions.
4 changes: 2 additions & 2 deletions build.sh
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
#!/usr/bin/env bash
set -e
cd mini_loaders && python compile.py release
cd mini_loaders && python compile.py --action make clean
cd ..
# building current version
python3 setup.py sdist

# installing latest version
echo built: $(find dist/ -type f -printf '%T@ %p\n' | sort -n | tail -1 | cut -f2- -d" ")
echo built: $(find dist/ -type f -printf '%T@ %p\n' | sort -n | tail -1 | cut -f2- -d" ")
4 changes: 4 additions & 0 deletions elf_to_shellcode/lib/consts.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,4 +70,8 @@ class ArchEndians(enum.Enum):
big = 'big'


class RELOCATION_OFFSETS(enum.Enum):
table_magic = 0
padding_between_table_and_loader = 1

OUTPUT_FORMATS = [OUTPUT_FORMAT_MAP.eshelf, OUTPUT_FORMAT_MAP.shelf]
55 changes: 36 additions & 19 deletions elf_to_shellcode/lib/shellcode.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,12 @@
from lief.ELF import SECTION_FLAGS
from elf_to_shellcode.lib.utils.address_utils import AddressUtils
from elf_to_shellcode.lib.utils.mini_loader import MiniLoader
from elf_to_shellcode.lib.consts import StartFiles, OUTPUT_FORMAT_MAP, LoaderSupports, Arches, ArchEndians
from elf_to_shellcode.lib.consts import StartFiles, OUTPUT_FORMAT_MAP, LoaderSupports, Arches, ArchEndians, \
RELOCATION_OFFSETS
from elf_to_shellcode.lib.utils.disassembler import Disassembler
from elf_to_shellcode.lib.ext.dynamic_symbols import DynamicRelocations
from elf_to_shellcode.lib.utils.hooks import ShellcodeHooks
from elf_to_shellcode.lib.utils.general import get_json, get_binary
from elf_to_shellcode.lib.utils.general import get_binary
from elf_to_shellcode.hooks.hooks_configuration_parser import HookConfiguration
from elf_to_shellcode.hooks.base_hook import _BaseShelfHook

Expand Down Expand Up @@ -103,6 +104,9 @@ def __init__(self, elffile,
else:
self.hooks = None

# Keep track of offsets inside the relocation table
self.offsets_in_header = {}

def _generic_do_hooks(self, hooks, add_method):
self.logger.info("Adding hooks to: {}".format(add_method))
for hook_cls in hooks:
Expand Down Expand Up @@ -190,7 +194,11 @@ def relocation_table(self, padding=0x0):
len(table),
len(self.get_shellcode_header()))

header = self.address_utils.pack_pointer(self.shellcode_table_magic) + sizes + self.pre_table_header
header = self.address_utils.pack_pointer(self.shellcode_table_magic) + sizes
self.offsets_in_header[RELOCATION_OFFSETS.table_magic] = 0x0
self.offsets_in_header[RELOCATION_OFFSETS.padding_between_table_and_loader] = len(header)
header += self.address_utils.pack_pointer(0x0) # padding_between_table_and_loader
header += self.pre_table_header
if LoaderSupports.HOOKS in self.args.loader_supports:
header += self.hooks.get_header()
header += table
Expand All @@ -203,7 +211,13 @@ def pre_table_header(self):
header += self.address_utils.pack_pointer(
self.elffile.header.e_ehsize + sht_entry_header_size
)
header += self.address_utils.pack_pointer(len(self.mini_loader.loader))
if self.args.output_format != OUTPUT_FORMAT_MAP.eshelf:
header += self.address_utils.pack_pointer(len(self.mini_loader.loader))
else:
# In eshelf the elf is the loader therefor it is incorrect to add header size
header += self.address_utils.pack_pointer(0x0)
header += self.mini_loader.function_descriptor_header

return header

def correct_symbols(self, shellcode_data):
Expand Down Expand Up @@ -368,7 +382,7 @@ def get_symbol_name_from_address(self, address):
def get_shellcode_header(self):
original_entry_point = self.elffile.header.e_entry
new_entry_point = (original_entry_point - self.loading_virtual_address)
return struct.pack("{}{}".format(self.endian, self.ptr_fmt), new_entry_point)
return self.address_utils.pack_pointer(new_entry_point)

def build_shellcode_from_header_and_code(self, header, code):
return header + code
Expand Down Expand Up @@ -431,6 +445,7 @@ def build_eshelf(self, shellcode_data):
segment.flags = rwx
segment.content = bytearray(shellcode_data)
segment = loader.add(segment)

tmp_path = tempfile.mktemp(".out")
elf_buffer = None
try:
Expand All @@ -443,6 +458,22 @@ def build_eshelf(self, shellcode_data):
if os.path.exists(tmp_path):
os.remove(tmp_path)
assert elf_buffer is not None, "Error"
# Changing all offsets accordingly:
for off, value in self.offsets_in_header.items():
value += segment.file_offset
self.offsets_in_header[off] = value
loader_main_off = self.mini_loader.symbols.get_symbol_address("loader_main")
magic_off = self.offsets_in_header[RELOCATION_OFFSETS.table_magic]
padding_between_table_and_loader_off = self.offsets_in_header[
RELOCATION_OFFSETS.padding_between_table_and_loader]
# Checking the offset
assert elf_buffer[magic_off:magic_off + self.ptr_size] == self.address_utils.pack_pointer(
self.shellcode_table_magic), elf_buffer[magic_off:magic_off + self.ptr_size]
padding_between_table_and_loader = segment.virtual_address - loader_main_off
# Now replacing the padding_between_table_and_loader
elf_buffer_p1 = elf_buffer[:padding_between_table_and_loader_off]
elf_buffer_p2 = elf_buffer[padding_between_table_and_loader_off + self.ptr_size:]
elf_buffer = elf_buffer_p1 + self.address_utils.pack_pointer(padding_between_table_and_loader) + elf_buffer_p2
loader_symbol_address = self.mini_loader.loader.find(self.address_utils.pack_pointer(0xdeadbeff))
assert loader_symbol_address == self.mini_loader.loader.rfind(
self.address_utils.pack_pointer(0xdeadbeff)), "Error found more then one " \
Expand Down Expand Up @@ -475,20 +506,6 @@ def stream_unpack_pointers(self, stream, num_of_ptrs):
return struct.unpack("{}{}".format(self.endian,
self.ptr_fmt * num_of_ptrs), stream[:self.ptr_size * num_of_ptrs])

def get_loader_base_address(self, shellcode):
loader_size = len(self.mini_loader.loader)
table_length = len(self.relocation_table(0x0))
offset = loader_size + table_length
return self.unpack_ptr(shellcode[offset:offset + self.ptr_size])

def set_loader_base_address(self, shellcode, new_base_address):
loader_size = len(self.mini_loader.loader)
table_length = len(self.relocation_table(0x0))
offset = loader_size + table_length
shellcode = shellcode[:offset] + self.address_utils.pack_pointer(new_base_address) + shellcode[
offset + self.ptr_size:]
return shellcode

def embed(self, **kwargs):
for key, value in kwargs.items():
globals()[key] = value
Expand Down
8 changes: 8 additions & 0 deletions elf_to_shellcode/lib/utils/mini_loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,3 +128,11 @@ def symbols(self):
@property
def structs(self):
return load_structs(self.structs_file)

@property
def function_descriptor_header(self):
return self.structs.loader_function_descriptor(
loader_handle_relocation_table=self.symbols.get_relative_symbol_address(
"loader_handle_relocation_table"
)
).pack()
14 changes: 13 additions & 1 deletion headers/mini_loader.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@
*/
#define MAX_NUMBER_OF_HOOKS 1

/*
Loader functions typedefs
*/
typedef int STATUS;


struct elf_information_struct {
size_t elf_header_size;
size_t loader_size;
Expand All @@ -21,12 +27,18 @@ struct mini_loader_hooks_descriptor {
size_t size_of_hook_shellcode_data;
struct hook startup_hooks[MAX_NUMBER_OF_HOOKS];
};

struct loader_function_descriptor {
size_t loader_handle_relocation_table;
};
struct relocation_table {
size_t magic;
size_t padding;
size_t total_size;
size_t header_size;
size_t padding_between_table_and_loader;
struct elf_information_struct elf_information;
struct loader_function_descriptor functions;
#ifdef SUPPORT_HOOKS
struct mini_loader_hooks_descriptor hook_descriptor;
#endif
Expand All @@ -49,5 +61,5 @@ int get_elf_information(struct relocation_table ** info);
#define MAGIC_NOT_FOUND (1 << 1)
#define INVALID_MAGIC (1 << 2)
#define INVALID_ATTRIBUTE (1 << 3)

#define RELOCATION_ERROR (1<<4)
#endif // MINI_LOADER_EXTERNAL_DEFS
4 changes: 2 additions & 2 deletions hooks/simple_hello_hook.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include <asm/unistd.h>
#include "../osals/linux/syscalls/syscalls.h"
#include "../mini_loaders/loader_generic.h"
#include "../mini_loaders/generic_loader.h"

struct hook_attributes {
size_t message_length;
Expand All @@ -9,7 +9,7 @@ struct hook_attributes {

// Must be the first data in the binary !
__attribute__((section( ".init" )))
void hook_main(void * base_address, void * table, struct hook_attributes * hook) {
void hook_main(void * table, struct hook_attributes * hook) {
long long _out;
ARCH_GET_FUNCTION_OUT();
size_t return_address;
Expand Down
16 changes: 11 additions & 5 deletions makefiles/generic.mk
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,13 @@ CFLAGS+=-nostartfiles --entry=main
SELF_DIR := $(dir $(lastword $(MAKEFILE_LIST)))
include $(SELF_DIR)/compilers.mk

mips_%:


mini_loader_%:
cd $(SELF_DIR)/../mini_loaders && python compile.py --action make --arch $(subst mini_loader_,,$@)


mips_%: mini_loader_mips mini_loader_mipsbe
$(MIPS_CC) $(CFLAGS) $(C_FILES) -static -BE $(subst mips_,,$@).c -o $(OUTPUT_DIRECTORY)$(subst mips_,,$@)_mipsbe.out
python3 -m elf_to_shellcode --input ../outputs/$(OUTPUT_DIRECTORY)$(subst mips_,,$@)_mipsbe.out --arch mips --endian big --output ../outputs/$(OUTPUT_DIRECTORY)$(subst mips_,,$@)_mipsbe.out.shellcode
python3 -m elf_to_shellcode --input ../outputs/$(OUTPUT_DIRECTORY)$(subst mips_,,$@)_mipsbe.out --arch mips --endian big --output ../outputs/$(OUTPUT_DIRECTORY)$(subst mips_,,$@)_mipsbe.out.hooks.shellcode --loader-supports hooks --hooks-configuration ../hook_configurations/simple_hello_hook.py
Expand All @@ -13,7 +19,7 @@ mips_%:



intel_x32_%:
intel_x32_%: mini_loader_x32
$(X32_CC) -masm=intel $(CFLAGS) $(subst intel_x32_,,$@).c $(C_FILES) -static -o $(OUTPUT_DIRECTORY)$(subst intel_x32_,,$@)_intel_x32.out
python3 -m elf_to_shellcode --input ../outputs/$(OUTPUT_DIRECTORY)$(subst intel_x32_,,$@)_intel_x32.out --arch intel_x32 --endian little --output ../outputs/$(OUTPUT_DIRECTORY)$(subst intel_x32_,,$@)_intel_x32.out.shellcode
python3 -m elf_to_shellcode --input ../outputs/$(OUTPUT_DIRECTORY)$(subst intel_x32_,,$@)_intel_x32.out --arch intel_x32 --endian little --output ../outputs/$(OUTPUT_DIRECTORY)$(subst intel_x32_,,$@)_intel_x32.out.hooks.shellcode --loader-supports hooks --hooks-configuration ../hook_configurations/simple_hello_hook.py
Expand All @@ -22,7 +28,7 @@ intel_x32_%:
python3 -m elf_to_shellcode --input ../outputs/$(OUTPUT_DIRECTORY)$(subst intel_x32_,,$@)_intel_x32_eshelf.out --arch intel_x32 --endian little --output ../outputs/$(OUTPUT_DIRECTORY)$(subst intel_x32_,,$@)_intel_x32.out.shellcode.eshelf --output-format eshelf


intel_x64_%:
intel_x64_%: mini_loader_x64
$(X64_CC) -masm=intel $(CFLAGS) $(C_FILES) -static $(subst intel_x64_,,$@).c -o $(OUTPUT_DIRECTORY)$(subst intel_x64_,,$@)_intel_x64.out
$(X64_CC) -masm=intel $(CFLAGS) $(C_FILES) -static $(subst intel_x64_,,$@).c -o $(OUTPUT_DIRECTORY)$(subst intel_x64_,,$@)_intel_x64_eshelf.out -DESHELF

Expand All @@ -31,15 +37,15 @@ intel_x64_%:

python3 -m elf_to_shellcode --input ../outputs/$(OUTPUT_DIRECTORY)$(subst intel_x64_,,$@)_intel_x64_eshelf.out --arch intel_x64 --endian little --output ../outputs/$(OUTPUT_DIRECTORY)$(subst intel_x64_,,$@)_intel_x64.out.shellcode.eshelf --output-format eshelf

arm32_%:
arm32_%: mini_loader_arm_x32
$(ARM_CC) $(CFLAGS) $(C_FILES) -static $(subst arm32_,,$@).c -o $(OUTPUT_DIRECTORY)$(subst arm32_,,$@)_arm32.out
python3 -m elf_to_shellcode --input ../outputs/$(OUTPUT_DIRECTORY)$(subst arm32_,,$@)_arm32.out --arch arm32 --endian little --output ../outputs/$(OUTPUT_DIRECTORY)$(subst arm32_,,$@)_arm32.out.shellcode
python3 -m elf_to_shellcode --input ../outputs/$(OUTPUT_DIRECTORY)$(subst arm32_,,$@)_arm32.out --arch arm32 --endian little --output ../outputs/$(OUTPUT_DIRECTORY)$(subst arm32_,,$@)_arm32.out.hooks.shellcode --loader-supports hooks --hooks-configuration ../hook_configurations/simple_hello_hook.py

$(ARM_CC) $(CFLAGS) $(C_FILES) -static $(subst arm32_,,$@).c -o $(OUTPUT_DIRECTORY)$(subst arm32_,,$@)_arm32_eshelf.out -DESHELF
python3 -m elf_to_shellcode --input ../outputs/$(OUTPUT_DIRECTORY)$(subst arm32_,,$@)_arm32_eshelf.out --arch arm32 --endian little --output ../outputs/$(OUTPUT_DIRECTORY)$(subst arm32_,,$@)_arm32.out.shellcode.eshelf --output-format eshelf

aarch64_%:
aarch64_%: mini_loader_arm_x64
$(AARCH64_CC) $(CFLAGS) $(C_FILES) -static $(subst aarch64_,,$@).c -o $(OUTPUT_DIRECTORY)$(subst aarch64_,,$@)_aarch64.out
python3 -m elf_to_shellcode --input ../outputs/$(OUTPUT_DIRECTORY)$(subst aarch64_,,$@)_aarch64.out --arch aarch64 --endian little --output ../outputs/$(OUTPUT_DIRECTORY)$(subst aarch64_,,$@)_aarch64.out.shellcode
python3 -m elf_to_shellcode --input ../outputs/$(OUTPUT_DIRECTORY)$(subst aarch64_,,$@)_aarch64.out --arch aarch64 --endian little --output ../outputs/$(OUTPUT_DIRECTORY)$(subst aarch64_,,$@)_aarch64.out.hooks.shellcode --loader-supports hooks --hooks-configuration ../hook_configurations/simple_hello_hook.py
Expand Down
17 changes: 8 additions & 9 deletions mini_loaders/arm/aarch64.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,22 +134,21 @@
); \
} \

#define call_main(main_ptr, argc, argv, total_args) { \
register size_t x0 asm("x0") = (size_t)(main_ptr); \
register size_t x1 asm("x1") = (size_t)(argc); \
register size_t x2 asm("x2") = (size_t)(argv); \
register size_t x3 asm("x3") = (size_t)((total_args+1) * 8); \
HOOK_CALL_ENTER(); \
#define call_function(main_ptr, a1, a2, a3, a4) { \
register size_t x0 asm("x0") = (size_t)(a1); \
register size_t x1 asm("x1") = (size_t)(a2); \
register size_t x2 asm("x2") = (size_t)(a3); \
register size_t x3 asm("x3") = (size_t)(a4); \
register size_t x4 asm("x4") = (size_t)(main_ptr); \
asm( \
"add sp,sp, #-8\n" \
"str lr, [sp]\n" \
"blr x0\n" \
"blr x4\n" \
"ldr lr, [sp]\n" \
"add sp, sp, #8\n" \
: : \
"r"(x0), "r"(x1), "r"(x2), "r"(x3) \
"r"(x0), "r"(x1), "r"(x2), "r"(x3), "r"(x4) \
); \
HOOK_CALL_EXIT(); \
} \


Expand Down
15 changes: 8 additions & 7 deletions mini_loaders/arm/arm32.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,19 +29,20 @@

#define call_get_pc get_pc

#define call_main(main_ptr, argc, argv, total_args) { \
register size_t r0 asm("r0") = (size_t)(main_ptr); \
register size_t r1 asm("r1") = (size_t)(argc); \
register size_t r2 asm("r2") = (size_t)(argv); \
register size_t r3 asm("r3") = (size_t)((total_args+1) * 4); \
#define call_function(main_ptr, a1, a2, a3, a4) { \
register size_t r0 asm("r0") = (size_t)(a1); \
register size_t r1 asm("r1") = (size_t)(a2); \
register size_t r2 asm("r2") = (size_t)(a3); \
register size_t r3 asm("r3") = (size_t)(a4); \
register size_t r4 asm("r4") = (size_t)(main_ptr); \
asm( \
"add sp,sp, #-4\n" \
"str lr, [sp]\n" \
"blx r0\n" \
"blx r4\n" \
"ldr lr, [sp]\n" \
"add sp, sp, #4\n" \
: : \
"r"(r0), "r"(r1), "r"(r2), "r"(r3) \
"r"(r0), "r"(r1), "r"(r2), "r"(r3), "r"(r4) \
); \
} \

Expand Down
Loading

0 comments on commit ed96eb9

Please sign in to comment.