feat: 清理不再需要的hook_write,新增交叉编译脚本

This commit is contained in:
Pan Qiancheng 2025-12-09 20:08:15 +08:00
parent dd7865e7f9
commit 5418ce4b38
3 changed files with 225 additions and 178 deletions

View File

@ -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 CFLAGS = -shared -fPIC -Wall -Wextra -Werror -fno-strict-aliasing -fPIC -fno-omit-frame-pointer -fno-stack-protector -Wl,-z,relro,-z,now
LDFLAGS = -ldl LDFLAGS = -ldl
HOOK_LDFLAGS = -ldl -pthread
TARGET_NAME = libbash_smart.so TARGET_NAME = libbash_smart$(TARGET_SUFFIX).so
HOOK_NAME = libbash_smart_hook_write.so
BUILD_DIR = build BUILD_DIR = build
SRC_DIR = src SRC_DIR = src
TESTS_DIR = tests TESTS_DIR = tests
SRC = $(wildcard $(SRC_DIR)/*.c) 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)) OBJ = $(patsubst $(SRC_DIR)/%.c,$(BUILD_DIR)/%.o,$(SRC))
TARGET = $(BUILD_DIR)/$(TARGET_NAME) 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 = $(BUILD_DIR)/test_client
TEST_CLIENT_SRC = $(TESTS_DIR)/test_client.c TEST_CLIENT_SRC = $(TESTS_DIR)/test_client.c
@ -45,15 +59,48 @@ ifeq ($(NO_CONFIG_CHECK),1)
CFLAGS += -DNO_CONFIG_CHECK CFLAGS += -DNO_CONFIG_CHECK
endif 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_client: pre_build $(TEST_CLIENT)
test_concurrent_client: pre_build $(TEST_CONCURRENT_CLIENT) test_concurrent_client: pre_build $(TEST_CONCURRENT_CLIENT)
pre_build: pre_build:
@echo "=========================================="
@echo "编译配置:"
@echo " 架构: $(ARCH)"
@echo " 编译器: $(CC)"
@echo " 目标文件: $(TARGET_NAME)"
@echo "=========================================="
ifeq ($(DEBUG),1) ifeq ($(DEBUG),1)
@echo "Building with debug flags..." @echo "Building with debug flags..."
endif endif
@ -71,14 +118,7 @@ $(BUILD_DIR)/%.o: $(SRC_DIR)/%.c
$(TARGET): $(OBJ) $(TARGET): $(OBJ)
@mkdir -p $(BUILD_DIR) @mkdir -p $(BUILD_DIR)
$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
@rm -f $(OBJ)
$(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 $@
$(TEST_CLIENT): $(TEST_CLIENT_SRC) $(TEST_CLIENT_DEPS) $(TEST_CLIENT): $(TEST_CLIENT_SRC) $(TEST_CLIENT_DEPS)
@mkdir -p $(BUILD_DIR) @mkdir -p $(BUILD_DIR)

166
build_all.sh Executable file
View File

@ -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:-}"

View File

@ -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.");
}