2012-04-17 63 views

回答

3

我想知道是否有辦法看到什麼是存儲在-0x10(%ebp)。

假設你已經編譯了調試信息,info locals會告訴你當前幀中的所有局部變量。之後,print (char*)&a_local - (char*)$ebp會告訴你從a_local開始到%ebp的偏移量,你通常可以找出本地接近0x176的地方。

另外,如果你的本地人有初始值設定項,你可以做info line NN來找出哪個彙編指令範圍對應給定本地的初始化,然後disas ADDR0,ADDR1看到反彙編,再次理解哪個本地位於哪個偏移處。

另一種方法是readelf -w a.out,尋找這樣的條目:

int foo(int x) { int a = x; int b = x + 1; return b - a; } 

<1><25>: Abbrev Number: 2 (DW_TAG_subprogram) 
<26> DW_AT_external : 1   
<27> DW_AT_name  : foo  
<2b> DW_AT_decl_file : 1   
<2c> DW_AT_decl_line : 1   
<2d> DW_AT_prototyped : 1   
<2e> DW_AT_type  : <0x67> 
<32> DW_AT_low_pc  : 0x0  
<36> DW_AT_high_pc  : 0x23  
<3a> DW_AT_frame_base : 0x0  (location list) 
<3e> DW_AT_sibling  : <0x67> 
<2><42>: Abbrev Number: 3 (DW_TAG_formal_parameter) 
<43> DW_AT_name  : x   
<45> DW_AT_decl_file : 1   
<46> DW_AT_decl_line : 1   
<47> DW_AT_type  : <0x67> 
<4b> DW_AT_location : 2 byte block: 91 0  (DW_OP_fbreg: 0) 
<2><4e>: Abbrev Number: 4 (DW_TAG_variable) 
<4f> DW_AT_name  : a   
<51> DW_AT_decl_file : 1   
<52> DW_AT_decl_line : 1   
<53> DW_AT_type  : <0x67> 
<57> DW_AT_location : 2 byte block: 91 74  (DW_OP_fbreg: -12) 
<2><5a>: Abbrev Number: 4 (DW_TAG_variable) 
<5b> DW_AT_name  : b   
<5d> DW_AT_decl_file : 1   
<5e> DW_AT_decl_line : 1   
<5f> DW_AT_type  : <0x67> 
<63> DW_AT_location : 2 byte block: 91 70  (DW_OP_fbreg: -16) 

這就告訴你,x存儲在fbreg+0afbreg-12,並在bfbreg-16。現在你只需要檢查位置列表來找出如何從%ebp派生fbreg。對於上面的代碼清單如下:

Contents of the .debug_loc section: 

Offset Begin End  Expression 
00000000 00000000 00000001 (DW_OP_breg4: 4) 
00000000 00000001 00000003 (DW_OP_breg4: 8) 
00000000 00000003 00000023 (DW_OP_breg5: 8) 
00000000 <End of list> 

因此,對於身體的大部分,fbreg%ebp+8,這意味着a%ebp-4。拆卸確認:

00000000 <foo>: 
    0: 55      push %ebp 
    1: 89 e5     mov %esp,%ebp 
    3: 83 ec 10    sub $0x10,%esp 
    6: 8b 45 08    mov 0x8(%ebp),%eax # 'x' => %eax 
    9: 89 45 fc    mov %eax,-0x4(%ebp) # '%eax' => 'a' 

...