Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/124.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/64.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 英特尔PIN例程地址检索:Linux与Windows_C++_C_Intel Pin - Fatal编程技术网

C++ 英特尔PIN例程地址检索:Linux与Windows

C++ 英特尔PIN例程地址检索:Linux与Windows,c++,c,intel-pin,C++,C,Intel Pin,我是个新手,所以也许有一个简单的解释。我对Windows上的常规地址PIN返回感到困惑。我创建了一个最小的测试程序来说明我的观点 我目前正在使用引脚2.14。我检查的应用程序是调试版本,在Windows上禁用了ASLR 首先考虑调用空方法的简单应用程序,并打印方法的地址: #include "stdio.h" class Test { public: void method() {} }; void main() { Test t; t.method(); printf("Tes

我是个新手,所以也许有一个简单的解释。我对Windows上的常规地址PIN返回感到困惑。我创建了一个最小的测试程序来说明我的观点

我目前正在使用引脚2.14。我检查的应用程序是调试版本,在Windows上禁用了ASLR

首先考虑调用空方法的简单应用程序,并打印方法的地址:

#include "stdio.h"
class Test {
public:
  void method() {}
};
void main() {
  Test t;
  t.method();
  printf("Test::method = 0x%p\n", &Test::method);
}
以下pin工具将反汇编程序的主例程并打印Test::method的地址:

#include <pin.H>
#include "stdio.h"
VOID disassemble(IMG img, VOID *v)
{
  for (SEC sec = IMG_SecHead(img); SEC_Valid(sec); sec = SEC_Next(sec))
  {
    for (RTN rtn = SEC_RtnHead(sec); RTN_Valid(rtn); rtn = RTN_Next(rtn))
    {
      auto name = RTN_Name(rtn);
      if(name == "Test::method" || name == "_ZN4Test6methodEv") {
        printf("%s detected by PIN resides at 0x%p.\n", name.c_str(), RTN_Address(rtn));
      }
      if (RTN_Name(rtn) != "main") continue;
      RTN_Open(rtn);
      for (INS ins = RTN_InsHead(rtn); INS_Valid(ins); ins = INS_Next(ins))     {
        printf("%s\n", INS_Disassemble(ins).c_str());
      }
      RTN_Close(rtn);
    }
  }
}
int main(int argc, char **argv)
{
  PIN_InitSymbols();
  PIN_Init(argc, argv);
  IMG_AddInstrumentFunction(disassemble, 0);
  PIN_StartProgram();
  return 0;
}
请注意,以t.method()为目标的调用以及PIN检索到的函数地址和应用程序的输出都显示Test::method驻留在地址0x400820处

我的Windows 10 x64计算机上的输出为:

push rdi
sub rsp, 0x40
mov rdi, rsp
mov ecx, 0x10
mov eax, 0xcccccccc
rep stosd dword ptr [rdi]
lea rcx, ptr [rsp+0x24]
call 0x14000104b
lea rdx, ptr [rip-0x2b]
lea rcx, ptr [rip+0x74ca3]
call 0x1400013f0
xor eax, eax
mov edi, eax
mov rcx, rsp
lea rdx, ptr [rip+0x74cf0]
call 0x1400015f0
mov eax, edi
add rsp, 0x40
pop rdi
ret
Test::method detected by PIN resides at 0x0000000140001120.
Test::method = 0x000000014000104B
应用程序的输出和反汇编中的调用目标显示相同的值。但是,PIN返回的例程地址不同
我对这种行为感到非常困惑。你知道怎么解释吗


谢谢你的建议

亲自回答我的问题:

经过一段时间的探索,很明显,两个函数指针、调用目标以及PIN返回的例程地址都是有效的,并最终调用了该方法

最后,我查看了呼叫目标地址的内存碎片,果然它看起来像这样:

0000000140001122 E9 D2 00 00 00       jmp         Test::method (014000104Bh)  
换句话说:PIN似乎用跳转到自己版本的代码取代了原来的方法。知道了这一点,关联原始函数指针和PIN例程地址再次成为可能,这就是我所需要做的

0000000140001122 E9 D2 00 00 00       jmp         Test::method (014000104Bh)