feat: 清理不再需要的hook_write,新增交叉编译脚本
This commit is contained in:
parent
dd7865e7f9
commit
5418ce4b38
78
Makefile
78
Makefile
|
|
@ -1,25 +1,39 @@
|
|||
CC = gcc
|
||||
# 检测架构
|
||||
ARCH ?= $(shell uname -m)
|
||||
|
||||
# 交叉编译工具链配置
|
||||
ifeq ($(ARCH),arm64)
|
||||
CC = aarch64-linux-gnu-gcc
|
||||
TARGET_SUFFIX = _arm64
|
||||
else ifeq ($(ARCH),aarch64)
|
||||
CC = aarch64-linux-gnu-gcc
|
||||
TARGET_SUFFIX = _arm64
|
||||
ARCH = arm64
|
||||
else ifeq ($(ARCH),arm)
|
||||
CC = arm-linux-gnueabihf-gcc
|
||||
TARGET_SUFFIX = _arm
|
||||
else ifeq ($(ARCH),x86_64)
|
||||
CC = gcc
|
||||
TARGET_SUFFIX = _x86_64
|
||||
else
|
||||
CC = gcc
|
||||
TARGET_SUFFIX = _x86_64
|
||||
endif
|
||||
|
||||
CFLAGS = -shared -fPIC -Wall -Wextra -Werror -fno-strict-aliasing -fPIC -fno-omit-frame-pointer -fno-stack-protector -Wl,-z,relro,-z,now
|
||||
LDFLAGS = -ldl
|
||||
HOOK_LDFLAGS = -ldl -pthread
|
||||
|
||||
TARGET_NAME = libbash_smart.so
|
||||
HOOK_NAME = libbash_smart_hook_write.so
|
||||
TARGET_NAME = libbash_smart$(TARGET_SUFFIX).so
|
||||
|
||||
BUILD_DIR = build
|
||||
SRC_DIR = src
|
||||
TESTS_DIR = tests
|
||||
|
||||
SRC = $(wildcard $(SRC_DIR)/*.c)
|
||||
SRC := $(filter-out $(SRC_DIR)/hook_write.c, $(SRC)) # 排除 hook_write.c
|
||||
|
||||
OBJ = $(patsubst $(SRC_DIR)/%.c,$(BUILD_DIR)/%.o,$(SRC))
|
||||
TARGET = $(BUILD_DIR)/$(TARGET_NAME)
|
||||
|
||||
HOOK_SRC = $(SRC_DIR)/hook_write.c
|
||||
HOOK_OBJ = $(BUILD_DIR)/hook_write.o
|
||||
HOOK_TARGET = $(BUILD_DIR)/$(HOOK_NAME)
|
||||
|
||||
# 测试客户端
|
||||
TEST_CLIENT = $(BUILD_DIR)/test_client
|
||||
TEST_CLIENT_SRC = $(TESTS_DIR)/test_client.c
|
||||
|
|
@ -45,15 +59,48 @@ ifeq ($(NO_CONFIG_CHECK),1)
|
|||
CFLAGS += -DNO_CONFIG_CHECK
|
||||
endif
|
||||
|
||||
.PHONY: all clean debug hook rebuild pre_build test_client test_concurrent_client
|
||||
.PHONY: all clean debug hook rebuild pre_build test_client test_concurrent_client arm64 arm install-cross-tools
|
||||
|
||||
all: pre_build $(TARGET) $(HOOK_TARGET)
|
||||
all: pre_build $(TARGET)
|
||||
|
||||
# 快捷方式:交叉编译到 ARM64
|
||||
arm64:
|
||||
$(MAKE) ARCH=arm64
|
||||
|
||||
# 快捷方式:交叉编译到 ARM32
|
||||
arm:
|
||||
$(MAKE) ARCH=arm
|
||||
|
||||
# 安装交叉编译工具链
|
||||
install-cross-tools:
|
||||
@echo "安装 ARM 交叉编译工具链..."
|
||||
@if ! command -v aarch64-linux-gnu-gcc > /dev/null 2>&1; then \
|
||||
echo "正在安装 gcc-aarch64-linux-gnu..."; \
|
||||
sudo apt-get install -y gcc-aarch64-linux-gnu g++-aarch64-linux-gnu || \
|
||||
(echo "安装失败,尝试不更新源..." && sudo apt-get install -y --no-update gcc-aarch64-linux-gnu g++-aarch64-linux-gnu); \
|
||||
else \
|
||||
echo "aarch64-linux-gnu-gcc 已安装"; \
|
||||
fi
|
||||
@if ! command -v arm-linux-gnueabihf-gcc > /dev/null 2>&1; then \
|
||||
echo "正在安装 gcc-arm-linux-gnueabihf..."; \
|
||||
sudo apt-get install -y gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf || \
|
||||
(echo "安装失败,尝试不更新源..." && sudo apt-get install -y --no-update gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf); \
|
||||
else \
|
||||
echo "arm-linux-gnueabihf-gcc 已安装"; \
|
||||
fi
|
||||
@echo "交叉编译工具链安装完成!"
|
||||
|
||||
test_client: pre_build $(TEST_CLIENT)
|
||||
|
||||
test_concurrent_client: pre_build $(TEST_CONCURRENT_CLIENT)
|
||||
|
||||
pre_build:
|
||||
@echo "=========================================="
|
||||
@echo "编译配置:"
|
||||
@echo " 架构: $(ARCH)"
|
||||
@echo " 编译器: $(CC)"
|
||||
@echo " 目标文件: $(TARGET_NAME)"
|
||||
@echo "=========================================="
|
||||
ifeq ($(DEBUG),1)
|
||||
@echo "Building with debug flags..."
|
||||
endif
|
||||
|
|
@ -71,14 +118,7 @@ $(BUILD_DIR)/%.o: $(SRC_DIR)/%.c
|
|||
$(TARGET): $(OBJ)
|
||||
@mkdir -p $(BUILD_DIR)
|
||||
$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
|
||||
|
||||
$(HOOK_TARGET): $(HOOK_OBJ)
|
||||
@mkdir -p $(BUILD_DIR)
|
||||
$(CC) $(CFLAGS) -Wno-error=unused-result -o $@ $^ $(HOOK_LDFLAGS)
|
||||
|
||||
$(HOOK_OBJ): $(HOOK_SRC)
|
||||
@mkdir -p $(BUILD_DIR)
|
||||
$(CC) $(CFLAGS) -Wno-error=unused-result -c $< -o $@
|
||||
@rm -f $(OBJ)
|
||||
|
||||
$(TEST_CLIENT): $(TEST_CLIENT_SRC) $(TEST_CLIENT_DEPS)
|
||||
@mkdir -p $(BUILD_DIR)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,166 @@
|
|||
#!/bin/bash
|
||||
|
||||
# 快速编译所有架构脚本
|
||||
# 用途: 一键编译 x86_64, arm64, arm 三个架构
|
||||
|
||||
set -e
|
||||
|
||||
# 定义颜色
|
||||
readonly RED='\033[0;31m'
|
||||
readonly GREEN='\033[0;32m'
|
||||
readonly YELLOW='\033[1;33m'
|
||||
readonly BLUE='\033[0;34m'
|
||||
readonly NC='\033[0m'
|
||||
|
||||
# 日志函数
|
||||
log_info() {
|
||||
echo -e "${GREEN}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
log_error() {
|
||||
echo -e "${RED}[ERROR]${NC} $1"
|
||||
}
|
||||
|
||||
log_success() {
|
||||
echo -e "${BLUE}[SUCCESS]${NC} $1"
|
||||
}
|
||||
|
||||
# 显示帮助信息
|
||||
show_help() {
|
||||
cat << EOF
|
||||
${BLUE}快速编译所有架构脚本${NC}
|
||||
|
||||
用法: $0 [选项]
|
||||
|
||||
选项:
|
||||
-h, --help 显示此帮助信息
|
||||
--hook 启用 HOOK=1
|
||||
--no-config-check 启用 NO_CONFIG_CHECK=1
|
||||
--debug 启用 DEBUG=1
|
||||
--no-clean 跳过清理步骤
|
||||
--arch <archs> 指定编译架构 (默认: x86_64 arm64 arm)
|
||||
可以用逗号或空格分隔,例如: --arch "x86_64,arm64"
|
||||
|
||||
示例:
|
||||
$0 # 编译所有架构
|
||||
$0 --hook --no-config-check # 编译所有架构并启用 HOOK 和 NO_CONFIG_CHECK
|
||||
$0 --debug --arch "x86_64,arm64" # 仅编译 x86_64 和 arm64,启用调试
|
||||
$0 --hook --no-config-check --debug # 编译所有架构,启用所有选项
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
# 解析参数
|
||||
HOOK=""
|
||||
NO_CONFIG_CHECK=""
|
||||
DEBUG=""
|
||||
DO_CLEAN=true
|
||||
ARCHS=("x86_64" "arm64" "arm")
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
-h|--help)
|
||||
show_help
|
||||
exit 0
|
||||
;;
|
||||
--hook)
|
||||
HOOK="HOOK=1"
|
||||
shift
|
||||
;;
|
||||
--no-config-check)
|
||||
NO_CONFIG_CHECK="NO_CONFIG_CHECK=1"
|
||||
shift
|
||||
;;
|
||||
--debug)
|
||||
DEBUG="DEBUG=1"
|
||||
shift
|
||||
;;
|
||||
--no-clean)
|
||||
DO_CLEAN=false
|
||||
shift
|
||||
;;
|
||||
--arch)
|
||||
if [[ -n "$2" && "$2" != --* ]]; then
|
||||
# 支持逗号或空格分隔
|
||||
IFS=', ' read -r -a ARCHS <<< "$2"
|
||||
shift 2
|
||||
else
|
||||
log_error "--arch 需要参数"
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
log_error "未知参数: $1"
|
||||
show_help
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# 构建 make 参数
|
||||
MAKE_FLAGS="$HOOK $NO_CONFIG_CHECK $DEBUG"
|
||||
|
||||
FAILED_ARCHS=()
|
||||
SUCCESS_ARCHS=()
|
||||
|
||||
echo ""
|
||||
log_info "=========================================="
|
||||
log_info "开始编译所有架构"
|
||||
log_info "架构列表: ${ARCHS[*]}"
|
||||
log_info "编译参数: $MAKE_FLAGS"
|
||||
log_info "=========================================="
|
||||
echo ""
|
||||
|
||||
# 清理之前的编译产物
|
||||
if [ "$DO_CLEAN" = true ]; then
|
||||
log_info "清理之前的编译产物..."
|
||||
make clean
|
||||
echo ""
|
||||
fi
|
||||
|
||||
# 遍历编译每个架构
|
||||
for arch in "${ARCHS[@]}"; do
|
||||
log_info "----------------------------------------"
|
||||
log_info "正在编译架构: $arch"
|
||||
log_info "----------------------------------------"
|
||||
|
||||
if make $MAKE_FLAGS ARCH=$arch; then
|
||||
log_success "架构 $arch 编译成功"
|
||||
SUCCESS_ARCHS+=("$arch")
|
||||
else
|
||||
log_error "架构 $arch 编译失败"
|
||||
FAILED_ARCHS+=("$arch")
|
||||
fi
|
||||
|
||||
echo ""
|
||||
done
|
||||
|
||||
# 显示编译结果
|
||||
log_info "=========================================="
|
||||
log_info "编译完成"
|
||||
log_info "=========================================="
|
||||
echo ""
|
||||
|
||||
if [ ${#SUCCESS_ARCHS[@]} -gt 0 ]; then
|
||||
log_success "成功编译的架构: ${SUCCESS_ARCHS[*]}"
|
||||
fi
|
||||
|
||||
if [ ${#FAILED_ARCHS[@]} -gt 0 ]; then
|
||||
log_error "失败编译的架构: ${FAILED_ARCHS[*]}"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
log_info "编译产物:"
|
||||
ls -lh build/*.so 2>/dev/null || log_error "没有找到编译产物"
|
||||
echo ""
|
||||
|
||||
# 如果有失败的架构,返回错误码
|
||||
if [ ${#FAILED_ARCHS[@]} -gt 0 ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_success "所有架构编译完成!"
|
||||
echo ""
|
||||
log_info "本次编译使用的参数:"
|
||||
log_info " 架构: ${ARCHS[*]}"
|
||||
log_info " 编译选项: ${MAKE_FLAGS:-无}"
|
||||
159
src/hook_write.c
159
src/hook_write.c
|
|
@ -1,159 +0,0 @@
|
|||
#define _GNU_SOURCE
|
||||
#include <dlfcn.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/uio.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "exec_hook.h"
|
||||
|
||||
static int log_fd = -1;
|
||||
|
||||
// 原始函数指针
|
||||
static ssize_t (*original_write)(int, const void *, size_t) = NULL;
|
||||
static ssize_t (*orig_writev)(int, const struct iovec *, int) = NULL;
|
||||
static size_t (*orig_fwrite)(const void *, size_t, size_t, FILE *) = NULL;
|
||||
static int (*orig_fflush)(FILE *) = NULL;
|
||||
static int (*orig_puts)(const char *) = NULL;
|
||||
static int (*orig_printf)(const char *, ...) = NULL;
|
||||
static int (*orig_vprintf)(const char *, va_list) = NULL;
|
||||
static int (*orig_vfprintf)(FILE *, const char *, va_list) = NULL;
|
||||
|
||||
void init_hook() {
|
||||
DEBUG_LOG("Initializing write hooks...");
|
||||
|
||||
original_write = dlsym(RTLD_NEXT, "write");
|
||||
orig_writev = dlsym(RTLD_NEXT, "writev");
|
||||
orig_fwrite = dlsym(RTLD_NEXT, "fwrite");
|
||||
orig_fflush = dlsym(RTLD_NEXT, "fflush");
|
||||
orig_puts = dlsym(RTLD_NEXT, "puts");
|
||||
orig_printf = dlsym(RTLD_NEXT, "printf");
|
||||
orig_vprintf = dlsym(RTLD_NEXT, "vprintf");
|
||||
orig_vfprintf = dlsym(RTLD_NEXT, "vfprintf");
|
||||
|
||||
log_fd = open(LOG_OUT_FILE, O_WRONLY | O_CREAT | O_APPEND, 0644);
|
||||
if (log_fd == -1) {
|
||||
perror("Failed to open log file");
|
||||
}
|
||||
}
|
||||
|
||||
ssize_t write(int fd, const void *buf, size_t count) {
|
||||
DEBUG_LOG("Intercepted write to fd %d", fd);
|
||||
ssize_t result = original_write(fd, buf, count);
|
||||
|
||||
if (log_fd != -1 && (fd == STDOUT_FILENO || fd == STDERR_FILENO) && fd != log_fd) {
|
||||
original_write(log_fd, buf, count);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
ssize_t writev(int fd, const struct iovec *iov, int iovcnt) {
|
||||
DEBUG_LOG("Intercepted writev to fd %d", fd);
|
||||
ssize_t result = orig_writev(fd, iov, iovcnt);
|
||||
|
||||
if (log_fd != -1 && (fd == STDOUT_FILENO || fd == STDERR_FILENO) && fd != log_fd) {
|
||||
for (int i = 0; i < iovcnt; ++i) {
|
||||
write(log_fd, iov[i].iov_base, iov[i].iov_len);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) {
|
||||
DEBUG_LOG("Intercepted fwrite to stream %p", stream);
|
||||
size_t result = orig_fwrite(ptr, size, nmemb, stream);
|
||||
int fd = fileno(stream);
|
||||
if (log_fd != -1 && (fd == STDOUT_FILENO || fd == STDERR_FILENO)) {
|
||||
write(log_fd, ptr, size * nmemb);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int puts(const char *s) {
|
||||
DEBUG_LOG("Intercepted puts: %s", s);
|
||||
int result = orig_puts(s);
|
||||
if (log_fd != -1) {
|
||||
write(log_fd, s, strlen(s));
|
||||
write(log_fd, "\n", 1);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int printf(const char *format, ...) {
|
||||
DEBUG_LOG("Intercepted printf: %s", format);
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
int result = orig_vprintf(format, args);
|
||||
va_end(args);
|
||||
|
||||
// 再次获取 args 写入日志
|
||||
va_start(args, format);
|
||||
if (log_fd != -1) {
|
||||
char buffer[4096];
|
||||
int len = vsnprintf(buffer, sizeof(buffer), format, args);
|
||||
if (len > 0) {
|
||||
write(log_fd, buffer, len);
|
||||
}
|
||||
}
|
||||
va_end(args);
|
||||
return result;
|
||||
}
|
||||
|
||||
int vprintf(const char *format, va_list args) {
|
||||
DEBUG_LOG("Intercepted vprintf: %s", format);
|
||||
int result = orig_vprintf(format, args);
|
||||
if (log_fd != -1) {
|
||||
char buffer[4096];
|
||||
va_list args_copy;
|
||||
va_copy(args_copy, args);
|
||||
int len = vsnprintf(buffer, sizeof(buffer), format, args_copy);
|
||||
va_end(args_copy);
|
||||
if (len > 0) {
|
||||
write(log_fd, buffer, len);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int vfprintf(FILE *stream, const char *format, va_list args) {
|
||||
DEBUG_LOG("Intercepted vfprintf to stream %p: %s", stream, format);
|
||||
int result = orig_vfprintf(stream, format, args);
|
||||
|
||||
int fd = fileno(stream);
|
||||
if (log_fd != -1 && (fd == STDOUT_FILENO || fd == STDERR_FILENO)) {
|
||||
va_list args_copy;
|
||||
va_copy(args_copy, args);
|
||||
char buffer[4096];
|
||||
int len = vsnprintf(buffer, sizeof(buffer), format, args_copy);
|
||||
va_end(args_copy);
|
||||
if (len > 0) {
|
||||
write(log_fd, buffer, len);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int fflush(FILE *stream) {
|
||||
DEBUG_LOG("Intercepted fflush to stream %p", stream);
|
||||
return orig_fflush(stream);
|
||||
}
|
||||
|
||||
__attribute__((constructor)) void init() {
|
||||
DEBUG_LOG("Write hook library loaded.");
|
||||
init_hook();
|
||||
}
|
||||
|
||||
__attribute__((destructor)) void cleanup() {
|
||||
if (log_fd != -1) {
|
||||
close(log_fd);
|
||||
log_fd = -1;
|
||||
}
|
||||
DEBUG_LOG("Write hook library unloaded.");
|
||||
}
|
||||
Loading…
Reference in New Issue