我是PIN的新手,所以也许有一个简单的解释。我对常见的地址仅在Windows上返回PIN感到困惑。我创建了一个最小的测试程序来说明我的观点。
我目前正在使用PIN 2.14。我检查过的应用程序是一个Debug版本,在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;
}
在Ubuntu 14.04.3 x64 VM上对测试应用程序运行此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返回的例程地址是不同的! 我对这种行为感到很困惑。你知道怎么解释这个吗?
感谢您的任何建议!
答案 0 :(得分:1)
自己回答我的问题:
在探测一段时间后,很明显函数指针,调用目标以及PIN返回的例程地址都是有效的,最后调用了该方法。
我最终查看了调用目标地址的内存中反汇编,确定它看起来像这样:
@{}
换句话说:PIN看似用原来的方法替换了自己的代码版本。知道这一点,再次关联原始函数指针和PIN例程地址成为可能,这就是我需要做的全部。