admin 管理员组

文章数量: 887006

文章目录

    • 安装包下载链接:
    • 环境配置
    • 编译Pintool
      • 报错1(无法打开包括文件:"xed-iclass-enum.h":No such file or directory):
      • 报错2(若编译时产生“XX模块对SAFESEH映像是不安全的”报错):
      • 报错3(若报错“无法解析的外部符号__fltused”):
      • 报错4(NO STACK TRACE ACAILABLE):
    • Pintool使用
    • Pintool基本框架

安装包下载链接:

https://software.intel/en-us/articles/pintool-downloads

环境配置

  1. 先将下载完的压缩包解压到某个目录,会看到目录下有pin.exe文件,这是32位的。由于pin与架构有关,有32位和64位的版本,为了方便使用,pin分为pin32和pin64。将当前目录的pin.exe重命名为pin.bak并新建pin32.bat,并填入如下代码:
@echo off
%~dp0\ia32\bin\pin.exe %*
  1. 随后创建pin64.bat,代码类似,只需要把“ia32”改成"intel64"。然后把当前目录加入环境变量PATH中。若配置正常,输出如下:

编译Pintool

在source\tools\MyPintool目录下有Intel提供的样例代码,需要用VS。打开MyPinTool.vcxproj,进行生成解决方案:

报错1(无法打开包括文件:“xed-iclass-enum.h”:No such file or directory):

  1. 打开MyPintool属性,在"c/c++ —>常规—>附加包含目录"中加入"..\..\..\extras\xed-ia32\include\xed"(若是64位,则加入"..\..\..\extras\xed-intel64\include\xed"

报错2(若编译时产生“XX模块对SAFESEH映像是不安全的”报错):

  1. 打开MyPintool属性,在“链接器—>高级—>映像具有安全异常处理程序”中把选项设置为“否”

报错3(若报错“无法解析的外部符号__fltused”):

  1. 打开MyPintool属性,在“链接器—>输入—>附加依赖项"中添加"crtbeginS.obj"

报错4(NO STACK TRACE ACAILABLE):

  1. 因为32位的Pintool不支持Windows 10,需要编译完后放置Windows 7或Windows 8虚拟机中运行

Pintool使用

 pin32 -t .\MyPinTool.dll -o log.log -- cmd /c echo 123


log.log其中记录了程序执行的基本块数目和指令数目。

pin32 -pid 17592 -t -h  .\MyPinTool.dll -o log.log

附加到现有的程序

Pintool基本框架

	int main(int argc,char *argv[])
	{
		//初始化PIN运行库
		//若是有参数-h,则输出帮助信息,即调用Usage函数
		if(PIN_Init(argc,argv))
		{
		return Usage();
		}

	string filename=KnobOutputFile.Value();
	if(!filename.empty())
	{
		out=new std::ofstream(fileName.c_str());
		}
			
	if(KnobCount)
	{
	TRACE_AddInstrumentFunction(Trace,0);//	注册在执行指令trace时会执行的函数
	PIN_AddThreadStartFunction(ThreadStart,0);//注册每个线程启动时会执行的函数
	PIN_AddFiniFunction(Fini,0);//注册程序结束时会执行的函数
	}
	PIN_StartProgram();	//启动程序,该函数不会返回
	return 0;
		}

Pintool会先执行Pin_Init对Pin运行库进行初始化,若是参数有-h或者初始化失败报错,则会输出工具的帮助信息,即调用Usage.

随后Pintool根据命令行输入的参数初始化filaName变量,KnobOutputFile和KnobCount的定义如下:

KNOB<string> KnobOutputFile(KNOB_MODE_WRITEONCE,"pintool","o","","specity file name for  MyPinTool output");

KNOB<BOOL> KnobCount(KNOB_MODE_WRITEONCE,"pintool","count","1","count instructions,basic blocks and threads in the application");;

参数为o时,会设置KnobOutputFile的值,默认为空,参数为count时,会设置KnobCount的值,默认值为1。在KnobCount被设置的情况下,会注册为3个插桩函数,随后调用PIN_StartProgram运行被插桩的程序(PIN_StartProgram不会返回)

插桩粒度API执行时机
指令级插桩(instruction)INS_AddInstrumentFunction执行一条新指令
轨迹级插桩(trace)TRACE_AddInstrumentFunction执行一个新trace
镜像级插桩(image)IMG_AddInstrumentFunction加载新镜像时
函数级插桩(routine)RTN_AddInstrumentFunction执行一个函数时
  1. 对于指令级插桩,Pin会在执行一条新指令时进行插桩,换句话说,对于动态生成的代码,Pin也能对其进行自动化的插桩,因此可以用Pin处理加壳的程序
  2. 轨迹级插桩可以认为是基本块(base block)级的插桩,但是Pin定义的基本块比一般情况定义的基本块要多。轨迹级插桩会在顶部的基本块被调用,若是执行程序中生成了新的基本块(如分支),则会生成新的轨迹,与上述指令级插桩有相同的特性,可以方便地处理动态生成的代码。
  3. 镜像级插桩和函数级插桩依赖符号信息,需要在调用PIN_Init前调用Pin_InitSymbols对程序进行符号分析

本文标签: 环境 引擎 Windows 态插桩 pin