使用 IARG_MEMORYREAD_EA
Using IARG_MEMORYREAD_EA
我对使用 Intel PIN 还很陌生。目前我正在使用实现 PIN 来处理指令的硬件模拟器。
对于我的应用程序,我需要使用 PIN 函数在硬件级别捕获一些工作负载变量。不幸的是,IARG_MEMORYREAD_EA、IARG_MEMORYREAD2_EA的日志中不存在由工作负载本身记录的变量指针地址和 IARG_MEMORYWRITE_EA 值。
我确信我遗漏了一个非常简单的点,因为我试图用 pin 进行的操作没有比这更简单的了。
这可能是什么原因?我是否需要地址转换,或者我应该为此使用一些其他功能?
谢谢
嗯,恐怕这个答案落在 "It works for me!"...
的范围内
这里是我的 "simple" 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:\data\CPP\Test\Release>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的地址然后传给std::cout
在0x4012bf显示结果
你能在你的程序上测试这个 pintool 看看它是否工作吗?不要忽略测试程序的反汇编,看看是否有任何优化,以防万一...
我对使用 Intel PIN 还很陌生。目前我正在使用实现 PIN 来处理指令的硬件模拟器。
对于我的应用程序,我需要使用 PIN 函数在硬件级别捕获一些工作负载变量。不幸的是,IARG_MEMORYREAD_EA、IARG_MEMORYREAD2_EA的日志中不存在由工作负载本身记录的变量指针地址和 IARG_MEMORYWRITE_EA 值。
我确信我遗漏了一个非常简单的点,因为我试图用 pin 进行的操作没有比这更简单的了。
这可能是什么原因?我是否需要地址转换,或者我应该为此使用一些其他功能?
谢谢
嗯,恐怕这个答案落在 "It works for me!"...
的范围内这里是我的 "simple" 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:\data\CPP\Test\Release>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的地址然后传给std::cout
在0x4012bf显示结果
你能在你的程序上测试这个 pintool 看看它是否工作吗?不要忽略测试程序的反汇编,看看是否有任何优化,以防万一...