그래서 objdump 유틸리티를 사용하여 어셈블리에서 제어 흐름 그래프를 작성하려고하는데 문제가 있습니다. 기본적으로 분기가 발생하고 대상 주소가 상대적 일 때마다 다음 기본 블록이 시작되는 위치를 알 수있는 방법을 모르겠습니다. 내가 확실한 지 모르겠다. 그래서 나는 예제를 추가 할 것이다. 내 프로그램이 objdump 출력을 통해 진행 중이며 첫 번째 기본 블록의 시작 주소를 기록했다고 가정 해보십시오. 그런 다음 상대 주소 지정을 사용하여 점프 할 올바른 주소를 가리키는 점프 명령을 실행합니다. 첫 번째 기본 블록의 끝 부분이 바로 발생하지만 다음 기본 블록의 시작 부분에 올바른 주소를 지정하려면 어떻게해야합니까? 누구나 제공 할 수있는 지침이 있으면 크게 반가 웠습니다. 저는 x86 초보자이며, 지난 주 동안이 문제를 저지르고 있습니다.objdump를 사용할 때 레지스터 값 결정
답변
내가이 질문을 이해한다고 가정하면, 아마도 당신이 시작하게 될 것입니다. 상대 점프는 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
- 1. 스택 포인터 레지스터 값
- 2. GCC의 레지스터 값 덤프
- 3. NSUInteger 값 결정
- 4. 런타임에 사용할 속성 결정
- 5. 사용할 이미지 형식 결정
- 6. 레지스터 단축키
- 7. NSOpenPanel이 닫힐 때 결정
- 8. ProC# call을 사용할 때 자체에 값 제공
- 9. DataContractSerializer를 사용할 때 속성의 초기 값 설정
- 10. objdump를 사용하여 개체 파일의 오프셋 찾기
- 11. 명령어로드 레지스터
- 12. 레지스터 할당 알고리즘의 효율성
- 13. C 레지스터 호출 규칙
- 14. 리얼 모드에서 32 비트 레지스터/명령어를 사용할 수 있습니까?
- 15. 팩토리 대리자가있는 레지스터 유형
- 16. GCC 레지스터 최적화
- 17. 일반 목적 레지스터
- 18. 일련의 바이트에 사용할 최상의 압축 알고리즘 결정
- 19. 배열 색인으로 80x86 레지스터 사용
- 20. 레지스터 할당을위한 간섭 그래프 구성
- 21. C90 - C99 : 레지스터 구조체
- 22. 레지스터 관리 팁
- 23. PHP 레지스터 시스템
- 24. MXCSR 제어 레지스터 범위?
- 25. vim에서 레지스터 결합하기
- 26. MIPS $ gp 레지스터
- 27. 결정
- 28. 결정
- 29. 다른 VIM 탭과 동일한 레지스터
- 30. sparc 어셈블리 및 % y 레지스터
감사합니다. 내 문제가 많이 해결되었습니다. 기본적으로 나는 objdump 출력을 완전히 이해하지 못하는 것처럼 보입니다. 누구 objdump 출력에 대한 자세한 내용은 좋은 리소스를 알고 있습니까? – Sam
일부 출력물을 다시 읽으므로이 점이 분명히 명확 해집니다. 나는 아직도 이렇게 선에 대해 확신하지 못한다 : 4020a6 : \t ff 25 4c 8f 21 00 jmpq * 0x218f4c (% 립) # 61aff8 <_fini + 0x207840> 기본적으로 objdump 출력을 완전히 이해하지 못하는 것처럼 보입니다. 나도 같이 일하고있어. 누구 objdump 출력에 대한 자세한 내용은 좋은 리소스를 알고 있습니까? – Sam
당신이 찾고있는 것은 x86 어셈블러가 반드시 objdump 일 필요는 없다는 것을 이해하는 것이라고 말하고 싶습니다. 해당 특정 명령어에 대한 opcode가 나에게 뛰어 오르는 것은 아닙니다 (말장난 의도는 없습니다).하지만 구문은 레지스터 기반의 것임을 의미합니다. 즉, 대상 주소가 런타임시 % rip의 내용과 관련이 있다는 것을 의미합니다. 점프 기본적으로 테이블.그리고이 코드를 실행하지 않고 검사 만하기 때문에 % rip의 내용이 무엇인지 명확하지 않을 수 있으며 결과적으로 대상 주소가 무엇인지 파악하지 못할 수도 있습니다. –