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

Intel Pin仅插装子进程expr问题:全局变量trg_pid未更新

问题根源

Intel Pin 工具中,全局变量是每个被插装进程独立拥有一份副本的。你在FollowChild回调中设置的trg_pid,仅会修改 Pin 控制进程或父进程(run.sh)的工具副本值,而expr进程的工具副本里的trg_pid仍保持初始值0,导致print_ins无法正确识别目标进程。

解决方法

以下是三种可行的解决方案,按实现复杂度从低到高排序:

方法一:通过进程名称直接过滤(最简单)

在插装回调中直接获取当前进程的可执行文件名称,判断是否为expr后再执行插装逻辑:

#include <cstring>
#include "pin.H"

VOID YourCallback(ADDRINT ins_ptr)
{
    // 你的指令处理逻辑,比如打印地址
    printf("Indirect call at: 0x%lx\n", ins_ptr);
}

VOID print_ins(INS ins, VOID *v)
{
    // 获取当前进程的可执行文件路径
    const char* app_path = PIN_GetApplicationName();
    // 匹配进程名(兼容绝对路径和相对路径)
    if (strstr(app_path, "expr") != nullptr)
    {
        // 仅处理间接调用指令
        if (INS_IsIndirectCall(ins))
        {
            INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)YourCallback, IARG_INST_PTR, IARG_END);
        }
    }
}

int main(int argc, char *argv[])
{
    if (PIN_Init(argc, argv)) return 1;
    
    INS_AddInstrumentFunction(print_ins, nullptr);
    PIN_StartProgram();
    
    return 0;
}

注意:如果需要精确匹配进程名(避免误匹配含expr字符串的其他进程),可以用basename函数提取路径的最后部分再对比。

方法二:利用 Pin 跨进程共享数据存储目标 PID

使用 Pin 提供的PIN_SetDataInPinTool和PIN_GetDataFromPinTool接口,在FollowChild回调中存储expr的 PID,再在插装回调中读取并对比:

#include <cstring>
#include "pin.H"

// 共享数据的唯一标识Key
static const int TRG_PID_KEY = 0;

VOID YourCallback(ADDRINT ins_ptr)
{
    printf("Indirect call at: 0x%lx\n", ins_ptr);
}

VOID FollowChild(CHILD_PROCESS childProcess, VOID *userData)
{
    PID child_pid = CHILD_PROCESS_GetId(childProcess);
    const char* child_path = CHILD_PROCESS_GetExecutablePath(childProcess);
    
    if (strstr(child_path, "expr") != nullptr)
    {
        // 将目标PID存入Pin共享存储
        PIN_SetDataInPinTool(TRG_PID_KEY, &child_pid, sizeof(PID));
        // 允许插装该子进程
        CHILD_PROCESS_SetPinFlags(childProcess, PIN_FLAG_DEFAULT);
    }
    else
    {
        // 跳过其他子进程的插装
        CHILD_PROCESS_SetPinFlags(childProcess, PIN_FLAG_NEVER_PIN);
    }
}

VOID print_ins(INS ins, VOID *v)
{
    PID trg_pid = 0;
    // 从共享存储读取目标PID
    if (PIN_GetDataFromPinTool(TRG_PID_KEY, &trg_pid, sizeof(PID)) == PIN_DATA_SUCCESS)
    {
        PID current_pid = PIN_GetApplicationPID();
        if (current_pid == trg_pid && INS_IsIndirectCall(ins))
        {
            INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)YourCallback, IARG_INST_PTR, IARG_END);
        }
    }
}

int main(int argc, char *argv[])
{
    if (PIN_Init(argc, argv)) return 1;
    
    PIN_AddFollowChildProcessFunction(FollowChild, nullptr);
    INS_AddInstrumentFunction(print_ins, nullptr);
    
    PIN_StartProgram();
    return 0;
}

方法三:通过环境变量标记目标进程

在FollowChild回调中给expr进程添加专属环境变量,插装回调通过检查环境变量判断是否为目标进程:

#include <cstring>
#include <cstdlib>
#include "pin.H"

VOID YourCallback(ADDRINT ins_ptr)
{
    printf("Indirect call at: 0x%lx\n", ins_ptr);
}

VOID FollowChild(CHILD_PROCESS childProcess, VOID *userData)
{
    const char* child_path = CHILD_PROCESS_GetExecutablePath(childProcess);
    if (strstr(child_path, "expr") != nullptr)
    {
        // 添加环境变量标记目标进程
        CHILD_PROCESS_AddEnvironmentVariable(childProcess, "PIN_TRACK_EXPR=1");
        CHILD_PROCESS_SetPinFlags(childProcess, PIN_FLAG_DEFAULT);
    }
    else
    {
        CHILD_PROCESS_SetPinFlags(childProcess, PIN_FLAG_NEVER_PIN);
    }
}

VOID print_ins(INS ins, VOID *v)
{
    // 检查环境变量是否存在并匹配
    char* track_flag = getenv("PIN_TRACK_EXPR");
    if (track_flag != nullptr && strcmp(track_flag, "1") == 0 && INS_IsIndirectCall(ins))
    {
        INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)YourCallback, IARG_INST_PTR, IARG_END);
    }
}

int main(int argc, char *argv[])
{
    if (PIN_Init(argc, argv)) return 1;
    
    PIN_AddFollowChildProcessFunction(FollowChild, nullptr);
    INS_AddInstrumentFunction(print_ins, nullptr);
    
    PIN_StartProgram();
    return 0;
}
注意事项
  • 如果不需要插装run.sh本身,可以在main函数中提前判断当前进程名,直接跳过插装逻辑。
  • 进程名匹配时,根据实际场景选择精确匹配或模糊匹配,避免误判。
  • 确保使用的 Pin API 与你的 Pin 版本兼容,部分旧版本可能存在接口差异。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 18:45:29