diff --git a/kernel/arch.h b/kernel/arch.h new file mode 100644 index 00000000..e92724e7 --- /dev/null +++ b/kernel/arch.h @@ -0,0 +1,59 @@ +#ifndef __KSU_H_ARCH +#define __KSU_H_ARCH + + +#if defined(__aarch64__) + +#define __PT_REGS_CAST(x) ((const struct user_pt_regs *)(x)) +#define __PT_PARM1_REG regs[0] +#define __PT_PARM2_REG regs[1] +#define __PT_PARM3_REG regs[2] +#define __PT_PARM4_REG regs[3] +#define __PT_PARM5_REG regs[4] +#define __PT_RET_REG regs[30] +#define __PT_FP_REG regs[29] /* Works only with CONFIG_FRAME_POINTER */ +#define __PT_RC_REG regs[0] +#define __PT_SP_REG sp +#define __PT_IP_REG pc + +#define PRCTL_SYMBOL "__arm64_sys_prctl" + +#elif defined(__x86_64__) + +#define __PT_PARM1_REG di +#define __PT_PARM2_REG si +#define __PT_PARM3_REG dx +/* syscall uses r10 for PARM4 */ +#define __PT_PARM4_REG r10 +// #define __PT_PARM4_REG cx +#define __PT_PARM5_REG r8 +#define __PT_RET_REG sp +#define __PT_FP_REG bp +#define __PT_RC_REG ax +#define __PT_SP_REG sp +#define __PT_IP_REG ip + +#define PRCTL_SYMBOL "__x64_sys_prctl" + +#else +#error "Unsupported arch" +#endif + +/* allow some architecutres to override `struct pt_regs` */ +#ifndef __PT_REGS_CAST +#define __PT_REGS_CAST(x) (x) +#endif + +#define PT_REGS_PARM1(x) (__PT_REGS_CAST(x)->__PT_PARM1_REG) +#define PT_REGS_PARM2(x) (__PT_REGS_CAST(x)->__PT_PARM2_REG) +#define PT_REGS_PARM3(x) (__PT_REGS_CAST(x)->__PT_PARM3_REG) +#define PT_REGS_PARM4(x) (__PT_REGS_CAST(x)->__PT_PARM4_REG) +#define PT_REGS_PARM5(x) (__PT_REGS_CAST(x)->__PT_PARM5_REG) +#define PT_REGS_RET(x) (__PT_REGS_CAST(x)->__PT_RET_REG) +#define PT_REGS_FP(x) (__PT_REGS_CAST(x)->__PT_FP_REG) +#define PT_REGS_RC(x) (__PT_REGS_CAST(x)->__PT_RC_REG) +#define PT_REGS_SP(x) (__PT_REGS_CAST(x)->__PT_SP_REG) +#define PT_REGS_IP(x) (__PT_REGS_CAST(x)->__PT_IP_REG) + + +#endif \ No newline at end of file diff --git a/kernel/ksu.c b/kernel/ksu.c index 998df17c..298b3331 100644 --- a/kernel/ksu.c +++ b/kernel/ksu.c @@ -23,6 +23,7 @@ #include "klog.h" #include "apk_sign.h" #include "allowlist.h" +#include "arch.h" #define KERNEL_SU_VERSION 3 @@ -149,12 +150,12 @@ static bool is_allow_su() { static int handler_pre(struct kprobe *p, struct pt_regs *regs) { - struct pt_regs* real_regs = (struct pt_regs*) regs->regs[0]; - int option = (int) real_regs->regs[0]; - unsigned long arg2 = (unsigned long) real_regs->regs[1]; - unsigned long arg3 = (unsigned long) real_regs->regs[2]; - unsigned long arg4 = (unsigned long) real_regs->regs[3]; - unsigned long arg5 = (unsigned long) real_regs->regs[4]; + struct pt_regs* real_regs = (struct pt_regs*) PT_REGS_PARM1(regs); + int option = (int) PT_REGS_PARM1(real_regs); + unsigned long arg2 = (unsigned long) PT_REGS_PARM2(real_regs); + unsigned long arg3 = (unsigned long) PT_REGS_PARM3(real_regs); + unsigned long arg4 = (unsigned long) PT_REGS_PARM4(real_regs); + unsigned long arg5 = (unsigned long) PT_REGS_PARM5(real_regs); // if success, we modify the arg5 as result! u32* result = (u32*) arg5; @@ -221,7 +222,7 @@ static int handler_pre(struct kprobe *p, struct pt_regs *regs) { } static struct kprobe kp = { - .symbol_name = "__arm64_sys_prctl", + .symbol_name = PRCTL_SYMBOL, .pre_handler = handler_pre, };