Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion kernel/include/cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ enum dma_data_direction
static inline uint32_t current_el(void)
{
uint32_t el;
asm volatile("mrs %w0, CurrentEL" : "=r"(el));
asm volatile("mrs %0, CurrentEL" : "=r"(el));
return el >> 2;
}

Expand Down
133 changes: 121 additions & 12 deletions kernel/include/hook.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,12 @@
typedef enum
{
HOOK_NO_ERR = 0,
HOOK_BAD_ADDRESS = 4089,
HOOK_NO_MEM = 4090,
HOOK_BAD_RELO = 4091,
HOOK_TRANSIT_NO_MEM = 4092,
HOOK_CHAIN_FULL = 4093,
HOOK_NOT_HOOK = 4094,
HOOK_INST_BUSY = 4095,
HOOK_BAD_ADDRESS = 4095,
HOOK_DUPLICATED = 4094,
HOOK_NO_MEM = 4093,
HOOK_BAD_RELO = 4092,
HOOK_TRANSIT_NO_MEM = 4091,
HOOK_CHAIN_FULL = 4090,
} hook_err_t;

enum hook_type
Expand All @@ -38,7 +37,7 @@ typedef int8_t chain_item_state;
#define CHAIN_ITEM_STATE_BUSY 2

#define local_offsetof(TYPE, MEMBER) ((size_t) & ((TYPE *)0)->MEMBER)
#define local_container_of(ptr, type, member) ({ (type *)((char *)(ptr)-local_offsetof(type, member)); })
#define local_container_of(ptr, type, member) ({ (type *)((char *)(ptr) - local_offsetof(type, member)); })

#define HOOK_MEM_REGION_NUM 4
#define TRAMPOLINE_NUM 4
Expand All @@ -50,6 +49,9 @@ typedef int8_t chain_item_state;
#define FP_HOOK_CHAIN_NUM 0x20

#define ARM64_NOP 0xd503201f
#define ARM64_BTI_C 0xd503245f
#define ARM64_BTI_J 0xd503249f
#define ARM64_BTI_JC 0xd50324df

typedef struct
{
Expand All @@ -59,8 +61,8 @@ typedef struct
uint64_t replace_addr;
uint64_t relo_addr;
// out
int32_t tramp_insts_len;
int32_t relo_insts_len;
int32_t tramp_insts_num;
int32_t relo_insts_num;
uint32_t origin_insts[TRAMPOLINE_NUM] __attribute__((aligned(8)));
uint32_t tramp_insts[TRAMPOLINE_NUM] __attribute__((aligned(8)));
uint32_t relo_insts[RELOCATE_INST_NUM] __attribute__((aligned(8)));
Expand Down Expand Up @@ -242,32 +244,139 @@ int32_t ret_absolute(uint32_t *buf, uint64_t addr);
hook_err_t hook_prepare(hook_t *hook);
void hook_install(hook_t *hook);
void hook_uninstall(hook_t *hook);

/**
* @brief Inline-hook function which address is @param func with function @param replace,
* after hook, original @param func is backuped in @param backup.
*
* @note If multiple modules hook this function simultaneously,
* it will cause abnormality when unload the modules. Please use hook_wrap instead
*
* @see hook_wrap
*
* @param func
* @param replace
* @param backup
* @return hook_err_t
*/
hook_err_t hook(void *func, void *replace, void **backup);

/**
* @brief unhook of hooked function
*
* @param func
*/
void unhook(void *func);

// todo: hook priority
/**
* @brief
*
* @param chain
* @param before
* @param after
* @param udata
* @return hook_err_t
*/
hook_err_t hook_chain_add(hook_chain_t *chain, void *before, void *after, void *udata);
/**
* @brief
*
* @param chain
* @param before
* @param after
*/
void hook_chain_remove(hook_chain_t *chain, void *before, void *after);

/**
* @brief Wrap a function with before and after function.
* The same function can do hook and unhook multiple times
*
* @see hook_chain0_callback
* @see hook_fargs0_t
*
* @param func The address of function
* @param argno The number of method arguments
* @param before This function will be called before hooked function,
* the type of before is hook_chain{n}_callback which n is equal to argno.
* @param after The same as before but will be call after hooked function
* @param udata
* @return hook_err_t
*/
hook_err_t hook_wrap(void *func, int32_t argno, void *before, void *after, void *udata);

/**
* @brief
*
* @param func
* @param before
* @param after
* @param remove
*/
void hook_unwrap_remove(void *func, void *before, void *after, int remove);

static inline void hook_unwrap(void *func, void *before, void *after)
{
return hook_unwrap_remove(func, before, after, 1);
}

static inline void *hook_chain_origin_func(void *hook_args)
/**
* @param hook_args
*/
static inline void *wrap_get_origin_func(void *hook_args)
{
hook_fargs0_t *args = (hook_fargs0_t *)hook_args;
hook_chain_t *chain = (hook_chain_t *)args->chain;
return (void *)chain->hook.relo_addr;
}

/**
* @brief
*
* @param fp_addr
* @param replace
* @param backup
*/
void fp_hook(uintptr_t fp_addr, void *replace, void **backup);

/**
* @brief
*
* @param fp_addr
* @param backup
*/
void fp_unhook(uintptr_t fp_addr, void *backup);

/**
* @brief
*
* @param fp_addr
* @param argno
* @param before
* @param after
* @param udata
* @return hook_err_t
*/
hook_err_t fp_hook_wrap(uintptr_t fp_addr, int32_t argno, void *before, void *after, void *udata);

/**
* @brief
*
* @param fp_addr
* @param before
* @param after
*/
void fp_hook_unwrap(uintptr_t fp_addr, void *before, void *after);

/**
*
*/
static inline void *fp_get_origin_func(void *hook_args)
{
hook_fargs0_t *args = (hook_fargs0_t *)hook_args;
fp_hook_chain_t *chain = (fp_hook_chain_t *)args->chain;
return (void *)chain->hook.origin_fp;
}

static inline void hook_chain_install(hook_chain_t *chain)
{
hook_install(&chain->hook);
Expand Down
13 changes: 13 additions & 0 deletions kernel/include/hotpatch.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Copyright (C) 2024 bmax121. All Rights Reserved.
*/

#ifndef _KP_HOTPATCH_H_
#define _KP_HOTPATCH_H_

#include <stdint.h>

int kp_insn_patch_text(void *addrs[], uint32_t insn[], int cnt);

#endif
2 changes: 0 additions & 2 deletions kernel/include/kallsyms.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,5 @@ struct module;

extern int (*kallsyms_on_each_symbol)(int (*fn)(void *, const char *, struct module *, unsigned long), void *data);
extern unsigned long (*kallsyms_lookup_name)(const char *name);
extern int (*lookup_symbol_attrs)(unsigned long addr, unsigned long *size, unsigned long *offset, char *modname,
char *name);

#endif
9 changes: 5 additions & 4 deletions kernel/include/predata.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,15 @@
#include <ktypes.h>
#include <preset.h>

extern struct patch_config *patch_config;
extern setup_header_t *setup_header;

int auth_superkey(const char *key);
void reset_superkey(const char *key);
void enable_auth_root_key(int skip_hash);
void enable_auth_root_key(bool enable);
const char *get_superkey();

const char *get_build_time();
uint64_t rand_next();
uint64_t get_build_config();
struct patch_symbol *get_preset_patch_sym();

int on_each_extra_item(int (*callback)(const patch_extra_item_t *extra, const char *arg, const void *data, void *udata),
void *udata);
Expand Down
37 changes: 17 additions & 20 deletions kernel/include/preset.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
#define COMPILE_TIME_LEN 0x18
#define MAP_MAX_SIZE 0xa00
#define HOOK_ALLOC_SIZE (1 << 20)
#define MEMORY_ROX_SIZE (2 << 20)
#define MEMORY_ROX_SIZE (4 << 20)
#define MEMORY_RW_SIZE (2 << 20)
#define MAP_ALIGN 0x10

Expand All @@ -30,7 +30,7 @@
#define MAP_SYMBOL_NUM (5)
#define MAP_SYMBOL_SIZE (MAP_SYMBOL_NUM * 8)

#define PATCH_SYMBOL_LEN (512)
#define PATCH_CONFIG_LEN (512)

#define ADDITIONAL_LEN (512)

Expand Down Expand Up @@ -98,15 +98,19 @@ _Static_assert(sizeof(map_symbol_t) == MAP_SYMBOL_SIZE, "sizeof map_symbol_t mis
#endif

#ifndef __ASSEMBLY__
struct patch_symbol

#define PATCH_CONFIG_SU_ENABLE 0x1
#define PATCH_CONFIG_SU_HOOK_NO_WRAP 0x2
#define PATCH_CONFIG_SU_ENABLE32 0x2

struct patch_config
{
union
{
struct
{
uint64_t kallsyms_lookup_name;
uint64_t printk;
uint64_t vm_area_add_early;

uint64_t panic;
uint64_t rest_init;
Expand All @@ -117,24 +121,17 @@ struct patch_symbol
uint64_t __cfi_slowpath;
uint64_t copy_process;
uint64_t cgroup_post_fork;
uint64_t do_execveat_common;
uint64_t __do_execve_file;
uint64_t do_execve_common;
uint64_t do_faccessat;
uint64_t sys_faccessat;
uint64_t sys_faccessat2;
uint64_t sys_newfstatat;
uint64_t vfs_statx;
uint64_t vfs_fstatat;
uint64_t avc_denied;
uint64_t slow_avc_audit;
uint64_t input_handle_event;

uint8_t patch_su_config;
};
char _cap[PATCH_SYMBOL_LEN];
char _cap[PATCH_CONFIG_LEN];
};
};
typedef struct patch_symbol patch_symbol_t;
_Static_assert(sizeof(patch_symbol_t) == PATCH_SYMBOL_LEN, "sizeof patch_symbol_t mismatch");
typedef struct patch_config patch_config_t;
_Static_assert(sizeof(patch_config_t) == PATCH_CONFIG_LEN, "sizeof patch_config_t mismatch");
#endif

#ifndef __ASSEMBLY__
Expand Down Expand Up @@ -220,7 +217,7 @@ typedef struct
map_symbol_t map_symbol;
uint8_t header_backup[HDR_BACKUP_SIZE];
uint8_t superkey[SUPER_KEY_LEN];
patch_symbol_t patch_symbol;
patch_config_t patch_config;
char additional[ADDITIONAL_LEN];
} setup_preset_be_000a04_t;

Expand All @@ -245,7 +242,7 @@ typedef struct _setup_preset_t
uint8_t superkey[SUPER_KEY_LEN];
uint8_t root_superkey[ROOT_SUPER_KEY_HASH_LEN];
uint8_t __[SETUP_PRESERVE_LEN];
patch_symbol_t patch_symbol;
patch_config_t patch_config;
char additional[ADDITIONAL_LEN];
} setup_preset_t;
#else
Expand All @@ -266,8 +263,8 @@ typedef struct _setup_preset_t
#define setup_header_backup_offset (setup_map_symbol_offset + MAP_SYMBOL_SIZE)
#define setup_superkey_offset (setup_header_backup_offset + HDR_BACKUP_SIZE)
#define setup_root_superkey_offset (setup_superkey_offset + SUPER_KEY_LEN)
#define setup_patch_symbol_offset (setup_root_superkey_offset + ROOT_SUPER_KEY_HASH_LEN + SETUP_PRESERVE_LEN)
#define setup_end (setup_patch_symbol_offset + PATCH_SYMBOL_LEN)
#define setup_patch_config_offset (setup_root_superkey_offset + ROOT_SUPER_KEY_HASH_LEN + SETUP_PRESERVE_LEN)
#define setup_end (setup_patch_config_offset + PATCH_CONFIG_LEN)
#endif

#ifndef __ASSEMBLY__
Expand Down
10 changes: 7 additions & 3 deletions kernel/include/stdbool.h
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
#ifndef _KP_STDBOOL_H_
#define _KP_STDBOOL_H_

typedef unsigned char bool;
#define true ((bool)1)
#define false ((bool)0)
#ifndef __bool_true_false_are_defined

#define bool _Bool
#define true 1
#define false 0

#endif

#endif
8 changes: 7 additions & 1 deletion kernel/include/symbol.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,14 @@ typedef struct

#define KP_EXPORT_SYMBOL(sym) _KP_EXPORT_SYMBOL(sym)

extern unsigned long link_base_addr;
extern unsigned long runtime_base_addr;

unsigned long symbol_lookup_name(const char *name);

int symbol_init();
static inline unsigned long link2runtime(unsigned long addr)
{
return addr - link_base_addr + runtime_base_addr;
}

#endif
Loading