5

iOS 태그가 포함되어 있지만 코어 i7 MacBook Pro (x86-64, 오른쪽?)의 시뮬레이터에서 실행 중이므로 중요하지 않습니다.범용 레지스터의 내용에는 무엇이 들어 있습니까?

현재 Flurry의 동영상 광고에서 크래시를 디버깅하고 있습니다. Objective-C 예외에 설정된 중단 점이 있습니다. 중단 점에 도달하면 objc_msgSend에 있습니다. 콜 스택에는 개인 Flurry 및 iOS 메소드가 포함되어 있으며 공개 된 것은 없으며 필자가 작성한 것도 없습니다. 다음은 objc_msgSend 스택 프레임 출력에서 ​​register read를 호출 :

(lldb) register read 
General Purpose Registers: 
     eax = 0x1ac082d0 
     ebx = 0x009600b5 "spaceWillDismiss:interstitial:" 
     ecx = 0x03e2cddb "makeKeyAndVisible" 
     edx = 0x0000003f 
     edi = 0x0097c6f3 "removeWindow" 
     esi = 0x00781e65 App`-[FlurryAdViewController removeWindow] + 12 
     ebp = 0xbfffd608 
     esp = 0xbfffd5e8 
     ss = 0x00000023 
    eflags = 0x00010202 App`-[FeedTableCell setupVisibleCommentAndLike] + 1778 at FeedTableCell.m:424 
     eip = 0x049bd09b libobjc.A.dylib`objc_msgSend + 15 
     cs = 0x0000001b 
     ds = 0x00000023 
     es = 0x00000023 
     fs = 0x00000000 
     gs = 0x0000000f 

나는이 출력에 대한 몇 가지 질문 있어요.

  • 나는 $ ebx에 크래시를 일으킨 선택기가 있고 $ edi가 마지막 실행 방법이라고 가정했습니다. 그럴까요?
  • $ eip은 내가 추락 한 곳입니다. 대개 그런 경우입니까?
  • $ eflags는 내가 아는 한이 충돌과 관련이없는 인스턴스 메서드를 참조합니다. 그게 뭐야?
  • 이 레지스터에서 캐어 수있는 다른 정보가 있습니까?

답변

1

iOS/Objective-C 프레임 레이아웃을 구체적으로 말할 수 없으므로 EBX 및 EDI에 관한 질문에 답변 할 수 없습니다. 하지만 EIP와 EFLAGS에 관해 당신을 도울 수 있고 ESP/EBP와 선택기 레지스터에 대한 일반적인 힌트를 줄 수 있습니다. (그런데, 시뮬레이터는 32 비트 x86 환경을 시뮬레이션한다, 당신의 레지스터는 32 비트 길이 때문에 말할 수 있습니다.)

EIP는 포함되어 또한 프로그램 카운터로 알려진 instruction pointer 레지스터이다 현재 실행중인 기계 명령어의 주소. 따라서 프로그램이 중단되거나보다 일반적으로 프로그램이 중단 점에 도달하거나 코어가 덤프되는 지점을 가리 킵니다.

EIP가 저장되고 복원되어 함수 호출을 구현합니다 (시스템 코드 수준에서 - 인라인 실제 통화를 수행하지 않는 고급 언어 호출이 발생할 수 있음). 메모리가 안전하지 않은 언어에서는 스택 버퍼 오버플로가 저장된 명령 포인터 값을 덮어 쓸 수 있으므로 반환 명령이 잘못된 위치로 돌아갑니다. 운이 좋으면 덮어 쓰여진 값이 다음 메모리 페치에서 세그 폴트를 유발하지만 EIP의 값은 임의적이며 문제를 디버깅하는 데 도움이되지 않습니다. 불행한 경우 공격자가 새로운 EIP를 만들어 유용한 코드를 가리 키도록 만들었습니다. 따라서 많은 환경에서 저장된/덮어 쓰기 된 EIP를 복원하기 전에 "스택 쿠키"또는 "카나리아"를 사용하여 이러한 덮어 쓰기를 검색합니다.이 경우 EIP 값은 유능한.

EFLAGS은 메모리 주소가 아니며 아마도 범용 레지스터가 아닙니다. EFLAGS의 각 비트는 다양한 명령어로 설정하거나 테스트 할 수있는 플래그입니다. 가장 중요한 플래그는 carry, zero 및 sign 플래그이며, 산술 명령어로 설정되고 조건부 분기에 사용됩니다. 디버거가 메모리 주소로 잘못 해석하여 가장 가까운 기능으로 표시하지만 실제로 충돌과 관련이 없습니다. (+ 1778은 공짜입니다 : 이것은 EFLAGS가 1778 바이트를 가리키는 것을 의미하지만 실제로 1778 바이트 길이는 아닙니다.)

ESP는 스택 포인터이고 EBP는 (일반적으로) 프레임 포인터입니다 기본 포인터라고 함). 이 레지스터는 호출 스택의 현재 프레임을 바인딩합니다. 디버거는 대개이 포인터를 기반으로 스택 변수 및 현재 호출 스택의 값을 표시 할 수 있습니다. 손상된 경우 스택을 수동으로 검사하여 EBP를 복구하고 수동으로 호출 스택을 풀 수 있습니다.코드는 프레임 포인터 (프레임 포인터 누락)없이 컴파일되어 다른 용도로 EBP를 확보 할 수 있습니다. x86에는 공통적인데, 그 이유는 범용 레지스터가 너무 적기 때문입니다.

SS, CS, DS, ES, FS 및 GS 홀드 세그먼트 선택자는 segmentation을 구현하기 위해 페이징 이전의 나쁜 옛날에 사용되었습니다. 오늘날 FS 및 GS는 프로세스 및 스레드 상태 블록에 대해 운영 체제에서 일반적으로 사용됩니다. 이들은 x86-64로 이월 된 유일한 선택기 레지스터였습니다. 선택기 레지스터는 일반적으로 디버깅에 유용하지 않습니다.

관련 문제