C++ 英特尔PIN例程地址检索:Linux与Windows
我是个新手,所以也许有一个简单的解释。我对Windows上的常规地址PIN返回感到困惑。我创建了一个最小的测试程序来说明我的观点 我目前正在使用引脚2.14。我检查的应用程序是调试版本,在Windows上禁用了ASLRC++ 英特尔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
首先考虑调用空方法的简单应用程序,并打印方法的地址:
#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)