1800b99b8Sopenharmony_ci/* 2800b99b8Sopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd. 3800b99b8Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4800b99b8Sopenharmony_ci * you may not use this file except in compliance with the License. 5800b99b8Sopenharmony_ci * You may obtain a copy of the License at 6800b99b8Sopenharmony_ci * 7800b99b8Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8800b99b8Sopenharmony_ci * 9800b99b8Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10800b99b8Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11800b99b8Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12800b99b8Sopenharmony_ci * See the License for the specific language governing permissions and 13800b99b8Sopenharmony_ci * limitations under the License. 14800b99b8Sopenharmony_ci */ 15800b99b8Sopenharmony_ci 16800b99b8Sopenharmony_ci#include "dfx_exit_hook.h" 17800b99b8Sopenharmony_ci 18800b99b8Sopenharmony_ci#include <dlfcn.h> 19800b99b8Sopenharmony_ci#include <signal.h> 20800b99b8Sopenharmony_ci#include <stdbool.h> 21800b99b8Sopenharmony_ci#include <stdio.h> 22800b99b8Sopenharmony_ci#include <stdlib.h> 23800b99b8Sopenharmony_ci#include <string.h> 24800b99b8Sopenharmony_ci#include <syscall.h> 25800b99b8Sopenharmony_ci#include <unistd.h> 26800b99b8Sopenharmony_ci 27800b99b8Sopenharmony_ci#include "dfx_log.h" 28800b99b8Sopenharmony_ci#include "dfx_hook_utils.h" 29800b99b8Sopenharmony_ci 30800b99b8Sopenharmony_ci#ifdef LOG_DOMAIN 31800b99b8Sopenharmony_ci#undef LOG_DOMAIN 32800b99b8Sopenharmony_ci#define LOG_DOMAIN 0xD002D11 33800b99b8Sopenharmony_ci#endif 34800b99b8Sopenharmony_ci 35800b99b8Sopenharmony_ci#ifdef LOG_TAG 36800b99b8Sopenharmony_ci#undef LOG_TAG 37800b99b8Sopenharmony_ci#define LOG_TAG "DfxExitHook" 38800b99b8Sopenharmony_ci#endif 39800b99b8Sopenharmony_ci 40800b99b8Sopenharmony_citypedef int (*KillFunc)(pid_t pid, int sig); 41800b99b8Sopenharmony_citypedef __attribute__((noreturn)) void (*ExitFunc)(int code); 42800b99b8Sopenharmony_cistatic KillFunc g_hookedKill = NULL; 43800b99b8Sopenharmony_cistatic ExitFunc g_hookedExit = NULL; 44800b99b8Sopenharmony_cistatic ExitFunc g_hookedExitEx = NULL; 45800b99b8Sopenharmony_cistatic bool g_abortWhenExit = false; 46800b99b8Sopenharmony_ci 47800b99b8Sopenharmony_cistatic void __attribute__((constructor)) InitExitHook(void) 48800b99b8Sopenharmony_ci{ 49800b99b8Sopenharmony_ci char* str = getenv("ABORT_EXIT"); 50800b99b8Sopenharmony_ci if (str != NULL && strlen(str) > 0) { 51800b99b8Sopenharmony_ci printf("AbortExit:%s\n", str); 52800b99b8Sopenharmony_ci g_abortWhenExit = true; 53800b99b8Sopenharmony_ci } 54800b99b8Sopenharmony_ci 55800b99b8Sopenharmony_ci StartHookExitFunc(); 56800b99b8Sopenharmony_ci} 57800b99b8Sopenharmony_ci 58800b99b8Sopenharmony_ciint kill(pid_t pid, int sig) 59800b99b8Sopenharmony_ci{ 60800b99b8Sopenharmony_ci DFXLOGF("%{public}d send signal(%{public}d) to %{public}d", getpid(), sig, pid); 61800b99b8Sopenharmony_ci if ((sig == SIGKILL) && (pid == getpid())) { 62800b99b8Sopenharmony_ci abort(); 63800b99b8Sopenharmony_ci } else if (sig == SIGKILL) { 64800b99b8Sopenharmony_ci LogBacktrace(); 65800b99b8Sopenharmony_ci } 66800b99b8Sopenharmony_ci 67800b99b8Sopenharmony_ci if (g_hookedKill == NULL) { 68800b99b8Sopenharmony_ci DFXLOGE("hooked kill is NULL?\n"); 69800b99b8Sopenharmony_ci return syscall(SYS_kill, pid, sig); 70800b99b8Sopenharmony_ci } 71800b99b8Sopenharmony_ci return g_hookedKill(pid, sig); 72800b99b8Sopenharmony_ci} 73800b99b8Sopenharmony_ci 74800b99b8Sopenharmony_civoid exit(int code) 75800b99b8Sopenharmony_ci{ 76800b99b8Sopenharmony_ci DFXLOGF("%{public}d call exit with code %{public}d", getpid(), code); 77800b99b8Sopenharmony_ci if (!g_abortWhenExit) { 78800b99b8Sopenharmony_ci LogBacktrace(); 79800b99b8Sopenharmony_ci } 80800b99b8Sopenharmony_ci 81800b99b8Sopenharmony_ci if ((!g_abortWhenExit) && (g_hookedExit != NULL)) { 82800b99b8Sopenharmony_ci g_hookedExit(code); 83800b99b8Sopenharmony_ci } else if (g_abortWhenExit) { 84800b99b8Sopenharmony_ci abort(); 85800b99b8Sopenharmony_ci } 86800b99b8Sopenharmony_ci 87800b99b8Sopenharmony_ci quick_exit(code); 88800b99b8Sopenharmony_ci} 89800b99b8Sopenharmony_ci 90800b99b8Sopenharmony_civoid _exit(int code) 91800b99b8Sopenharmony_ci{ 92800b99b8Sopenharmony_ci DFXLOGF("%{public}d call exit with code %{public}d", getpid(), code); 93800b99b8Sopenharmony_ci if (!g_abortWhenExit) { 94800b99b8Sopenharmony_ci LogBacktrace(); 95800b99b8Sopenharmony_ci } 96800b99b8Sopenharmony_ci 97800b99b8Sopenharmony_ci if ((!g_abortWhenExit) && (g_hookedExitEx != NULL)) { 98800b99b8Sopenharmony_ci g_hookedExitEx(code); 99800b99b8Sopenharmony_ci } else if (g_abortWhenExit) { 100800b99b8Sopenharmony_ci abort(); 101800b99b8Sopenharmony_ci } 102800b99b8Sopenharmony_ci 103800b99b8Sopenharmony_ci quick_exit(code); 104800b99b8Sopenharmony_ci} 105800b99b8Sopenharmony_ci 106800b99b8Sopenharmony_ciGEN_HOOK_FUNC(StartHookKillFunction, KillFunc, "kill", g_hookedKill) 107800b99b8Sopenharmony_ciGEN_HOOK_FUNC(StartHookExitFunction, ExitFunc, "exit", g_hookedExit) 108800b99b8Sopenharmony_ciGEN_HOOK_FUNC(StartHookExitExFunction, ExitFunc, "_exit", g_hookedExitEx) 109800b99b8Sopenharmony_ci 110800b99b8Sopenharmony_civoid StartHookExitFunc(void) 111800b99b8Sopenharmony_ci{ 112800b99b8Sopenharmony_ci StartHookKillFunction(); 113800b99b8Sopenharmony_ci StartHookExitFunction(); 114800b99b8Sopenharmony_ci StartHookExitExFunction(); 115800b99b8Sopenharmony_ci} 116