提交 003920c2 编写于 作者: chuxuezhe1111's avatar chuxuezhe1111

add native hook feature

Signed-off-by: chuxuezhe1111's avatarchuxuezhe111 <hanjixiao@huawei.com>
上级 496e030a
......@@ -43,6 +43,7 @@ group("musl_headers") {
":create_version_h",
":musl_copy_inc_arpa",
":musl_copy_inc_bits",
":musl_copy_inc_hook",
":musl_copy_inc_net",
":musl_copy_inc_netinet",
":musl_copy_inc_netpacket",
......@@ -258,6 +259,11 @@ copy("musl_copy_inc_root") {
deps = [ ":create_porting_src" ]
}
copy("musl_copy_inc_hook") {
sources = musl_inc_hook_files
outputs = [ "${target_out_dir}/${musl_inc_out_dir}/{{source_file_part}}" ]
}
group("libctest") {
testonly = true
deps = [ "libc-test:musl_libc_test" ]
......
......@@ -149,5 +149,7 @@ typedef struct __ucontext {
#define SIGPWR 30
#define SIGSYS 31
#define SIGUNUSED SIGSYS
#define SIGHOOK 36
#define SIGUNHOOK 37
#define _NSIG 65
......@@ -82,5 +82,7 @@ typedef struct __ucontext {
#define SIGPWR 30
#define SIGSYS 31
#define SIGUNUSED SIGSYS
#define SIGHOOK 36
#define SIGUNHOOK 37
#define _NSIG 65
......@@ -9,6 +9,7 @@ group("musl_libc_test") {
"src/functional:functional_test",
"src/math:math_test",
"src/musl:pleval",
"src/nativehook:nativehook_test",
"src/regression:regression_test",
]
}
import("//build/test.gni")
ohos_unittest("nativehook_test") {
module_out_path = "libc-test/src/nativehook"
sources = [
"print.c",
"runtest.c",
]
configs = [ ":config_runtest" ]
}
config("config_runtest") {
include_dirs = [ "." ]
cflags_c = [
"-pipe",
"-std=c11",
"-D_POSIX_C_SOURCE=200809L",
"-Wall",
"-Wno-unused",
"-Wno-unused-function",
"-Wno-missing-braces",
"-Wno-overflow",
"-Wno-unknown-pragmas",
"-fno-builtin",
"-frounding-math",
"-Werror=implicit-function-declaration",
"-Werror=implicit-int",
"-Werror=pointer-sign",
"-Werror=pointer-arith",
"-Wno-error=unused-function",
"-g",
"-D_FILE_OFFSET_BITS=64",
]
ldflags = [ "-nostdlib" ]
}
#include <stdio.h>
#include <stdarg.h>
#include <unistd.h>
#include "test.h"
volatile int t_status = 0;
int t_printf(const char *s, ...)
{
va_list ap;
char buf[512];
int n;
t_status = 1;
va_start(ap, s);
n = vsnprintf(buf, sizeof buf, s, ap);
va_end(ap);
if (n < 0)
n = 0;
else if (n >= sizeof buf) {
n = sizeof buf;
buf[n - 1] = '\n';
buf[n - 2] = '.';
buf[n - 3] = '.';
buf[n - 4] = '.';
}
return write(1, buf, n);
}
#include <limits.h>
#include <stdio.h>
#include <stdatomic.h>
#include <memory.h>
#include "test.h"
#include "musl_preinit_common.h"
#define TEST(c, ...) \
( (c) || (t_error(#c " failed: " __VA_ARGS__),0) )
static bool client_hook_flag;
bool get_hook_flag()
{
return client_hook_flag;
}
bool set_hook_flag(bool flag)
{
bool before_flag = client_hook_flag;
client_hook_flag = flag;
return before_flag;
}
void install_hook_function()
{
memset(function_of_shared_lib, 0, sizeof(function_of_shared_lib[0]) * LAST_FUNCTION);
function_of_shared_lib[GET_HOOK_FLAG_FUNCTION] = get_hook_flag;
function_of_shared_lib[SET_HOOK_FLAG_FUNCTION] = set_hook_flag;
}
int main(int argc, char **argv)
{
printf("Installing client's functions...");
install_hook_function();
printf("\nInstallation Completes\n");
printf("Start 7 scenes testing...\n");
printf("Case 1: client shared library has not been loaded.\n");
atomic_store_explicit(&ohos_malloc_hook_shared_liibrary, (volatile long long)0, memory_order_seq_cst);
bool hook_flag = __get_hook_flag();
TEST(hook_flag == false, "hook_flag shoud be false\n");
volatile const struct MallocDispatchType* malloc_dispatch_table = get_current_dispatch_table();
TEST(malloc_dispatch_table == NULL, "malloc_dispatch_table shoud be NULL\n");
printf("Case 2: client shared library is loading, no uninstall signal raising, but the functions hasn't been loaded, using the temporary malloc table.\n");
atomic_store_explicit(&ohos_malloc_hook_shared_liibrary, (volatile long long)-1, memory_order_seq_cst);
atomic_store_explicit(&__musl_libc_globals.current_dispatch_table, (volatile const long long)0x95919591, memory_order_seq_cst);
atomic_store_explicit(&__hook_enable_hook_flag, (volatile bool)true, memory_order_seq_cst);
hook_flag = __get_hook_flag();
TEST(hook_flag == true, "hook_flag shoud be true\n");
malloc_dispatch_table = get_current_dispatch_table();
TEST(malloc_dispatch_table != NULL, "malloc_dispatch_table shoud be not NULL\n");
printf("Case 3: client shared library is loading, uninstall signal raising, but the functions hasn't been loaded, using the temporary malloc table.\n");
atomic_store_explicit(&ohos_malloc_hook_shared_liibrary, (volatile long long)-1, memory_order_seq_cst);
atomic_store_explicit(&__musl_libc_globals.current_dispatch_table, (volatile const long long)0x95919591, memory_order_seq_cst);
atomic_store_explicit(&__hook_enable_hook_flag, (volatile bool)false, memory_order_seq_cst);
hook_flag = __get_hook_flag();
TEST(hook_flag == true, "hook_flag shoud be true\n");
malloc_dispatch_table = get_current_dispatch_table();
TEST(malloc_dispatch_table == NULL, "malloc_dispatch_table shoud be NULL\n");
printf("Case 4: client shared library is loaded, no uninstall signal raising, outside client malloc.\n");
atomic_store_explicit(&ohos_malloc_hook_shared_liibrary, (volatile long long)0x10319090, memory_order_seq_cst);
atomic_store_explicit(&__hook_enable_hook_flag, (volatile bool)true, memory_order_seq_cst);
set_hook_flag(true);
hook_flag = __get_hook_flag();
TEST(hook_flag == true, "hook_flag shoud be true\n");
malloc_dispatch_table = get_current_dispatch_table();
TEST(malloc_dispatch_table != NULL, "malloc_dispatch_table shoud be not NULL\n");
printf("Case 5: client shared library is loaded, no uninstall signal raising, inside client malloc.\n");
atomic_store_explicit(&ohos_malloc_hook_shared_liibrary, (volatile long long)0x10319090, memory_order_seq_cst);
atomic_store_explicit(&__hook_enable_hook_flag, (volatile bool)true, memory_order_seq_cst);
set_hook_flag(false);
hook_flag = __get_hook_flag();
TEST(hook_flag == false, "hook_flag shoud be false\n");
malloc_dispatch_table = get_current_dispatch_table();
TEST(malloc_dispatch_table == NULL, "malloc_dispatch_table shoud be NULL\n");
printf("Case 6: client shared library is loaded, uninstall signal raising, outside client malloc.\n");
atomic_store_explicit(&ohos_malloc_hook_shared_liibrary, (volatile long long)0x10319090, memory_order_seq_cst);
atomic_store_explicit(&__hook_enable_hook_flag, (volatile bool)false, memory_order_seq_cst);
set_hook_flag(true);
hook_flag = __get_hook_flag();
TEST(hook_flag == true, "hook_flag shoud be true\n");
malloc_dispatch_table = get_current_dispatch_table();
TEST(malloc_dispatch_table == NULL, "malloc_dispatch_table shoud be NULL\n");
printf("Case 7: client shared library is loaded, uninstall signal raising, inside client malloc.\n");
atomic_store_explicit(&ohos_malloc_hook_shared_liibrary, (volatile long long)0x10319090, memory_order_seq_cst);
atomic_store_explicit(&__hook_enable_hook_flag, (volatile bool)false, memory_order_seq_cst);
set_hook_flag(false);
hook_flag = __get_hook_flag();
TEST(hook_flag == false, "hook_flag shoud be false\n");
malloc_dispatch_table = get_current_dispatch_table();
TEST(malloc_dispatch_table == NULL, "malloc_dispatch_table shoud be NULL\n");
TEST(malloc_dispatch_table == NULL, "malloc_dispatch_table shoud be NULL\n");
if (t_status == 0) {
printf("All test cases passed!\n");
} else {
printf("***There are some test cases not passed.\n");
}
return t_status;
}
#include <stdint.h>
#include <unistd.h>
#define T_LOC2(l) __FILE__ ":" #l
#define T_LOC1(l) T_LOC2(l)
#define t_error(...) t_printf(T_LOC1(__LINE__) ": " __VA_ARGS__)
extern volatile int t_status;
int t_printf(const char *s, ...);
......@@ -1845,3 +1845,9 @@ musl_src_porting_file = [
"src/thread/arm/clone.s",
"src/thread/arm/syscall_cp.s",
]
musl_inc_hook_files = [
"porting/linux/user/src/hook/musl_malloc_dispatch_table.h",
"porting/linux/user/src/hook/musl_malloc_dispatch.h",
"porting/linux/user/src/hook/musl_preinit_common.h",
]
......@@ -157,6 +157,7 @@ template("musl_libs") {
"-Werror=pointer-sign",
"-Werror=pointer-arith",
"-Qunused-arguments",
"-DHOOK_ENABLE",
]
cflags_c99fse = [
......@@ -193,6 +194,36 @@ template("musl_libs") {
asmflags = cflags
}
config("${abi_prefix}_hook") {
defines = []
configs = []
if (is_posix) {
configs += [ "//build/config/posix:runtime_library" ]
}
cflags_cc = []
defines = [
"__GNU_SOURCE=1", # Necessary for clone().
"CHROMIUM_CXX_TWEAK_INLINES", # Saves binary size.
]
defines += [
"__MUSL__",
"_LIBCPP_HAS_MUSL_LIBC",
"__BUILD_LINUX_WITH_CLANG",
"HOOK_ENABLE",
]
ldflags = [ "-nostdlib" ]
libs = []
if (is_component_build) {
defines += [ "COMPONENT_BUILD" ]
}
}
source_set("${abi_prefix}_musl_crt") {
sources = [
"${target_out_dir}/${musl_ported_dir}/crt/${musl_arch}/crti.s",
......@@ -306,6 +337,30 @@ template("musl_libs") {
deps = porting_deps
}
source_set("${abi_prefix}_musl_hook") {
sources = [
"./porting/linux/user/src/hook/malloc_common.c",
"./porting/linux/user/src/hook/musl_preinit.c",
"./porting/linux/user/src/hook/musl_preinit_common.c",
]
deps = [
"//third_party/musl:create_alltypes_h",
"//third_party/musl:create_porting_src",
"//third_party/musl:create_syscall_h",
"//third_party/musl:create_version_h",
"//third_party/musl:musl_copy_inc_bits",
"//third_party/musl:musl_copy_inc_root",
]
configs -= musl_inherited_configs
configs += [
"//build/config/compiler:compiler",
":${abi_prefix}_hook",
]
}
static_library("${abi_prefix}_libc_musl_static") {
output_name = "libc"
complete_static_lib = true
......@@ -403,6 +458,7 @@ template("musl_libs") {
deps = [
":${abi_prefix}_libdl",
":${abi_prefix}_libpthread",
":${abi_prefix}_musl_hook",
":${abi_prefix}_musl_ldso",
":${abi_prefix}_musl_src",
":${abi_prefix}_musl_src_nossp",
......
#ifndef _COMMON_DEF_H
#define _COMMON_DEF_H
#include <unistd.h>
#include <stdlib.h>
#define __predict_true(exp) __builtin_expect((exp) != 0, 1)
#define __predict_false(exp) __builtin_expect((exp) != 0, 0)
#endif
\ No newline at end of file
#ifdef HOOK_ENABLE
#include <unistd.h>
#include <sys/types.h>
#include "musl_malloc.h"
#include <malloc.h>
#include "musl_malloc_dispatch_table.h"
#include "common_def.h"
#include "musl_preinit_common.h"
void* malloc(size_t bytes)
{
volatile const struct MallocDispatchType* dispatch_table = get_current_dispatch_table();
if (__predict_false(dispatch_table != NULL)) {
void*ret = dispatch_table->malloc(bytes);
return ret;
}
void* result = MuslMalloc(malloc)(bytes);
if (__predict_false(result == NULL)) {
//__musl_log(__MUSL_LOG_WARN, "malloc(%zu) failed: returning null pointer\n", bytes);
}
return result;
}
void free(void* mem)
{
volatile const struct MallocDispatchType* dispatch_table = get_current_dispatch_table();
if (__predict_false(dispatch_table != NULL)) {
dispatch_table->free(mem);
} else {
MuslMalloc(free)(mem);
}
}
#endif
#ifndef _MUSL_MALLOC_H
#define _MUSL_MALLOC_H
#ifdef __cplusplus
extern "C" {
#endif
#ifdef HOOK_ENABLE
#define MuslMalloc(func) __libc_ ## func
#else
#define MuslMalloc(func) func
#endif
void *__libc_malloc(size_t);
void *__libc_calloc(size_t, size_t);
void *__libc_realloc(void *, size_t);
void __libc_free(void *);
void *__libc_valloc(size_t);
void *__libc_memalign(size_t, size_t);
size_t __libc_malloc_usable_size(void *);
#ifdef __cplusplus
}
#endif
#endif
#ifndef _MUSL_MALLOC_DISPATCH_H
#define _MUSL_MALLOC_DISPATCH_H
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef void* (*MallocMallocType)(size_t);
typedef void* (*MallocReallocType)(void*, size_t);
typedef void* (*MallocCallocType)(size_t, size_t);
typedef void* (*MallocVallocType)(size_t);
typedef void (*MallocFreeType)(void*);
typedef void* (*MallocMemalignType)(size_t, size_t);
typedef size_t (*MallocMallocUsableSizeType)(void*);
typedef bool (*GetHookFlagType)();
typedef bool (*SetHookFlagType)(bool);
struct MallocDispatchType {
MallocMallocType malloc;
MallocCallocType calloc;
MallocReallocType realloc;
MallocVallocType valloc;
MallocFreeType free;
MallocMemalignType memalign;
MallocMallocUsableSizeType malloc_usable_size;
GetHookFlagType get_hook_flag;
SetHookFlagType set_hook_flag;
};
#ifdef __cplusplus
}
#endif
#endif
#ifndef _MUSL_MALLOC_DISPATCH_TABLE_H
#define _MUSL_MALLOC_DISPATCH_TABLE_H
#include "musl_malloc_dispatch.h"
#include <stdatomic.h>
struct musl_libc_globals {
volatile atomic_llong current_dispatch_table;
volatile atomic_llong so_dispatch_table;
struct MallocDispatchType malloc_dispatch_table;
};
#endif
/*
The hook mode has 3 kinds which can be set by command "param set":
(1) param set libc.hook_mode "startup:\"prog1 \""
(2) param set libc.hook_mode startup:program1
(3) param set libc.hook_mode step
(4) param set libc.hook_mode direct
Case 1 represents "startup" mode, and the hooked process is "prog1 ",
which loads hooking shared library when the program starts up.
The path is added with two quotation marks because a quotation mark is a special charcter,
which need be escaped.
(2) is similar with (1), but no escaped character, so quotation marks doesn't need.
(3) represents "step" mode, which loads hooking shared library by some steps.
(4) represetnt "direct" mode, which loads hooking shared library by a step.
*/
#ifdef HOOK_ENABLE
#include <unistd.h>
#include <signal.h>
#include "musl_malloc_dispatch_table.h"
#include "musl_malloc.h"
#include "musl_preinit_common.h"
#include <pthread.h>
#include <stdlib.h>
#include <limits.h>
#include <dlfcn.h>
#include <stdatomic.h>
#include <ctype.h>
#include <assert.h>
#include <string.h>
#include <malloc.h>
void* ohos_malloc_hook_init_function(size_t bytes);
static struct MallocDispatchType __ohos_malloc_hook_init_dispatch = {
.malloc = ohos_malloc_hook_init_function,
.free = MuslMalloc(free),
};
#define MAX_SYM_NAME_SIZE 1000
static char *__malloc_hook_shared_lib = "libnative_hook.z.so";
static char *__malloc_hook_function_prefix = "ohos_malloc_hook";
static char *__get_param_shared_Lib = "libparam_client.z.so";
volatile atomic_llong ohos_malloc_hook_shared_liibrary;
void* function_of_shared_lib[LAST_FUNCTION];
static enum EnumHookMode __hook_mode = STEP_HOOK_MODE;
static char __hook_process_path[PATH_MAX+ 1] = {0};
static char __progname[PATH_MAX + 1] = {0};
static char* get_native_hook_param()
{
int (*getFunction)(const char *name, char *value, unsigned int *len);
void* shared_library_handle = dlopen(__get_param_shared_Lib, RTLD_NOW | RTLD_LOCAL);
if (!shared_library_handle) {
return NULL;
}
getFunction = (int (*)(const char *name, char *value, unsigned int *len))dlsym((void*)shared_library_handle, "SystemGetParameter");
if (getFunction == NULL) {
dlclose(shared_library_handle);
return NULL;
}
const char *key = MUSL_HOOK_PARAM_NAME;
char *value = (char *)malloc(OHOS_PARAM_MAX_SIZE);
memset(value, 0, OHOS_PARAM_MAX_SIZE);
if (value == NULL) {
dlclose(shared_library_handle);
return NULL;
}
unsigned int len = OHOS_PARAM_MAX_SIZE;
getFunction(key, value, &len);
dlclose(shared_library_handle);
return value;
}
static int parse_hook_variable(enum EnumHookMode* mode, char* path, int size)
{
if (!mode || !path || size <= 0) {
return -1;
}
bool flag = __set_hook_flag(false);
char* hook_param_value = get_native_hook_param();
if (!hook_param_value) {
*mode = STEP_HOOK_MODE;
path[0] = '\0';
} else {
char* ptr = hook_param_value;
char* mode_str = hook_param_value;
while (*ptr && *ptr != ':') {
++ptr;
}
if (*ptr == ':') {
*ptr = '\0';
++ptr;
}
if (strcmp(mode_str, "startup") == 0) {
*mode = STATRUP_HOOK_MODE;
} else if (strcmp(mode_str, "direct") == 0) {
*mode = DIRECT_HOOK_MODE;
} else if (strcmp(mode_str, "step") == 0) {
*mode = STEP_HOOK_MODE;
} else {
*mode = STEP_HOOK_MODE;
}
if (*mode == STATRUP_HOOK_MODE) {
if (*ptr == '\"') {
++ptr;
int idx = 0;
while (idx < size - 1 && *ptr && *ptr != '\"') {
path[idx++] = *ptr++;
}
path[idx] = '\0';
} else {
int idx = 0;
while (idx < size - 1 && *ptr) {
path[idx++] = *ptr++;
}
path[idx] = '\0';
}
}
free(hook_param_value);
}
__set_hook_flag(flag);
return 0;
}
static bool init_malloc_function(void* malloc_shared_library_handler, MallocMallocType* func, const char* prefix)
{
char symbol[MAX_SYM_NAME_SIZE];
snprintf(symbol, sizeof(symbol), "%s_%s", prefix, "malloc");
*func = (MallocMallocType)(dlsym(malloc_shared_library_handler, symbol));
if (*func == NULL) {
return false;
}
return true;
}
static bool init_free_function(void* malloc_shared_library_handler, MallocFreeType* func, const char* prefix)
{
char symbol[MAX_SYM_NAME_SIZE];
snprintf(symbol, sizeof(symbol), "%s_%s", prefix, "free");
*func = (MallocFreeType)(dlsym(malloc_shared_library_handler, symbol));
if (*func == NULL) {
return false;
}
return true;
}
static bool init_hook_functions(void* shared_library_handler, struct MallocDispatchType* table, const char* prefix)
{
if (!init_malloc_function(shared_library_handler, &table->malloc, prefix)) {
return false;
}
if (!init_free_function(shared_library_handler, &table->free, prefix)) {
return false;
}
return true;
}
static void clear_function_table()
{
for (size_t i = 0; i < LAST_FUNCTION; i++) {
function_of_shared_lib[i] = NULL;
}
}
bool init_malloc_hook_shared_library(void* shared_library_handle, const char* shared_lib, const char* prefix, struct MallocDispatchType* dispatch_table)
{
static const char* names[] = {
"initialize",
"finalize",
"get_hook_flag",
"set_hook_flag",
"on_start",
"on_end",
};
for (int i = 0; i < LAST_FUNCTION; i++) {
char symbol[MAX_SYM_NAME_SIZE];
snprintf(symbol, sizeof(symbol), "%s_%s", prefix, names[i]);
function_of_shared_lib[i] = dlsym(shared_library_handle, symbol);
if (function_of_shared_lib[i] == NULL) {
// __musl_log(__MUSL_LOG_ERROR, "%s: %s routine not found in %s\n", getprogname(), symbol, shared_lib);
clear_function_table();
return false;
}
}
if (!init_hook_functions(shared_library_handle, dispatch_table, prefix)) {
clear_function_table();
return false;
}
return true;
}
void* load_malloc_hook_shared_library(const char* shared_lib, const char* prefix, struct MallocDispatchType* dispatch_table)
{
void* shared_library_handle = NULL;
shared_library_handle = dlopen(shared_lib, RTLD_NOW | RTLD_LOCAL);
if (shared_library_handle == NULL) {
printf("Unable to open shared library %s: %s\n", shared_lib, dlerror());
return NULL;
}
if (!init_malloc_hook_shared_library(shared_library_handle, shared_lib, prefix, dispatch_table)) {
dlclose(shared_library_handle);
shared_library_handle = NULL;
}
// printf("load_malloc_hook_shared_library success new version test\n");
return shared_library_handle;
}
typedef void (*finalize_func_t)();
typedef bool (*init_func_t)(const struct MallocDispatchType*, bool*, const char*);
typedef bool (*on_start_func_t)();
typedef bool (*on_end_func_t)();
static void malloc_finalize()
{
__set_hook_flag(false);
((finalize_func_t)function_of_shared_lib[FINALIZE_FUNCTION])();
fclose(stdin);
fclose(stdout);
fclose(stderr);
}
bool finish_install_ohos_malloc_hooks(struct musl_libc_globals* globals, const char* options, const char* prefix)
{
init_func_t init_func = (init_func_t)(function_of_shared_lib[INITIALIZE_FUNCTION]);
if (!init_func(&__libc_malloc_default_dispatch, NULL, options)) {
// __musl_log(__MUSL_LOG_ERROR, "%s: failed to enable malloc %s\n", getprogname(), prefix);
clear_function_table();
return false;
}
on_start_func_t start_func = (on_start_func_t)(function_of_shared_lib[ON_START_FUNCTION]);
if (!start_func()) {
// __musl_log(__MUSL_LOG_ERROR, "%s: failed to start %s\n", getprogname(), prefix);
clear_function_table();
return false;
}
atomic_store_explicit(&__musl_libc_globals.so_dispatch_table, (volatile long long)&globals->malloc_dispatch_table, memory_order_seq_cst);
atomic_store_explicit(&__musl_libc_globals.current_dispatch_table, (volatile long long)&globals->malloc_dispatch_table, memory_order_seq_cst);
int ret_value = atexit(malloc_finalize);
if (ret_value != 0) {
// __musl_log(__MUSL_LOG_ERROR, "failed to set atexit cleanup function: %d\n", ret_value);
}
return true;
}
static bool is_empty_string(const char* str)
{
while (*str) {
if (!isspace((unsigned char)(*str))) {
return false;
}
}
return true;
}
static void install_ohos_malloc_hook(struct musl_libc_globals* globals)
{
volatile void* shared_library_handle = (volatile void *)atomic_load_explicit(&ohos_malloc_hook_shared_liibrary, memory_order_acquire);
assert(shared_library_handle == NULL || shared_library_handle == (volatile void*)-1);
shared_library_handle = (volatile void*)load_malloc_hook_shared_library(__malloc_hook_shared_lib, __malloc_hook_function_prefix, &globals->malloc_dispatch_table);
if (shared_library_handle == NULL) {
// __musl_log(__MUSL_LOG_ERROR, "Can't load shared library '%s'\n", __malloc_hook_shared_lib);
return;
}
if (finish_install_ohos_malloc_hooks(globals, NULL, __malloc_hook_function_prefix)) {
atomic_store_explicit(&ohos_malloc_hook_shared_liibrary, (volatile long long)shared_library_handle, memory_order_seq_cst);
} else {
// __musl_log(__MUSL_LOG_ERROR, "finish_install_ohos_malloc_hooks failed\n");
dlclose((void *)shared_library_handle);
atomic_store_explicit(&ohos_malloc_hook_shared_liibrary, (volatile long long)0, memory_order_seq_cst);
}
}
static void* init_ohos_malloc_hook()
{
bool flag = __set_hook_flag(false);
install_ohos_malloc_hook(&__musl_libc_globals);
__set_hook_flag(flag);
return NULL;
}
void* ohos_malloc_hook_init_function(size_t bytes)
{
if (atomic_exchange(&__musl_libc_globals.current_dispatch_table, (volatile const long long)NULL)) {
pthread_t thread_id;
if (pthread_create(&thread_id, NULL, init_ohos_malloc_hook, NULL) != 0) {
// __musl_log(__MUSL_LOG_ERROR, "%s: ohos_malloc_hook: failed to pthread_create\n", getprogname());
} else if (pthread_detach(thread_id) != 0) {
// __musl_log(__MUSL_LOG_ERROR, "%s: ohos_malloc_hook: failed to pthread_detach\n", getprogname());
}
}
void*ptr = MuslMalloc(malloc)(bytes);
return ptr;
}
static void __set_default_malloc()
{
atomic_store_explicit(&__musl_libc_globals.current_dispatch_table, (volatile const long long)NULL, memory_order_seq_cst);
}
static void __install_malloc_hook()
{
atomic_store_explicit(&__hook_enable_hook_flag, (volatile bool)true, memory_order_seq_cst);
volatile void* shared_library_handle = (volatile void* )atomic_load_explicit(&ohos_malloc_hook_shared_liibrary, memory_order_acquire);
if (shared_library_handle == NULL) {
if (__hook_mode == STEP_HOOK_MODE) {
atomic_store_explicit(&__musl_libc_globals.current_dispatch_table, (volatile const long long)&__ohos_malloc_hook_init_dispatch, memory_order_seq_cst);
atomic_store_explicit(&ohos_malloc_hook_shared_liibrary, (volatile long long)-1, memory_order_seq_cst);
} else {
init_ohos_malloc_hook();
}
} else if (shared_library_handle != (void*)-1) {
bool flag = __set_hook_flag(false);
on_start_func_t start_func = (on_start_func_t)(function_of_shared_lib[ON_START_FUNCTION]);
if (start_func && !start_func()) {
// __musl_log(__MUSL_LOG_ERROR, "%s: failed to enable malloc\n", getprogname());
}
__set_hook_flag(flag);
volatile const struct MallocDispatchType* so_dispatch_value = (volatile const struct MallocDispatchType* )atomic_load_explicit(&__musl_libc_globals.so_dispatch_table, memory_order_acquire);
atomic_store_explicit(&__musl_libc_globals.current_dispatch_table, (volatile long long)so_dispatch_value, memory_order_seq_cst);
}
}
static void __uninstal_malloc_hook()
{
atomic_store_explicit(&__hook_enable_hook_flag, (volatile bool)false, memory_order_seq_cst);
bool flag = __set_hook_flag(false);
__set_default_malloc();
on_end_func_t end_func = (on_end_func_t)(function_of_shared_lib[ON_END_FUNCTION]);
if (end_func) {
end_func();
}
__set_hook_flag(flag);
}
static void __install_malloc_hook_signal_handler()
{
struct sigaction actionInstallHook = {};
actionInstallHook.sa_handler = __install_malloc_hook;
sigemptyset(&actionInstallHook.sa_mask);
sigaddset(&actionInstallHook.sa_mask, SIGUNHOOK);
sigaction(SIGHOOK, &actionInstallHook, NULL);
struct sigaction actionDef = {};
actionDef.sa_handler = __uninstal_malloc_hook;
sigemptyset(&actionDef.sa_mask);
sigaddset(&actionDef.sa_mask, SIGHOOK);
sigaction(SIGUNHOOK, &actionDef, NULL);
}
static void __initialize_malloc()
{
__install_malloc_hook_signal_handler();
}
__attribute__((constructor(1))) static void __musl_initialize()
{
atomic_store_explicit(&__hook_enable_hook_flag, (volatile bool)false, memory_order_seq_cst);
__set_default_malloc();
//__init_musl_log();
parse_hook_variable(&__hook_mode, __hook_process_path, sizeof(__hook_process_path));
if (__hook_mode == STATRUP_HOOK_MODE) {
readlink("/proc/self/exe", __progname, sizeof(__progname) - 1);
const char *pos = strrchr(__progname, '/');
const char* filename;
if (pos) {
filename = pos + 1;
} else {
filename = __progname;
}
if (strcmp(filename, __hook_process_path) == 0) {
atomic_store_explicit(&__hook_enable_hook_flag, (volatile bool)true, memory_order_seq_cst);
init_ohos_malloc_hook();
} else {
__hook_mode = STEP_HOOK_MODE;
}
}
__initialize_malloc();
}
#endif
#ifdef HOOK_ENABLE
#include "musl_preinit_common.h"
#include "musl_malloc.h"
#include <stdatomic.h>
#include <malloc.h>
#include <stdlib.h>
struct musl_libc_globals __musl_libc_globals;
struct MallocDispatchType __libc_malloc_default_dispatch = {
.malloc = MuslMalloc(malloc),
.free = MuslMalloc(free),
};
volatile atomic_bool __hook_enable_hook_flag;
#endif
#ifndef _MUSL_PREINIT_COMMON_H
#define _MUSL_PREINIT_COMMON_H
#include <stdatomic.h>
#include "musl_malloc_dispatch_table.h"
#include "musl_malloc_dispatch.h"
extern struct musl_libc_globals __musl_libc_globals;
extern struct MallocDispatchType __libc_malloc_default_dispatch;
extern volatile atomic_bool __hook_enable_hook_flag;
enum EnumFunc {
INITIALIZE_FUNCTION,
FINALIZE_FUNCTION,
GET_HOOK_FLAG_FUNCTION,
SET_HOOK_FLAG_FUNCTION,
ON_START_FUNCTION,
ON_END_FUNCTION,
LAST_FUNCTION,
};
enum EnumHookMode {
STATRUP_HOOK_MODE,
DIRECT_HOOK_MODE,
STEP_HOOK_MODE,
};
extern void* function_of_shared_lib[];
extern volatile atomic_llong ohos_malloc_hook_shared_liibrary;
#ifdef __cplusplus
extern "C" {
#endif
__attribute__((always_inline))
inline bool __get_global_hook_flag()
{
volatile bool g_flag = atomic_load_explicit(&__hook_enable_hook_flag, memory_order_acquire);
return g_flag;
}
__attribute__((always_inline))
inline bool __get_hook_flag()
{
volatile void* impl_handle = (void *)atomic_load_explicit(&ohos_malloc_hook_shared_liibrary, memory_order_acquire);
if (impl_handle == NULL) {
return false;
}
else if (impl_handle == (void *)-1) {
return true;
}
else {
GetHookFlagType get_hook_func_ptr = (GetHookFlagType)(function_of_shared_lib[GET_HOOK_FLAG_FUNCTION]);
bool flag = get_hook_func_ptr();
return flag;
}
}
__attribute__((always_inline))
inline bool __set_hook_flag(bool flag)
{
volatile void* impl_handle = (void *)atomic_load_explicit(&ohos_malloc_hook_shared_liibrary, memory_order_acquire);
if (impl_handle == NULL) {
return false;
}
else if (impl_handle == (void *)-1) {
return true;
}
else {
SetHookFlagType set_hook_func_ptr = (SetHookFlagType)(function_of_shared_lib[SET_HOOK_FLAG_FUNCTION]);
return set_hook_func_ptr(flag);
}
}
__attribute__((always_inline))
inline volatile const struct MallocDispatchType* get_current_dispatch_table()
{
volatile const struct MallocDispatchType* ret = (struct MallocDispatchType *)atomic_load_explicit(&__musl_libc_globals.current_dispatch_table, memory_order_acquire);
if (ret != NULL) {
if (!__get_global_hook_flag()) {
ret = NULL;
}
else if (!__get_hook_flag()) {
ret = NULL;
}
}
return ret;
}
#define MUSL_HOOK_PARAM_NAME "libc.hook_mode"
#define OHOS_PARAM_MAX_SIZE 96
#ifdef __cplusplus
}
#endif
#endif
......@@ -14,6 +14,11 @@
#define inline inline __attribute__((always_inline))
#endif
#ifdef HOOK_ENABLE
void *__libc_malloc(size_t);
void __libc_free(void *p);
#endif
static struct {
volatile uint64_t binmap;
struct bin bins[64];
......@@ -281,7 +286,11 @@ static void trim(struct chunk *self, size_t n)
__bin_chunk(split);
}
#ifdef HOOK_ENABLE
void *__libc_malloc(size_t n)
#else
void *malloc(size_t n)
#endif
{
struct chunk *c;
int i, j;
......@@ -520,7 +529,11 @@ static void unmap_chunk(struct chunk *self)
__munmap(base, len);
}
#ifdef HOOK_ENABLE
void __libc_free(void *p)
#else
void free(void *p)
#endif
{
if (!p) return;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册