• 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的功能。

  • 相关阅读:
    rosbag遍历数据出错:(unicode error) 'utf-8' codec can't decode byte 0xcd in position 31: invalid continuation byte
    Java 学习笔记
    Android 中如何使用 App Links
    jmap执行失败了,怎么获取heapdump?
    JavaScript基础
    补码的最终理解
    第四章 c数组
    Java中的Servlet
    重载运算符C++---学习笔记
    基于FPGA的电磁超声脉冲压缩检测系统 论文+源文件
  • 原文地址:https://blog.csdn.net/qq_42931917/article/details/125513299