如何通过pin和libelf.h获取可执行程序的全局变量地址
How to get the global variable address of the executable program through pin and libelf.h
我想开发一个 pintool 来找出我的 C 的全局变量的地址 program.Suppose 我有一个 C 程序,其中有一些全局指针变量。当我 运行 使用 pintool 执行相同的程序时,我希望通过 pintool 找到那些全局变量的地址。
我想通过pin获取一个全局变量的地址,但是我们
都知道 Pin 似乎没有提供这样的功能。根据文档:“符号对象仅提供有关应用程序中功能符号的信息。有关其他类型符号(例如数据符号)的信息,必须由工具独立获取,libelf.h 似乎可以获取地址全局变量,请帮助我并建议我如何才能做到这一点?
我本来只想发表评论,但有点太长了...
根据定义,全局变量驻留在可执行文件中(更准确地说,驻留在 .data 或 .bss 部分中,具体取决于它们是否已初始化)。分配其他变量(在堆栈或堆上)。
你甚至不需要符号来检查一个变量(给定它的地址)是否在一个可执行部分中:使用图像检测函数(IMG_xxx
),循环部分( SEC_xxx
) 获取节的基础和结尾,检查它是哪一个(.data 或 .bss)。您可以使用 SEC_Type
获取带 PIN 的部分的类型;一旦你有了一个地址,如果它位于 .bss 或 .data 中,那么你就有了一个全局变量。
现在,如果您想要位于给定地址的变量的名称,它会更复杂,并且如 PIN 文档所述,您将需要符号信息。我不知道 libelf 是否可以轻松做到这一点,但 libdwarf 可以。您还可以查看 llvm-dwarfdump 代码,它是开源的并且也能够做到这一点。
注意:我在Windows(.data
部分)做了实验,但在Linux上的输出应该有点相似。
这是一个带有一个已知全局变量的小虚拟示例;未经优化编译:
#include <iostream>
int global_counter; // global
void count(const int i)
{
int local_counter = 0; // local
for(int j = 0; j < i; j++)
{
global_counter += 1;
if(j % 2 == 0) {
local_counter += 1;
}
}
std::cout << "local counter: " << local_counter << std::endl;
}
int main(int argc, char** argv)
{
if(argc < 2) {
return -1;
}
const auto i = std::atoi(argv[1]);
if (i >= 0) {
count(i);
std::cout << "global counter: " << global_counter << std::endl;
}
return 0;
}
下面是使用全局变量的count
函数部分的反汇编:
00007FF7077B10BE | 8B | mov eax,dword ptr ds:[<global_counter>] | PinTestSimpleTarget.cpp:14
00007FF7077B10C4 | FF | inc eax |
00007FF7077B10C6 | 89 | mov dword ptr ds:[<global_counter>],eax |
00007FF7077B10CC | 8B | mov eax,dword ptr ss:[rsp+20] | PinTestSimpleTarget.cpp:15
00007FF7077B10D0 | 99 | cdq |
00007FF7077B10D1 | 83 | and eax,1 |
00007FF7077B10D4 | 33 | xor eax,edx |
00007FF7077B10D6 | 2B | sub eax,edx |
00007FF7077B10D8 | 85 | test eax,eax |
00007FF7077B10DA | 75 | jne pintestsimpletarget.7FF7077B10E6 |
对全局变量 std::cout 的反汇编:
00007FF7077B117A | 8B | mov edx,dword ptr ds:[<global_counter>] |
00007FF7077B1180 | 48 | mov rcx,rax | rax:$LN23
00007FF7077B1183 | FF | call qword ptr ds:[<&??6?$basic_ostream@DU?$char_traits@D@std |
注意 3 个地址:
- 00007FF7077B10BE(读取)
- 00007FF7077B10C6(写入)
- 00007FF7077B117A (std::cout)
全局变量本身位于:
- 00007FF7077B5628
这是 pintool 源代码(注意:由于未知原因,我在使用 std::cout
时无法正确初始化 CRT,所以我改用 printf
)。
#include "pin.H"
typedef struct _BOUNDARIES
{
ADDRINT lowest_address;
ADDRINT highest_address;
std::string to_str() const
{
std::stringstream stream;
stream << "Low Addr: " << std::hex << lowest_address <<
"; High Addr: " << highest_address;
return std::string(stream.str());
}
bool is_in_bounds(const ADDRINT addr) const
{
return addr >= lowest_address && addr < highest_address;
}
} BOUNDARIES;
/* ================================================================== */
// Global variables
/* ================================================================== */
BOUNDARIES main_executable_boundaries;
BOUNDARIES data_section_boundaries;
/* ===================================================================== */
// Utilities
/* ===================================================================== */
/*!
* Print out help message.
*/
INT32 Usage()
{
//std::cout << "[PINTOOL] This tool display the addresses of global variables in the .data section " << std::endl;
printf("[PINTOOL] This tool display the addresses of global variables in the .data section\n");
return -1;
}
/* ===================================================================== */
// Analysis routines
/* ===================================================================== */
// analysis for memory read
VOID record_mem_read(ADDRINT ip, ADDRINT addr)
{
if(data_section_boundaries.is_in_bounds(addr))
{
printf("[PINTOOL] Read on a global variable (.data); Instruction addr: %p; Read addr: %p\n", ip, addr);
}
}
// analysis for memory write
VOID record_mem_write(VOID* ip, ADDRINT addr)
{
if (data_section_boundaries.is_in_bounds(addr))
{
printf("[PINTOOL] Write on a global variable (.data); Instruction addr: %p; Write addr: %p\n", ip, addr);
}
}
/* ===================================================================== */
// Instrumentation callbacks
/* ===================================================================== */
VOID instrument_instruction(INS ins, VOID *v)
{
// must be valid and within bounds of the main executable.
if(!INS_Valid(ins) || !main_executable_boundaries.is_in_bounds(INS_Address(ins))) {
return;
}
const UINT32 mem_operands = INS_MemoryOperandCount(ins);
// Iterate over each memory operand of the instruction.
for (UINT32 memOp = 0; memOp < mem_operands; memOp++)
{
if (INS_MemoryOperandIsRead(ins, memOp))
{
INS_InsertPredicatedCall(
ins, IPOINT_BEFORE, reinterpret_cast<AFUNPTR>(record_mem_read),
IARG_INST_PTR,
IARG_MEMORYOP_EA, memOp,
IARG_END);
}
if (INS_MemoryOperandIsWritten(ins, memOp))
{
INS_InsertPredicatedCall(
ins, IPOINT_BEFORE, reinterpret_cast<AFUNPTR>(record_mem_write),
IARG_INST_PTR,
IARG_MEMORYOP_EA, memOp,
IARG_END);
}
}
}
VOID image_load(IMG img, VOID* v)
{
printf("[PINTOOL] Loading image: %s; Image ID: %i\n",IMG_Name(img).c_str(), IMG_Id(img));
if(IMG_IsMainExecutable(img)) {
// register lowest and highest addresses to restrict the trace between those addresses.
main_executable_boundaries.lowest_address = IMG_LowAddress(img);
main_executable_boundaries.highest_address = IMG_HighAddress(img);
printf("Main executable boundaries: %s\n", main_executable_boundaries.to_str().c_str());
// cycle through all sections of the main executable.
for (SEC sec = IMG_SecHead(img); SEC_Valid(sec); sec = SEC_Next(sec))
{
// get boundaries of the '.data' section
if(SEC_Name(sec) == ".data") {
const auto sec_address = SEC_Address(sec);
data_section_boundaries.lowest_address = sec_address;
data_section_boundaries.highest_address = sec_address + SEC_Size(sec);
printf("Data section boundaries: %s\n", data_section_boundaries.to_str().c_str());
}
}
}
}
VOID image_unload(IMG img, VOID* v)
{
printf("[PINTOOL] Unloading image: %s\n", IMG_Name(img).c_str());
}
VOID fini(INT32 code, VOID *v)
{
printf("[PINTOOL] Instrumentation tear down.\n");
}
/* ===================================================================== */
// Main
/* ===================================================================== */
int main(int argc, char *argv[])
{
//std::cerr << "[PINTOOL] Loading." << std::endl;
// Initialize PIN library. Print help message if -h(elp) is specified
// in the command line or the command line is invalid
if( PIN_Init(argc,argv) )
{
return Usage();
}
// Register Instruction to be called to instrument instructions
INS_AddInstrumentFunction(instrument_instruction, nullptr);
// Register ImageLoad to be called when an image is loaded
IMG_AddInstrumentFunction(image_load, nullptr);
// Register ImageUnload to be called when an image is unloaded
IMG_AddUnloadFunction(image_unload, nullptr);
// Register function to be called when the application exits
PIN_AddFiniFunction(fini, nullptr);
//std::cerr << "[PINTOOL] Starting instrumentation." << std::endl;
// Start the program, never returns
PIN_StartProgram();
return 0;
}
.\pin.exe -t MyPinTool.dll -- PinTestSimpleTarget.exe 6
输出:
[PINTOOL] Loading image: G:\Appdata\CPP\PinTestSimpleTarget\x64\Release\PinTestSimpleTarget.exe; Image ID: 1
Main executable boundaries: Low Addr: 7ff7077b0000; High Addr: 7ff7077b8fff
Data section boundaries: Low Addr: 7ff7077b5000; High Addr: 7ff7077b5640
[PINTOOL] Loading image: C:\WINDOWS\System32\KERNELBASE.dll; Image ID: 2
[PINTOOL] Loading image: C:\WINDOWS\System32\KERNEL32.DLL; Image ID: 3
[PINTOOL] Loading image: C:\WINDOWS\SYSTEM32\ntdll.dll; Image ID: 4
[PINTOOL] Loading image: C:\WINDOWS\System32\ucrtbase.dll; Image ID: 5
[PINTOOL] Loading image: C:\WINDOWS\SYSTEM32\VCRUNTIME140.dll; Image ID: 6
[PINTOOL] Loading image: C:\WINDOWS\SYSTEM32\MSVCP140.dll; Image ID: 7
[PINTOOL] Read on a global variable (.data); Instruction addr: 0x7ff7077b1ed1; Read addr: 0x7ff7077b5008
[PINTOOL] Write on a global variable (.data); Instruction addr: 0x7ff7077b1f63; Write addr: 0x7ff7077b5000
[PINTOOL] Read on a global variable (.data); Instruction addr: 0x7ff7077b1cb6; Read addr: 0x7ff7077b55c0
[PINTOOL] Write on a global variable (.data); Instruction addr: 0x7ff7077b1cc7; Write addr: 0x7ff7077b55c0
[PINTOOL] Write on a global variable (.data); Instruction addr: 0x7ff7077b2265; Write addr: 0x7ff7077b501c
[PINTOOL] Write on a global variable (.data); Instruction addr: 0x7ff7077b2271; Write addr: 0x7ff7077b5018
[PINTOOL] Read on a global variable (.data); Instruction addr: 0x7ff7077b22c0; Read addr: 0x7ff7077b5020
[PINTOOL] Write on a global variable (.data); Instruction addr: 0x7ff7077b22c0; Write addr: 0x7ff7077b5020
[PINTOOL] Read on a global variable (.data); Instruction addr: 0x7ff7077b2310; Read addr: 0x7ff7077b5624
[PINTOOL] Write on a global variable (.data); Instruction addr: 0x7ff7077b233f; Write addr: 0x7ff7077b5624
[PINTOOL] Write on a global variable (.data); Instruction addr: 0x7ff7077b234d; Write addr: 0x7ff7077b5018
[PINTOOL] Write on a global variable (.data); Instruction addr: 0x7ff7077b2357; Write addr: 0x7ff7077b501c
[PINTOOL] Read on a global variable (.data); Instruction addr: 0x7ff7077b238b; Read addr: 0x7ff7077b501c
[PINTOOL] Write on a global variable (.data); Instruction addr: 0x7ff7077b2394; Write addr: 0x7ff7077b5018
[PINTOOL] Write on a global variable (.data); Instruction addr: 0x7ff7077b239e; Write addr: 0x7ff7077b501c
[PINTOOL] Write on a global variable (.data); Instruction addr: 0x7ff7077b23ad; Write addr: 0x7ff7077b5018
[PINTOOL] Write on a global variable (.data); Instruction addr: 0x7ff7077b23b7; Write addr: 0x7ff7077b501c
[PINTOOL] Read on a global variable (.data); Instruction addr: 0x7ff7077b23d2; Read addr: 0x7ff7077b5030
[PINTOOL] Read on a global variable (.data); Instruction addr: 0x7ff7077b1c97; Read addr: 0x7ff7077b55b8
[PINTOOL] Write on a global variable (.data); Instruction addr: 0x7ff7077b1c97; Write addr: 0x7ff7077b55b8
[PINTOOL] Read on a global variable (.data); Instruction addr: 0x7ff7077b1998; Read addr: 0x7ff7077b55b0
[PINTOOL] Write on a global variable (.data); Instruction addr: 0x7ff7077b19ab; Write addr: 0x7ff7077b55b0
[PINTOOL] Read on a global variable (.data); Instruction addr: 0x7ff7077b1d02; Read addr: 0x7ff7077b55c1
[PINTOOL] Read on a global variable (.data); Instruction addr: 0x7ff7077b23d2; Read addr: 0x7ff7077b5030
[PINTOOL] Write on a global variable (.data); Instruction addr: 0x7ff7077b1d4f; Write addr: 0x7ff7077b55c8
[PINTOOL] Write on a global variable (.data); Instruction addr: 0x7ff7077b1d57; Write addr: 0x7ff7077b55d8
[PINTOOL] Write on a global variable (.data); Instruction addr: 0x7ff7077b1d5e; Write addr: 0x7ff7077b55e0
[PINTOOL] Write on a global variable (.data); Instruction addr: 0x7ff7077b1d66; Write addr: 0x7ff7077b55f0
[PINTOOL] Write on a global variable (.data); Instruction addr: 0x7ff7077b1d6d; Write addr: 0x7ff7077b55c1
[PINTOOL] Read on a global variable (.data); Instruction addr: 0x7ff7077b1e76; Read addr: 0x7ff7077b55c8
[PINTOOL] Read on a global variable (.data); Instruction addr: 0x7ff7077b1fca; Read addr: 0x7ff7077b5014
[PINTOOL] Read on a global variable (.data); Instruction addr: 0x7ff7077b1fb5; Read addr: 0x7ff7077b5610
[PINTOOL] Write on a global variable (.data); Instruction addr: 0x7ff7077b1fb5; Write addr: 0x7ff7077b5610
[PINTOOL] Read on a global variable (.data); Instruction addr: 0x7ff7077b1fbe; Read addr: 0x7ff7077b5618
[PINTOOL] Write on a global variable (.data); Instruction addr: 0x7ff7077b1fbe; Write addr: 0x7ff7077b5618
[PINTOOL] Write on a global variable (.data); Instruction addr: 0x7ff7077b19e9; Write addr: 0x7ff7077b55b0
[PINTOOL] Read on a global variable (.data); Instruction addr: 0x7ff7077b23d2; Read addr: 0x7ff7077b5030
[PINTOOL] Read on a global variable (.data); Instruction addr: 0x7ff7077b1e37; Read addr: 0x7ff7077b55b8
[PINTOOL] Write on a global variable (.data); Instruction addr: 0x7ff7077b1e37; Write addr: 0x7ff7077b55b8
[PINTOOL] Read on a global variable (.data); Instruction addr: 0x7ff7077b1a0c; Read addr: 0x7ff7077b5638
[PINTOOL] Read on a global variable (.data); Instruction addr: 0x7ff7077b1a38; Read addr: 0x7ff7077b5630
[PINTOOL] Read on a global variable (.data); Instruction addr: 0x7ff7077b10be; Read addr: 0x7ff7077b5628
[PINTOOL] Write on a global variable (.data); Instruction addr: 0x7ff7077b10c6; Write addr: 0x7ff7077b5628
[PINTOOL] Read on a global variable (.data); Instruction addr: 0x7ff7077b10be; Read addr: 0x7ff7077b5628
[PINTOOL] Write on a global variable (.data); Instruction addr: 0x7ff7077b10c6; Write addr: 0x7ff7077b5628
[PINTOOL] Read on a global variable (.data); Instruction addr: 0x7ff7077b10be; Read addr: 0x7ff7077b5628
[PINTOOL] Write on a global variable (.data); Instruction addr: 0x7ff7077b10c6; Write addr: 0x7ff7077b5628
[PINTOOL] Read on a global variable (.data); Instruction addr: 0x7ff7077b10be; Read addr: 0x7ff7077b5628
[PINTOOL] Write on a global variable (.data); Instruction addr: 0x7ff7077b10c6; Write addr: 0x7ff7077b5628
[PINTOOL] Read on a global variable (.data); Instruction addr: 0x7ff7077b10be; Read addr: 0x7ff7077b5628
[PINTOOL] Write on a global variable (.data); Instruction addr: 0x7ff7077b10c6; Write addr: 0x7ff7077b5628
[PINTOOL] Read on a global variable (.data); Instruction addr: 0x7ff7077b10be; Read addr: 0x7ff7077b5628
[PINTOOL] Write on a global variable (.data); Instruction addr: 0x7ff7077b10c6; Write addr: 0x7ff7077b5628
[PINTOOL] Read on a global variable (.data); Instruction addr: 0x7ff7077b143d; Read addr: 0x7ff7077b5008
[PINTOOL] Read on a global variable (.data); Instruction addr: 0x7ff7077b1860; Read addr: 0x7ff7077b5008
local counter: 3
[PINTOOL] Read on a global variable (.data); Instruction addr: 0x7ff7077b143d; Read addr: 0x7ff7077b5008
global counter: [PINTOOL] Read on a global variable (.data); Instruction addr: 0x7ff7077b1860; Read addr: 0x7ff7077b5008
[PINTOOL] Read on a global variable (.data); Instruction addr: 0x7ff7077b117a; Read addr: 0x7ff7077b5628
6
[PINTOOL] Loading image: C:\WINDOWS\System32\kernel.appcore.dll; Image ID: 8
[PINTOOL] Loading image: C:\WINDOWS\System32\msvcrt.dll; Image ID: 9
[PINTOOL] Loading image: C:\WINDOWS\System32\RPCRT4.dll; Image ID: 10
[PINTOOL] Unloading image: G:\Appdata\CPP\PinTestSimpleTarget\x64\Release\PinTestSimpleTarget.exe
[PINTOOL] Unloading image: C:\WINDOWS\System32\KERNELBASE.dll
[PINTOOL] Unloading image: C:\WINDOWS\System32\KERNEL32.DLL
[PINTOOL] Unloading image: C:\WINDOWS\SYSTEM32\ntdll.dll
[PINTOOL] Unloading image: C:\WINDOWS\System32\ucrtbase.dll
[PINTOOL] Unloading image: C:\WINDOWS\SYSTEM32\VCRUNTIME140.dll
[PINTOOL] Unloading image: C:\WINDOWS\SYSTEM32\MSVCP140.dll
[PINTOOL] Unloading image: C:\WINDOWS\System32\kernel.appcore.dll
[PINTOOL] Unloading image: C:\WINDOWS\System32\msvcrt.dll
[PINTOOL] Unloading image: C:\WINDOWS\System32\RPCRT4.dll
[PINTOOL] Instrumentation tear down.
很明显还有其他一些程序内部使用的全局变量显示出来了;但至少它应该让您了解如何在程序中跟踪全局变量。
我想开发一个 pintool 来找出我的 C 的全局变量的地址 program.Suppose 我有一个 C 程序,其中有一些全局指针变量。当我 运行 使用 pintool 执行相同的程序时,我希望通过 pintool 找到那些全局变量的地址。
我想通过pin获取一个全局变量的地址,但是我们 都知道 Pin 似乎没有提供这样的功能。根据文档:“符号对象仅提供有关应用程序中功能符号的信息。有关其他类型符号(例如数据符号)的信息,必须由工具独立获取,libelf.h 似乎可以获取地址全局变量,请帮助我并建议我如何才能做到这一点?
我本来只想发表评论,但有点太长了...
根据定义,全局变量驻留在可执行文件中(更准确地说,驻留在 .data 或 .bss 部分中,具体取决于它们是否已初始化)。分配其他变量(在堆栈或堆上)。
你甚至不需要符号来检查一个变量(给定它的地址)是否在一个可执行部分中:使用图像检测函数(IMG_xxx
),循环部分( SEC_xxx
) 获取节的基础和结尾,检查它是哪一个(.data 或 .bss)。您可以使用 SEC_Type
获取带 PIN 的部分的类型;一旦你有了一个地址,如果它位于 .bss 或 .data 中,那么你就有了一个全局变量。
现在,如果您想要位于给定地址的变量的名称,它会更复杂,并且如 PIN 文档所述,您将需要符号信息。我不知道 libelf 是否可以轻松做到这一点,但 libdwarf 可以。您还可以查看 llvm-dwarfdump 代码,它是开源的并且也能够做到这一点。
注意:我在Windows(.data
部分)做了实验,但在Linux上的输出应该有点相似。
这是一个带有一个已知全局变量的小虚拟示例;未经优化编译:
#include <iostream>
int global_counter; // global
void count(const int i)
{
int local_counter = 0; // local
for(int j = 0; j < i; j++)
{
global_counter += 1;
if(j % 2 == 0) {
local_counter += 1;
}
}
std::cout << "local counter: " << local_counter << std::endl;
}
int main(int argc, char** argv)
{
if(argc < 2) {
return -1;
}
const auto i = std::atoi(argv[1]);
if (i >= 0) {
count(i);
std::cout << "global counter: " << global_counter << std::endl;
}
return 0;
}
下面是使用全局变量的count
函数部分的反汇编:
00007FF7077B10BE | 8B | mov eax,dword ptr ds:[<global_counter>] | PinTestSimpleTarget.cpp:14
00007FF7077B10C4 | FF | inc eax |
00007FF7077B10C6 | 89 | mov dword ptr ds:[<global_counter>],eax |
00007FF7077B10CC | 8B | mov eax,dword ptr ss:[rsp+20] | PinTestSimpleTarget.cpp:15
00007FF7077B10D0 | 99 | cdq |
00007FF7077B10D1 | 83 | and eax,1 |
00007FF7077B10D4 | 33 | xor eax,edx |
00007FF7077B10D6 | 2B | sub eax,edx |
00007FF7077B10D8 | 85 | test eax,eax |
00007FF7077B10DA | 75 | jne pintestsimpletarget.7FF7077B10E6 |
对全局变量 std::cout 的反汇编:
00007FF7077B117A | 8B | mov edx,dword ptr ds:[<global_counter>] |
00007FF7077B1180 | 48 | mov rcx,rax | rax:$LN23
00007FF7077B1183 | FF | call qword ptr ds:[<&??6?$basic_ostream@DU?$char_traits@D@std |
注意 3 个地址:
- 00007FF7077B10BE(读取)
- 00007FF7077B10C6(写入)
- 00007FF7077B117A (std::cout)
全局变量本身位于:
- 00007FF7077B5628
这是 pintool 源代码(注意:由于未知原因,我在使用 std::cout
时无法正确初始化 CRT,所以我改用 printf
)。
#include "pin.H"
typedef struct _BOUNDARIES
{
ADDRINT lowest_address;
ADDRINT highest_address;
std::string to_str() const
{
std::stringstream stream;
stream << "Low Addr: " << std::hex << lowest_address <<
"; High Addr: " << highest_address;
return std::string(stream.str());
}
bool is_in_bounds(const ADDRINT addr) const
{
return addr >= lowest_address && addr < highest_address;
}
} BOUNDARIES;
/* ================================================================== */
// Global variables
/* ================================================================== */
BOUNDARIES main_executable_boundaries;
BOUNDARIES data_section_boundaries;
/* ===================================================================== */
// Utilities
/* ===================================================================== */
/*!
* Print out help message.
*/
INT32 Usage()
{
//std::cout << "[PINTOOL] This tool display the addresses of global variables in the .data section " << std::endl;
printf("[PINTOOL] This tool display the addresses of global variables in the .data section\n");
return -1;
}
/* ===================================================================== */
// Analysis routines
/* ===================================================================== */
// analysis for memory read
VOID record_mem_read(ADDRINT ip, ADDRINT addr)
{
if(data_section_boundaries.is_in_bounds(addr))
{
printf("[PINTOOL] Read on a global variable (.data); Instruction addr: %p; Read addr: %p\n", ip, addr);
}
}
// analysis for memory write
VOID record_mem_write(VOID* ip, ADDRINT addr)
{
if (data_section_boundaries.is_in_bounds(addr))
{
printf("[PINTOOL] Write on a global variable (.data); Instruction addr: %p; Write addr: %p\n", ip, addr);
}
}
/* ===================================================================== */
// Instrumentation callbacks
/* ===================================================================== */
VOID instrument_instruction(INS ins, VOID *v)
{
// must be valid and within bounds of the main executable.
if(!INS_Valid(ins) || !main_executable_boundaries.is_in_bounds(INS_Address(ins))) {
return;
}
const UINT32 mem_operands = INS_MemoryOperandCount(ins);
// Iterate over each memory operand of the instruction.
for (UINT32 memOp = 0; memOp < mem_operands; memOp++)
{
if (INS_MemoryOperandIsRead(ins, memOp))
{
INS_InsertPredicatedCall(
ins, IPOINT_BEFORE, reinterpret_cast<AFUNPTR>(record_mem_read),
IARG_INST_PTR,
IARG_MEMORYOP_EA, memOp,
IARG_END);
}
if (INS_MemoryOperandIsWritten(ins, memOp))
{
INS_InsertPredicatedCall(
ins, IPOINT_BEFORE, reinterpret_cast<AFUNPTR>(record_mem_write),
IARG_INST_PTR,
IARG_MEMORYOP_EA, memOp,
IARG_END);
}
}
}
VOID image_load(IMG img, VOID* v)
{
printf("[PINTOOL] Loading image: %s; Image ID: %i\n",IMG_Name(img).c_str(), IMG_Id(img));
if(IMG_IsMainExecutable(img)) {
// register lowest and highest addresses to restrict the trace between those addresses.
main_executable_boundaries.lowest_address = IMG_LowAddress(img);
main_executable_boundaries.highest_address = IMG_HighAddress(img);
printf("Main executable boundaries: %s\n", main_executable_boundaries.to_str().c_str());
// cycle through all sections of the main executable.
for (SEC sec = IMG_SecHead(img); SEC_Valid(sec); sec = SEC_Next(sec))
{
// get boundaries of the '.data' section
if(SEC_Name(sec) == ".data") {
const auto sec_address = SEC_Address(sec);
data_section_boundaries.lowest_address = sec_address;
data_section_boundaries.highest_address = sec_address + SEC_Size(sec);
printf("Data section boundaries: %s\n", data_section_boundaries.to_str().c_str());
}
}
}
}
VOID image_unload(IMG img, VOID* v)
{
printf("[PINTOOL] Unloading image: %s\n", IMG_Name(img).c_str());
}
VOID fini(INT32 code, VOID *v)
{
printf("[PINTOOL] Instrumentation tear down.\n");
}
/* ===================================================================== */
// Main
/* ===================================================================== */
int main(int argc, char *argv[])
{
//std::cerr << "[PINTOOL] Loading." << std::endl;
// Initialize PIN library. Print help message if -h(elp) is specified
// in the command line or the command line is invalid
if( PIN_Init(argc,argv) )
{
return Usage();
}
// Register Instruction to be called to instrument instructions
INS_AddInstrumentFunction(instrument_instruction, nullptr);
// Register ImageLoad to be called when an image is loaded
IMG_AddInstrumentFunction(image_load, nullptr);
// Register ImageUnload to be called when an image is unloaded
IMG_AddUnloadFunction(image_unload, nullptr);
// Register function to be called when the application exits
PIN_AddFiniFunction(fini, nullptr);
//std::cerr << "[PINTOOL] Starting instrumentation." << std::endl;
// Start the program, never returns
PIN_StartProgram();
return 0;
}
.\pin.exe -t MyPinTool.dll -- PinTestSimpleTarget.exe 6
输出:
[PINTOOL] Loading image: G:\Appdata\CPP\PinTestSimpleTarget\x64\Release\PinTestSimpleTarget.exe; Image ID: 1
Main executable boundaries: Low Addr: 7ff7077b0000; High Addr: 7ff7077b8fff
Data section boundaries: Low Addr: 7ff7077b5000; High Addr: 7ff7077b5640
[PINTOOL] Loading image: C:\WINDOWS\System32\KERNELBASE.dll; Image ID: 2
[PINTOOL] Loading image: C:\WINDOWS\System32\KERNEL32.DLL; Image ID: 3
[PINTOOL] Loading image: C:\WINDOWS\SYSTEM32\ntdll.dll; Image ID: 4
[PINTOOL] Loading image: C:\WINDOWS\System32\ucrtbase.dll; Image ID: 5
[PINTOOL] Loading image: C:\WINDOWS\SYSTEM32\VCRUNTIME140.dll; Image ID: 6
[PINTOOL] Loading image: C:\WINDOWS\SYSTEM32\MSVCP140.dll; Image ID: 7
[PINTOOL] Read on a global variable (.data); Instruction addr: 0x7ff7077b1ed1; Read addr: 0x7ff7077b5008
[PINTOOL] Write on a global variable (.data); Instruction addr: 0x7ff7077b1f63; Write addr: 0x7ff7077b5000
[PINTOOL] Read on a global variable (.data); Instruction addr: 0x7ff7077b1cb6; Read addr: 0x7ff7077b55c0
[PINTOOL] Write on a global variable (.data); Instruction addr: 0x7ff7077b1cc7; Write addr: 0x7ff7077b55c0
[PINTOOL] Write on a global variable (.data); Instruction addr: 0x7ff7077b2265; Write addr: 0x7ff7077b501c
[PINTOOL] Write on a global variable (.data); Instruction addr: 0x7ff7077b2271; Write addr: 0x7ff7077b5018
[PINTOOL] Read on a global variable (.data); Instruction addr: 0x7ff7077b22c0; Read addr: 0x7ff7077b5020
[PINTOOL] Write on a global variable (.data); Instruction addr: 0x7ff7077b22c0; Write addr: 0x7ff7077b5020
[PINTOOL] Read on a global variable (.data); Instruction addr: 0x7ff7077b2310; Read addr: 0x7ff7077b5624
[PINTOOL] Write on a global variable (.data); Instruction addr: 0x7ff7077b233f; Write addr: 0x7ff7077b5624
[PINTOOL] Write on a global variable (.data); Instruction addr: 0x7ff7077b234d; Write addr: 0x7ff7077b5018
[PINTOOL] Write on a global variable (.data); Instruction addr: 0x7ff7077b2357; Write addr: 0x7ff7077b501c
[PINTOOL] Read on a global variable (.data); Instruction addr: 0x7ff7077b238b; Read addr: 0x7ff7077b501c
[PINTOOL] Write on a global variable (.data); Instruction addr: 0x7ff7077b2394; Write addr: 0x7ff7077b5018
[PINTOOL] Write on a global variable (.data); Instruction addr: 0x7ff7077b239e; Write addr: 0x7ff7077b501c
[PINTOOL] Write on a global variable (.data); Instruction addr: 0x7ff7077b23ad; Write addr: 0x7ff7077b5018
[PINTOOL] Write on a global variable (.data); Instruction addr: 0x7ff7077b23b7; Write addr: 0x7ff7077b501c
[PINTOOL] Read on a global variable (.data); Instruction addr: 0x7ff7077b23d2; Read addr: 0x7ff7077b5030
[PINTOOL] Read on a global variable (.data); Instruction addr: 0x7ff7077b1c97; Read addr: 0x7ff7077b55b8
[PINTOOL] Write on a global variable (.data); Instruction addr: 0x7ff7077b1c97; Write addr: 0x7ff7077b55b8
[PINTOOL] Read on a global variable (.data); Instruction addr: 0x7ff7077b1998; Read addr: 0x7ff7077b55b0
[PINTOOL] Write on a global variable (.data); Instruction addr: 0x7ff7077b19ab; Write addr: 0x7ff7077b55b0
[PINTOOL] Read on a global variable (.data); Instruction addr: 0x7ff7077b1d02; Read addr: 0x7ff7077b55c1
[PINTOOL] Read on a global variable (.data); Instruction addr: 0x7ff7077b23d2; Read addr: 0x7ff7077b5030
[PINTOOL] Write on a global variable (.data); Instruction addr: 0x7ff7077b1d4f; Write addr: 0x7ff7077b55c8
[PINTOOL] Write on a global variable (.data); Instruction addr: 0x7ff7077b1d57; Write addr: 0x7ff7077b55d8
[PINTOOL] Write on a global variable (.data); Instruction addr: 0x7ff7077b1d5e; Write addr: 0x7ff7077b55e0
[PINTOOL] Write on a global variable (.data); Instruction addr: 0x7ff7077b1d66; Write addr: 0x7ff7077b55f0
[PINTOOL] Write on a global variable (.data); Instruction addr: 0x7ff7077b1d6d; Write addr: 0x7ff7077b55c1
[PINTOOL] Read on a global variable (.data); Instruction addr: 0x7ff7077b1e76; Read addr: 0x7ff7077b55c8
[PINTOOL] Read on a global variable (.data); Instruction addr: 0x7ff7077b1fca; Read addr: 0x7ff7077b5014
[PINTOOL] Read on a global variable (.data); Instruction addr: 0x7ff7077b1fb5; Read addr: 0x7ff7077b5610
[PINTOOL] Write on a global variable (.data); Instruction addr: 0x7ff7077b1fb5; Write addr: 0x7ff7077b5610
[PINTOOL] Read on a global variable (.data); Instruction addr: 0x7ff7077b1fbe; Read addr: 0x7ff7077b5618
[PINTOOL] Write on a global variable (.data); Instruction addr: 0x7ff7077b1fbe; Write addr: 0x7ff7077b5618
[PINTOOL] Write on a global variable (.data); Instruction addr: 0x7ff7077b19e9; Write addr: 0x7ff7077b55b0
[PINTOOL] Read on a global variable (.data); Instruction addr: 0x7ff7077b23d2; Read addr: 0x7ff7077b5030
[PINTOOL] Read on a global variable (.data); Instruction addr: 0x7ff7077b1e37; Read addr: 0x7ff7077b55b8
[PINTOOL] Write on a global variable (.data); Instruction addr: 0x7ff7077b1e37; Write addr: 0x7ff7077b55b8
[PINTOOL] Read on a global variable (.data); Instruction addr: 0x7ff7077b1a0c; Read addr: 0x7ff7077b5638
[PINTOOL] Read on a global variable (.data); Instruction addr: 0x7ff7077b1a38; Read addr: 0x7ff7077b5630
[PINTOOL] Read on a global variable (.data); Instruction addr: 0x7ff7077b10be; Read addr: 0x7ff7077b5628
[PINTOOL] Write on a global variable (.data); Instruction addr: 0x7ff7077b10c6; Write addr: 0x7ff7077b5628
[PINTOOL] Read on a global variable (.data); Instruction addr: 0x7ff7077b10be; Read addr: 0x7ff7077b5628
[PINTOOL] Write on a global variable (.data); Instruction addr: 0x7ff7077b10c6; Write addr: 0x7ff7077b5628
[PINTOOL] Read on a global variable (.data); Instruction addr: 0x7ff7077b10be; Read addr: 0x7ff7077b5628
[PINTOOL] Write on a global variable (.data); Instruction addr: 0x7ff7077b10c6; Write addr: 0x7ff7077b5628
[PINTOOL] Read on a global variable (.data); Instruction addr: 0x7ff7077b10be; Read addr: 0x7ff7077b5628
[PINTOOL] Write on a global variable (.data); Instruction addr: 0x7ff7077b10c6; Write addr: 0x7ff7077b5628
[PINTOOL] Read on a global variable (.data); Instruction addr: 0x7ff7077b10be; Read addr: 0x7ff7077b5628
[PINTOOL] Write on a global variable (.data); Instruction addr: 0x7ff7077b10c6; Write addr: 0x7ff7077b5628
[PINTOOL] Read on a global variable (.data); Instruction addr: 0x7ff7077b10be; Read addr: 0x7ff7077b5628
[PINTOOL] Write on a global variable (.data); Instruction addr: 0x7ff7077b10c6; Write addr: 0x7ff7077b5628
[PINTOOL] Read on a global variable (.data); Instruction addr: 0x7ff7077b143d; Read addr: 0x7ff7077b5008
[PINTOOL] Read on a global variable (.data); Instruction addr: 0x7ff7077b1860; Read addr: 0x7ff7077b5008
local counter: 3
[PINTOOL] Read on a global variable (.data); Instruction addr: 0x7ff7077b143d; Read addr: 0x7ff7077b5008
global counter: [PINTOOL] Read on a global variable (.data); Instruction addr: 0x7ff7077b1860; Read addr: 0x7ff7077b5008
[PINTOOL] Read on a global variable (.data); Instruction addr: 0x7ff7077b117a; Read addr: 0x7ff7077b5628
6
[PINTOOL] Loading image: C:\WINDOWS\System32\kernel.appcore.dll; Image ID: 8
[PINTOOL] Loading image: C:\WINDOWS\System32\msvcrt.dll; Image ID: 9
[PINTOOL] Loading image: C:\WINDOWS\System32\RPCRT4.dll; Image ID: 10
[PINTOOL] Unloading image: G:\Appdata\CPP\PinTestSimpleTarget\x64\Release\PinTestSimpleTarget.exe
[PINTOOL] Unloading image: C:\WINDOWS\System32\KERNELBASE.dll
[PINTOOL] Unloading image: C:\WINDOWS\System32\KERNEL32.DLL
[PINTOOL] Unloading image: C:\WINDOWS\SYSTEM32\ntdll.dll
[PINTOOL] Unloading image: C:\WINDOWS\System32\ucrtbase.dll
[PINTOOL] Unloading image: C:\WINDOWS\SYSTEM32\VCRUNTIME140.dll
[PINTOOL] Unloading image: C:\WINDOWS\SYSTEM32\MSVCP140.dll
[PINTOOL] Unloading image: C:\WINDOWS\System32\kernel.appcore.dll
[PINTOOL] Unloading image: C:\WINDOWS\System32\msvcrt.dll
[PINTOOL] Unloading image: C:\WINDOWS\System32\RPCRT4.dll
[PINTOOL] Instrumentation tear down.
很明显还有其他一些程序内部使用的全局变量显示出来了;但至少它应该让您了解如何在程序中跟踪全局变量。