我是如何安装 Intel-Pin 的【Windows - Visual Studio 2022 】

0. 资料

Intel-Pin的官方下载地址:https://www.intel.cn/content/www/cn/zh/developer/articles/tool/pin-a-binary-instrumentation-tool-downloads.html
概述文档:https://www.intel.cn/content/www/cn/zh/developer/articles/tool/pin-a-dynamic-binary-instrumentation-tool.html
用户手册:https://software.intel.com/sites/landingpage/pintool/docs/98749/Pin/doc/html/index.html (版本号可能会更新,请注意)

问题讨论:https://groups.io/g/pinheads

1. 下载

Intel PIN是一款由Intel公司开发的动态二进制分析框架,主要用于构建程序分析工具。目前该框架并未开源,所以没有相关的源代码,但intel提供了编译发行版本,我们用这个编译版本即可。

前往 https://www.intel.cn/content/www/cn/zh/developer/articles/tool/pin-a-binary-instrumentation-tool-downloads.html 下载
在这里插入图片描述
因为我们是在Windows平台上使用pin,并且打算用visual studio来编写代码,所以我们拉到中间,找到 Windows* (MSVC)
在这里插入图片描述
直接下载最新版本即可,点击"Kit"并等待下载完成。

下载完成后我们打开压缩包:
在这里插入图片描述
直接解压出来
在这里插入图片描述
可以注意到,解压后的根目录有一个 pin.exe 程序,这个程序就是我们用pin的关键了,这时候你可以在环境变量中添加路径,方便在cmd中使用pin。

2. 编译一个 pintool

pintool也是我们用pin的一个关键,我们所有的探针代码都在这里编写,intel官方已经给我们提供了模板,就在source\tools\MyPinTool这个目录。以后我们要写代码,就直接从这个模板开始写了

在这里插入图片描述

/*      MyPinTool.cpp      */
/*
 * Copyright (C) 2007-2023 Intel Corporation.
 * SPDX-License-Identifier: MIT
 */

/*! @file
 *  This is an example of the PIN tool that demonstrates some basic PIN APIs 
 *  and could serve as the starting point for developing your first PIN tool
 */

#include "pin.H"
#include <iostream>
#include <fstream>
using std::cerr;
using std::endl;
using std::string;

/* ================================================================== */
// Global variables
/* ================================================================== */

UINT64 insCount    = 0; //number of dynamically executed instructions
UINT64 bblCount    = 0; //number of dynamically executed basic blocks
UINT64 threadCount = 0; //total number of threads, including main thread

std::ostream* out = &cerr;

/* ===================================================================== */
// Command line switches
/* ===================================================================== */
KNOB< string > KnobOutputFile(KNOB_MODE_WRITEONCE, "pintool", "o", "", "specify file name for MyPinTool output");

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

/* ===================================================================== */
// Utilities
/* ===================================================================== */

/*!
 *  Print out help message.
 */
INT32 Usage()
{
    cerr << "This tool prints out the number of dynamically executed " << endl
         << "instructions, basic blocks and threads in the application." << endl
         << endl;

    cerr << KNOB_BASE::StringKnobSummary() << endl;

    return -1;
}

/* ===================================================================== */
// Analysis routines
/* ===================================================================== */

/*!
 * Increase counter of the executed basic blocks and instructions.
 * This function is called for every basic block when it is about to be executed.
 * @param[in]   numInstInBbl    number of instructions in the basic block
 * @note use atomic operations for multi-threaded applications
 */
VOID CountBbl(UINT32 numInstInBbl)
{
    bblCount++;
    insCount += numInstInBbl;
}

/* ===================================================================== */
// Instrumentation callbacks
/* ===================================================================== */

/*!
 * Insert call to the CountBbl() analysis routine before every basic block 
 * of the trace.
 * This function is called every time a new trace is encountered.
 * @param[in]   trace    trace to be instrumented
 * @param[in]   v        value specified by the tool in the TRACE_AddInstrumentFunction
 *                       function call
 */
VOID Trace(TRACE trace, VOID* v)
{
    // Visit every basic block in the trace
    for (BBL bbl = TRACE_BblHead(trace); BBL_Valid(bbl); bbl = BBL_Next(bbl))
    {
        // Insert a call to CountBbl() before every basic bloc, passing the number of instructions
        BBL_InsertCall(bbl, IPOINT_BEFORE, (AFUNPTR)CountBbl, IARG_UINT32, BBL_NumIns(bbl), IARG_END);
    }
}

/*!
 * Increase counter of threads in the application.
 * This function is called for every thread created by the application when it is
 * about to start running (including the root thread).
 * @param[in]   threadIndex     ID assigned by PIN to the new thread
 * @param[in]   ctxt            initial register state for the new thread
 * @param[in]   flags           thread creation flags (OS specific)
 * @param[in]   v               value specified by the tool in the 
 *                              PIN_AddThreadStartFunction function call
 */
VOID ThreadStart(THREADID threadIndex, CONTEXT* ctxt, INT32 flags, VOID* v) { threadCount++; }

/*!
 * Print out analysis results.
 * This function is called when the application exits.
 * @param[in]   code            exit code of the application
 * @param[in]   v               value specified by the tool in the 
 *                              PIN_AddFiniFunction function call
 */
VOID Fini(INT32 code, VOID* v)
{
    *out << "===============================================" << endl;
    *out << "MyPinTool analysis results: " << endl;
    *out << "Number of instructions: " << insCount << endl;
    *out << "Number of basic blocks: " << bblCount << endl;
    *out << "Number of threads: " << threadCount << endl;
    *out << "===============================================" << endl;
}

/*!
 * The main procedure of the tool.
 * This function is called when the application image is loaded but not yet started.
 * @param[in]   argc            total number of elements in the argv array
 * @param[in]   argv            array of command line arguments, 
 *                              including pin -t <toolname> -- ...
 */
int main(int argc, char* argv[])
{
    // Initialize PIN library. Print help message if -h(elp) is specified
    // in the command line or the command line is invalid
    if (PIN_Init(argc, argv))
    {
        return Usage();
    }

    string fileName = KnobOutputFile.Value();

    if (!fileName.empty())
    {
        out = new std::ofstream(fileName.c_str());
    }

    if (KnobCount)
    {
        // Register function to be called to instrument traces
        TRACE_AddInstrumentFunction(Trace, 0);

        // Register function to be called for every thread before it starts running
        PIN_AddThreadStartFunction(ThreadStart, 0);

        // Register function to be called when the application exits
        PIN_AddFiniFunction(Fini, 0);
    }

    cerr << "===============================================" << endl;
    cerr << "This application is instrumented by MyPinTool" << endl;
    if (!KnobOutputFile.Value().empty())
    {
        cerr << "See file " << KnobOutputFile.Value() << " for analysis results" << endl;
    }
    cerr << "===============================================" << endl;

    // Start the program, never returns
    PIN_StartProgram();

    return 0;
}

/* ===================================================================== */
/* eof */
/* ===================================================================== */

这里有一个vcxproj项目文件,我们直接在vs的解决方案中添加项目即可

在这里插入图片描述
随后就能编译了
在这里插入图片描述
在这里插入图片描述

3. 测试

现在我们拿32位程序作测试,我们随便创建个目录,把要测试的程序和你的pintool的dll文件都放进去(这里就假定你把pin.exe的路径弄到环境变量里边来了)
在这里插入图片描述
然后我们在此处打开cmd,输入以下命令

pin -t MyPinTool.dll -- test.exe

在这里插入图片描述
好的,现在看来我们安装Intel-Pin的过程都完美成功了

4. 其他说明

C:\Users\90965\Desktop\pin_study>pin -h
Pin: pin-3.31-98869-fa6f126a8  
版权所有 © 2002-2024 英特尔公司。

用法:pin [选项] [-t <工具> [<工具参数>]] -- <命令行>  
使用 -help 查看选项的详细说明。

通用开关:

-assert_check_inline  [默认 0]  
  当被标记为 IARG_CHECK_INLINE 的分析函数无法内联时触发断言。

-debug_instrumented_processes  [默认 0]  
  打印消息,以便调试器可以附加到已插桩的进程。

-detach_reattach  [默认 0]  
  在探测模式中允许分离和重新附加。

-error_file  [默认 空]  
  错误日志文件名。

-follow_execv  [默认 0]  
  对通过 execv 类系统调用生成的所有进程都使用 Pin 执行。

-inline  [默认 1]  
  内联简单的分析函数。

-log_inline  [默认 0]  
  打印分析函数是否已被内联。

-logfile  [默认 pin.log]  
  日志文件路径和名称。

-move_then_to_stub  [默认 1]  
  将 IF-THEN 插桩结构中的 THEN 部分移动到 stub 区域。

-mt  [默认 1]  
  允许多线程程序。

-p32  [默认 空]  
  指定适用于 IA-32 架构的 Pin 可执行文件。

-p64  [默认 空]  
  指定适用于 Intel® 64 架构的 Pin 可执行文件。

-pause_tool  [默认 0]  
  在加载工具之前暂停 Pin 指定的秒数,以便调试器可以附加到 Pin 所插桩的进程。Pin 会在标准输出和日志中打印详细的调试器连接说明,包括添加调试信息的命令。此选项主要供 Pin 开发者调试使用。  
  特殊值:1 - 打印信息但不暂停。

-pid  [默认 0]  
  附加到指定 PID 的进程。

-probe  [默认 0]  
  表示工具使用 Pin Probes。

-smc_strict  [默认 0]  
  检测基本块内的自修改代码。

-smc_support  [默认 1]  
  支持自修改代码(SMC)。

-t64  [默认 空]  
  指定适用于 Intel® 64 架构的工具二进制文件。

-tool_load_option  
  加载工具时的附加选项。

-unique_error_file  [默认 0]  
  错误日志文件名中将包含进程ID。

-unique_logfile  [默认 0]  
  日志文件名中将包含进程ID。

-version  [默认 0]  
  打印版本信息。

通用开关(在 pin 和工具中都可用):

-h  [默认 0]  
  打印帮助信息(等同于 -help)。

-help  [默认 0]  
  打印帮助信息。

-ifeellucky  [默认 0]  
  跳过不支持平台的警告信息,并将某些错误转化为警告。

-slow_asserts  [默认 0]  
  执行耗时的健全性检查。

调试应用程序的开关:

-appdebug  [默认 0]  
  调试应用程序,在程序启动时立刻在调试器中暂停。

-appdebug_allow_remote  [默认 0]  
  在启用应用程序调试时,默认要求调试器与 Pin 在同一系统上运行。此选项允许连接运行在远程系统上的调试器。  
  注意:如果指定了 -appdebug_connection,则忽略此选项,因为后者已明确指定调试器运行的机器。

-appdebug_connection  [默认 空]  
  在启用应用程序调试时,Pin 默认打开一个 TCP 端口并等待调试器连接。此选项可反转角色:调试器打开一个 TCP 端口并等待 Pin 连接,地址格式为 “[ip]:端口”。  
  如果指定了 ip,则应使用点分十进制表示;若省略 ip,则表示连接到本机的指定端口。端口号为十进制。  
  注意:使用 GDB 调试时不会使用该选项。

-appdebug_enable  [默认 0]  
  启用应用程序级调试器支持,但不在应用启动时暂停。可在启动后连接调试器。

-appdebug_exclude  
  在启用应用程序调试并启用 -follow_execv 时,默认对所有子进程启用调试。此可重复使用的选项指定禁用调试的应用程序名称,如果 argv[0] 匹配某个名称,则该子进程不启用调试。

-appdebug_server_port  [默认 0]  
  在启用应用程序调试时,Pin 默认绑定到系统分配的随机 TCP 端口并等待调试器连接。此选项可指定特定端口供调试器连接。

-appdebug_silent  [默认 0]  
  在启用调试时,Pin 通常会打印一条提示如何连接调试器的信息。此选项关闭该提示信息。如果指定了 -appdebug_connection,则不会打印该信息。

代码缓存相关开关:

-cache_block_size  [默认 262144]  
  代码缓存分配单元的大小(以字节为单位)。为获得最佳效果,请设为页面大小的整数倍。

-cc_memory_size  [默认 0]  
  最大代码缓存大小(单位字节,0表示默认)。必须是缓存块大小的整数倍。

-cc_memory_size_64  [默认 0]  
  64位系统上的最大代码缓存大小(单位字节,0表示默认)。必须是缓存块大小的整数倍。

限制内存使用的参数:

-pin_memory_range  
  为 Pin 和工具的动态内存分配指定虚拟内存地址范围。例如:  
  0x80000000:0x90000000。此选项可以重复使用以指定多个范围。

-pin_memory_size  [默认 0]  
  Pin 和工具可动态分配的最大字节数(0 = 不限制,建议至少分配30MB)。

Windows 11系统中使用GPIO(通用输入/输出)接口进行开发,通常需要依赖特定的硬件平台支持以及操作系统提供的相关驱动和API。Windows 11通过**Windows IoT Core**或**Windows 10/11 Desktop with GPIO驱动支持**的方式为开发者提供GPIO编程能力。 ### Windows 11 中 GPIO 编程的技术实现 Windows 11 桌面版本本身并不直接支持GPIO操作,因为大多数标准PC主板并不具备原生的GPIO引脚接口。然而,在某些嵌入式设备、单板计算机(如基于Intel Apollo Lake架构的设备、Qualcomm DragonBoard 410c 或其它兼容设备)上,如果硬件制造商提供了相应的GPIO驱动程序,则可以在Windows 10或Windows 11环境中进行GPIO编程。 Windows 提供了 **Windows.Devices.Gpio** 命名空间,属于 **Universal Windows Platform (UWP)** 的一部分,允许开发者通过高级语言(如C#、C++、Python)访问GPIO控制器[^1]。 --- ### 开发环境准备 #### 1. 硬件要求 - 支持GPIO功能的嵌入式设备(例如:DragonBoard 410c、UP Squared等) - 设备需运行 Windows 10 IoT Core 或 Windows 11 Desktop 并安装合适的GPIO驱动程序 #### 2. 软件要求 - Visual Studio(用于UWP应用开发) - Windows SDK - Python(可选,需配合PyWinRT或其他绑定库) --- ### 使用 C# 进行 GPIO 编程示例 以下是一个使用 C# 和 UWP API 控制 GPIO 引脚的简单示例: ```csharp using Windows.Devices.Gpio; using System.Threading.Tasks; public sealed partial class MainPage { private GpioPin pin; private GpioPinValue value = GpioPinValue.High; public MainPage() { this.InitializeComponent(); InitGPIO(); } private void InitGPIO() { var gpio = GpioController.GetDefault(); if (gpio == null) { // 无法初始化GPIO控制器 return; } pin = gpio.OpenPin(5); // 打开GPIO编号为5的引脚 pin.SetDriveMode(GpioPinDriveMode.Output); value = GpioPinValue.Low; pin.Write(value); } private async void BlinkLED() { while (true) { value = (value == GpioPinValue.Low) ? GpioPinValue.High : GpioPinValue.Low; pin.Write(value); await Task.Delay(1000); } } } ``` --- ### 使用 Python 进行 GPIO 编程 虽然 Windows 上没有像 RPi.GPIO 这样的原生库支持所有设备,但如果你使用的是支持 PyWinRT 的设备,可以尝试使用 `winrt` 模块来调用 Windows.Devices.Gpio 接口: ```python import asyncio from winrt.windows.devices.gpio import GpioController, GpioPinValue, GpioPinDriveMode async def blink_led(): gpio = GpioController.get_default() if gpio is None: print("No GPIO controller found.") return pin = gpio.open_pin(5) pin.set_drive_mode(GpioPinDriveMode.OUTPUT) value = GpioPinValue.LOW while True: value = GpioPinValue.HIGH if value == GpioPinValue.LOW else GpioPinValue.LOW pin.write(value) await asyncio.sleep(1) asyncio.run(blink_led()) ``` > 注意:此代码需要支持 WinRT 的 Python 绑定环境,并且目标设备必须具备可用的GPIO驱动。 --- ### 开发建议与注意事项 - 在开发前确认设备是否支持GPIO接口并已安装正确的驱动。 - 对于非IoT设备,建议使用虚拟机或远程调试方式连接到支持GPIO的设备进行开发。 - Windows IoT Core 是专为嵌入式设备设计的操作系统,适合用于长期运行的物联网项目。 - 可参考微软官方文档 [Windows.Devices.Gpio Namespace](https://learn.microsoft.com/en-us/uwp/api/windows.devices.gpio) 获取详细的API说明和示例。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值