使用 Intel 的 PinTool 获取堆栈指针内容

Getting the stack pointer content using Intel's PinTool

使用 objdump 实用程序,我们能够检索变量的相对地址,例如考虑一个简单的 C 程序: 源代码:

#include<stdio.h>
void do_stuff(int my_arg){
    int my_local=my_arg+2;
    int i;
    for(i=0;i<my_local;i++)
        printf("i=%d\n",i);
}

int main(){
    do_stuff(2);
    return 0;
}

用 gcc 编译:

$ gcc -g example.c -o 示例

运行 带有用于 ELF 信息的 dwarf 标志的 objdump 实用程序。

$objdump --dwarf=信息示例

输出:

Contents of the .debug_info section:

  Compilation Unit @ offset 0x0:
   Length:        0xd3 (32-bit)
   Version:       4
   Abbrev Offset: 0x0
   Pointer Size:  8
 <0><b>: Abbrev Number: 1 (DW_TAG_compile_unit)
    <c>   DW_AT_producer    : (indirect string, offset: 0x0): GNU C 4.8.4 -mtune=generic -march=x86-64 -g -fstack-protector 
    <10>   DW_AT_language    : 1    (ANSI C)
    <11>   DW_AT_name        : (indirect string, offset: 0xcd): sample1.c   
    <15>   DW_AT_comp_dir    : (indirect string, offset: 0x7e): /home/bernard/PhD/TEJAS/tejas_installation_kit/Tejas-Simulator/Tejas/benchmark  
    <19>   DW_AT_low_pc      : 0x40052d 
    <21>   DW_AT_high_pc     : 0x54 
    <29>   DW_AT_stmt_list   : 0x0  
 <1><2d>: Abbrev Number: 2 (DW_TAG_base_type)
    <2e>   DW_AT_byte_size   : 8    
    <2f>   DW_AT_encoding    : 7    (unsigned)
    <30>   DW_AT_name        : (indirect string, offset: 0x47): long unsigned int   
 <1><34>: Abbrev Number: 2 (DW_TAG_base_type)
    <35>   DW_AT_byte_size   : 1    
    <36>   DW_AT_encoding    : 8    (unsigned char)
    <37>   DW_AT_name        : (indirect string, offset: 0x62): unsigned char   
 <1><3b>: Abbrev Number: 2 (DW_TAG_base_type)
    <3c>   DW_AT_byte_size   : 2    
    <3d>   DW_AT_encoding    : 7    (unsigned)
    <3e>   DW_AT_name        : (indirect string, offset: 0xde): short unsigned int  
 <1><42>: Abbrev Number: 2 (DW_TAG_base_type)
    <43>   DW_AT_byte_size   : 4    
    <44>   DW_AT_encoding    : 7    (unsigned)
    <45>   DW_AT_name        : (indirect string, offset: 0x4c): unsigned int    
 <1><49>: Abbrev Number: 2 (DW_TAG_base_type)
    <4a>   DW_AT_byte_size   : 1    
    <4b>   DW_AT_encoding    : 6    (signed char)
    <4c>   DW_AT_name        : (indirect string, offset: 0x64): signed char 
 <1><50>: Abbrev Number: 2 (DW_TAG_base_type)
    <51>   DW_AT_byte_size   : 2    
    <52>   DW_AT_encoding    : 5    (signed)
    <53>   DW_AT_name        : (indirect string, offset: 0xf1): short int   
 <1><57>: Abbrev Number: 3 (DW_TAG_base_type)
    <58>   DW_AT_byte_size   : 4    
    <59>   DW_AT_encoding    : 5    (signed)
    <5a>   DW_AT_name        : int  
 <1><5e>: Abbrev Number: 2 (DW_TAG_base_type)
    <5f>   DW_AT_byte_size   : 8    
    <60>   DW_AT_encoding    : 5    (signed)
    <61>   DW_AT_name        : (indirect string, offset: 0x75): long int    
 <1><65>: Abbrev Number: 2 (DW_TAG_base_type)
    <66>   DW_AT_byte_size   : 8    
    <67>   DW_AT_encoding    : 7    (unsigned)
    <68>   DW_AT_name        : (indirect string, offset: 0xfb): sizetype    
 <1><6c>: Abbrev Number: 2 (DW_TAG_base_type)
    <6d>   DW_AT_byte_size   : 1    
    <6e>   DW_AT_encoding    : 6    (signed char)
    <6f>   DW_AT_name        : (indirect string, offset: 0x6b): char    
 <1><73>: Abbrev Number: 4 (DW_TAG_subprogram)
    <74>   DW_AT_external    : 1    
    <74>   DW_AT_name        : (indirect string, offset: 0x59): do_stuff    
    <78>   DW_AT_decl_file   : 1    
    <79>   DW_AT_decl_line   : 2    
    <7a>   DW_AT_prototyped  : 1    
    <7a>   DW_AT_low_pc      : 0x40052d 
    <82>   DW_AT_high_pc     : 0x3f 
    <8a>   DW_AT_frame_base  : 1 byte block: 9c     (DW_OP_call_frame_cfa)
    <8c>   DW_AT_GNU_all_tail_call_sites: 1 
    <8c>   DW_AT_sibling     : <0xb9>   
 <2><90>: Abbrev Number: 5 (DW_TAG_formal_parameter)
    <91>   DW_AT_name        : (indirect string, offset: 0xd7): my_arg  
    <95>   DW_AT_decl_file   : 1    
    <96>   DW_AT_decl_line   : 2    
    <97>   DW_AT_type        : <0x57>   
    <9b>   DW_AT_location    : 2 byte block: 91 5c  (DW_OP_fbreg: -36)
 <2><9e>: Abbrev Number: 6 (DW_TAG_variable)
    <9f>   DW_AT_name        : (indirect string, offset: 0x3e): my_local    
    <a3>   DW_AT_decl_file   : 1    
    <a4>   DW_AT_decl_line   : 3    
    <a5>   DW_AT_type        : <0x57>   
    <a9>   DW_AT_location    : 2 byte block: 91 6c  (DW_OP_fbreg: -20)
 <2><ac>: Abbrev Number: 7 (DW_TAG_variable)
    <ad>   DW_AT_name        : i    
    <af>   DW_AT_decl_file   : 1    
    <b0>   DW_AT_decl_line   : 4    
    <b1>   DW_AT_type        : <0x57>   
    <b5>   DW_AT_location    : 2 byte block: 91 68  (DW_OP_fbreg: -24)
 <2><b8>: Abbrev Number: 0
 <1><b9>: Abbrev Number: 8 (DW_TAG_subprogram)
    <ba>   DW_AT_external    : 1    
    <ba>   DW_AT_name        : (indirect string, offset: 0x70): main    
    <be>   DW_AT_decl_file   : 1    
    <bf>   DW_AT_decl_line   : 9    
    <c0>   DW_AT_type        : <0x57>   
    <c4>   DW_AT_low_pc      : 0x40056c 
    <cc>   DW_AT_high_pc     : 0x15 
    <d4>   DW_AT_frame_base  : 1 byte block: 9c     (DW_OP_call_frame_cfa)
    <d6>   DW_AT_GNU_all_tail_call_sites: 1 
 <1><d6>: Abbrev Number: 0

我想做的是:-

  1. 我想检索变量的地址,比如 my_local。首先,我将查看 DW_TAG_Variable,然后是 DW_AT_name,DW_AT_location,这是由基址寄存器在函数 -20 从顶部给出的。

问题: 如何知道运行时基址寄存器的内容。 我们可以使用 PinTool 实现它吗?

广义的问题: 我想要变量 my_local 映射到内存中给定来自 dwarf 和 Pintool 的信息的地址。

提前致谢。

您应该可以使用 Pin 的 SafeCopy 功能访问应用程序内存并将其复制到 pintool 内存中。

但是正如评论中指出的那样,并非总是能够可靠地知道变量值存储在何处,因此请记住这一点。