You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何认证进程?C/C++中如何限制特定函数仅被可信应用调用?

嘿,我来帮你梳理下这个问题的解决方案——既要做进程认证,又要限制特定函数的调用范围,确实得避开那些不靠谱的方案,咱们一步步来:

一、避开坑点后的进程认证可行方案

你说的PID、argv[0]确实不靠谱:PID每次重启都变,argv[0]能被轻易篡改;哈希整个可执行文件又太耗性能,尤其是大文件。下面几个方案更实用:

1. 基于进程真实路径的白名单验证

内核会维护每个进程的真实可执行文件路径,Linux下可以通过/proc/[pid]/exe这个符号链接读取,Windows下可以用GetModuleFileNameEx获取。这个路径是绝对路径,不会因为启动方式不同而变化,也很难被伪造。

具体做法:

  • 预先把可信应用A、B的绝对路径存入白名单(比如/opt/trusted/app_a、/opt/trusted/app_b)
  • 在foo()被调用时,获取当前进程的真实路径,和白名单对比,匹配才允许执行逻辑

示例代码(Linux下):

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#define MAX_PATH 4096
// 可信路径白名单
const char* trusted_paths[] = {"/opt/trusted/app_a", "/opt/trusted/app_b", NULL};

// 获取进程的真实可执行路径
char* get_real_exe_path() {
    char proc_path[MAX_PATH];
    char* exe_path = malloc(MAX_PATH);
    if (!exe_path) return NULL;

    snprintf(proc_path, sizeof(proc_path), "/proc/%d/exe", getpid());
    ssize_t len = readlink(proc_path, exe_path, MAX_PATH - 1);
    if (len == -1) {
        free(exe_path);
        return NULL;
    }
    exe_path[len] = '\0';
    return exe_path;
}

void foo() {
    char* exe_path = get_real_exe_path();
    if (!exe_path) {
        printf("无法获取进程路径,调用失败\n");
        return;
    }

    int is_trusted = 0;
    for (int i = 0; trusted_paths[i] != NULL; i++) {
        if (strcmp(exe_path, trusted_paths[i]) == 0) {
            is_trusted = 1;
            break;
        }
    }

    if (is_trusted) {
        printf("可信进程,执行foo()逻辑\n");
        // 这里写你的函数逻辑
    } else {
        printf("非可信进程,调用foo()失败\n");
    }

    free(exe_path);
}

2. 利用系统权限/能力机制

如果你的运行环境是Linux,可以借助Capabilities;Windows下可以用权限令牌。给可信应用分配专属的权限,然后在foo()里检查当前进程是否拥有该权限。

比如Linux下:

  • 给应用A、B添加自定义能力(或者用现有非敏感能力):sudo setcap cap_sys_resource+ep /opt/trusted/app_a
  • 在foo()里调用prctl(PR_CAPBSET_READ, CAP_SYS_RESOURCE)检查是否拥有该能力,只有拥有才允许执行

这种方案的优势是系统级别的安全,很难被绕过,缺点是需要管理员权限配置可信应用。

3. 数字签名验证

如果需要更高的安全性(防止可信应用被篡改后调用foo()),可以给可信应用的可执行文件做数字签名,然后在foo()里验证调用进程的签名是否合法。

具体步骤:

  • 生成一对RSA密钥,用私钥给A、B的可执行文件签名,把公钥嵌入到你的库中
  • 在foo()里读取当前进程的可执行文件,计算其哈希值,然后用公钥验证签名是否匹配

这个方案比哈希整个文件高效,因为只需要验证签名对应的哈希,不用计算整个文件的哈希,而且能防止文件被篡改后伪造哈希值。

4. 基于UID/GID的身份验证

如果你的可信应用都是以特定用户或用户组运行的(比如专属的trusted_user用户),可以在foo()里调用getuid()或getgid(),检查当前进程的身份是否在可信列表中。

这个方案最简单,适合内部受控环境,但缺点是如果用户能切换身份(比如sudo),安全性会打折扣。

二、方案选型建议
  • 普通场景:优先选真实路径白名单,实现简单,性能开销小
  • 高安全要求场景:结合真实路径+数字签名,既保证调用者是可信应用,又防止应用被篡改
  • 系统级管控场景:用Capabilities/权限令牌,借助系统机制实现强管控

内容的提问来源于stack exchange,提问作者jungsooboo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 06:17:18