2014-09-18 16 views
2

필자는 함수의 프롤로그가 끝나고 에필로그가 시작되는 주소를 정확하게 찾아야하는 ARM 바이너리를 가지고 있습니다. 즉, 함수 본문의 경계가 필요합니다. 내가 누구의 조립 기능이있는 경우 예를 들어, 같은 것입니다 :DWARF - 주어진 바이너리에서 함수의 프롤로그 끝/끝점 시작 주소를 찾는 방법은 무엇입니까?

0x00000320 <+0>: push {r7, lr} 
0x00000322 <+2>: sub sp, #16 
0x00000324 <+4>: add r7, sp, #0 
0x00000326 <+6>: str r0, [r7, #4] 
0x00000328 <+8>: (Function body starts here) 
... 
0x0000034c <+44>: (Function body ends here) 
0x0000034e <+46>: mov sp, r7 
0x00000350 <+48>: pop {r7, pc} 

내가 빨리 찾을 수있는 방법이 필요 하나 0x000003260x0000034e (프롤로그 끝/에필로그 시작) 또는 0x000003280x0000034c (함수 본문의 시작/끝) readelf 또는 objdump와 같은 것을 사용합니다. 단순히 해체하고 코드를 검사하지 않아도됩니다 (이상적으로는 readelf 또는 DWARF 정보를 얻기 위해 사용하는 프로그램의 출력을 구문 분석하는 스크립트를 사용하는 것이 이상적입니다).

DWARF 4 표준에 따르면 .debug_line 섹션에는 "prologue_end"및 "epilogue_begin"이 포함 된 줄 번호 정보가 있는데 이는 필자에게 필요한 정보입니다. 그러나 arm-linux-readelf --debug-dump=rawline,decodedline의 출력은 그 정보를 제공하지 않습니다.

-ggdb3 플래그가있는 gcc 4.8.2을 사용하여 컴파일 중입니다.

편집 : 좀 더 정보가 : objdump를하고 readelf 모두가 나에게 이런 식으로 뭔가 보여

Line Number Statements: 
[0x00000074] Extended opcode 2: set Address to 0x100 
[0x0000007b] Advance Line by 302 to 303 
[0x0000007e] Copy 
[0x0000007f] Special opcode 34: advance Address by 4 to 0x104 and Line by 1 to 304 
[0x00000080] Special opcode 34: advance Address by 4 to 0x108 and Line by 1 to 305 
[0x00000081] Special opcode 37: advance Address by 4 to 0x10c and Line by 4 to 309 
[0x00000082] Special opcode 34: advance Address by 4 to 0x110 and Line by 1 to 310 
[0x00000083] Special opcode 20: advance Address by 2 to 0x112 and Line by 1 to 311 
[0x00000084] Special opcode 37: advance Address by 4 to 0x116 and Line by 4 to 315 
[0x00000085] Special opcode 34: advance Address by 4 to 0x11a and Line by 1 to 316 
[0x00000086] Advance Line by -13 to 303 
[0x00000088] Special opcode 19: advance Address by 2 to 0x11c and Line by 0 to 303 
[0x00000089] Special opcode 34: advance Address by 4 to 0x120 and Line by 1 to 304 
[0x0000008a] Advance PC by 4 to 0x124 
[0x0000008c] Extended opcode 1: End of Sequence 

은 바이너리 유틸리티 'dwarf.c의 소스를보고, prologue_end 설정 "과 같은 인쇄해야한다는 것 true "로 설정하고"epilogue_begin을 true로 설정 "합니다. 그러나 모든 opcode는 표준이 아닌 특수한 것으로 보입니다.

+0

"clang-3.6 -gdwarf-4 -g3"으로 컴파일 할 가치가있는 경우 "Set prologue_end true"가됩니다. DWARF 정보 : GCC가 이것을 생성 할 수없는 것 같습니다 (아직?). – ysdx

답변

0

readelf -wi 

을 시도하고 당신이보고있는 서브 루틴 DW_AT_low_pc 및 DW_AT_high_pc를 찾습니다.

드워프 스펙 말한다

서브 루틴 항목 속성 DW_AT_low_pc 및 DW_AT_high_pc 쌍 또는 DW_AT_ranges 어느 기계 명령어 각각 값을 가진 연속 또는 비 연속적인 어드레스 범위를 인코딩 속성을 가질 수있다 서브 루틴을 위해 생성됩니다 (2.17 절 참조).

정확하게 기억하면 DW_AT_low_pc는 프롤로그 직후의 주소이고 DW_AT_high_pc는 에필로그 전의 마지막 주소입니다.

opcode가 'special'인 것에 대해 걱정하지 마십시오. 단지 인코딩 된 줄 번호 프로그램의 공간을 절약하기 위해 인수를 사용하지 않는다는 의미입니다.

+0

불행히도 DW_AT_low_pc는 서브 루틴의 첫 번째 명령어 (즉 첫 번째 프롤로그 명령어)의 주소와 일치하는 것으로 보이며 DW_AT_high_pc는 마지막 에필로그 명령어를 따르는 명령어의 오프셋 인 것으로 보입니다. – Martin