Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

0.7.0 for APatch #5

Merged
merged 2 commits into from
Dec 21, 2023
Merged
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
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,10 @@

If you are using Android, [APatch](https://github.com/bmax121/APatch) would be a better choice.

KernelPatch provides the fundamental capability to parse Linux kernel images without source code and symbol information, allowing for the retrieval of arbitrary symbol offsets and the injection of arbitrary code into the kernel.
Building upon this foundation, KernelPatch offers essential features such as system-call-hook and inline-hook in the kernel.
You have complete control over the kernel, allowing you to implement desired functionalities such as privilege escalation, hiding, monitoring, and more.
- Obtain all symbol information without source code and symbol information.
- Inject arbitrary code into the kernel. (Static patching the kernel image or Runtime dynamic loading).
- Kernel symbol lookup, function inline hook and syscall table hook are provided.
- Additional SU compatibility for Android.

## Supported Versions

Expand Down
4 changes: 2 additions & 2 deletions kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@ ${TARGET}.elf: ${OBJS}

.PHONY: hdr
hdr:
cp -r patch/include/uapi ../user
cp include/preset.h ../tools
cp -Rf patch/include/uapi ../user
cp -f include/preset.h ../tools

.PHONY: clean
clean:
Expand Down
4 changes: 2 additions & 2 deletions kernel/patch/android/kpuserd.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ static const char patch_rc[] = ""
" rm %s \n"
"on post-fs-data\n"
" start logd\n"
" exec -- /system/bin/truncate %s --android_user_init\n"
" exec -- /system/bin/truncate %s android_user_init --kernel\n"
" exec u:r:magisk:s0 root -- " APD_PATH " post-fs-data\n"
"on nonencrypted\n"
" exec u:r:magisk:s0 root -- " APD_PATH " services\n"
Expand Down Expand Up @@ -242,7 +242,7 @@ static void before_input_handle_event(hook_fargs4_t *args, void *udata)
volumedown_pressed_count++;
if (volumedown_pressed_count == 3) {
log_boot("entering safemode ...");
struct file *filp = filp_open(replace_rc_file, O_WRONLY | O_CREAT | O_TRUNC, 0666);
struct file *filp = filp_open(SAFE_MODE_FLAG_FILE, O_WRONLY | O_CREAT | O_TRUNC, 0666);
if (filp && !IS_ERR(filp)) filp_close(filp, 0);
}
}
Expand Down
13 changes: 7 additions & 6 deletions kernel/patch/android/sucompat.c
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ int su_remove_allow_uid(uid_t uid, int async)
if (pos->uid == uid) {
list_del_rcu(&pos->list);
spin_unlock(&list_lock);
logkfi("remove uid: %d, to_uid: %d, sctx: %s\n", pos->uid, pos->profile.to_uid, pos->profile.scontext);
logkfi("uid: %d, to_uid: %d, sctx: %s\n", pos->uid, pos->profile.to_uid, pos->profile.scontext);
if (async) {
call_rcu(&pos->rcu, allow_reclaim_callback);
} else {
Expand All @@ -161,7 +161,7 @@ int su_allow_uid_nums()
num++;
}
rcu_read_unlock();
logkd("allow uid num: %d\n", num);
logkfd("%d\n", num);
return num;
}

Expand All @@ -178,7 +178,7 @@ int su_allow_uids(uid_t *__user uuids, int unum)
}
uid_t uid = pos->profile.uid;
int cplen = seq_copy_to_user(uuids + num, &uid, sizeof(uid));
logkd("copy_to_user allow uid: %d\n", uid);
logkfd("uid: %d\n", uid);
if (cplen <= 0) {
logkfd("seq_copy_to_user error: %d", cplen);
rc = cplen;
Expand All @@ -201,7 +201,7 @@ int su_allow_uid_profile(uid_t uid, struct su_profile *__user uprofile)
{
if (pos->profile.uid != uid) continue;
int cplen = seq_copy_to_user(uprofile, &pos->profile, sizeof(struct su_profile));
logkd("copy_to_user allow uid profile: %d %d %s\n", uid, pos->profile.to_uid, pos->profile.scontext);
logkfd("profile: %d %d %s\n", uid, pos->profile.to_uid, pos->profile.scontext);
if (cplen <= 0) {
logkfd("seq_copy_to_user error: %d", cplen);
rc = cplen;
Expand All @@ -218,18 +218,19 @@ int su_allow_uid_profile(uid_t uid, struct su_profile *__user uprofile)
// no free, no lock
int su_reset_path(const char *path)
{
if (!strcmp(current_su_path, path)) return 0;
char *new_su_path = kstrdup(path, GFP_ATOMIC);
current_su_path = new_su_path;
dsb(ishst);
logki(": %s\n", current_su_path);
logkfi("%s\n", current_su_path);
return 0;
}

int su_get_path(char *__user ubuf, int buf_len)
{
int len = strnlen(current_su_path, SU_PATH_MAX_LEN);
if (buf_len < len) return -ENOMEM;
logkfi(": %s\n", current_su_path);
logkfi("%s\n", current_su_path);
return seq_copy_to_user(ubuf, current_su_path, len + 1);
}

Expand Down
1 change: 1 addition & 0 deletions kernel/patch/include/uapi/scdefs.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ struct su_profile
#define APATCH_LOG_FLODER "/data/adb/ap/log/"
#define KPATCH_PATH "/data/adb/kpatch"
#define KPATCH_SHADOW_PATH "/system/bin/truncate"
#define SAFE_MODE_FLAG_FILE "/dev/.sefemode"

#define SUPERCALL_SU_GRANT_UID 0x1100
#define SUPERCALL_SU_REVOKE_UID 0x1101
Expand Down
16 changes: 8 additions & 8 deletions user/android/sumgr.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,14 +89,14 @@ void usage(int status)
" whose full PATH is '/system/bin/kp'. This can avoid conflicts with the existing 'su' command.\n"
" If you wish to modify this PATH, you can use the 'reset' command. \n"
"\n"
"help Print this help message. \n"
"grant UID [TO_UID] [SCONTE] Grant access permission to UID.\n"
"revoke Revoke access permission to UID.\n"
"num Get the number of uids with the aforementioned permissions.\n"
"list List aforementioned uids.\n"
"profile UID Get the profile of the uid configuration.\n"
"reset PATH Reset '/system/bin/kp' to PATH. The length of PATH must be between 14-63.\n"
"get Get current PATH.\n"
"help Print this help message. \n"
"grant <UID> [TO_UID] [SCONTEXT] Grant access permission to UID.\n"
"revoke Revoke access permission to UID.\n"
"num Get the number of uids with the aforementioned permissions.\n"
"list List aforementioned uids.\n"
"profile <UID> Get the profile of the uid configuration.\n"
"reset <PATH> Reset '/system/bin/kp' to PATH. The length of PATH must be between 14-63.\n"
"get Get current su PATH.\n"
"");
}
exit(status);
Expand Down
44 changes: 31 additions & 13 deletions user/android/user_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <getopt.h>

#include "../supercall.h"
#include "user_init.h"

#define PKG_NAME_LEN 256

Expand All @@ -26,9 +28,8 @@ static char magiskpolicy_path[] = APATCH_BIN_FLODER "magiskpolicy";
static char allow_uids_path[] = APATCH_FLODER ".allow_uid";
static char su_path_path[] = APATCH_FLODER ".su_path";

static char boot0_log_path[] = ADB_FLODER ".kpatch_0.log";
static char boot0_log_path[] = APATCH_LOG_FLODER ".kpatch_0.log";
static char boot1_log_path[] = APATCH_LOG_FLODER ".kpatch_1.log";
static char boot2_log_path[] = APATCH_LOG_FLODER ".kpatch_2.log";

char *strip(char *str)
{
Expand Down Expand Up @@ -95,7 +96,7 @@ static void load_config_allow_uids(const char *key)

int len = strlen(line);
for (int i = 0; i < len; i++) {
if (isspace(line[i]) || line[i] == ':') line[i] = '\0';
if (isspace(line[i]) || line[i] == ',') line[i] = '\0';
}

char *split[4] = { 0 };
Expand Down Expand Up @@ -159,38 +160,55 @@ static void load_magisk_policy(const char *key)
NULL,
};
int rc = execv(argv[0], argv);
log_kernel(key, "%d exec magiskpolicy error %s\n", getpid(), strerror(errno));
log_kernel(key, "%d exec magiskpolicy error: %s\n", getpid(), strerror(errno));
} else {
int status;
wait(&status);
log_kernel(key, "%d wait magiskpolicy status: 0x%x\n", getpid(), status);
}
}

int android_user_init(const char *key)
static struct option const longopts[] = { { "kernel", no_argument, NULL, 'k' }, { NULL, 0, NULL, 0 } };

int android_user_init(const char *key, int argc, char **argv)
{
// check kernel_patch
if (!sc_ready(key)) return -EFAULT;

struct su_profile profile = { 0 };
profile.uid = getuid();
int from_kernel = false;

int optc;
while ((optc = getopt_long(argc, argv, "k", longopts, NULL)) != -1) {
switch (optc) {
case 'k':
from_kernel = true;
break;
default:
break;
}
}

struct su_profile profile = {
.uid = getuid(),
};

sc_su(key, &profile);

save_dmegs(key, boot0_log_path);
if (from_kernel) log_kernel(key, "%d called from kernel.\n", getpid());

// create floder is not exist, but in actually, apatch is not installed
if (!opendir(APATCH_FLODER)) mkdir(APATCH_FLODER, 0700);
if (!opendir(APATCH_BIN_FLODER)) mkdir(APATCH_BIN_FLODER, 0700);
if (!opendir(APATCH_LOG_FLODER)) mkdir(APATCH_LOG_FLODER, 0700);

if (from_kernel) save_dmegs(key, boot0_log_path);

log_kernel(key, "%d starting android user init ...\n", getpid());

load_config_su_path(key);
load_config_allow_uids(key);
load_magisk_policy(key);

save_dmegs(key, boot1_log_path);
if (from_kernel) save_dmegs(key, boot1_log_path);

log_kernel(key, "%d finished android user init.\n", getpid());

fprintf(stdout, "%d finished android user init.\n", getpid());
return 0;
}
3 changes: 1 addition & 2 deletions user/android/user_init.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ extern "C"
{
#endif

int android_user_init(const char *key);

int android_user_init(const char *key, int argc, char **argv);
#ifdef __cplusplus
}
#endif
Expand Down
2 changes: 0 additions & 2 deletions user/kpatch.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ extern "C"

int __test(const char *key);

int android_user_init(const char *key);

#ifdef __cplusplus
}
#endif
Expand Down
12 changes: 6 additions & 6 deletions user/kpm.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,12 @@ static void usage(int status)
fprintf(stdout, ""
"KernelPatch Module command set.\n"
"\n"
"help Print this help message. \n"
"load KPM_PATH [KPM_ARGS] Load KernelPatch Module with KPM_PATH and KPM_ARGS.\n"
"unload KPM_NAME Unload KernelPatch Module named KPM_NAME.\n"
"num Get the number of modules that have been loaded.\n"
"list List names of all loaded modules.\n"
"info KPM_NAME Get detailed information about module named KPM_NAME.\n"
"help Print this help message. \n"
"load <KPM_PATH> [KPM_ARGS] Load KernelPatch Module with KPM_PATH and KPM_ARGS.\n"
"unload <KPM_NAME> Unload KernelPatch Module named KPM_NAME.\n"
"num Get the number of modules that have been loaded.\n"
"list List names of all loaded modules.\n"
"info <KPM_NAME> Get detailed information about module named KPM_NAME.\n"
"");
}
exit(status);
Expand Down
5 changes: 3 additions & 2 deletions user/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ static void usage(int status)
fprintf(stdout,
" \n"
"Options: \n"
"%s -h, --help Print this message. \n"
"%s -h, --help Print this help message. \n"
"%s -v, --version Print version. \n"
"\n",
program_name, program_name);
Expand Down Expand Up @@ -116,8 +116,9 @@ int main(int argc, char **argv)
strcat(program_name, " <SUPERKEY> sumgr");
return sumgr_main(key, argc - 2, argv + 2);
case 'a':
return android_user_init(key);
return android_user_init(key, argc - 2, argv + 2);
case 'h':
strcat(program_name, " <SUPERKEY>");
usage(EXIT_SUCCESS);
default:
fprintf(stderr, "Invalid command: %s!\n", scmd);
Expand Down
4 changes: 2 additions & 2 deletions version
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
#define MAJOR 0
#define MINOR 6
#define PATCH 2
#define MINOR 7
#define PATCH 0