工具下载地址: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
To build all examples in a directory for ia32 architecture:
$ cd source/tools/ManualExamples
$ make all TARGET=ia32
To build all examples in a directory for intel64 architecture:
$ cd source/tools/ManualExamples
$ make all TARGET=intel64
To build and run a specific example (e.g., inscount0):
$ cd source/tools/ManualExamples
$ make inscount0.test TARGET=intel64
To build a specific example without running it (e.g., inscount0):
$ cd source/tools/ManualExamples
$ make obj-intel64/inscount0.so TARGET=intel64
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
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
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
目的:获取用户态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);
}
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 */
/* ===================================================================== */
$ 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
从上面例子来看,Pin成功获取到了函数的入参100和200,返回值为较大数200,这个功能有点类似于内核的kprobe的功能。