You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Intel Pin获取无符号信息可执行文件中自定义函数的读写内存值

Solution for Tracking Memory Reads/Writes in a Custom Function Without Symbol Info Using Intel Pin

Got it, let's break down how to solve this problem. Since your executable lacks symbol information, we can't rely on Intel Pin's routine-level instrumentation to target getSum directly. Instead, we'll use instruction-level instrumentation paired with manual address range tracking to isolate the instructions belonging to your custom function. Here's a step-by-step approach:

1. Identify the Instruction Range of getSum

First, you need to pinpoint the start and end virtual addresses of the getSum function. Use a disassembler tool like objdump or IDA Pro to analyze your executable:

  • Run objdump -d your_executable > disasm.txt to generate a full disassembly of the binary.
  • Search for the assembly logic matching getSum (look for the loop that increments i from 1 to 10 and adds it to a sum variable).
  • Note down the start address (the first instruction of the function) and end address (the address immediately after the function's ret instruction).

2. Build a Pin Tool with Address-Range Filtering

We'll create a Pin tool that tracks whether the current executing instruction falls within getSum's address range. When it does, we'll instrument memory read/write operations to log their values.

Here's a sample Pin tool implementation (C++):

#include "pin.H"
#include <fstream>
#include <iostream>

// Replace these with the actual start/end addresses of getSum from your disassembly
ADDRINT g_getSum_start = 0x00401000;
ADDRINT g_getSum_end = 0x00401030;
std::ofstream trace_file;

// Flag to track if we're executing inside getSum
bool g_in_getSum = false;

// Callback to update the in-function flag before each instruction runs
VOID InstructionEntry(ADDRINT addr) {
    g_in_getSum = (addr >= g_getSum_start && addr < g_getSum_end);
}

// Callback to log memory read operations
VOID LogMemRead(ADDRINT addr, UINT32 size) {
    if (g_in_getSum) {
        // Read and log the value based on memory size
        switch(size) {
            case 1: 
                trace_file << "[READ] Address: 0x" << std::hex << addr 
                           << " Value: 0x" << static_cast<UINT32>(*reinterpret_cast<UINT8*>(addr)) 
                           << std::endl; 
                break;
            case 4: 
                trace_file << "[READ] Address: 0x" << std::hex << addr 
                           << " Value: 0x" << *reinterpret_cast<UINT32*>(addr) 
                           << std::endl; 
                break;
            // Add cases for 2-byte, 8-byte operations if needed
        }
    }
}

// Callback to log memory write operations
VOID LogMemWrite(ADDRINT addr, UINT32 size, ADDRINT value) {
    if (g_in_getSum) {
        trace_file << "[WRITE] Address: 0x" << std::hex << addr 
                   << " Value: 0x" << value 
                   << " Size: " << std::dec << size 
                   << std::endl;
    }
}

// Core instrumentation routine
VOID Instruction(INS ins, VOID *v) {
    // Check if we're entering getSum before each instruction
    INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)InstructionEntry, IARG_INST_PTR, IARG_END);

    // Instrument memory reads
    if (INS_IsMemoryRead(ins)) {
        INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)LogMemRead, IARG_MEMORYREAD_EA, IARG_MEMORYREAD_SIZE, IARG_END);
    }

    // Instrument memory writes
    if (INS_IsMemoryWrite(ins)) {
        INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)LogMemWrite, IARG_MEMORYWRITE_EA, IARG_MEMORYWRITE_SIZE, IARG_MEMORYWRITE_VALUE, IARG_END);
    }
}

// Tool usage help
INT32 Usage() {
    std::cerr << "Usage: pin -t <tool.so> -- <your_executable>" << std::endl;
    return -1;
}

int main(int argc, char *argv[]) {
    if (PIN_Init(argc, argv)) return Usage();

    trace_file.open("mem_trace.log");
    if (!trace_file.is_open()) {
        std::cerr << "Failed to open trace file!" << std::endl;
        return -1;
    }

    INS_AddInstrumentFunction(Instruction, 0);
    PIN_StartProgram();

    trace_file.close();
    return 0;
}

3. Key Details Explained

  • Address Range Check: The InstructionEntry callback runs before every instruction, updating the g_in_getSum flag to track whether we're inside the target function's boundaries.
  • Memory Logging: We use Pin's built-in APIs (INS_IsMemoryRead/INS_IsMemoryWrite) to detect memory operations. For reads, we fetch the value directly from memory; for writes, Pin provides the value being written via IARG_MEMORYWRITE_VALUE.
  • Size Handling: The code handles 1-byte and 4-byte operations (matching the int variables in getSum). Extend this to other sizes if your function uses different data types.

4. Compile and Run the Tool

  • Compile the Pin tool using the Pin SDK's make utility (follow Intel's official build instructions for your OS).
  • Run it with your executable:
    pin -t your_tool.so -- path/to/your_executable
    
  • Check the mem_trace.log file for the memory operations logged from within getSum.

Important Notes

  • If your executable uses ASLR (Address Space Layout Randomization), disable it first (e.g., setarch $(uname -m) -R ./your_executable on Linux) to ensure the disassembly addresses match runtime addresses.
  • For complex functions, double-check the address range to exclude inline functions or shared library calls nested inside getSum.

内容的提问来源于stack exchange,提问作者wentaolu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 06:50:59