Using IARG_MEMORYREAD_EA

Using IARG_MEMORYREAD_EA

本文关键字:EA MEMORYREAD Using IARG      更新时间:2023-10-16

我对使用英特尔PIN非常陌生。目前,我正在使用一个硬件模拟器,它实现PIN来处理指令。

对于我的应用程序,我需要通过使用PIN函数来捕捉硬件级别的一些工作负载变量。不幸的是,由工作负载本身记录的变量指针地址不存在于IARG_MEMORYREAD_EAIACG_MMORYREAD2_EAIARG_MEMORYWRITE_EA值的日志中。

我确信我错过了一个非常简单的点,因为我试图用pin做的操作,再简单不过了。

这可能是什么原因?我需要地址翻译吗?或者我应该使用其他功能吗?

感谢

好吧,恐怕这个答案属于"它对我有用!"。。。

这里是我在主模块中捕获读写访问的"简单"pintool(很抱歉,如果它有点长:它是基于示例pintool的,所以一些注释或代码可能断章取义,我只是快速编码了它):

/*! @file
 *  This is an example of the PIN tool that demonstrates some basic PIN APIs 
 *  and could serve as the starting point for developing your first PIN tool
 */
#include "pin.H"
#include <iostream>
#include <fstream>
typedef enum _tag_ReadWrite{
    Unknown = 0UL,
    Read = 2UL,
    Write = 4UL
}ENUM_READWRITE;
typedef struct _tag_ImgAddr{
    ADDRINT low;
    ADDRINT high;
}IMG_ADDR, *PIMG_ADDR;
/* ================================================================== */
// Global variables 
/* ================================================================== */
IMG_ADDR g_MainImg = { 0 };
std::ostream * out = &cerr;
/* ===================================================================== */
// Command line switches
/* ===================================================================== */
KNOB<string> KnobOutputFile(KNOB_MODE_WRITEONCE,  "pintool",
    "o", "", "specify file name for MyPinTool output");
KNOB<BOOL>   KnobCount(KNOB_MODE_WRITEONCE,  "pintool",
    "count", "1", "count instructions, basic blocks and threads in the application");

/* ===================================================================== */
// Utilities
/* ===================================================================== */
/*!
 *  Print out help message.
 */
INT32 Usage()
{
    cerr << "This tool prints out the number of dynamically executed " << endl <<
            "instructions, basic blocks and threads in the application." << endl << endl;
    cerr << KNOB_BASE::StringKnobSummary() << endl;
    return -1;
}
/* ===================================================================== */
// Analysis routines
/* ===================================================================== */
VOID InsAnalysis(ADDRINT addr, ADDRINT rw_ea, UINT32 rw_size, UINT32 type)
{
    if (g_MainImg.low == 0){
        return;
    }
    //restrict trace to main module only
    if (addr >= g_MainImg.low && addr < g_MainImg.high){
        std::string str_type;
        switch (type){
        case Read:
            str_type = "[R] ";
            break;
        case Write:
            str_type = "[W] ";
            break;
        default:
            break;
        }
        *out << str_type << std::hex << addr <<
            " [" << rw_ea << "] " <<
            " (" << rw_size << ") " <<
            std::endl;
    }
}
/* ===================================================================== */
// Instrumentation callbacks
/* ===================================================================== */

VOID ImageLoad(IMG img, VOID * pData){
    if (!IMG_Valid(img))
        return;
    if (IMG_IsMainExecutable(img)){
        g_MainImg.low = IMG_LowAddress(img);
        g_MainImg.high = IMG_HighAddress(img);
    }
}
/*!
 * This function is called every time a new instruction is encountered.
 * @param[in]   trace    trace to be instrumented
 * @param[in]   v        value specified by the tool in the INS_AddInstrumentFunction
 *                       function call
 */
VOID InsInstrument(INS ins, VOID *v)
{
    if (g_MainImg.low == 0){
        return;
    }
    if (INS_IsMemoryRead(ins)){
        INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)InsAnalysis,
            IARG_INST_PTR,
            IARG_MEMORYREAD_EA,
            IARG_MEMORYREAD_SIZE,
            IARG_UINT32, Read,
            IARG_END);
    }
    if (INS_IsMemoryWrite(ins)){
        INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)InsAnalysis,
            IARG_INST_PTR,
            IARG_MEMORYWRITE_EA,
            IARG_MEMORYWRITE_SIZE,
            IARG_UINT32, Write,
            IARG_END);
    }
}
/*!
 * Print out analysis results.
 * This function is called when the application exits.
 * @param[in]   code            exit code of the application
 * @param[in]   v               value specified by the tool in the 
 *                              PIN_AddFiniFunction function call
 */
VOID Fini(INT32 code, VOID *v)
{
    *out <<  "[*] Fini called!" << endl;
}
/*!
 * The main procedure of the tool.
 * This function is called when the application image is loaded but not yet started.
 * @param[in]   argc            total number of elements in the argv array
 * @param[in]   argv            array of command line arguments, 
 *                              including pin -t <toolname> -- ...
 */
int main(int argc, char *argv[])
{
    // 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();
    }
    string fileName = KnobOutputFile.Value();
    if (!fileName.empty()) { out = new std::ofstream(fileName.c_str());}
    if (KnobCount)
    {
        // Register function to be called to instrument traces
        INS_AddInstrumentFunction(InsInstrument, 0);
        IMG_AddInstrumentFunction(ImageLoad, 0);
        // Register function to be called when the application exits
        PIN_AddFiniFunction(Fini, 0);
    }
    cerr <<  "===============================================" << endl;
    cerr <<  "This application is instrumented by MyPinTool" << endl;
    if (!KnobOutputFile.Value().empty()) 
    {
        cerr << "See file " << KnobOutputFile.Value() << " for analysis results" << endl;
    }
    cerr <<  "===============================================" << endl;
    // Start the program, never returns
    PIN_StartProgram();
    return 0;
}
/* ===================================================================== */
/* eof */
/* ===================================================================== */

我的程序:

#include <cstdint>
#include <iostream>
int main(){
    uint8_t a = 0x35;
    uint8_t * b;
    b = &a;
    std::cout << &b;
    return 0;
}

装配:

CPU Disasm
Address    Command                                                                                              Comments
004012A0 < PUSH EBP                                                                                             ; INT Test.<ModuleEntryPoint>(void)
004012A1   MOV EBP,ESP
004012A3   SUB ESP,0C
004012A6   MOV EAX,DWORD PTR DS:[__security_cookie]
004012AB   XOR EAX,EBP
004012AD   MOV DWORD PTR SS:[EBP-4],EAX
004012B0   MOV ECX,DWORD PTR DS:[<&MSVCP120.std::cout>]
004012B6   LEA EAX,[EBP-5]
004012B9   MOV DWORD PTR SS:[EBP-0C],EAX
004012BC   LEA EAX,[EBP-0C]
004012BF   PUSH EAX
004012C0   MOV BYTE PTR SS:[EBP-5],35
004012C4   CALL NEAR DWORD PTR DS:[<&MSVCP120.std::basic_ostream<char,std::char_traits<char> >::operator<<>]
004012CA   MOV ECX,DWORD PTR SS:[EBP-4]
004012CD   XOR EAX,EAX
004012CF   XOR ECX,EBP
004012D1   CALL __security_check_cookie
004012D6   MOV ESP,EBP
004012D8   POP EBP
004012D9   RETN

pintool的输出:

[Read|Write] <ins address> [Read|Write target] (Read|Write size)

[W] 4012a0 [18ff80]  (4) 
[R] 4012a6 [403000]  (4) 
[W] 4012ad [18ff7c]  (4) 
[R] 4012b0 [402028]  (4) 
[W] 4012b9 [18ff74]  (4) 
[W] 4012bf [18ff70]  (4) 
[W] 4012c0 [18ff7b]  (1) 
[R] 4012c4 [402018]  (4) 
[W] 4012c4 [18ff6c]  (4) 
[R] 4012ca [18ff7c]  (4) 
[W] 4012d1 [18ff70]  (4) 
[R] 40171d [403000]  (4) 
[R] 401725 [18ff70]  (4) 
[R] 4012d8 [18ff80]  (4) 
[R] 4012d9 [18ff84]  (4) 
[*] Fini called!

控制台输出:

Z:dataCPPTestRelease>pin -t MyPinTool.dll -o out.txt -- test.exe
===============================================
This application is instrumented by MyPinTool
See file out.txt for analysis results
===============================================
0018FF74

所以,如果我们把所有东西都混在一起:

console output:     0018FF74
Pin output:    [W] 4012b9 [18ff74]  (4) 
asm:    004012B9   MOV DWORD PTR SS:[EBP-0C],EAX

哪一个是正确的:在0x4012b9写入的地址然后在0x4012bf传递给std::cout以显示结果。

你能在你的程序上测试这个pintool,看看它是否工作吗?不要忽视测试程序的反汇编,看看是否有任何东西被优化掉了,以防万一。。。