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

  • 相关阅读:
    设计模式:迭代器模式
    Cryptology
    Python项目实战 —— 04. 淘宝用户行为分析
    PCF8574/ PCF8574A/ PCF8574T I2C to parellal 8-bits I/O
    Teams Tab App 分析
    使用react 写前端代码,使用javascript 写后端代码,前端向后端patch数据,如果后端要求integer型,前端要传什么型的数据才能成功修改后端的数据并返回给前端?
    MCollections——15
    北大肖臻老师《区块链技术与应用》系列课程学习笔记[6]比特币脚本
    外设篇:触摸屏
    修改借款金额的操作方法
  • 原文地址:https://blog.csdn.net/qq_42931917/article/details/125513299