首页
社区
课程
招聘
[原创]分享一个Pintools----跟踪LoadLibrary和GetProcAddress并打印参数
发表于: 2019-1-23 09:10 5739

[原创]分享一个Pintools----跟踪LoadLibrary和GetProcAddress并打印参数

2019-1-23 09:10
5739
说明:
  • 参考样例工具malloctrace的代码(下载解压Pin就有)
  • 修改工程模板MyPinTool (下载解压Pin就有)
  • 代码简介:
    • 在main中使用IMG_AddInstrumentFunction(Image, 0);进行函数插桩
    • 在 Image 函数总插桩了5个函数:LoadLibraryExW、LoadLibraryExA、LoadLibraryW、LoadLibraryA、GetProcAddress,都插桩在函数调用前。
    • 插桩的函数(分ascii版和unicode版)打印被插桩函数的第一个参数:加载的库路径或者要获取地址的函数。
    • 结果写在当前目录的LoadlibraryArguments.out内。


具体代码:
#include "pin.H"
#include <iostream>
#include <fstream>

#include <stdio.h>
#include <unistd.h>

#define LOADLIBRARYEXW "LoadLibraryExW"
#define LOADLIBRARYEXA "LoadLibraryExA"
#define LOADLIBRARYW "LoadLibraryW"
#define LOADLIBRARYA "LoadLibraryA"
#define GETPROCADDRESS "GetProcAddress"


/* ===================================================================== */
/* Global Variables */
/* ===================================================================== */

std::ofstream TraceFile;

/* ===================================================================== */
/* Commandline Switches */
/* ===================================================================== */

KNOB<string> KnobOutputFile(KNOB_MODE_WRITEONCE, "pintool",
    "o", "LoadlibraryArguments.out", "specify trace file name");

/* ===================================================================== */


/* ===================================================================== */
/* Analysis routines                                                     */
/* ===================================================================== */
 
VOID ArgBeforeA(CHAR * name, CHAR * size)
{
	//TraceFile << "in" << endl;
    TraceFile << name << "(" << size << ")" << endl;
}

VOID ArgBeforeA1(CHAR * name, CHAR * size)
{
	//TraceFile << "in" << endl;
	//这里判断是为了排除第一个参数为非法参数的情况,不判断的话,在读出现异常时会进程提出,暂时不知道Pin中如何做异常处理
	if((INT)size > 0xFFFF)
		TraceFile << "------" << name << "(" << size << ")" << endl;
}


VOID ArgBeforeW(CHAR * name, CHAR * size)
{
	//TraceFile << "in" << endl;
    TraceFile << name << "(" ;
	//*
	while(1)
	{
		if(size[0] == 0x00 && size[1] == 0x00)
		{
			break;
		}
		TraceFile << size;
		size++;
		size++;
	}
	//*/
	TraceFile << ")" << endl;
	return;	
	//<< size <<
}


/* ===================================================================== */
/* Instrumentation routines                                              */
/* ===================================================================== */
   
VOID Image(IMG img, VOID *v)
{
    // Instrument the malloc() and free() functions.  Print the input argument
    // of each malloc() or free(), and the return value of malloc().
    //
    //  Find the malloc() function.
	//*/
    RTN LoadLibraryExWRtn = RTN_FindByName(img, LOADLIBRARYEXW);
    if (RTN_Valid(LoadLibraryExWRtn))
    {
        RTN_Open(LoadLibraryExWRtn);

        // Instrument malloc() to print the input argument value and the return value.
        RTN_InsertCall(LoadLibraryExWRtn, IPOINT_BEFORE, (AFUNPTR)ArgBeforeW,
                       IARG_ADDRINT, LOADLIBRARYEXW,
                       IARG_FUNCARG_ENTRYPOINT_VALUE, 0,
                       IARG_END);

        RTN_Close(LoadLibraryExWRtn);
    }

	RTN LoadLibraryExARtn = RTN_FindByName(img, LOADLIBRARYEXA);
    if (RTN_Valid(LoadLibraryExARtn))
    {
        RTN_Open(LoadLibraryExARtn);

        // Instrument malloc() to print the input argument value and the return value.
        RTN_InsertCall(LoadLibraryExARtn, IPOINT_BEFORE, (AFUNPTR)ArgBeforeA,
                       IARG_ADDRINT, LOADLIBRARYEXA,
                       IARG_FUNCARG_ENTRYPOINT_VALUE, 0,
                       IARG_END);

        RTN_Close(LoadLibraryExARtn);
    }
	
	RTN LoadLibraryWRtn = RTN_FindByName(img, LOADLIBRARYW);
    if (RTN_Valid(LoadLibraryWRtn))
    {
        RTN_Open(LoadLibraryWRtn);

        // Instrument malloc() to print the input argument value and the return value.
        RTN_InsertCall(LoadLibraryWRtn, IPOINT_BEFORE, (AFUNPTR)ArgBeforeW,
                       IARG_ADDRINT, LOADLIBRARYW,
                       IARG_FUNCARG_ENTRYPOINT_VALUE, 0,
                       IARG_END);

        RTN_Close(LoadLibraryWRtn);
    }
	//*/

	RTN LoadLibraryARtn = RTN_FindByName(img, LOADLIBRARYA);
    if (RTN_Valid(LoadLibraryARtn))
    {
        RTN_Open(LoadLibraryARtn);

        // Instrument malloc() to print the input argument value and the return value.
        RTN_InsertCall(LoadLibraryARtn, IPOINT_BEFORE, (AFUNPTR)ArgBeforeA,
                       IARG_ADDRINT, LOADLIBRARYA,
                       IARG_FUNCARG_ENTRYPOINT_VALUE , 0,
                       IARG_END);

        RTN_Close(LoadLibraryARtn);
    }
	
	//*
	RTN GetProcAddressRtn = RTN_FindByName(img, GETPROCADDRESS);
    if (RTN_Valid(GetProcAddressRtn))
    {
        RTN_Open(GetProcAddressRtn);

        // Instrument malloc() to print the input argument value and the return value.
        RTN_InsertCall(GetProcAddressRtn, IPOINT_BEFORE, (AFUNPTR)ArgBeforeA1,
                       IARG_ADDRINT, GETPROCADDRESS,
                       IARG_FUNCARG_ENTRYPOINT_VALUE , 1,
                       IARG_END);

        RTN_Close(GetProcAddressRtn);
    }
	//*/
}

/* ===================================================================== */

VOID Fini(INT32 code, VOID *v)
{
    TraceFile.close();
}

/* ===================================================================== */
/* Print Help Message                                                    */
/* ===================================================================== */
   
INT32 Usage()
{
    cerr << "This tool produces a trace of calls to malloc." << 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 */
/* ===================================================================== */
结果样例:

#include "pin.H"
#include <iostream>
#include <fstream>

#include <stdio.h>
#include <unistd.h>

#define LOADLIBRARYEXW "LoadLibraryExW"
#define LOADLIBRARYEXA "LoadLibraryExA"
#define LOADLIBRARYW "LoadLibraryW"
#define LOADLIBRARYA "LoadLibraryA"
#define GETPROCADDRESS "GetProcAddress"


/* ===================================================================== */
/* Global Variables */
/* ===================================================================== */

std::ofstream TraceFile;

/* ===================================================================== */
/* Commandline Switches */
/* ===================================================================== */

KNOB<string> KnobOutputFile(KNOB_MODE_WRITEONCE, "pintool",
    "o", "LoadlibraryArguments.out", "specify trace file name");

/* ===================================================================== */


/* ===================================================================== */
/* Analysis routines                                                     */
/* ===================================================================== */
 
VOID ArgBeforeA(CHAR * name, CHAR * size)
{
	//TraceFile << "in" << endl;
    TraceFile << name << "(" << size << ")" << endl;
}

VOID ArgBeforeA1(CHAR * name, CHAR * size)
{
	//TraceFile << "in" << endl;
	//这里判断是为了排除第一个参数为非法参数的情况,不判断的话,在读出现异常时会进程提出,暂时不知道Pin中如何做异常处理
	if((INT)size > 0xFFFF)
		TraceFile << "------" << name << "(" << size << ")" << endl;
}


VOID ArgBeforeW(CHAR * name, CHAR * size)
{
	//TraceFile << "in" << endl;
    TraceFile << name << "(" ;
	//*
	while(1)
	{
		if(size[0] == 0x00 && size[1] == 0x00)
		{
			break;
		}
		TraceFile << size;
		size++;
		size++;
	}
	//*/
	TraceFile << ")" << endl;
	return;	
	//<< size <<
}


/* ===================================================================== */
/* Instrumentation routines                                              */
/* ===================================================================== */
   
VOID Image(IMG img, VOID *v)
{
    // Instrument the malloc() and free() functions.  Print the input argument
    // of each malloc() or free(), and the return value of malloc().
    //
    //  Find the malloc() function.
	//*/
    RTN LoadLibraryExWRtn = RTN_FindByName(img, LOADLIBRARYEXW);
    if (RTN_Valid(LoadLibraryExWRtn))
    {
        RTN_Open(LoadLibraryExWRtn);

        // Instrument malloc() to print the input argument value and the return value.
        RTN_InsertCall(LoadLibraryExWRtn, IPOINT_BEFORE, (AFUNPTR)ArgBeforeW,
                       IARG_ADDRINT, LOADLIBRARYEXW,
                       IARG_FUNCARG_ENTRYPOINT_VALUE, 0,
                       IARG_END);

        RTN_Close(LoadLibraryExWRtn);
    }

	RTN LoadLibraryExARtn = RTN_FindByName(img, LOADLIBRARYEXA);
    if (RTN_Valid(LoadLibraryExARtn))
    {
        RTN_Open(LoadLibraryExARtn);

        // Instrument malloc() to print the input argument value and the return value.
        RTN_InsertCall(LoadLibraryExARtn, IPOINT_BEFORE, (AFUNPTR)ArgBeforeA,
                       IARG_ADDRINT, LOADLIBRARYEXA,
                       IARG_FUNCARG_ENTRYPOINT_VALUE, 0,
                       IARG_END);

        RTN_Close(LoadLibraryExARtn);
    }
	
	RTN LoadLibraryWRtn = RTN_FindByName(img, LOADLIBRARYW);
    if (RTN_Valid(LoadLibraryWRtn))
    {
        RTN_Open(LoadLibraryWRtn);

        // Instrument malloc() to print the input argument value and the return value.
        RTN_InsertCall(LoadLibraryWRtn, IPOINT_BEFORE, (AFUNPTR)ArgBeforeW,
                       IARG_ADDRINT, LOADLIBRARYW,
                       IARG_FUNCARG_ENTRYPOINT_VALUE, 0,
                       IARG_END);

        RTN_Close(LoadLibraryWRtn);
    }
	//*/

	RTN LoadLibraryARtn = RTN_FindByName(img, LOADLIBRARYA);
    if (RTN_Valid(LoadLibraryARtn))
    {
        RTN_Open(LoadLibraryARtn);

        // Instrument malloc() to print the input argument value and the return value.
        RTN_InsertCall(LoadLibraryARtn, IPOINT_BEFORE, (AFUNPTR)ArgBeforeA,
                       IARG_ADDRINT, LOADLIBRARYA,
                       IARG_FUNCARG_ENTRYPOINT_VALUE , 0,
                       IARG_END);

        RTN_Close(LoadLibraryARtn);
    }
	
	//*
	RTN GetProcAddressRtn = RTN_FindByName(img, GETPROCADDRESS);
    if (RTN_Valid(GetProcAddressRtn))
    {
        RTN_Open(GetProcAddressRtn);

        // Instrument malloc() to print the input argument value and the return value.
        RTN_InsertCall(GetProcAddressRtn, IPOINT_BEFORE, (AFUNPTR)ArgBeforeA1,
                       IARG_ADDRINT, GETPROCADDRESS,
                       IARG_FUNCARG_ENTRYPOINT_VALUE , 1,
                       IARG_END);

        RTN_Close(GetProcAddressRtn);
    }
	//*/
}

/* ===================================================================== */

VOID Fini(INT32 code, VOID *v)
{
    TraceFile.close();
}

/* ===================================================================== */
/* Print Help Message                                                    */
/* ===================================================================== */
   
INT32 Usage()
{
    cerr << "This tool produces a trace of calls to malloc." << 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 */
/* ===================================================================== */
结果样例:

#include "pin.H"
#include <iostream>
#include <fstream>

#include <stdio.h>
#include <unistd.h>

#define LOADLIBRARYEXW "LoadLibraryExW"
#define LOADLIBRARYEXA "LoadLibraryExA"
#define LOADLIBRARYW "LoadLibraryW"
#define LOADLIBRARYA "LoadLibraryA"
#define GETPROCADDRESS "GetProcAddress"


/* ===================================================================== */
/* Global Variables */
/* ===================================================================== */

std::ofstream TraceFile;

/* ===================================================================== */
/* Commandline Switches */
/* ===================================================================== */

KNOB<string> KnobOutputFile(KNOB_MODE_WRITEONCE, "pintool",
    "o", "LoadlibraryArguments.out", "specify trace file name");

/* ===================================================================== */


/* ===================================================================== */
/* Analysis routines                                                     */
/* ===================================================================== */
 
VOID ArgBeforeA(CHAR * name, CHAR * size)
{
	//TraceFile << "in" << endl;
    TraceFile << name << "(" << size << ")" << endl;
}

VOID ArgBeforeA1(CHAR * name, CHAR * size)
{
	//TraceFile << "in" << endl;
	//这里判断是为了排除第一个参数为非法参数的情况,不判断的话,在读出现异常时会进程提出,暂时不知道Pin中如何做异常处理
	if((INT)size > 0xFFFF)
		TraceFile << "------" << name << "(" << size << ")" << endl;
}


VOID ArgBeforeW(CHAR * name, CHAR * size)
{
	//TraceFile << "in" << endl;
    TraceFile << name << "(" ;
	//*
	while(1)
	{
		if(size[0] == 0x00 && size[1] == 0x00)
		{
			break;
		}
		TraceFile << size;
		size++;
		size++;
	}
	//*/
	TraceFile << ")" << endl;
	return;	
	//<< size <<
}


/* ===================================================================== */
/* Instrumentation routines                                              */
/* ===================================================================== */
   
VOID Image(IMG img, VOID *v)
{
    // Instrument the malloc() and free() functions.  Print the input argument
    // of each malloc() or free(), and the return value of malloc().
    //
    //  Find the malloc() function.
	//*/
    RTN LoadLibraryExWRtn = RTN_FindByName(img, LOADLIBRARYEXW);
    if (RTN_Valid(LoadLibraryExWRtn))
    {
        RTN_Open(LoadLibraryExWRtn);

        // Instrument malloc() to print the input argument value and the return value.
        RTN_InsertCall(LoadLibraryExWRtn, IPOINT_BEFORE, (AFUNPTR)ArgBeforeW,
                       IARG_ADDRINT, LOADLIBRARYEXW,
                       IARG_FUNCARG_ENTRYPOINT_VALUE, 0,
                       IARG_END);

        RTN_Close(LoadLibraryExWRtn);
    }

	RTN LoadLibraryExARtn = RTN_FindByName(img, LOADLIBRARYEXA);
    if (RTN_Valid(LoadLibraryExARtn))
    {
        RTN_Open(LoadLibraryExARtn);

        // Instrument malloc() to print the input argument value and the return value.
        RTN_InsertCall(LoadLibraryExARtn, IPOINT_BEFORE, (AFUNPTR)ArgBeforeA,
                       IARG_ADDRINT, LOADLIBRARYEXA,
                       IARG_FUNCARG_ENTRYPOINT_VALUE, 0,
                       IARG_END);

        RTN_Close(LoadLibraryExARtn);
    }
	
	RTN LoadLibraryWRtn = RTN_FindByName(img, LOADLIBRARYW);
    if (RTN_Valid(LoadLibraryWRtn))
    {
        RTN_Open(LoadLibraryWRtn);

        // Instrument malloc() to print the input argument value and the return value.
        RTN_InsertCall(LoadLibraryWRtn, IPOINT_BEFORE, (AFUNPTR)ArgBeforeW,
                       IARG_ADDRINT, LOADLIBRARYW,
                       IARG_FUNCARG_ENTRYPOINT_VALUE, 0,
                       IARG_END);

        RTN_Close(LoadLibraryWRtn);
    }
	//*/

	RTN LoadLibraryARtn = RTN_FindByName(img, LOADLIBRARYA);
    if (RTN_Valid(LoadLibraryARtn))
    {
        RTN_Open(LoadLibraryARtn);

        // Instrument malloc() to print the input argument value and the return value.
        RTN_InsertCall(LoadLibraryARtn, IPOINT_BEFORE, (AFUNPTR)ArgBeforeA,
                       IARG_ADDRINT, LOADLIBRARYA,
                       IARG_FUNCARG_ENTRYPOINT_VALUE , 0,
                       IARG_END);

        RTN_Close(LoadLibraryARtn);
    }
	
	//*
	RTN GetProcAddressRtn = RTN_FindByName(img, GETPROCADDRESS);
    if (RTN_Valid(GetProcAddressRtn))
    {
        RTN_Open(GetProcAddressRtn);

        // Instrument malloc() to print the input argument value and the return value.
        RTN_InsertCall(GetProcAddressRtn, IPOINT_BEFORE, (AFUNPTR)ArgBeforeA1,
                       IARG_ADDRINT, GETPROCADDRESS,
                       IARG_FUNCARG_ENTRYPOINT_VALUE , 1,
                       IARG_END);

        RTN_Close(GetProcAddressRtn);
    }
	//*/
}

/* ===================================================================== */

VOID Fini(INT32 code, VOID *v)
{
    TraceFile.close();
}

/* ===================================================================== */
/* Print Help Message                                                    */
/* ===================================================================== */
   
INT32 Usage()
{
    cerr << "This tool produces a trace of calls to malloc." << 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 */
/* ===================================================================== */

[培训]科锐逆向工程师培训第53期2025年7月8日开班!

最后于 2019-1-23 09:28 被不懂就乐编辑 ,原因: 完善内容
收藏
免费 2
支持
分享
最新回复 (5)
雪    币: 21
活跃值: (27)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
挺不错的。学习下
2019-1-23 10:09
0
雪    币: 42947
活跃值: (65767)
能力值: (RANK:135 )
在线值:
发帖
回帖
粉丝
3
感谢分享!
2019-1-23 10:50
0
雪    币: 403
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
谢谢分享啦
2019-1-23 17:38
0
雪    币: 3500
活跃值: (820)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
5
新手请教 如何将pin.h的编译环境整合到vs中
2019-2-23 10:57
0
雪    币: 703
活跃值: (858)
能力值: ( LV4,RANK:45 )
在线值:
发帖
回帖
粉丝
6
噗咚Four 新手请教 如何将pin.h的编译环境整合到vs中
我没重新编译过Pin.exe,只是编译过Pintools。如果是Pintools的话,我都是使用VS的命令行编译工具编译的,因为官方文档这样介绍的,流程:
使用Visual Studio操作系统命令行,如:
    Visual Studio 命令提示(2010)
    或,VS2015 x64 Native Tools Command Prompt
定位到“%Pin安装目录%\source\tools\ManualExamples”
运行make,就可以将该目录下的所有cpp文件进行编译了
结果在%\source\tools\ManualExamples\obj-intel64下。
2019-2-25 09:17
0
游客
登录 | 注册 方可回帖
返回