【问题标题】:How can I use Intel PIN to catch all loads to an array?如何使用英特尔 PIN 捕获阵列的所有负载?
【发布时间】:2020-10-19 03:15:57
【问题描述】:

我正在分析我使用 PIN 编写的应用程序。应用程序的源代码使用了一个数组 - 我希望 PIN 能够捕获对数组进行的每条加载指令。

目前,我已经注释了我要分析的应用程序的源代码。每次从数组中读取时,我首先调用一个函数 startRegionOfInterest()。一旦我从数组中读取完毕,我就会调用另一个函数 endRegionOfInterest()。我可以使用 PIN 轻松捕获对这两个函数的调用 - 每当这两个调用之间存在负载时,我认为这是对我感兴趣的数组的负载。

但是,这是相当粗粒度的,因此我最终将大量不属于感兴趣数组的负载分类为对数组的读取。

有没有一种更简单的方法可以更准确地捕获对我感兴趣的阵列产生的所有负载?

【问题讨论】:

  • 我假设你知道数组的地址和长度? PIN我不是很了解,但想必它能解码一条指令,从它的寻址方式中找出有效地址。
  • @PeterCordes 我有数组的长度,但我将如何使用 PIN 检索地址?
  • 如果它是静态分配的,应该有一个与之关联的符号。如果没有,您需要找到以某种方式加载地址的负载。如果您知道编译器使用了特定的寻址模式,则可以使用它。碰巧与某个构建匹配的易碎的东西可能适合一次性使用。也许像特定 NOP 编码这样的标记可以帮助您通过 PIN 找到它。
  • 听起来您需要在问题中提供更多详细信息,了解您的程序如何访问此数组,以及它是什么类型的数组。

标签: c++ assembly profiling intel-pin


【解决方案1】:

在您的startRegionOfInterest 方法中,您可以使用某种指标序列将数组地址传递给您的PIN 工具。例如,存储一个魔术常数,然后存储数组地址,例如:

volatile void *sink;

void startRegionOfInterest(void *array) {
    sink = (void *)0x48829d2f384be;
    sink = array;
}

在您的 PIN 工具中,您查找魔术常量的存储(如果需要,可以在 startRegionOfInterest 调用中获得额外的特异性),然后您知道下一个存储是数组的地址。您可以类似地传达长度。

使用内联 asm 实现序列,您可以消除与编译器和优化器行为相关的可变性,尽管我认为 volatile 方法在实践中应该有效(尽管您可能必须跳过一些干预的非存储指令。A @ 987654321@.

【讨论】:

  • 谢谢,这应该可行,但我最终做的是在我正在分析的程序中编写一个函数,该函数将数组开始和结束地址作为参数。然后我通过检测所有函数调用在 Pin 中找到了这个函数,并读取了参数以找到我的数组的开始和结束地址。
猜你喜欢
  • 1970-01-01
  • 2018-07-28
  • 2014-06-21
  • 2017-01-30
  • 2020-10-23
  • 1970-01-01
  • 2019-06-28
  • 2019-03-03
  • 2018-04-20
相关资源
最近更新 更多