我如何使用英特尔 PIN 捕获阵列的所有负载?

How can I use Intel PIN to catch all loads to an array?

我正在分析我使用 PIN 编写的应用程序。应用程序的源代码使用了一个数组——我希望 PIN 捕捉对数组所做的每条加载指令。

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

但是,这是非常粗粒度的,所以我最终将许多不属于感兴趣数组的负载分类为读取数组。

有没有更简单的方法让我更准确地捕获对我感兴趣的阵列所做的所有加载?

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

volatile void *sink;

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

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

使用内联 asm 实现序列,您可以消除与编译器和优化器行为相关的可变性,尽管我认为 volatile 方法应该在实践中起作用(尽管您可能不得不跳过一些中间的非存储说明。A godbolt.