2010-11-30 4 views
6

그래서 objdump 유틸리티를 사용하여 어셈블리에서 제어 흐름 그래프를 작성하려고하는데 문제가 있습니다. 기본적으로 분기가 발생하고 대상 주소가 상대적 일 때마다 다음 기본 블록이 시작되는 위치를 알 수있는 방법을 모르겠습니다. 내가 확실한 지 모르겠다. 그래서 나는 예제를 추가 할 것이다. 내 프로그램이 objdump 출력을 통해 진행 중이며 첫 번째 기본 블록의 시작 주소를 기록했다고 가정 해보십시오. 그런 다음 상대 주소 지정을 사용하여 점프 할 올바른 주소를 가리키는 점프 명령을 실행합니다. 첫 번째 기본 블록의 끝 부분이 바로 발생하지만 다음 기본 블록의 시작 부분에 올바른 주소를 지정하려면 어떻게해야합니까? 누구나 제공 할 수있는 지침이 있으면 크게 반가 웠습니다. 저는 x86 초보자이며, 지난 주 동안이 문제를 저지르고 있습니다.objdump를 사용할 때 레지스터 값 결정

답변

4

내가이 질문을 이해한다고 가정하면, 아마도 당신이 시작하게 될 것입니다. 상대 점프는 pc 기반입니다.

 
d: eb 04 jmp 13 

0xEB는 8 비트 즉치에 기반한 상대 점프를위한 opcode입니다. 명령의 주소는 objdump 출력에 있으며이 경우에는 d ​​또는 0xD입니다. 그것은 2 바이트 명령어입니다 (x86은 가변 길이입니다). 출력에서 대상 주소 (이 경우 jmp 13)를 알려줍니다. 따라서 13으로 시작하고 콜론 (:)으로 시작하는 objdump 출력의 행을 찾으려면 다음 번 코드 조각의 시작 부분입니다.

주소 계산 방법을 이해해야합니다. PC는 명령을 가져 오기 시작할 때 0xD에 있으며 2 바이트를 필요로하므로이 명령을 실행할 준비가되면 0xD + 2 = 0xF에 있습니다. 오프셋은 0x4이므로 대상 주소는 0xF + ​​0x4 = 0x13입니다.

 
20: 75 ed jne f 

이전과 동일합니다. PC와 바이트 수 = 0x20 + 2 = 0x22. 0xED는 부호있는 숫자이며 음수이므로 부호는 0xEDFF 0xFFFFFFF ... FFFFED로 확장되지만 주소록은 크지 만. 0x22 + 0xFFFFFF ... FFFED를 추가하면 대상 주소가 0x0F가됩니다. 또한 0xED를 사용하고 반전하고 1을 추가하여이를 무효화 할 수 있습니다. ~ 0xED = 0x12, 0x12 + 1 = 0x13. 따라서 0xED는 0x13을 뺍니다. 0x22-0x13 = 0x0F.

여기에 더 많은 내용이 있습니다. 각각의 경우에 objdump 출력에서 ​​찾을 수있는 대상 주소를 제공합니다.

이 값을 계산하는 방법을 이해해야합니다. 같은 이야기입니다. 0x400A81에서 opcode로 시작합니다.이 경우 가변 길이 명령어의 경우 6 바이트가 필요합니다. 따라서 PC를 실행할 준비가 될 때까지는 0x400A81 + 6 = 0x400A87입니다. 오프셋은 0x107이므로 조건이 충족되면 대상 주소는 0x400A87 + 0x107 = 0x400B8E입니다.

이러한 것들은 순차적 코드가 아니라 더 큰 프로그램에서 따온 것입니다. 단지 고립 된 예제 모음 일뿐입니다.

 
    400a81: 0f 8f 07 01 00 00  jg  400b8e 
    400a8f: 0f 8f e6 00 00 00  jg  400b7b 
    400a9d: 0f 8f c5 00 00 00  jg  400b68 
    400aab: 0f 8f a4 00 00 00  jg  400b55 
    400ab9: 0f 8f 83 00 00 00  jg  400b42 
    401d76: 0f 8f 31 01 00 00  jg  401ead 
+0

감사합니다. 내 문제가 많이 해결되었습니다. 기본적으로 나는 objdump 출력을 완전히 이해하지 못하는 것처럼 보입니다. 누구 objdump 출력에 대한 자세한 내용은 좋은 리소스를 알고 있습니까? – Sam

+0

일부 출력물을 다시 읽으므로이 점이 분명히 명확 해집니다. 나는 아직도 이렇게 선에 대해 확신하지 못한다 : 4020a6 : \t ff 25 4c 8f 21 00 jmpq * 0x218f4c (% 립) # 61aff8 <_fini + 0x207840> 기본적으로 objdump 출력을 완전히 이해하지 못하는 것처럼 보입니다. 나도 같이 일하고있어. 누구 objdump 출력에 대한 자세한 내용은 좋은 리소스를 알고 있습니까? – Sam

+0

당신이 찾고있는 것은 x86 어셈블러가 반드시 objdump 일 필요는 없다는 것을 이해하는 것이라고 말하고 싶습니다. 해당 특정 명령어에 대한 opcode가 나에게 뛰어 오르는 것은 아닙니다 (말장난 의도는 없습니다).하지만 구문은 레지스터 기반의 것임을 의미합니다. 즉, 대상 주소가 런타임시 % rip의 내용과 관련이 있다는 것을 의미합니다. 점프 기본적으로 테이블.그리고이 코드를 실행하지 않고 검사 만하기 때문에 % rip의 내용이 무엇인지 명확하지 않을 수 있으며 결과적으로 대상 주소가 무엇인지 파악하지 못할 수도 있습니다. –