英特尔PIN例行地址检索:Linux与Windows

Intel PIN Routine address retrieval: Linux vs. Windows

本文关键字:Linux Windows 检索 PIN 行地址 英特尔      更新时间:2023-10-16

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

我目前使用的是个人识别码2.14。我检查的应用程序是调试版本,在Windows上禁用了ASLR。

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

#include "stdio.h"
class Test {
public:
void method() {}
};
void main() {
Test t;
t.method();
printf("Test::method = 0x%pn", &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("%sn", 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;
}

针对Ubuntu 14.04.3 x64虚拟机上的测试应用程序运行此PIN工具打印:

push rbp
mov rbp, rsp
push r13
push r12
push rbx
sub rsp, 0x18
lea rax, ptr [rbp-0x21]
mov rdi, rax
call 0x400820
mov r12d, 0x400820
mov r13d, 0x0
mov rcx, r12
mov rbx, r13
mov rax, r12
mov rdx, r13
mov rax, rdx
mov rsi, rcx
mov rdx, rax
mov edi, 0x4008b4
mov eax, 0x0
call 0x4006a0
mov eax, 0x0
add rsp, 0x18
pop rbx
pop r12
pop r13
pop rbp
ret 
_ZN4Test6methodEv detected by PIN resides at 0x0x400820.
Test::method = 0x0x400820

请注意,以t.method()为目标的调用,以及PIN检索到的函数地址和应用程序的输出都显示Test::方法位于地址0x0x400820。

我的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例程地址关联起来就成为可能,这就是我所需要做的