Android中/system/bin/raccoon无法记录控制套接字传入变量的问题排查
问题排查与修复方案
核心问题1:日志代码中argv引用错误
你的日志代码对argv的取值逻辑完全错误,*argv[i]等价于*(argv[i]),只会取到指针指向的第一个字符而非完整字符串,命令行场景下能“正常显示”纯属巧合(未触发崩溃)。正确写法应为(*argv)[i]——因为argv是char***类型,*argv才是指向参数数组的char**指针。
核心问题2:套接字参数接收后的日志输出错误
在android_get_control_and_arguments函数末尾,你使用do_plog(LLV_DEBUG, "\n*Received %s Arguments");时,格式占位符%s对应字符串类型,但未传入任何参数,导致日志输出异常。应改为%d并传入实际接收的参数数量i-1(循环从i=1开始计数)。
次要问题:日志文件打开方式可能导致覆盖
用fopen("/sdcard/log.txt", "w")每次打开都会清空文件,若套接字服务是常驻进程,新连接的日志会覆盖旧内容,建议改为"a"(追加模式)。
修正后的代码
日志代码修正:
FILE *filepntr = fopen("/sdcard/log.txt", "a"); // 改为追加模式 if (!filepntr) { // 增加文件打开失败判断 do_plog(LLV_ERROR, "Failed to open log file"); return; } fprintf(filepntr, "\nThis line was for shits and giggles\n"); fprintf(filepntr, "*argc: %d\n", *argc ); fprintf(filepntr, "*argv[0]: %s\n", (*argv)[0] ); // 修正参数引用方式 if ( *argc == 1 ) { fprintf(filepntr, "No arguments were passed.\n" ); } else { fprintf(filepntr, "Arguments:\n" ); for ( int i = 1; i < *argc; ++i ) { // 声明局部变量i fprintf(filepntr, " %d. %s\n", i, (*argv)[i] ); // 修正参数引用方式 } } fclose(filepntr); // 关闭文件句柄,避免资源泄漏
套接字处理代码修正:
static int android_get_control_and_arguments(int *argc, char ***argv) { static char *args[32]; int control; int i; atexit(notify_death); if ((i = android_get_control_socket("racoon")) == -1) { return -1; } do_plog(LLV_DEBUG, "Waiting for control socket"); if (listen(i, 1) == -1 || (control = accept(i, NULL, 0)) == -1) { do_plog(LLV_ERROR, "Cannot get control socket"); exit(1); } close(i); fcntl(control, F_SETFD, FD_CLOEXEC); args[0] = (*argv)[0]; for (i = 1; i < 32; ++i) { unsigned char bytes[2]; if (recv(control, &bytes[0], 1, 0) != 1 || recv(control, &bytes[1], 1, 0) != 1) { do_plog(LLV_ERROR, "Cannot get argument length"); exit(1); } else { int length = bytes[0] << 8 | bytes[1]; int offset = 0; if (length == 0xFFFF) { break; } args[i] = malloc(length + 1); if (!args[i]) { // 增加内存分配失败判断 do_plog(LLV_ERROR, "Failed to allocate memory for argument"); exit(1); } while (offset < length) { int n = recv(control, &args[i][offset], length - offset, 0); if (n > 0) { offset += n; } else { do_plog(LLV_ERROR, "Cannot get argument value"); free(args[i]); // 释放已分配内存,避免泄漏 exit(1); } } args[i][length] = 0; } } do_plog(LLV_DEBUG, "\n*Received %d Arguments", i-1); // 修正格式符与传入参数 *argc = i; *argv = args; return control; }
额外检查点
- 确认外部应用发送参数的格式符合接收逻辑:每个参数前必须先发送两个字节的大端序长度,最后发送
0xFFFF作为结束标记。 - 检查
raccoon进程是否有读写/sdcard/log.txt的权限,Android 10+需WRITE_EXTERNAL_STORAGE权限,或改用/data/local/tmp/log.txt这类无需特殊权限的路径。
内容的提问来源于stack exchange,提问作者Corey F
相关产品推荐
相关产品推荐

