• Intel Pin实现函数probe以及修改原代码路径


    一、工具下载

    工具下载地址:Pin - A Binary Instrumentation Tool - Downloads (intel.com)

    Pin使用手册:Pin: Pin 3.23 User Guide (intel.com)

    # 解压即用
    tar zxvf pin-3.23-98579-gb15ab7903-gcc-linux.tar.gz
    
    • 1
    • 2

    二、sample编译

    Building the Example Tools

    To build all examples in a directory for ia32 architecture:

    $ cd source/tools/ManualExamples
    $ make all TARGET=ia32
    
    • 1
    • 2

    To build all examples in a directory for intel64 architecture:

    $ cd source/tools/ManualExamples
    $ make all TARGET=intel64
    
    • 1
    • 2

    To build and run a specific example (e.g., inscount0):

    $ cd source/tools/ManualExamples
    $ make inscount0.test TARGET=intel64
    
    • 1
    • 2

    To build a specific example without running it (e.g., inscount0):

    $ cd source/tools/ManualExamples
    $ make obj-intel64/inscount0.so TARGET=intel64
    
    • 1
    • 2

    The above applies to the Intel® 64 architecture. For the IA-32 architecture, use TARGET=ia32 instead.

    $ cd source/tools/ManualExamples
    $ make obj-ia32/inscount0.so TARGET=ia32
    
    • 1
    • 2

    三、工具使用

    Simple Instruction Count (Instruction Instrumentation)

    The example below instruments a program to count the total number of instructions executed. It inserts a call to docount before every instruction. When the program exits, it saves the count in the file inscount.out.

    Here is how to run it and display its output (note that the file list is the ls output, so it may be different on your machine, similarly the instruction count will depend on the implementation of ls):

    $ ../../../pin -t obj-intel64/inscount0.so -- /bin/ls
    Makefile          atrace.o     imageload.out  itrace      proccount
    Makefile.example  imageload    inscount0      itrace.o    proccount.o
    atrace            imageload.o  inscount0.o    itrace.out
    # 日志输出文件
    $ cat inscount.out
    Count 422838
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    The KNOB exhibited in the example below overwrites the default name for the output file. To use this feature, add “-o <file_name>” to the command line. Tool command line options should be inserted between the tool name and the double dash (“–”). For more information on how to add command line options to your tool, please see KNOB: Commandline Option Handling.

    # 可以把日志输出到文件
    $ ../../../pin -t obj-intel64/inscount0.so -o inscount0.log -- /bin/ls
    
    • 1
    • 2

    四、根据sample写用例

    目的:获取用户态C语言函数的入参和返回值。

    #include <stdio.h>
    #include <stdlib.h>
    
    static int max(int num1, int num2)
    {
        int result = 0;
        if (num1 > num2) {
            result = num1;
        } else {
            result = num2;
        }
        return result;
    }
    
    int main(void)
    {
        int ret = 0;
        int a = 100, b = 200;
        
        ret = max(a, b);
        printf("最大值为 %d\n", ret);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    intel pin调用程序

    #include "pin.H"
    #include <iostream>
    #include <fstream>
    using std::cerr;
    using std::endl;
    using std::hex;
    using std::ios;
    using std::string;
    
    /* ===================================================================== */
    /* Names of max */
    /* ===================================================================== */
    #define FUNC_MAX "max"
    
    /* ===================================================================== */
    /* Global Variables */
    /* ===================================================================== */
    
    std::ofstream TraceFile;
    
    /* ===================================================================== */
    /* Commandline Switches */
    /* ===================================================================== */
    
    KNOB< string > KnobOutputFile(KNOB_MODE_WRITEONCE, "pintool", "o", "mypintool.out", "specify trace file name");
    
    /* ===================================================================== */
    
    /* ===================================================================== */
    /* Analysis routines                                                     */
    /* ===================================================================== */
    
    VOID Arg1Before(CHAR* name, ADDRINT num1, ADDRINT num2) { TraceFile << name << "(" << num1 << " " << num2 << ")" << endl; }
    
    VOID MallocAfter(ADDRINT ret) { TraceFile << "  returns " << ret << endl; }
    
    /* ===================================================================== */
    /* Instrumentation routines                                              */
    /* ===================================================================== */
    
    VOID Image(IMG img, VOID* v)
    {
        //  Find the max() function.
        RTN mallocRtn = RTN_FindByName(img, FUNC_MAX);
        if (RTN_Valid(mallocRtn))
        {
            RTN_Open(mallocRtn);
    
            // Instrument max() to print the input argument value and the return value.
            RTN_InsertCall(mallocRtn, IPOINT_BEFORE, (AFUNPTR)Arg1Before, IARG_ADDRINT, FUNC_MAX, IARG_FUNCARG_ENTRYPOINT_VALUE, 0,
                           IARG_FUNCARG_ENTRYPOINT_VALUE, 1, IARG_END);
            RTN_InsertCall(mallocRtn, IPOINT_AFTER, (AFUNPTR)MallocAfter, IARG_FUNCRET_EXITPOINT_VALUE, IARG_END);
    
    	RTN_Close(mallocRtn);
        }
     }
    
    /* ===================================================================== */
    
    VOID Fini(INT32 code, VOID* v) { TraceFile.close(); }
    
    /* ===================================================================== */
    /* Print Help Message                                                    */
    /* ===================================================================== */
    
    INT32 Usage()
    {
        cerr << "This tool produces a trace of calls to max." << endl;
        cerr << endl << KNOB_BASE::StringKnobSummary() << endl;
        return -1;
    }
    
    /* ===================================================================== */
    /* Main                                                                  */
    /* ===================================================================== */
    
    int main(int argc, char* argv[])
    {
        // Initialize pin & symbol manager
        PIN_InitSymbols();
        if (PIN_Init(argc, argv))
        {
            return Usage();
        }
    
        // Write to a file since cout and cerr maybe closed by the application
        TraceFile.open(KnobOutputFile.Value().c_str());
        TraceFile << hex;
        TraceFile.setf(ios::showbase);
    
        // Register Image to be called to instrument functions.
        IMG_AddInstrumentFunction(Image, 0);
        PIN_AddFiniFunction(Fini, 0);
    
        // Never returns
        PIN_StartProgram();
    
        return 0;
    }
    
    /* ===================================================================== */
    /* eof */
    /* ===================================================================== */
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    $ gcc test.c -o max
    $ make obj-intel64/mypintool.so TARGET=intel64
    $ ../../../pin -t obj-intel64/mypintool.so -- ./max
    $ cat mypintool.out
    max(0x64 0xc8)
      returns 0xc8
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    从上面例子来看,Pin成功获取到了函数的入参100和200,返回值为较大数200,这个功能有点类似于内核的kprobe的功能。

  • 相关阅读:
    StringBuilder的底层实现原理
    关于工作方法和高效工作的建议
    STM32——STM32F4系统架构
    Android 13.0 解锁状态下禁止下拉状态栏功能实现
    PHP服务器端API原理及示例讲解(接口开发)
    UG\NX二次开发 清除所有对象高亮
    Python 实现 PDF 文件转换为图片 / PaddleOCR
    图像分割笔记(二): 使用YOLOv5-Seg对图像进行分割检测完整版(从自定义数据集到测试验证的完整流程))
    Win11系统点击wifi图标没有反应怎么解决?
    [ Windows-Nginx ]Windows服务器,Tomcat容器部署项目,整合Nginx
  • 原文地址:https://blog.csdn.net/qq_42931917/article/details/125513299