From e6be9ccd590e382c7fcf8c7e9b061a58996c9b24 Mon Sep 17 00:00:00 2001 From: unkn0wName Date: Thu, 17 Aug 2023 20:14:02 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=96=87=E4=BB=B6=E7=BB=93=E6=9E=84?= =?UTF-8?q?=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/src/main/cpp/CMakeLists.txt | 6 +- PermissionManager/app/src/main/cpp/root.cpp | 22 +- su/jni/Android.mk | 4 +- su/su.cpp | 25 +- su/su.vcxproj | 98 ---- su/su.vcxproj.filters | 27 - su/su.vcxproj.user | 4 - su/su_hide_path_utils.h | 5 +- testRoot/jni/Android.mk | 10 +- testRoot/kernel_root_key.h | 4 - .../kernel_root_kit_command.h} | 16 +- .../kernel_root_kit_fork_helper.h} | 9 +- .../kernel_root_kit_init64_process_helper.h} | 8 +- .../kernel_root_kit/kernel_root_kit_log.h | 22 + .../kernel_root_kit_maps_helper.h} | 4 +- .../kernel_root_kit_process64_inject.cpp} | 180 +++--- .../kernel_root_kit_process64_inject.h} | 4 +- .../kernel_root_kit_process_cmdline_utils.h} | 6 +- .../kernel_root_kit_ptrace_arm64_utils.cpp} | 543 +++++++++--------- .../kernel_root_kit_ptrace_arm64_utils.h} | 109 ++-- .../kernel_root_kit_random.h} | 3 +- .../kernel_root_kit_so_symbol_parser.h} | 3 +- .../kernel_root_kit_su_install_helper.cpp} | 13 +- .../kernel_root_kit_su_install_helper.h} | 5 +- .../kernel_root_kit_umbrella.h | 7 + testRoot/main.cpp | 147 ----- testRoot/myself_path_utils.h | 23 - testRoot/testRoot.cpp | 114 ++-- testRoot/testRoot.h | 27 - 29 files changed, 580 insertions(+), 868 deletions(-) delete mode 100644 su/su.vcxproj delete mode 100644 su/su.vcxproj.filters delete mode 100644 su/su.vcxproj.user delete mode 100644 testRoot/kernel_root_key.h rename testRoot/{kernel_root_helper.h => kernel_root_kit/kernel_root_kit_command.h} (90%) rename testRoot/{safe_fork_helper.h => kernel_root_kit/kernel_root_kit_fork_helper.h} (97%) rename testRoot/{init64_process_helper.h => kernel_root_kit/kernel_root_kit_init64_process_helper.h} (89%) create mode 100644 testRoot/kernel_root_kit/kernel_root_kit_log.h rename testRoot/{maps_helper.h => kernel_root_kit/kernel_root_kit_maps_helper.h} (98%) rename testRoot/{process64_inject.cpp => kernel_root_kit/kernel_root_kit_process64_inject.cpp} (86%) rename testRoot/{process64_inject.h => kernel_root_kit/kernel_root_kit_process64_inject.h} (98%) rename testRoot/{process_cmdline_utils.h => kernel_root_kit/kernel_root_kit_process_cmdline_utils.h} (98%) rename testRoot/{ptrace_arm64_utils.cpp => kernel_root_kit/kernel_root_kit_ptrace_arm64_utils.cpp} (84%) rename testRoot/{ptrace_arm64_utils.h => kernel_root_kit/kernel_root_kit_ptrace_arm64_utils.h} (97%) rename testRoot/{random_utils.h => kernel_root_kit/kernel_root_kit_random.h} (94%) rename testRoot/{so_symbol_parser.h => kernel_root_kit/kernel_root_kit_so_symbol_parser.h} (98%) rename testRoot/{su_install_helper.cpp => kernel_root_kit/kernel_root_kit_su_install_helper.cpp} (96%) rename testRoot/{su_install_helper.h => kernel_root_kit/kernel_root_kit_su_install_helper.h} (89%) create mode 100644 testRoot/kernel_root_kit/kernel_root_kit_umbrella.h delete mode 100644 testRoot/main.cpp delete mode 100644 testRoot/myself_path_utils.h delete mode 100644 testRoot/testRoot.h diff --git a/PermissionManager/app/src/main/cpp/CMakeLists.txt b/PermissionManager/app/src/main/cpp/CMakeLists.txt index d70571e..0bc4aea 100644 --- a/PermissionManager/app/src/main/cpp/CMakeLists.txt +++ b/PermissionManager/app/src/main/cpp/CMakeLists.txt @@ -21,9 +21,9 @@ add_library( # Sets the name of the library. SHARED # Provides a relative path to your source file(s). - ../../../../../testRoot/process64_inject.cpp - ../../../../../testRoot/ptrace_arm64_utils.cpp - ../../../../../testRoot/su_install_helper.cpp + ../../../../../testRoot/kernel_root_kit/kernel_root_kit_process64_inject.cpp + ../../../../../testRoot/kernel_root_kit/kernel_root_kit_ptrace_arm64_utils.cpp + ../../../../../testRoot/kernel_root_kit/kernel_root_kit_su_install_helper.cpp ../../../../../testRoot/base64.cpp root.cpp) diff --git a/PermissionManager/app/src/main/cpp/root.cpp b/PermissionManager/app/src/main/cpp/root.cpp index 3dd0bb4..0661cda 100644 --- a/PermissionManager/app/src/main/cpp/root.cpp +++ b/PermissionManager/app/src/main/cpp/root.cpp @@ -7,11 +7,7 @@ #include #include -#include "../../../../../testRoot/testRoot.h" -#include "../../../../../testRoot/kernel_root_helper.h" -#include "../../../../../testRoot/process64_inject.h" -#include "../../../../../testRoot/init64_process_helper.h" -#include "../../../../../testRoot/su_install_helper.h" +#include "../../../../../testRoot/kernel_root_kit/kernel_root_kit_umbrella.h" using namespace std; @@ -76,7 +72,7 @@ Java_com_linux_permissionmanager_MainActivity_testRoot( env->ReleaseStringUTFChars(rootKey, str1); std::string result; - fork_pipe_info finfo; + kernel_root::fork_pipe_info finfo; ssize_t err = 0; if(fork_pipe_child_process(finfo)) { err = kernel_root::get_root(strRootKey.c_str()); @@ -144,7 +140,7 @@ Java_com_linux_permissionmanager_MainActivity_runInit64ProcessCmd( ssize_t err; - string result = safe_run_init64_cmd_wrapper(strRootKey.c_str(), strCmd.c_str(), err); + string result = kernel_root::safe_run_init64_cmd_wrapper(strRootKey.c_str(), strCmd.c_str(), err); stringstream sstr; sstr << "runInit64Cmd err:" << err << ", result:" << result; @@ -174,7 +170,7 @@ Java_com_linux_permissionmanager_MainActivity_installSu( stringstream sstr; //安装su工具套件 ssize_t err; - std::string su_hide_full_path = safe_install_su(strRootKey.c_str(), strBasePath.c_str(), strOriginSuFullPath.c_str(), err); + std::string su_hide_full_path = kernel_root::safe_install_su(strRootKey.c_str(), strBasePath.c_str(), strOriginSuFullPath.c_str(), err); sstr << "install su err:" << err<<", su_hide_full_path:" << su_hide_full_path << std::endl; g_last_su_full_path = su_hide_full_path; if (err == 0) { @@ -207,7 +203,7 @@ Java_com_linux_permissionmanager_MainActivity_uninstallSu( stringstream sstr; - ssize_t err = safe_uninstall_su(strRootKey.c_str(), strBasePath.c_str()); + ssize_t err = kernel_root::safe_uninstall_su(strRootKey.c_str(), strBasePath.c_str()); sstr << "uninstallSu err:" << err << std::endl; if (err != 0) { return env->NewStringUTF(sstr.str().c_str()); @@ -239,21 +235,21 @@ Java_com_linux_permissionmanager_MainActivity_autoSuEnvInject( //杀光所有历史进程 std::vector vOut; - ssize_t err = safe_find_all_cmdline_process(strRootKey.c_str(), strTargetProcessCmdline.c_str(), vOut); + ssize_t err = kernel_root::safe_find_all_cmdline_process(strRootKey.c_str(), strTargetProcessCmdline.c_str(), vOut); sstr << "find_all_cmdline_process err:"<< err<<", cnt:"<NewStringUTF(sstr.str().c_str()); } std::string kill_cmd; for (pid_t t : vOut) { - err = safe_kill_process(strRootKey.c_str(), t); + err = kernel_root::safe_kill_process(strRootKey.c_str(), t); sstr << "kill_ret err:"<< err << std::endl; if (err != 0) { return env->NewStringUTF(sstr.str().c_str()); } } pid_t pid; - err = safe_wait_and_find_cmdline_process(strRootKey.c_str(), strTargetProcessCmdline.c_str(), 60*1000, pid); + err = kernel_root::safe_wait_and_find_cmdline_process(strRootKey.c_str(), strTargetProcessCmdline.c_str(), 60*1000, pid); std::string folder_path = g_last_su_full_path; int n = folder_path.find_last_of("/"); @@ -264,7 +260,7 @@ Java_com_linux_permissionmanager_MainActivity_autoSuEnvInject( if (err != 0) { return env->NewStringUTF(sstr.str().c_str()); } - err = safe_inject_process_env64_PATH_wrapper(strRootKey.c_str(), pid, folder_path.c_str()); + err = kernel_root::safe_inject_process_env64_PATH_wrapper(strRootKey.c_str(), pid, folder_path.c_str()); sstr << "autoSuEnvInject ret val:" << err << std::endl; if (err != 0) { return env->NewStringUTF(sstr.str().c_str()); diff --git a/su/jni/Android.mk b/su/jni/Android.mk index cc3f69f..4076c5f 100644 --- a/su/jni/Android.mk +++ b/su/jni/Android.mk @@ -1,9 +1,7 @@ LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) -LOCAL_CPPFLAGS += -std=c++17 -LOCAL_CFLAGS += -fPIE -LOCAL_CFLAGS += -fvisibility=hidden +LOCAL_CPPFLAGS += -std=c++17 -fPIE -fvisibility=hidden -frtti -fexceptions LOCAL_LDFLAGS += -fPIE -pie LOCAL_DISABLE_FATAL_LINKER_WARNINGS := true LOCAL_MODULE := su diff --git a/su/su.cpp b/su/su.cpp index 5d5d5c4..c1dab64 100644 --- a/su/su.cpp +++ b/su/su.cpp @@ -1,10 +1,22 @@ #include "su.h" #include "log.h" #include "su_hide_path_utils.h" -#include "../testRoot/kernel_root_helper.h" -#include "../testRoot/myself_path_utils.h" +#include "../testRoot/kernel_root_kit/kernel_root_kit_command.h" namespace { + std::string get_executable_directory() { + char processdir[4096] = { 0 }; // Consider using PATH_MAX from limits.h + ssize_t path_len = readlink("/proc/self/exe", processdir, sizeof(processdir)); + if(path_len > 0) { + char* path_end = strrchr(processdir, '/'); + if(path_end) { + *path_end = '\0'; + return std::string(processdir); + } + } + return {}; + } + /* * Bionic's atoi runs through strtol(). * Use our own implementation for faster conversion. @@ -55,11 +67,8 @@ void usage(int status) { } static inline std::string get_root_key() { - char myself_path[1024] = { 0 }; - char processname[1024]; - get_executable_path(myself_path, processname, sizeof(myself_path)); - TRACE("su start: my directory:%s, processname:%s\n", myself_path, processname); - std::string str_root_key = parse_root_key_by_myself_path(myself_path); + std::string myself_path = get_executable_directory(); + std::string str_root_key = kernel_root::parse_root_key_by_myself_path(myself_path.c_str()); return str_root_key; } @@ -167,7 +176,7 @@ int su_client_main(int argc, char* argv[]) { new_argv[1] = "-c"; new_argv[2] = su_req.command.data(); } - + // If you need it, you can unblock this line of code yourself //set_identity(su_req.uid); diff --git a/su/su.vcxproj b/su/su.vcxproj deleted file mode 100644 index 511692a..0000000 --- a/su/su.vcxproj +++ /dev/null @@ -1,98 +0,0 @@ - - - - - Debug - ARM - - - Release - ARM - - - Debug - ARM64 - - - Release - ARM64 - - - Debug - x86 - - - Release - x86 - - - Debug - x64 - - - Release - x64 - - - - {0ae121c5-8222-45b9-b543-86318a1c88c3} - Linux - su - 15.0 - Linux - 1.0 - Generic - {D51BCBC9-82E9-4017-911E-C93873C4EA2B} - - - - true - - - false - - - true - - - false - - - true - - - false - - - false - - - true - - - - - - - - D:\android-ndk-r25b\toolchains\llvm\prebuilt\windows-x86_64\sysroot\usr\include - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/su/su.vcxproj.filters b/su/su.vcxproj.filters deleted file mode 100644 index e9270ef..0000000 --- a/su/su.vcxproj.filters +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - {457d7200-d49a-432e-817b-81eb3f5f2924} - - - - - jni - - - jni - - - - - - - - - - \ No newline at end of file diff --git a/su/su.vcxproj.user b/su/su.vcxproj.user deleted file mode 100644 index be25078..0000000 --- a/su/su.vcxproj.user +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/su/su_hide_path_utils.h b/su/su_hide_path_utils.h index dd12881..2de4c2d 100644 --- a/su/su_hide_path_utils.h +++ b/su/su_hide_path_utils.h @@ -9,11 +9,12 @@ #include #include "base64.h" #include "log.h" -#include "../testRoot/random_utils.h" +#include "../testRoot/kernel_root_kit/kernel_root_kit_random.h" #define RANDOM_GUID_LEN 10 #define ROOT_KEY_LEN 48 +namespace kernel_root { namespace { namespace __private { @@ -196,5 +197,5 @@ static inline std::string parse_root_key_by_myself_path(const char* myself_path) } return decodeRootKey.substr(decodeRootKey.length() - ROOT_KEY_LEN); } - +} #endif /* _SU_HIDDEN_FOLDER_PATH_UTILS_H_ */ diff --git a/testRoot/jni/Android.mk b/testRoot/jni/Android.mk index 0958e57..11823c4 100644 --- a/testRoot/jni/Android.mk +++ b/testRoot/jni/Android.mk @@ -1,15 +1,15 @@ LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) -LOCAL_CPPFLAGS += -std=c++17 -fPIE -frtti -fvisibility=hidden +LOCAL_CPPFLAGS += -std=c++17 -fPIE -fvisibility=hidden -frtti -fexceptions LOCAL_LDFLAGS += -fPIE -pie LOCAL_DISABLE_FATAL_LINKER_WARNINGS := true -LOCAL_MODULE := testRoot.out +LOCAL_MODULE := testRoot LOCAL_SRC_FILES := \ ../testRoot.cpp \ ../base64.cpp \ -../process64_inject.cpp \ -../ptrace_arm64_utils.cpp \ -../su_install_helper.cpp +../kernel_root_kit/kernel_root_kit_process64_inject.cpp \ +../kernel_root_kit/kernel_root_kit_ptrace_arm64_utils.cpp \ +../kernel_root_kit/kernel_root_kit_su_install_helper.cpp include $(BUILD_EXECUTABLE) diff --git a/testRoot/kernel_root_key.h b/testRoot/kernel_root_key.h deleted file mode 100644 index e6abf97..0000000 --- a/testRoot/kernel_root_key.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifndef KERNEL_ROOT_KEY_H_ -#define KERNEL_ROOT_KEY_H_ -#define ROOT_KEY "OM4kKoPVGFG2tnVFcs1PJ1qp6HtVymjV0CoTgFDmMdSDALve" -#endif /* KERNEL_ROOT_KEY_H_ */ diff --git a/testRoot/kernel_root_helper.h b/testRoot/kernel_root_kit/kernel_root_kit_command.h similarity index 90% rename from testRoot/kernel_root_helper.h rename to testRoot/kernel_root_kit/kernel_root_kit_command.h index 549e2c7..670bee4 100644 --- a/testRoot/kernel_root_helper.h +++ b/testRoot/kernel_root_kit/kernel_root_kit_command.h @@ -1,7 +1,6 @@ -#ifndef KERNEL_ROOT_HELPER_H_ -#define KERNEL_ROOT_HELPER_H_ +#ifndef _KERNEL_ROOT_KIT_COMMAND_H_ +#define _KERNEL_ROOT_KIT_COMMAND_H_ -#ifdef __linux__ #include #include #include @@ -16,7 +15,7 @@ #include #include #include -#include "safe_fork_helper.h" +#include "kernel_root_kit_fork_helper.h" namespace kernel_root { @@ -24,10 +23,11 @@ namespace kernel_root { static inline ssize_t get_root(const char* str_root_key) { if (str_root_key == NULL) { return -100; } syscall(__NR_execve, str_root_key, NULL, NULL); + if(getuid() != 0) { return -101; } return 0; } - //是否启用SELinux + //检查系统SELinux的是否为禁用状态 static bool is_enable_selinux() { int cnt = 0; DIR* dir = opendir("/"); @@ -101,8 +101,4 @@ namespace kernel_root { return result; } } - -#endif /*__linux__*/ - - -#endif /* KERNEL_ROOT_HELPER_H_ */ +#endif /* _KERNEL_ROOT_KIT_COMMAND_H_ */ diff --git a/testRoot/safe_fork_helper.h b/testRoot/kernel_root_kit/kernel_root_kit_fork_helper.h similarity index 97% rename from testRoot/safe_fork_helper.h rename to testRoot/kernel_root_kit/kernel_root_kit_fork_helper.h index ad6a7c1..f50b05a 100644 --- a/testRoot/safe_fork_helper.h +++ b/testRoot/kernel_root_kit/kernel_root_kit_fork_helper.h @@ -1,5 +1,5 @@ -#ifndef _SAFE_FORK_HELPER_H_ -#define _SAFE_FORK_HELPER_H_ +#ifndef _KERNEL_ROOT_KIT_FORK_HELPER_H_ +#define _KERNEL_ROOT_KIT_FORK_HELPER_H_ #include #include #include @@ -8,8 +8,8 @@ #include #include #include -#include +namespace kernel_root { class fork_base_info { public: fork_base_info() { reset(); } @@ -243,5 +243,6 @@ static bool read_fd_from_child(const fork_socketpair_info & finfo, int & fd) { fd = *(int*)CMSG_DATA(&cm); return true; } +} -#endif /* _SAFE_FORK_HELPER_H_ */ +#endif /* _KERNEL_ROOT_KIT_FORK_HELPER_H_ */ diff --git a/testRoot/init64_process_helper.h b/testRoot/kernel_root_kit/kernel_root_kit_init64_process_helper.h similarity index 89% rename from testRoot/init64_process_helper.h rename to testRoot/kernel_root_kit/kernel_root_kit_init64_process_helper.h index 4ffa546..7d35abc 100644 --- a/testRoot/init64_process_helper.h +++ b/testRoot/kernel_root_kit/kernel_root_kit_init64_process_helper.h @@ -3,10 +3,11 @@ #include #include #include -#include "random_utils.h" -#include "process64_inject.h" -#include "process_cmdline_utils.h" +#include "kernel_root_kit_random.h" +#include "kernel_root_kit_process64_inject.h" +#include "kernel_root_kit_process_cmdline_utils.h" +namespace kernel_root { //注入init64进程远程执行命令 static std::string run_init64_cmd_wrapper( const char* str_root_key, @@ -54,4 +55,5 @@ static std::string safe_run_init64_cmd_wrapper( } return str_cmd_result; } +} #endif /* INIT64_HELPER_H_ */ diff --git a/testRoot/kernel_root_kit/kernel_root_kit_log.h b/testRoot/kernel_root_kit/kernel_root_kit_log.h new file mode 100644 index 0000000..d76766b --- /dev/null +++ b/testRoot/kernel_root_kit/kernel_root_kit_log.h @@ -0,0 +1,22 @@ +#ifndef _KERNEL_ROOT_KIT_LOG_H_ +#define _KERNEL_ROOT_KIT_LOG_H_ +#include +namespace kernel_root { +#define QUIET_KERNEL_ROOT_KIT_PRINTF + +#ifdef QUIET_KERNEL_ROOT_KIT_PRINTF +#undef ROOT_PRINTF +#define ROOT_PRINTF(fmt, ...) +#else +#ifdef __ANDROID__ +#undef ROOT_PRINTF +#include +#define ROOT_PRINTF "JNIGlue" +//#define TRACE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__) +#define ROOT_PRINTF(fmt, ...) printf(fmt, ##__VA_ARGS__) +#else +#define ROOT_PRINTF(fmt, ...) printf(fmt, ##__VA_ARGS__) +#endif +#endif +} +#endif /* _KERNEL_ROOT_KIT_LOG_H_ */ diff --git a/testRoot/maps_helper.h b/testRoot/kernel_root_kit/kernel_root_kit_maps_helper.h similarity index 98% rename from testRoot/maps_helper.h rename to testRoot/kernel_root_kit/kernel_root_kit_maps_helper.h index e1a1a1c..a96f204 100644 --- a/testRoot/maps_helper.h +++ b/testRoot/kernel_root_kit/kernel_root_kit_maps_helper.h @@ -6,7 +6,7 @@ #include #include - +namespace kernel_root { static std::string find_process_libc_so_path(pid_t pid) { char line[1024] = { 0 }; std::string so_path; @@ -82,6 +82,6 @@ static void* get_module_base(pid_t pid, const char* module_name) { return (void*)addr; } - +} #endif /* MAPS_HELPER_H_ */ diff --git a/testRoot/process64_inject.cpp b/testRoot/kernel_root_kit/kernel_root_kit_process64_inject.cpp similarity index 86% rename from testRoot/process64_inject.cpp rename to testRoot/kernel_root_kit/kernel_root_kit_process64_inject.cpp index cf6ddc9..c0519f9 100644 --- a/testRoot/process64_inject.cpp +++ b/testRoot/kernel_root_kit/kernel_root_kit_process64_inject.cpp @@ -15,11 +15,14 @@ #include #include -#include "process64_inject.h" -#include "ptrace_arm64_utils.h" -#include "maps_helper.h" -#include "kernel_root_helper.h" -#include "so_symbol_parser.h" +#include "kernel_root_kit_process64_inject.h" +#include "kernel_root_kit_ptrace_arm64_utils.h" +#include "kernel_root_kit_maps_helper.h" +#include "kernel_root_kit_command.h" +#include "kernel_root_kit_so_symbol_parser.h" +#include "kernel_root_kit_log.h" + +namespace kernel_root { int safe_load_libc64_run_cmd_func_addr( const char* so_path, @@ -37,7 +40,7 @@ int safe_load_libc64_run_cmd_func_addr( void* p_so_addr = get_module_base(-1, so_path); if (p_so_addr) { - TRACE("myself have this so.\n"); + ROOT_PRINTF("myself have this so.\n"); //自身有这个so void* p_so = dlopen(so_path, RTLD_NOW | RTLD_GLOBAL); if (p_so) { @@ -257,7 +260,7 @@ std::string inject_process64_run_cmd( } memset(sp_out_shell_buf.get(), 0, remote_alloc_buf_size); - TRACE("[+] Injecting process: %d\n", target_pid); + ROOT_PRINTF("[+] Injecting process: %d\n", target_pid); //①ATTATCH,指定目标进程,开始调试 if (ptrace_attach(target_pid) == -1) { @@ -281,7 +284,7 @@ std::string inject_process64_run_cmd( //获取远程pid的某个模块的起始地址 remote_libc64_handle = (size_t)get_module_base(target_pid, libc64_so_path); if (remote_libc64_handle == 0) { - TRACE("[+] get_module_base failed.\n"); + ROOT_PRINTF("[+] get_module_base failed.\n"); goto _deatch; } mmap_addr = p_mmap_offset ? remote_libc64_handle + p_mmap_offset : 0; @@ -295,16 +298,16 @@ std::string inject_process64_run_cmd( pclose_addr = p_pclose_offset ? remote_libc64_handle + p_pclose_offset : 0; read_addr = p_read_offset ? remote_libc64_handle + p_read_offset : 0; - TRACE("[+] Remote mmap address: %p\n", (void*)mmap_addr); - TRACE("[+] Remote munmap address: %p\n", (void*)munmap_addr); - TRACE("[+] Remote chdir address: %p\n", (void*)p_chdir_offset); - TRACE("[+] Remote clearenv address: %p\n", (void*)p_clearenv_offset); - TRACE("[+] Remote setenv address: %p\n", (void*)p_setenv_offset); - TRACE("[+] Remote execve address: %p\n", (void*)execve_addr); - TRACE("[+] Remote fileno address: %p\n", (void*)fileno_addr); - TRACE("[+] Remote popen address: %p\n", (void*)popen_addr); - TRACE("[+] Remote pclose address: %p\n", (void*)pclose_addr); - TRACE("[+] Remote read address: %p\n", (void*)read_addr); + ROOT_PRINTF("[+] Remote mmap address: %p\n", (void*)mmap_addr); + ROOT_PRINTF("[+] Remote munmap address: %p\n", (void*)munmap_addr); + ROOT_PRINTF("[+] Remote chdir address: %p\n", (void*)p_chdir_offset); + ROOT_PRINTF("[+] Remote clearenv address: %p\n", (void*)p_clearenv_offset); + ROOT_PRINTF("[+] Remote setenv address: %p\n", (void*)p_setenv_offset); + ROOT_PRINTF("[+] Remote execve address: %p\n", (void*)execve_addr); + ROOT_PRINTF("[+] Remote fileno address: %p\n", (void*)fileno_addr); + ROOT_PRINTF("[+] Remote popen address: %p\n", (void*)popen_addr); + ROOT_PRINTF("[+] Remote pclose address: %p\n", (void*)pclose_addr); + ROOT_PRINTF("[+] Remote read address: %p\n", (void*)read_addr); @@ -327,7 +330,7 @@ std::string inject_process64_run_cmd( map_base = (uint8_t*)ptrace_retval(®s); //判断是否需要提权 if (user_root_auth) { - TRACE("[+] start get root:%s\n", str_root_key); + ROOT_PRINTF("[+] start get root:%s\n", str_root_key); //提权ROOT ptrace_writedata(target_pid, map_base, (uint8_t*)str_root_key, strlen(str_root_key) + 1); parameters[0] = (unsigned long)map_base; @@ -336,7 +339,7 @@ std::string inject_process64_run_cmd( if (ptrace_call_wrapper(target_pid, "execve", (void*)execve_addr, parameters, 3, ®s) == -1) { goto _recovery; } - TRACE("[+] get root finished.\n"); + ROOT_PRINTF("[+] get root finished.\n"); } //判断是否需要改变工作目录 @@ -389,17 +392,17 @@ std::string inject_process64_run_cmd( fp_cmd = (FILE *)ptrace_retval(®s); if (!fp_cmd || fp_cmd == (FILE *)-1) { //popen error - TRACE("[+] popen error\n"); + ROOT_PRINTF("[+] popen error\n"); goto _recovery; } - TRACE("[+] popen success: %p\n", fp_cmd); + ROOT_PRINTF("[+] popen success: %p\n", fp_cmd); parameters[0] = (unsigned long)fp_cmd; if (ptrace_call_wrapper(target_pid, "fileno", (void*)fileno_addr, parameters, 1, ®s) == -1) { goto _recovery; } pip_fp = (int)ptrace_retval(®s); - TRACE("[+] pip_fp:%d\n", pip_fp); + ROOT_PRINTF("[+] pip_fp:%d\n", pip_fp); // 循环读取内容 while(true) { @@ -411,7 +414,7 @@ std::string inject_process64_run_cmd( goto _recovery; } remote_really_read = (ssize_t)ptrace_retval(®s); - TRACE("[+] remote_really_read: %zd, %p\n", remote_really_read, erron_regs.regs[0]); + ROOT_PRINTF("[+] remote_really_read: %zd, %p\n", remote_really_read, erron_regs.regs[0]); //获取erron if (ptrace_getregs(target_pid, &erron_regs) == -1) { @@ -430,7 +433,7 @@ std::string inject_process64_run_cmd( } } - TRACE("[+] popen result: %s\n", cmd_exec_result.c_str()); + ROOT_PRINTF("[+] popen result: %s\n", cmd_exec_result.c_str()); parameters[0] = (unsigned long)fp_cmd; //执行pclose(fp_cmd); @@ -447,7 +450,7 @@ std::string inject_process64_run_cmd( } out_err = 0; - //TRACE("Press enter to detach\n"); + //ROOT_PRINTF("Press enter to detach\n"); //getchar(); /* restore */ @@ -492,7 +495,7 @@ ssize_t inject_process_env64_PATH( input_env_buf_size = getpagesize(); } - TRACE("[+] Injecting process: %d\n", target_pid); + ROOT_PRINTF("[+] Injecting process: %d\n", target_pid); //①ATTATCH,指定目标进程,开始调试 if (ptrace_attach(target_pid) == -1) { @@ -518,7 +521,7 @@ ssize_t inject_process_env64_PATH( //获取远程pid的某个模块的起始地址 remote_libc64_handle = (size_t)get_module_base(target_pid, libc64_so_path); if (remote_libc64_handle == 0) { - TRACE("[+] get_module_base failed.\n"); + ROOT_PRINTF("[+] get_module_base failed.\n"); goto _deatch; } mmap_addr = p_mmap_offset ? remote_libc64_handle + p_mmap_offset : 0; @@ -526,10 +529,10 @@ ssize_t inject_process_env64_PATH( getenv_addr = p_getenv_offset ? remote_libc64_handle + p_getenv_offset : 0; setenv_addr = p_setenv_offset ? remote_libc64_handle + p_setenv_offset : 0; - TRACE("[+] Remote mmap address: %p\n", (void*)mmap_addr); - TRACE("[+] Remote munmap address: %p\n", (void*)munmap_addr); - TRACE("[+] Remote getenv address: %p\n", (void*)getenv_addr); - TRACE("[+] Remote setenv address: %p\n", (void*)setenv_addr); + ROOT_PRINTF("[+] Remote mmap address: %p\n", (void*)mmap_addr); + ROOT_PRINTF("[+] Remote munmap address: %p\n", (void*)munmap_addr); + ROOT_PRINTF("[+] Remote getenv address: %p\n", (void*)getenv_addr); + ROOT_PRINTF("[+] Remote setenv address: %p\n", (void*)setenv_addr); /* call mmap (null, 0x4000, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0); @@ -561,7 +564,7 @@ ssize_t inject_process_env64_PATH( ret_getenv = (char*)ptrace_retval(®s); if (!ret_getenv) { //getenv error - TRACE("getenv error\n"); + ROOT_PRINTF("getenv error\n"); goto _recovery; } str_cur_path += add_path; @@ -575,7 +578,7 @@ ssize_t inject_process_env64_PATH( } while (tmp_read_byte[0] != '\x00'); - TRACE("[+] Remote cur path: %s\n", str_cur_path.c_str()); + ROOT_PRINTF("[+] Remote cur path: %s\n", str_cur_path.c_str()); //写PATH变量进mmap出来的内存 ptrace_writedata(target_pid, map_base + strlen(str_flag_path) + 1, (uint8_t*)str_cur_path.c_str(), str_cur_path.length() + 1); @@ -590,7 +593,7 @@ ssize_t inject_process_env64_PATH( } if (ptrace_retval(®s)) { //setenv error - TRACE("setenv error\n"); + ROOT_PRINTF("setenv error\n"); goto _recovery; } @@ -603,7 +606,7 @@ ssize_t inject_process_env64_PATH( } ret = 0; - //TRACE("Press enter to detach\n"); + //ROOT_PRINTF("Press enter to detach\n"); //getchar(); /* restore */ @@ -645,7 +648,7 @@ ssize_t inject_process64_so( goto _ret; } - TRACE("[+] Injecting process: %d\n", target_pid); + ROOT_PRINTF("[+] Injecting process: %d\n", target_pid); //①ATTATCH,指定目标进程,开始调试 if (ptrace_attach(target_pid) == -1) { @@ -670,7 +673,7 @@ ssize_t inject_process64_so( //获取远程pid的某个模块的起始地址 remote_libc64_handle = (size_t)get_module_base(target_pid, libc64_so_path); if (remote_libc64_handle == 0) { - TRACE("[+] get_module_base failed.\n"); + ROOT_PRINTF("[+] get_module_base failed.\n"); goto _deatch; } dlopen_addr = p_dlopen_offset ? remote_libc64_handle + p_dlopen_offset : 0; @@ -678,10 +681,10 @@ ssize_t inject_process64_so( mmap_addr = p_mmap_offset ? remote_libc64_handle + p_mmap_offset : 0; munmap_addr = p_munmap_offset ? remote_libc64_handle + p_munmap_offset : 0; - TRACE("[+] Remote dlopen address: %p\n", (void*)p_dlopen_offset); - TRACE("[+] Remote dlsym address: %p\n", (void*)p_dlsym_offset); - TRACE("[+] Remote mmap address: %p\n", (void*)mmap_addr); - TRACE("[+] Remote munmap address: %p\n", (void*)munmap_addr); + ROOT_PRINTF("[+] Remote dlopen address: %p\n", (void*)p_dlopen_offset); + ROOT_PRINTF("[+] Remote dlsym address: %p\n", (void*)p_dlsym_offset); + ROOT_PRINTF("[+] Remote mmap address: %p\n", (void*)mmap_addr); + ROOT_PRINTF("[+] Remote munmap address: %p\n", (void*)munmap_addr); /* call mmap (null, 0x4000, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0); @@ -714,7 +717,7 @@ ssize_t inject_process64_so( target_so_handle = (void*)ptrace_retval(®s); if (!target_so_handle) { //dlopen error - TRACE("dlopen error\n"); + ROOT_PRINTF("dlopen error\n"); goto _recovery; } @@ -731,7 +734,7 @@ ssize_t inject_process64_so( target_func_addr = (void*)ptrace_retval(®s); if (!target_func_addr) { //dlsym error - TRACE("dlsym error\n"); + ROOT_PRINTF("dlsym error\n"); goto _recovery; } @@ -749,7 +752,7 @@ ssize_t inject_process64_so( // goto _recovery; //} ret = 0; - //TRACE("Press enter to detach\n"); + //ROOT_PRINTF("Press enter to detach\n"); //getchar(); /* restore */ @@ -771,7 +774,7 @@ ssize_t inject_process64_run_exit( size_t exit_addr; struct pt_regs regs, original_regs; unsigned long parameters[1]; - TRACE("[+] Injecting process: %d\n", target_pid); + ROOT_PRINTF("[+] Injecting process: %d\n", target_pid); //①ATTATCH,指定目标进程,开始调试 if (ptrace_attach(target_pid) == -1) { @@ -796,18 +799,18 @@ ssize_t inject_process64_run_exit( //获取远程pid的某个模块的起始地址 remote_libc64_handle = (size_t)get_module_base(target_pid, libc64_so_path); if (remote_libc64_handle == 0) { - TRACE("[+] get_module_base failed.\n"); + ROOT_PRINTF("[+] get_module_base failed.\n"); goto _deatch; } exit_addr = p_exit_offset ? remote_libc64_handle + p_exit_offset : 0; - TRACE("[+] Remote exit address: %p\n", (void*)p_exit_offset); + ROOT_PRINTF("[+] Remote exit address: %p\n", (void*)p_exit_offset); parameters[0] = 0; if (ptrace_call_wrapper(target_pid, "_exit", (void*)exit_addr, parameters, 1, ®s) == -1) { goto _recovery; } ret = 0; - //TRACE("Press enter to detach\n"); + //ROOT_PRINTF("Press enter to detach\n"); //getchar(); /* restore */ @@ -847,7 +850,7 @@ std::string inject_process64_run_cmd_wrapper( out_err = -243; return {}; } - TRACE("target_process_libc_so_path:%s\n", target_process_libc_so_path.c_str()); + ROOT_PRINTF("target_process_libc_so_path:%s\n", target_process_libc_so_path.c_str()); size_t p_mmap_offset; size_t p_munmap_offset; @@ -873,20 +876,20 @@ std::string inject_process64_run_cmd_wrapper( p_read_offset); if (r != 0) { - TRACE("safe_load_libc64_run_cmd_func_addr error:%d\n", r); + ROOT_PRINTF("safe_load_libc64_run_cmd_func_addr error:%d\n", r); out_err = r; return {}; } - TRACE("p_mmap_offset:%zu\n", p_mmap_offset); - TRACE("p_munmap_offset:%zu\n", p_munmap_offset); - TRACE("p_chdir_offset:%zu\n", p_chdir_offset); - TRACE("p_clearenv_offset:%zu\n", p_clearenv_offset); - TRACE("p_setenv_offset:%zu\n", p_setenv_offset); - TRACE("p_execve_offset:%zu\n", p_execve_offset); - TRACE("p_fileno_offset:%zu\n", p_fileno_offset); - TRACE("p_popen_offset:%zu\n", p_popen_offset); - TRACE("p_pclose_offset:%zu\n", p_pclose_offset); - TRACE("p_read_offset:%zu\n", p_read_offset); + ROOT_PRINTF("p_mmap_offset:%zu\n", p_mmap_offset); + ROOT_PRINTF("p_munmap_offset:%zu\n", p_munmap_offset); + ROOT_PRINTF("p_chdir_offset:%zu\n", p_chdir_offset); + ROOT_PRINTF("p_clearenv_offset:%zu\n", p_clearenv_offset); + ROOT_PRINTF("p_setenv_offset:%zu\n", p_setenv_offset); + ROOT_PRINTF("p_execve_offset:%zu\n", p_execve_offset); + ROOT_PRINTF("p_fileno_offset:%zu\n", p_fileno_offset); + ROOT_PRINTF("p_popen_offset:%zu\n", p_popen_offset); + ROOT_PRINTF("p_pclose_offset:%zu\n", p_pclose_offset); + ROOT_PRINTF("p_read_offset:%zu\n", p_read_offset); return inject_process64_run_cmd( str_root_key, @@ -979,7 +982,7 @@ ssize_t inject_process_env64_PATH_wrapper(const char* str_root_key, int target_p if (target_process_libc_so_path.empty()) { return -273; } - TRACE("target_process_libc_so_path:%s\n", target_process_libc_so_path.c_str()); + ROOT_PRINTF("target_process_libc_so_path:%s\n", target_process_libc_so_path.c_str()); size_t p_mmap_offset; @@ -995,13 +998,13 @@ ssize_t inject_process_env64_PATH_wrapper(const char* str_root_key, int target_p p_setenv_offset); if (ret != 0) { - TRACE("safe_load_libc64_modify_env_func_addr error:%d\n", ret); + ROOT_PRINTF("safe_load_libc64_modify_env_func_addr error:%d\n", ret); return ret; } - TRACE("p_mmap_offset:%zu\n", p_mmap_offset); - TRACE("p_munmap_offset:%zu\n", p_munmap_offset); - TRACE("p_getenv_offset:%zu\n", p_getenv_offset); - TRACE("p_setenv_offset:%zu\n", p_setenv_offset); + ROOT_PRINTF("p_mmap_offset:%zu\n", p_mmap_offset); + ROOT_PRINTF("p_munmap_offset:%zu\n", p_munmap_offset); + ROOT_PRINTF("p_getenv_offset:%zu\n", p_getenv_offset); + ROOT_PRINTF("p_setenv_offset:%zu\n", p_setenv_offset); if (inject_process_env64_PATH(target_pid, target_process_libc_so_path.c_str(), p_mmap_offset, p_munmap_offset, p_getenv_offset, p_setenv_offset, add_path) != 0) { return -274; @@ -1046,7 +1049,7 @@ ssize_t safe_inject_process_env64_PATH_wrapper(const char* str_root_key, int tar out_err = -286; return {}; } - TRACE("target_process_libc_so_path:%s\n", libc_path.c_str()); + ROOT_PRINTF("target_process_libc_so_path:%s\n", libc_path.c_str()); size_t p_mmap_offset; @@ -1062,13 +1065,13 @@ ssize_t safe_inject_process_env64_PATH_wrapper(const char* str_root_key, int tar p_setenv_offset); if (out_err != 0) { - TRACE("safe_load_libc64_modify_env_func_addr error:%zd\n", out_err); + ROOT_PRINTF("safe_load_libc64_modify_env_func_addr error:%zd\n", out_err); return out_err; } - TRACE("p_mmap_offset:%zu\n", p_mmap_offset); - TRACE("p_munmap_offset:%zu\n", p_munmap_offset); - TRACE("p_getenv_offset:%zu\n", p_getenv_offset); - TRACE("p_setenv_offset:%zu\n", p_setenv_offset); + ROOT_PRINTF("p_mmap_offset:%zu\n", p_mmap_offset); + ROOT_PRINTF("p_munmap_offset:%zu\n", p_munmap_offset); + ROOT_PRINTF("p_getenv_offset:%zu\n", p_getenv_offset); + ROOT_PRINTF("p_setenv_offset:%zu\n", p_setenv_offset); finfo.reset(); @@ -1105,7 +1108,7 @@ ssize_t inject_process64_so_wrapper(const char* str_root_key, pid_t target_pid, if (target_process_libc_so_path.empty()) { return -303; } - TRACE("target_process_libc_so_path:%s\n", target_process_libc_so_path.c_str()); + ROOT_PRINTF("target_process_libc_so_path:%s\n", target_process_libc_so_path.c_str()); size_t p_dlopen_offset; size_t p_dlsym_offset; @@ -1119,13 +1122,13 @@ ssize_t inject_process64_so_wrapper(const char* str_root_key, pid_t target_pid, p_munmap_offset); if (ret != 0) { - TRACE("safe_load_libc64_so_inject_func_addr error:%d\n", ret); + ROOT_PRINTF("safe_load_libc64_so_inject_func_addr error:%d\n", ret); return ret; } - TRACE("p_dlopen_offset:%zu\n", p_dlopen_offset); - TRACE("p_dlsym_offset:%zu\n", p_dlsym_offset); - TRACE("p_mmap_offset:%zu\n", p_mmap_offset); - TRACE("p_munmap_offset:%zu\n", p_munmap_offset); + ROOT_PRINTF("p_dlopen_offset:%zu\n", p_dlopen_offset); + ROOT_PRINTF("p_dlsym_offset:%zu\n", p_dlsym_offset); + ROOT_PRINTF("p_mmap_offset:%zu\n", p_mmap_offset); + ROOT_PRINTF("p_munmap_offset:%zu\n", p_munmap_offset); if (inject_process64_so( target_pid, @@ -1177,7 +1180,7 @@ ssize_t safe_inject_process64_so_wrapper(const char* str_root_key, pid_t target_ out_err = -315; return {}; } - TRACE("target process libc so path:%s\n", libc_path.c_str()); + ROOT_PRINTF("target process libc so path:%s\n", libc_path.c_str()); size_t p_dlopen_offset; size_t p_dlsym_offset; @@ -1191,13 +1194,13 @@ ssize_t safe_inject_process64_so_wrapper(const char* str_root_key, pid_t target_ p_munmap_offset); if (out_err != 0) { - TRACE("safe_load_libc64_so_inject_func_addr error:%zd\n", out_err); + ROOT_PRINTF("safe_load_libc64_so_inject_func_addr error:%zd\n", out_err); return out_err; } - TRACE("p_dlopen_offset:%zu\n", p_dlopen_offset); - TRACE("p_dlsym_offset:%zu\n", p_dlsym_offset); - TRACE("p_mmap_offset:%zu\n", p_mmap_offset); - TRACE("p_munmap_offset:%zu\n", p_munmap_offset); + ROOT_PRINTF("p_dlopen_offset:%zu\n", p_dlopen_offset); + ROOT_PRINTF("p_dlsym_offset:%zu\n", p_dlsym_offset); + ROOT_PRINTF("p_mmap_offset:%zu\n", p_mmap_offset); + ROOT_PRINTF("p_munmap_offset:%zu\n", p_munmap_offset); finfo.reset(); if(fork_pipe_child_process(finfo)) { @@ -1253,7 +1256,7 @@ ssize_t inject_process_run_exit_wrapper(const char* str_root_key, int target_pid if (target_process_libc_so_path.empty()) { return -273; } - TRACE("target_process_libc_so_path:%s\n", target_process_libc_so_path.c_str()); + ROOT_PRINTF("target_process_libc_so_path:%s\n", target_process_libc_so_path.c_str()); size_t p_exit_offset; @@ -1263,10 +1266,10 @@ ssize_t inject_process_run_exit_wrapper(const char* str_root_key, int target_pid p_exit_offset); if (err != 0) { - TRACE("safe_load_libc64_exit_func_addr error:%d\n", err); + ROOT_PRINTF("safe_load_libc64_exit_func_addr error:%d\n", err); return err; } - TRACE("p_exit_offset:%zu\n", p_exit_offset); + ROOT_PRINTF("p_exit_offset:%zu\n", p_exit_offset); if (inject_process64_run_exit(target_pid, target_process_libc_so_path.c_str(), p_exit_offset) != 0) { return -274; @@ -1331,3 +1334,4 @@ ssize_t safe_kill_process(const char* str_root_key, pid_t pid) { } return err; } +} diff --git a/testRoot/process64_inject.h b/testRoot/kernel_root_kit/kernel_root_kit_process64_inject.h similarity index 98% rename from testRoot/process64_inject.h rename to testRoot/kernel_root_kit/kernel_root_kit_process64_inject.h index 90000e9..bec1256 100644 --- a/testRoot/process64_inject.h +++ b/testRoot/kernel_root_kit/kernel_root_kit_process64_inject.h @@ -1,10 +1,9 @@ #ifndef _PROCESS64_INJECT_H_ #define _PROCESS64_INJECT_H_ -#include "testRoot.h" #include #include - +namespace kernel_root { //注入64位进程远程执行命令 struct process64_env { char key[0x1000]; //key和name的值不能大于pagesize @@ -49,4 +48,5 @@ ssize_t safe_inject_process_run_exit_wrapper(const char* str_root_key, int targe ssize_t kill_process(const char* str_root_key, pid_t pid); ssize_t safe_kill_process(const char* str_root_key, pid_t pid); +} #endif /* _PROCESS64_INJECT_H_ */ diff --git a/testRoot/process_cmdline_utils.h b/testRoot/kernel_root_kit/kernel_root_kit_process_cmdline_utils.h similarity index 98% rename from testRoot/process_cmdline_utils.h rename to testRoot/kernel_root_kit/kernel_root_kit_process_cmdline_utils.h index a325c9b..747fb48 100644 --- a/testRoot/process_cmdline_utils.h +++ b/testRoot/kernel_root_kit/kernel_root_kit_process_cmdline_utils.h @@ -7,9 +7,9 @@ #include #include #include -#include "kernel_root_helper.h" -#include "kernel_root_key.h" +#include "kernel_root_kit_command.h" +namespace kernel_root { static ssize_t find_all_cmdline_process(const char* str_root_key, const char* target_cmdline, std::vector & vOut) { int pid; @@ -107,7 +107,6 @@ static ssize_t wait_and_find_cmdline_process(const char* str_root_key, const cha if (kernel_root::get_root(str_root_key) != 0) { return -1000021; } - setpriority(PRIO_PROCESS, 0, -20); clock_t start = clock(); while (1) { sleep(0); @@ -200,5 +199,6 @@ static ssize_t safe_wait_and_find_cmdline_process(const char* str_root_key, cons } return err; } +} #endif /* PROCESS_CMDLINE_UTILS_H_ */ diff --git a/testRoot/ptrace_arm64_utils.cpp b/testRoot/kernel_root_kit/kernel_root_kit_ptrace_arm64_utils.cpp similarity index 84% rename from testRoot/ptrace_arm64_utils.cpp rename to testRoot/kernel_root_kit/kernel_root_kit_ptrace_arm64_utils.cpp index ce2373e..077bb56 100644 --- a/testRoot/ptrace_arm64_utils.cpp +++ b/testRoot/kernel_root_kit/kernel_root_kit_ptrace_arm64_utils.cpp @@ -1,272 +1,273 @@ -#include "ptrace_arm64_utils.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "testRoot.h" - -int ptrace_readdata(pid_t pid, uint8_t *src, uint8_t *buf, size_t size) -{ - long i, j, remain; - uint8_t *laddr; - size_t bytes_width = sizeof(long); - - union u { - long val; - char chars[sizeof(val)]; - } d; - - j = size / bytes_width; - remain = size % bytes_width; - - laddr = buf; - - for (i = 0; i < j; i++) { - d.val = ptrace(PTRACE_PEEKTEXT, pid, src, 0); - memcpy(laddr, d.chars, bytes_width); - src += bytes_width; - laddr += bytes_width; - } - - if (remain > 0) { - d.val = ptrace(PTRACE_PEEKTEXT, pid, src, 0); - memcpy(laddr, d.chars, remain); - } - - return 0; -} - -/* -Func : 将size字节的data数据写入到pid进程的dest地址处 -@param dest: 目的进程的栈地址 -@param data: 需要写入的数据的起始地址 -@param size: 需要写入的数据的大小,以字节为单位 -*/ -int ptrace_writedata(pid_t pid, uint8_t *dest, uint8_t *data, size_t size) -{ - long i, j, remain; - uint8_t *laddr; - size_t bytes_width = sizeof(long); - - //很巧妙的联合体,这样就可以方便的以字节为单位写入4字节数据,再以long为单位ptrace_poketext到栈中 - union u { - long val; - char chars[sizeof(val)]; - } d; - - j = size / bytes_width; - remain = size % bytes_width; - - laddr = data; - - //先以4字节为单位进行数据写入 - - for (i = 0; i < j; i++) { - memcpy(d.chars, laddr, bytes_width); - ptrace(PTRACE_POKETEXT, pid, dest, d.val); - - dest += bytes_width; - laddr += bytes_width; - } - - if (remain > 0) { - //为了最大程度的保持原栈的数据,先读取dest的long数据,然后只更改其中的前remain字节,再写回 - d.val = ptrace(PTRACE_PEEKTEXT, pid, dest, 0); - for (i = 0; i < remain; i++) { - d.chars[i] = *laddr++; - } - - ptrace(PTRACE_POKETEXT, pid, dest, d.val); - } - - return 0; -} - - -int ptrace_getregs(pid_t pid, struct pt_regs * regs) -{ - int regset = NT_PRSTATUS; - struct iovec ioVec; - - ioVec.iov_base = regs; - ioVec.iov_len = sizeof(*regs); - if (ptrace(PTRACE_GETREGSET, pid, (size_t)regset, &ioVec) < 0) { - perror("ptrace_getregs: Can not get register values"); - TRACE(" io %p, %lu", ioVec.iov_base, ioVec.iov_len); - return -1; - } - return 0; -} - -int ptrace_setregs(pid_t pid, struct pt_regs * regs) -{ - int regset = NT_PRSTATUS; - struct iovec ioVec; - - ioVec.iov_base = regs; - ioVec.iov_len = sizeof(*regs); - if (ptrace(PTRACE_SETREGSET, pid, (size_t)regset, &ioVec) < 0) { - perror("ptrace_setregs: Can not get register values"); - return -1; - } - return 0; -} - -int ptrace_continue(pid_t pid) -{ - if (ptrace(PTRACE_CONT, pid, NULL, 0) < 0) { - perror("ptrace_cont"); - return -1; - } - - return 0; -} - -int ptrace_attach(pid_t pid) -{ - if (ptrace(PTRACE_ATTACH, pid, NULL, 0) < 0) { - perror("ptrace_attach"); - return -1; - } - - int status = 0; - waitpid(pid, &status, WUNTRACED); - - return 0; -} - -int ptrace_detach(pid_t pid) -{ - if (ptrace(PTRACE_DETACH, pid, NULL, 0) < 0) { - perror("ptrace_detach"); - return -1; - } - - return 0; -} - -uint64_t ptrace_retval(struct pt_regs * regs) -{ - return regs->ARM_r0; -} - -uint64_t ptrace_ip(struct pt_regs * regs) -{ - return regs->ARM_pc; -} - -//总结一下ptrace_call_wrapper,它的完成两个功能: -//一是调用ptrace_call函数来执行指定函数,执行完后将子进程挂起; -//二是调用ptrace_getregs函数获取所有寄存器的值,主要是为了获取r0即函数的返回值。 -int ptrace_call_wrapper(pid_t target_pid, const char * func_name, void * func_addr, unsigned long * parameters, int param_num, struct pt_regs * regs) -{ - TRACE("[+] Calling %s in target process.\n", func_name); - if (ptrace_call(target_pid, (uintptr_t)func_addr, parameters, param_num, regs) == -1) - return -1; - - if (ptrace_getregs(target_pid, regs) == -1) - return -1; - TRACE("[+] Target process returned from %s, return value=%" PRIu64 ", pc=%" PRIu64 " \n", - func_name, ptrace_retval(regs), ptrace_ip(regs)); - return 0; -} - -/* -功能总结: -1,将要执行的指令写入寄存器中,指令长度大于4个long的话,需要将剩余的指令通过ptrace_writedata函数写入栈中; -2,使用ptrace_continue函数运行目的进程,直到目的进程返回状态值0xb7f(对该值的分析见后面红字); -3,函数执行完之后,目标进程挂起,使用ptrace_getregs函数获取当前的所有寄存器值,方便后面使用ptrace_retval函数获取函数的返回值。 -*/ -int ptrace_call(pid_t pid, uintptr_t addr, unsigned long *params, int num_params, struct pt_regs* regs) -{ - int i; - int num_param_registers = 8; //aarch64 - for (i = 0; i < num_params && i < num_param_registers; i++) { - regs->uregs[i] = params[i]; - } - - // - // push remained params onto stack - // - if (i < num_params) { - regs->ARM_sp -= (num_params - i) * sizeof(long); - ptrace_writedata(pid, (uint8_t *)regs->ARM_sp, (uint8_t *)& params[i], (num_params - i) * sizeof(long)); - } - //将PC寄存器值设为目标函数的地址 - regs->ARM_pc = addr; - //进行指令集判断 - if (regs->ARM_pc & 1) { - /* thumb */ - regs->ARM_pc &= (~1u); - // #define CPSR_T_MASK ( 1u << 5 ) CPSR为程序状态寄存器 - regs->ARM_cpsr |= CPSR_T_MASK; - } - else { - /* arm */ - regs->ARM_cpsr &= ~CPSR_T_MASK; - } - - //设置子程序的返回地址为空,以便函数执行完后,返回到null地址,产生SIGSEGV错误,详细作用见后面的红字分析 - regs->ARM_lr = 0; - - /* - *Ptrace_setregs就是将修改后的regs写入寄存器中,然后调用ptrace_continue来执行我们指定的代码 - */ - if (ptrace_setregs(pid, regs) == -1 || ptrace_continue(pid) == -1) { - return -1; - } - -/* -WUNTRACED告诉waitpid,如果子进程进入暂停状态,那么就立即返回。如果是被ptrace的子进程,那么即使不提供WUNTRACED参数,也会在子进程进入暂停状态的时候立即返回。对于使用PTRACE_CONT运行的子进程,它会在3种情况下进入暂停状态:①下一次系统调用;②子进程退出;③子进程的执行发生错误。这里的0xb7f就表示子进程进入了暂停状态,且发送的错误信号为11(SIGSEGV),它表示试图访问未分配给自己的内存, 或试图往没有写权限的内存地址写数据。那么什么时候会发生这种错误呢?显然,当子进程执行完注入的函数后,由于我们在前面设置了regs->ARM_lr = 0,它就会返回到0地址处继续执行,这样就会产生SIGSEGV。 -这里还需要了解下arm架构的相关知识。首先是函数参数传递,在arm中,函数的前4个参数分别保存在r0-r3中,当参数大于4个,就依次压入栈中。此外,arm处理器实际上支持两套指令集,即arm和thumb。thumb为16位,arm为32位。这里通过判断pc的最后一位是否是1来确定指令集,这是因为编译器在用thmub指令集编译一个函数时,会将函数的符号地址设置成真正的映射地址+1,实现arm和thumb混编。此外,在切换arm和thumb指令时,还会修改CPSR处理器。在arm中,出了r0-r15这16个处理器,还有状态寄存器CPSR。关于CPSR的其他位这里先不讨论,我们只要知道CPSR寄存器的第低5位T标识了当前的指令集(T=0表示执行arm指令,T=1表示执行Thumb指令),所以在切换指令集时需要修改这一位。 - -Arm与Thumb之间的状态切换是通过专用的转移交换指令BX来实现。BX指令以通用寄存器(R0~R15)为操作数,通过拷贝Rn到PC实现绝对跳转。BX利用Rn寄存器中目的地址值的最后一位判断跳转后的状态,如果为“1”表示跳转到Thumb指令集的函数中,如果为“0”表示跳转到Arm指令集的函数中。而Arm指令集的每条指令是32位,即4个字节,也就是说Arm指令的地址肯定是4的倍数,最后两位必定为“00”。所以,直接就可以将从符号表中获得的调用地址模4,看是否为0来判断要修改的函数是用Arm指令集还是Thumb指令集。 - - */ - // waitpid(pid, NULL, WUNTRACED); - - int status = 0; - // waitpid(pid,&stat,WUNTRACED); - pid_t res; - waitpid(pid, NULL, WUNTRACED); - /* - * Restarts the stopped child as for PTRACE_CONT, but arranges for - * the child to be stopped at the next entry to or exit from a sys‐ - * tem call, or after execution of a single instruction, respec‐ - * tively. - */ - if (ptrace(PTRACE_SYSCALL, pid, NULL, 0) < 0) { - TRACE("ptrace_syscall"); - return -1; - } - - waitpid(pid, NULL, WUNTRACED); - - if (ptrace(PTRACE_SYSCALL, pid, NULL, NULL) < 0) { - TRACE("ptrace_syscall"); - return -1; - } - - res = waitpid(pid, NULL, WUNTRACED); - - TRACE("[+] status is %x\n", status); - if (res != pid || !WIFSTOPPED(status))//WIFSTOPPED(status) 若为当前暂停子进程返回的状态,则为真 - return 0; - TRACE("[+]done %d\n", (WSTOPSIG(status) == SIGSEGV) ? 1 : 0); - //设置siginal 11信号处理函数 -/* if(signal(SIGSEGV,handler) == SIG_ERR){ - LOGE("[-]can not set handler for SIGSEGV"); - }*/ - - return 0; +#include "kernel_root_kit_log.h" +#include "kernel_root_kit_ptrace_arm64_utils.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace kernel_root { +int ptrace_readdata(pid_t pid, uint8_t *src, uint8_t *buf, size_t size) +{ + long i, j, remain; + uint8_t *laddr; + size_t bytes_width = sizeof(long); + + union u { + long val; + char chars[sizeof(val)]; + } d; + + j = size / bytes_width; + remain = size % bytes_width; + + laddr = buf; + + for (i = 0; i < j; i++) { + d.val = ptrace(PTRACE_PEEKTEXT, pid, src, 0); + memcpy(laddr, d.chars, bytes_width); + src += bytes_width; + laddr += bytes_width; + } + + if (remain > 0) { + d.val = ptrace(PTRACE_PEEKTEXT, pid, src, 0); + memcpy(laddr, d.chars, remain); + } + + return 0; +} + +/* +Func : 将size字节的data数据写入到pid进程的dest地址处 +@param dest: 目的进程的栈地址 +@param data: 需要写入的数据的起始地址 +@param size: 需要写入的数据的大小,以字节为单位 +*/ +int ptrace_writedata(pid_t pid, uint8_t *dest, uint8_t *data, size_t size) +{ + long i, j, remain; + uint8_t *laddr; + size_t bytes_width = sizeof(long); + + //很巧妙的联合体,这样就可以方便的以字节为单位写入4字节数据,再以long为单位ptrace_poketext到栈中 + union u { + long val; + char chars[sizeof(val)]; + } d; + + j = size / bytes_width; + remain = size % bytes_width; + + laddr = data; + + //先以4字节为单位进行数据写入 + + for (i = 0; i < j; i++) { + memcpy(d.chars, laddr, bytes_width); + ptrace(PTRACE_POKETEXT, pid, dest, d.val); + + dest += bytes_width; + laddr += bytes_width; + } + + if (remain > 0) { + //为了最大程度的保持原栈的数据,先读取dest的long数据,然后只更改其中的前remain字节,再写回 + d.val = ptrace(PTRACE_PEEKTEXT, pid, dest, 0); + for (i = 0; i < remain; i++) { + d.chars[i] = *laddr++; + } + + ptrace(PTRACE_POKETEXT, pid, dest, d.val); + } + + return 0; +} + + +int ptrace_getregs(pid_t pid, struct pt_regs * regs) +{ + int regset = NT_PRSTATUS; + struct iovec ioVec; + + ioVec.iov_base = regs; + ioVec.iov_len = sizeof(*regs); + if (ptrace(PTRACE_GETREGSET, pid, (size_t)regset, &ioVec) < 0) { + perror("ptrace_getregs: Can not get register values"); + ROOT_PRINTF(" io %p, %lu", ioVec.iov_base, ioVec.iov_len); + return -1; + } + return 0; +} + +int ptrace_setregs(pid_t pid, struct pt_regs * regs) +{ + int regset = NT_PRSTATUS; + struct iovec ioVec; + + ioVec.iov_base = regs; + ioVec.iov_len = sizeof(*regs); + if (ptrace(PTRACE_SETREGSET, pid, (size_t)regset, &ioVec) < 0) { + perror("ptrace_setregs: Can not get register values"); + return -1; + } + return 0; +} + +int ptrace_continue(pid_t pid) +{ + if (ptrace(PTRACE_CONT, pid, NULL, 0) < 0) { + perror("ptrace_cont"); + return -1; + } + + return 0; +} + +int ptrace_attach(pid_t pid) +{ + if (ptrace(PTRACE_ATTACH, pid, NULL, 0) < 0) { + perror("ptrace_attach"); + return -1; + } + + int status = 0; + waitpid(pid, &status, WUNTRACED); + + return 0; +} + +int ptrace_detach(pid_t pid) +{ + if (ptrace(PTRACE_DETACH, pid, NULL, 0) < 0) { + perror("ptrace_detach"); + return -1; + } + + return 0; +} + +uint64_t ptrace_retval(struct pt_regs * regs) +{ + return regs->ARM_r0; +} + +uint64_t ptrace_ip(struct pt_regs * regs) +{ + return regs->ARM_pc; +} + +//总结一下ptrace_call_wrapper,它的完成两个功能: +//一是调用ptrace_call函数来执行指定函数,执行完后将子进程挂起; +//二是调用ptrace_getregs函数获取所有寄存器的值,主要是为了获取r0即函数的返回值。 +int ptrace_call_wrapper(pid_t target_pid, const char * func_name, void * func_addr, unsigned long * parameters, int param_num, struct pt_regs * regs) +{ + ROOT_PRINTF("[+] Calling %s in target process.\n", func_name); + if (ptrace_call(target_pid, (uintptr_t)func_addr, parameters, param_num, regs) == -1) + return -1; + + if (ptrace_getregs(target_pid, regs) == -1) + return -1; + ROOT_PRINTF("[+] Target process returned from %s, return value=%" PRIu64 ", pc=%" PRIu64 " \n", + func_name, ptrace_retval(regs), ptrace_ip(regs)); + return 0; +} + +/* +功能总结: +1,将要执行的指令写入寄存器中,指令长度大于4个long的话,需要将剩余的指令通过ptrace_writedata函数写入栈中; +2,使用ptrace_continue函数运行目的进程,直到目的进程返回状态值0xb7f(对该值的分析见后面红字); +3,函数执行完之后,目标进程挂起,使用ptrace_getregs函数获取当前的所有寄存器值,方便后面使用ptrace_retval函数获取函数的返回值。 +*/ +int ptrace_call(pid_t pid, uintptr_t addr, unsigned long *params, int num_params, struct pt_regs* regs) +{ + int i; + int num_param_registers = 8; //aarch64 + for (i = 0; i < num_params && i < num_param_registers; i++) { + regs->uregs[i] = params[i]; + } + + // + // push remained params onto stack + // + if (i < num_params) { + regs->ARM_sp -= (num_params - i) * sizeof(long); + ptrace_writedata(pid, (uint8_t *)regs->ARM_sp, (uint8_t *)& params[i], (num_params - i) * sizeof(long)); + } + //将PC寄存器值设为目标函数的地址 + regs->ARM_pc = addr; + //进行指令集判断 + if (regs->ARM_pc & 1) { + /* thumb */ + regs->ARM_pc &= (~1u); + // #define CPSR_T_MASK ( 1u << 5 ) CPSR为程序状态寄存器 + regs->ARM_cpsr |= CPSR_T_MASK; + } + else { + /* arm */ + regs->ARM_cpsr &= ~CPSR_T_MASK; + } + + //设置子程序的返回地址为空,以便函数执行完后,返回到null地址,产生SIGSEGV错误,详细作用见后面的红字分析 + regs->ARM_lr = 0; + + /* + *Ptrace_setregs就是将修改后的regs写入寄存器中,然后调用ptrace_continue来执行我们指定的代码 + */ + if (ptrace_setregs(pid, regs) == -1 || ptrace_continue(pid) == -1) { + return -1; + } + +/* +WUNTRACE告诉waitpid,如果子进程进入暂停状态,那么就立即返回。如果是被ptrace的子进程,那么即使不提供WUNTRACE参数,也会在子进程进入暂停状态的时候立即返回。对于使用PTRACE_CONT运行的子进程,它会在3种情况下进入暂停状态:①下一次系统调用;②子进程退出;③子进程的执行发生错误。这里的0xb7f就表示子进程进入了暂停状态,且发送的错误信号为11(SIGSEGV),它表示试图访问未分配给自己的内存, 或试图往没有写权限的内存地址写数据。那么什么时候会发生这种错误呢?显然,当子进程执行完注入的函数后,由于我们在前面设置了regs->ARM_lr = 0,它就会返回到0地址处继续执行,这样就会产生SIGSEGV。 +这里还需要了解下arm架构的相关知识。首先是函数参数传递,在arm中,函数的前4个参数分别保存在r0-r3中,当参数大于4个,就依次压入栈中。此外,arm处理器实际上支持两套指令集,即arm和thumb。thumb为16位,arm为32位。这里通过判断pc的最后一位是否是1来确定指令集,这是因为编译器在用thmub指令集编译一个函数时,会将函数的符号地址设置成真正的映射地址+1,实现arm和thumb混编。此外,在切换arm和thumb指令时,还会修改CPSR处理器。在arm中,出了r0-r15这16个处理器,还有状态寄存器CPSR。关于CPSR的其他位这里先不讨论,我们只要知道CPSR寄存器的第低5位T标识了当前的指令集(T=0表示执行arm指令,T=1表示执行Thumb指令),所以在切换指令集时需要修改这一位。 + +Arm与Thumb之间的状态切换是通过专用的转移交换指令BX来实现。BX指令以通用寄存器(R0~R15)为操作数,通过拷贝Rn到PC实现绝对跳转。BX利用Rn寄存器中目的地址值的最后一位判断跳转后的状态,如果为“1”表示跳转到Thumb指令集的函数中,如果为“0”表示跳转到Arm指令集的函数中。而Arm指令集的每条指令是32位,即4个字节,也就是说Arm指令的地址肯定是4的倍数,最后两位必定为“00”。所以,直接就可以将从符号表中获得的调用地址模4,看是否为0来判断要修改的函数是用Arm指令集还是Thumb指令集。 + + */ + // waitpid(pid, NULL, WUNTRACED); + + int status = 0; + // waitpid(pid,&stat,WUNTRACED); + pid_t res; + waitpid(pid, NULL, WUNTRACED); + /* + * Restarts the stopped child as for PTRACE_CONT, but arranges for + * the child to be stopped at the next entry to or exit from a sys‐ + * tem call, or after execution of a single instruction, respec‐ + * tively. + */ + if (ptrace(PTRACE_SYSCALL, pid, NULL, 0) < 0) { + ROOT_PRINTF("ptrace_syscall"); + return -1; + } + + waitpid(pid, NULL, WUNTRACED); + + if (ptrace(PTRACE_SYSCALL, pid, NULL, NULL) < 0) { + ROOT_PRINTF("ptrace_syscall"); + return -1; + } + + res = waitpid(pid, NULL, WUNTRACED); + + ROOT_PRINTF("[+] status is %x\n", status); + if (res != pid || !WIFSTOPPED(status))//WIFSTOPPED(status) 若为当前暂停子进程返回的状态,则为真 + return 0; + ROOT_PRINTF("[+]done %d\n", (WSTOPSIG(status) == SIGSEGV) ? 1 : 0); + //设置siginal 11信号处理函数 +/* if(signal(SIGSEGV,handler) == SIG_ERR){ + LOGE("[-]can not set handler for SIGSEGV"); + }*/ + + return 0; +} } \ No newline at end of file diff --git a/testRoot/ptrace_arm64_utils.h b/testRoot/kernel_root_kit/kernel_root_kit_ptrace_arm64_utils.h similarity index 97% rename from testRoot/ptrace_arm64_utils.h rename to testRoot/kernel_root_kit/kernel_root_kit_ptrace_arm64_utils.h index 0bcb963..1c1e197 100644 --- a/testRoot/ptrace_arm64_utils.h +++ b/testRoot/kernel_root_kit/kernel_root_kit_ptrace_arm64_utils.h @@ -1,53 +1,56 @@ -#ifndef PTRACE_ARM64_UTILS_H_ -#define PTRACE_ARM64_UTILS_H_ -#include - -#ifndef __aarch64__ -#error "Not supported" -#endif - -#define pt_regs user_pt_regs -#define uregs regs -#define ARM_pc pc -#define ARM_sp sp -#define ARM_cpsr pstate -#define ARM_lr regs[30] -#define ARM_r0 regs[0] - -#define CPSR_T_MASK ( 1u << 5 ) -#define MAX_PATH 256 - -int ptrace_readdata(pid_t pid, uint8_t *src, uint8_t *buf, size_t size); -/* -Func : 将size字节的data数据写入到pid进程的dest地址处 -@param dest: 目的进程的栈地址 -@param data: 需要写入的数据的起始地址 -@param size: 需要写入的数据的大小,以字节为单位 -*/ -int ptrace_writedata(pid_t pid, uint8_t *dest, uint8_t *data, size_t size); - -int ptrace_getregs(pid_t pid, struct pt_regs * regs); - -int ptrace_setregs(pid_t pid, struct pt_regs * regs); - -int ptrace_continue(pid_t pid); -int ptrace_attach(pid_t pid); - -int ptrace_detach(pid_t pid); - -uint64_t ptrace_retval(struct pt_regs * regs); - -uint64_t ptrace_ip(struct pt_regs * regs); -//总结一下ptrace_call_wrapper,它的完成两个功能: -//一是调用ptrace_call函数来执行指定函数,执行完后将子进程挂起; -//二是调用ptrace_getregs函数获取所有寄存器的值,主要是为了获取r0即函数的返回值。 -int ptrace_call_wrapper(pid_t target_pid, const char * func_name, void * func_addr, unsigned long * parameters, int param_num, struct pt_regs * regs); -/* -功能总结: -1,将要执行的指令写入寄存器中,指令长度大于4个long的话,需要将剩余的指令通过ptrace_writedata函数写入栈中; -2,使用ptrace_continue函数运行目的进程,直到目的进程返回状态值0xb7f(对该值的分析见后面红字); -3,函数执行完之后,目标进程挂起,使用ptrace_getregs函数获取当前的所有寄存器值,方便后面使用ptrace_retval函数获取函数的返回值。 -*/ -int ptrace_call(pid_t pid, uintptr_t addr, unsigned long *params, int num_params, struct pt_regs* regs); - -#endif /* PTRACE_ARM64_UTILS_H_ */ +#ifndef PTRACE_ARM64_UTILS_H_ +#define PTRACE_ARM64_UTILS_H_ +#include +#include + + +namespace kernel_root { +#ifndef __aarch64__ +#error "Not supported" +#endif + +#define pt_regs user_pt_regs +#define uregs regs +#define ARM_pc pc +#define ARM_sp sp +#define ARM_cpsr pstate +#define ARM_lr regs[30] +#define ARM_r0 regs[0] + +#define CPSR_T_MASK ( 1u << 5 ) +#define MAX_PATH 256 + +int ptrace_readdata(pid_t pid, uint8_t *src, uint8_t *buf, size_t size); +/* +Func : 将size字节的data数据写入到pid进程的dest地址处 +@param dest: 目的进程的栈地址 +@param data: 需要写入的数据的起始地址 +@param size: 需要写入的数据的大小,以字节为单位 +*/ +int ptrace_writedata(pid_t pid, uint8_t *dest, uint8_t *data, size_t size); + +int ptrace_getregs(pid_t pid, struct pt_regs * regs); + +int ptrace_setregs(pid_t pid, struct pt_regs * regs); + +int ptrace_continue(pid_t pid); +int ptrace_attach(pid_t pid); + +int ptrace_detach(pid_t pid); + +uint64_t ptrace_retval(struct pt_regs * regs); + +uint64_t ptrace_ip(struct pt_regs * regs); +//总结一下ptrace_call_wrapper,它的完成两个功能: +//一是调用ptrace_call函数来执行指定函数,执行完后将子进程挂起; +//二是调用ptrace_getregs函数获取所有寄存器的值,主要是为了获取r0即函数的返回值。 +int ptrace_call_wrapper(pid_t target_pid, const char * func_name, void * func_addr, unsigned long * parameters, int param_num, struct pt_regs * regs); +/* +功能总结: +1,将要执行的指令写入寄存器中,指令长度大于4个long的话,需要将剩余的指令通过ptrace_writedata函数写入栈中; +2,使用ptrace_continue函数运行目的进程,直到目的进程返回状态值0xb7f(对该值的分析见后面红字); +3,函数执行完之后,目标进程挂起,使用ptrace_getregs函数获取当前的所有寄存器值,方便后面使用ptrace_retval函数获取函数的返回值。 +*/ +int ptrace_call(pid_t pid, uintptr_t addr, unsigned long *params, int num_params, struct pt_regs* regs); +} +#endif /* PTRACE_ARM64_UTILS_H_ */ diff --git a/testRoot/random_utils.h b/testRoot/kernel_root_kit/kernel_root_kit_random.h similarity index 94% rename from testRoot/random_utils.h rename to testRoot/kernel_root_kit/kernel_root_kit_random.h index 2f62793..62b7eee 100644 --- a/testRoot/random_utils.h +++ b/testRoot/kernel_root_kit/kernel_root_kit_random.h @@ -4,7 +4,7 @@ #include #include #include - +namespace kernel_root { /*生成随机数*/ static void rand_str(char* dest, int n) { int i, randno; @@ -16,5 +16,6 @@ static void rand_str(char* dest, int n) { dest++; } } +} #endif /* _RANDOM_UTILS_H_ */ diff --git a/testRoot/so_symbol_parser.h b/testRoot/kernel_root_kit/kernel_root_kit_so_symbol_parser.h similarity index 98% rename from testRoot/so_symbol_parser.h rename to testRoot/kernel_root_kit/kernel_root_kit_so_symbol_parser.h index 1d99fd7..e337ee9 100644 --- a/testRoot/so_symbol_parser.h +++ b/testRoot/kernel_root_kit/kernel_root_kit_so_symbol_parser.h @@ -11,7 +11,7 @@ #include #include #include - +namespace kernel_root { static bool is_elf64_file(int fd) { Elf64_Ehdr elf; int r = read(fd, &elf, sizeof(elf)); @@ -84,4 +84,5 @@ static int get_so_symbol_addr(const char* so_path, std::map #include #include @@ -13,7 +12,7 @@ #include #include #include - +namespace kernel_root { /* * xattr name for SELinux attributes. * This may have been exported via Kernel uapi header. @@ -92,7 +91,6 @@ std::string install_su(const char* str_root_key, const char* base_path, const ch return {}; } std::string su_hide_full_path = _su_hide_folder_path + "/" + "su"; - //如果存在了就不要理了 if(access(su_hide_full_path.c_str(), F_OK) == -1) { if (!copy_file(origin_su_full_path, su_hide_full_path.c_str())) { TRACE("copy file error.\n"); @@ -186,6 +184,7 @@ ssize_t safe_uninstall_su(const char* str_root_key, const char* base_path, const } return err; } +} diff --git a/testRoot/su_install_helper.h b/testRoot/kernel_root_kit/kernel_root_kit_su_install_helper.h similarity index 89% rename from testRoot/su_install_helper.h rename to testRoot/kernel_root_kit/kernel_root_kit_su_install_helper.h index 43d068b..4a642dc 100644 --- a/testRoot/su_install_helper.h +++ b/testRoot/kernel_root_kit/kernel_root_kit_su_install_helper.h @@ -1,12 +1,13 @@ #ifndef _SU_INSTALL_HELPER_H_ #define _SU_INSTALL_HELPER_H_ #include +namespace kernel_root { std::string install_su(const char* str_root_key, const char* base_path, const char* origin_su_full_path, ssize_t & err, const char* su_hide_folder_head_flag = "su"); std::string safe_install_su(const char* str_root_key, const char* base_path, const char* origin_su_full_path, ssize_t& err, const char* su_hide_folder_head_flag = "su"); ssize_t uninstall_su(const char* str_root_key, const char* base_path, const char* su_hide_folder_head_flag = "su" ); -//forkȫ汾ڰ׿APPֱӵã +//fork安全版本(可用于安卓APP直接调用) ssize_t safe_uninstall_su(const char* str_root_key, const char* base_path, const char* su_hide_folder_head_flag = "su"); - +} #endif /* _SU_INSTALL_HELPER_H_ */ diff --git a/testRoot/kernel_root_kit/kernel_root_kit_umbrella.h b/testRoot/kernel_root_kit/kernel_root_kit_umbrella.h new file mode 100644 index 0000000..b9b4f1d --- /dev/null +++ b/testRoot/kernel_root_kit/kernel_root_kit_umbrella.h @@ -0,0 +1,7 @@ +#ifndef KERNEL_ROOT_KIT_UMBRELLA_H_ +#define KERNEL_ROOT_KIT_UMBRELLA_H_ +#include "kernel_root_kit_command.h" +#include "kernel_root_kit_process64_inject.h" +#include "kernel_root_kit_init64_process_helper.h" +#include "kernel_root_kit_su_install_helper.h" +#endif /* KERNEL_ROOT_KIT_UMBRELLA_H_ */ diff --git a/testRoot/main.cpp b/testRoot/main.cpp deleted file mode 100644 index ca905fe..0000000 --- a/testRoot/main.cpp +++ /dev/null @@ -1,147 +0,0 @@ -#include -#include - -#include "super_root.h" -#include "adb_inject.h" -#define ROOT_KEY 0x7F6766F8 - -void show_capability_info() -{ - struct __user_cap_header_struct cap_header_data; - cap_user_header_t cap_header = &cap_header_data; - - struct __user_cap_data_struct cap_data_data; - cap_user_data_t cap_data = &cap_data_data; - - cap_header->pid = getpid(); - cap_header->version = _LINUX_CAPABILITY_VERSION_3; //_1、_2、_3 - - if (capget(cap_header, cap_data) < 0) { - perror("FAILED capget()"); - exit(1); - } - - printf("Cap data 0x%x, 0x%x, 0x%x\n", cap_data->effective, cap_data->permitted, cap_data->inheritable); - printf("now getuid()=%d,geteuid()=%d,getgid()=%d,getegid()=%d\n", getuid(), geteuid(), getgid(), getegid()); - - FILE * fp = popen("getenforce", "r"); - if (fp) - { - char cmd[512] = { 0 }; - fread(cmd, 1, sizeof(cmd), fp); - pclose(fp); - - printf("SELinux status: %s\n", cmd); - } -} -void test_root() -{ - show_capability_info(); - - printf("get_root ret:%d\n", get_root(ROOT_KEY)); - - show_capability_info(); - - //system("id"); - //system("/data/local/tmp/getmyinfo"); - //system("insmod /sdcard/rwProcMem37.ko ; echo $?"); - //system("cat /proc/1/maps"); - //system("ls /proc"); - //system("screencap -p /sdcard/temp.png"); - return; -} - -void test_disable_selinux() -{ - int ret = disable_selinux(ROOT_KEY); - printf("disable_selinux ret:%d\n", ret); - printf("done.\n"); - return; -} - -void test_enable_selinux() -{ - int ret = enable_selinux(ROOT_KEY); - printf("enable_selinux ret:%d\n", ret); - printf("done.\n"); - return; -} - - -void test_run_cmd(char * cmd, bool bKeepAdbRoot = false) { - printf("inject_cmd_remote_process(%s)\n", cmd); - char szResult[0x1000] = { 0 }; - ssize_t ret = safe_inject_adb_process_run_cmd_wrapper(ROOT_KEY, cmd, bKeepAdbRoot, szResult, sizeof(szResult)); - printf("inject_cmd_remote_process ret val:%zd\n", ret); - printf("inject_cmd_remote_process result:%s\n", szResult); -} - -int main(int argc, char *argv[]) -{ - printf( - "======================================================\n" - "本工具名称: Linux ARM64 完美隐藏ROOT演示\n" - "本工具功能列表:\n" - "\t1.显示自身权限信息\n" - "\t2.获取ROOT权限\n" - "\t3.绕过SELinux\n" - "\t4.还原SELinux\n" - "\t5.执行ROOT权限级别的Shell命令\n" - "\t6.赋予ADB最高级别权限\n" - "\t新一代root,跟面具完全不同思路,摆脱面具被检测的弱点,完美隐藏root功能,挑战全网root检测手段,兼容安卓APP直接JNI调用,稳定、流畅、不闪退。\n" - "======================================================\n" - ); - - - ++argv; - --argc; - - - int cmdc; - char *cmdv[6]; - - while (argc) { - // Clean up - cmdc = 0; - memset(cmdv, 0, sizeof(cmdv)); - - // Split the commands - for (char *tok = strtok(argv[0], " "); tok; tok = strtok(nullptr, " ")) - { - cmdv[cmdc++] = tok; - if (cmdc == 0) - { - continue; - } - } - - - if (strcmp(cmdv[0], "show") == 0) { - show_capability_info(); - } - else if (strcmp(cmdv[0], "root") == 0) { - test_root(); - } - else if (strcmp(cmdv[0], "disable") == 0) { - test_disable_selinux(); - } - else if (strcmp(cmdv[0], "enable") == 0) { - test_enable_selinux(); - } - else if (strcmp(cmdv[0], "cmd") == 0) { - test_run_cmd("id"); - //test_run_cmd("id > /sdcard/run.txt"); - //test_run_cmd("insmod rwProcMem37.ko > /sdcard/run.txt"); - } - else if (strcmp(cmdv[0], "adb") == 0) { - test_run_cmd("id", true); - } - else { - return 1; - } - - --argc; - ++argv; - } - return 0; -} \ No newline at end of file diff --git a/testRoot/myself_path_utils.h b/testRoot/myself_path_utils.h deleted file mode 100644 index 3b31f39..0000000 --- a/testRoot/myself_path_utils.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef _MYSELF_PATH_UTILS_H_ -#define _MYSELF_PATH_UTILS_H_ -#include - -static size_t get_executable_path(char* processdir, char* processname, size_t len) -{ - char* path_end; - if (readlink("/proc/self/exe", processdir, len) <= 0) - { - return -1; - } - path_end = strrchr(processdir, '/'); - if (path_end == NULL) - { - return -1; - } - ++path_end; - strcpy(processname, path_end); - *path_end = '\0'; - return (size_t)(path_end - processdir); -} - -#endif /* _MYSELF_PATH_UTILS_H_ */ diff --git a/testRoot/testRoot.cpp b/testRoot/testRoot.cpp index a251758..d993135 100644 --- a/testRoot/testRoot.cpp +++ b/testRoot/testRoot.cpp @@ -1,16 +1,30 @@ -#include "testRoot.h" +#include +#include +#include +#include +#include +#include #include #include #include -#include "kernel_root_helper.h" -#include "kernel_root_key.h" -#include "process64_inject.h" -#include "process_cmdline_utils.h" -#include "init64_process_helper.h" -#include "su_install_helper.h" -#include "myself_path_utils.h" +#include "kernel_root_kit/kernel_root_kit_umbrella.h" #include "../su/su_hide_path_utils.h" +#define ROOT_KEY "OM4kKoPVGFG2tnVFcs1PJ1qp6HtVymjV0CoTgFDmMdSDALve" + +std::string get_executable_directory() { + char processdir[4096] = { 0 }; // Consider using PATH_MAX from limits.h + ssize_t path_len = readlink("/proc/self/exe", processdir, sizeof(processdir)); + if(path_len > 0) { + char* path_end = strrchr(processdir, '/'); + if(path_end) { + *path_end = '\0'; + return std::string(processdir); + } + } + return {}; +} + void show_capability_info() { printf("Current process information:\n"); __uid_t now_uid, now_euid, now_suid; @@ -71,47 +85,55 @@ void test_root() { return; } -void test_run_root_cmd(const char* shell) { - printf("test_run_root_cmd(%s)\n", shell); +void test_run_root_cmd(int argc, char* argv[]) { + std::stringstream sstrCmd; + for (int i = 0; i < argc; i++) { + sstrCmd << argv[i]; + if (i != (argc - 1)) { + sstrCmd << " "; + } + } + printf("test_run_root_cmd(%s)\n", sstrCmd.str().c_str()); ssize_t err; - std::string result = kernel_root::run_root_cmd(ROOT_KEY, shell, err); + std::string result = kernel_root::run_root_cmd(ROOT_KEY, sstrCmd.str().c_str(), err); printf("test_run_root_cmd err:%zd\n", err); printf("test_run_root_cmd result:%s\n", result.c_str()); } -void test_run_init64_cmd(const char* cmd) { - printf("test_run_init64_cmd(%s)\n", cmd); + +void test_run_init64_cmd(int argc, char* argv[]) { + std::stringstream sstrCmd; + for (int i = 0; i < argc; i++) { + sstrCmd << argv[i]; + if (i != (argc - 1)) { + sstrCmd << " "; + } + } + printf("test_run_init64_cmd(%s)\n", sstrCmd.str().c_str()); ssize_t err; - std::string result = run_init64_cmd_wrapper(ROOT_KEY, cmd, err); + std::string result = kernel_root::run_init64_cmd_wrapper(ROOT_KEY, sstrCmd.str().c_str(), err); printf("run_init64_cmd_wrapper err:%zd\n", err); printf("run_init64_cmd_wrapper result:%s\n", result.c_str()); } void test_install_su_env() { - char myself_path[1024] = { 0 }; - char processname[1024]; - get_executable_path(myself_path, processname, sizeof(myself_path)); - TRACE("my directory:%s\nprocessname:%s\n", myself_path, processname); + std::string myself_path = get_executable_directory(); //1.安装su工具套件 ssize_t err; - std::string su_hide_full_path = install_su(ROOT_KEY, myself_path, std::string(myself_path + std::string("/su")).c_str(), err); + std::string su_hide_full_path = kernel_root::install_su(ROOT_KEY, myself_path.c_str(), std::string(myself_path + std::string("/su")).c_str(), err); printf("install su hide full path:%s, err:%zd\n", su_hide_full_path.c_str(), err); } void test_su_env_inject(const char* target_pid_cmdline) { - char myself_path[1024] = { 0 }; - char processname[1024]; - get_executable_path(myself_path, processname, sizeof(myself_path)); - TRACE("my directory:%s\nprocessname:%s\n", myself_path, processname); - + std::string myself_path = get_executable_directory(); if (kernel_root::get_root(ROOT_KEY) != 0) { return; } //1.获取su_xxx隐藏目录 - std::string su_hide_path = find_su_hide_folder_path(myself_path, "su"); + std::string su_hide_path = kernel_root::find_su_hide_folder_path(myself_path.c_str(), "su"); printf("su_hide_path ret val:%s\n", su_hide_path.c_str()); if (su_hide_path.empty()) { return; @@ -119,13 +141,13 @@ void test_su_env_inject(const char* target_pid_cmdline) { //2.杀光所有历史进程 std::vector vOut; - ssize_t err = find_all_cmdline_process(ROOT_KEY, target_pid_cmdline, vOut); + ssize_t err = kernel_root::find_all_cmdline_process(ROOT_KEY, target_pid_cmdline, vOut); printf("find_all_cmdline_process err:%zd, cnt:%zu\n", err, vOut.size()); if (err != 0) { return; } for (pid_t pid : vOut) { - err = kill_process(ROOT_KEY, pid); + err = kernel_root::kill_process(ROOT_KEY, pid); printf("kill err:%zd\n", err); if (err != 0) { return; @@ -135,26 +157,23 @@ void test_su_env_inject(const char* target_pid_cmdline) { //3.注入su环境变量到指定进程 printf("test_auto_su_env_inject Waiting for process creation(%s)\n", target_pid_cmdline); pid_t pid; - err = wait_and_find_cmdline_process(ROOT_KEY, target_pid_cmdline, 60 * 1000, pid); + err = kernel_root::wait_and_find_cmdline_process(ROOT_KEY, target_pid_cmdline, 60 * 1000, pid); printf("test_auto_su_env_inject(%zd)\n", err); - err = inject_process_env64_PATH_wrapper(ROOT_KEY, pid, su_hide_path.c_str()); + err = kernel_root::inject_process_env64_PATH_wrapper(ROOT_KEY, pid, su_hide_path.c_str()); printf("test_auto_su_env_inject ret val:%zd, error:%s\n", err, strerror(errno)); } void test_clean_su_env() { - char myself_path[1024] = { 0 }; - char processname[1024]; - get_executable_path(myself_path, processname, sizeof(myself_path)); - TRACE("my directory:%s\nprocessname:%s\n", myself_path, processname); + std::string myself_path = get_executable_directory(); - ssize_t err = uninstall_su(ROOT_KEY, myself_path, "su"); + ssize_t err = kernel_root::uninstall_su(ROOT_KEY, myself_path.c_str(), "su"); printf("uninstall_su err:%zd\n", err); } int main(int argc, char* argv[]) { printf( "======================================================\n" - "本工具名称: SKRoot - Linux 完美内核级隐藏ROOT演示\n" + "本工具名称: Linux ARM64 完美隐藏ROOT演示\n" "本工具功能列表:\n" "\t1.显示自身权限信息\n" "\t2.获取ROOT权限\n" @@ -166,7 +185,6 @@ int main(int argc, char* argv[]) { "\t新一代SKRoot,跟面具完全不同思路,摆脱面具被检测的弱点,完美隐藏root功能,兼容安卓APP直接JNI稳定调用。\n" "======================================================\n" ); - ++argv; --argc; if (argc == 0 || strcmp(argv[0], "id") == 0) { //1.显示自身权限信息 @@ -174,31 +192,13 @@ int main(int argc, char* argv[]) { } else if (strcmp(argv[0], "get") == 0) { //2.获取ROOT权限 test_root(); } else if (argc >= 2 && strcmp(argv[0], "cmd") == 0) { //3.执行ROOT命令 - std::stringstream sstrCmd; - for (int i = 1; i < argc; i++) { - sstrCmd << argv[i]; - if (i != (argc - 1)) { - sstrCmd << " "; - } - } - test_run_root_cmd((char*)sstrCmd.str().c_str()); + test_run_root_cmd(argc - 1, argv + 1); } else if (argc >= 2 && strcmp(argv[0], "init") == 0) { //4.执行原生内核命令 - std::stringstream sstrCmd; - for (int i = 1; i < argc; i++) { - sstrCmd << argv[i]; - if (i != argc) { - sstrCmd << " "; - } - } - test_run_init64_cmd((char*)sstrCmd.str().c_str()); + test_run_init64_cmd(argc - 1, argv + 1); } else if (strcmp(argv[0], "su") == 0) { //5.安装部署隐藏版su test_install_su_env(); } else if (argc > 1 && strcmp(argv[0], "process") == 0) { //6.注入su到指定进程 - std::stringstream sstrCmd; - sstrCmd << argv[1]; - if (sstrCmd.str().length()) { - test_su_env_inject(sstrCmd.str().c_str()); - } + test_su_env_inject(argv[1]); } else if (strcmp(argv[0], "cleansu") == 0) { //7.完全卸载清理su test_clean_su_env(); } else { diff --git a/testRoot/testRoot.h b/testRoot/testRoot.h deleted file mode 100644 index d9a34ec..0000000 --- a/testRoot/testRoot.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef TEST_ROOT_H_ -#define TEST_ROOT_H_ -#include -#include -#include -#include -#include -#include -//安静输出模式 -#define QUIET_PRINTF - -#ifdef QUIET_PRINTF -#undef TRACE -#define TRACE(fmt, ...) -#else -#ifdef __ANDROID__ -#undef TRACE -#include -#define LOG_TAG "JNIGlue" -//#define TRACE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__) -#define TRACE(fmt, ...) printf(fmt, ##__VA_ARGS__) -#else -#define TRACE(fmt, ...) printf(fmt, ##__VA_ARGS__) -#endif -#endif - -#endif /* TEST_ROOT_H_ */