2012-06-18 5 views
1

Cortex-M3 임베디드 마이크로 컨트롤러 (Atmel SAM3S) IAR EWARM IDE & 컴파일러를 사용하는 소프트웨어를 개발 중입니다. 어떤 이유로 버퍼 오버플로가 발생하거나 스택이 손상 될 수있는 메모리 누수가있는 것으로 의심됩니다. 갑자기 자신이 내 코드 공간 밖에 갇혀 있기 때문입니다.스택 덮어 쓰기 오류 감지

내가이 질문을하는 이유는이 혼란을 실제로 일으킨 것이 무엇인지 알아내는 것이고 문제의 원인을 찾으려 할 때 어떤 기술을 사용하고 있는지 알고 싶습니다.

답변

2

프로그램 카운터는 레지스터 및 등이 "덮어 쓰기"가 될 수없는 등의 회로 트레이스 디버깅 하드웨어, 메모리 디버거를 사용하면이다. 스택이 덮어 쓰여진 다음 스택에서 잘못된 반환 주소를 읽는 반환 명령을 실행하여 라라 땅으로 점프하게됩니다.

내가 가장 좋아하는 디버깅 방법은 포함 된 타겟에서 어려울 수있는 것들을 인쇄하는 것입니다. 차선책은 용의자 루틴을 밟을 것입니다.

또한 인터럽트 서비스 루틴과 같이 점프를 유발하는 것으로 조사해야합니다.

+0

PC에 관해서는 정확합니다. 제 질문을 수정하겠습니다. – stdcall

4

카나리아 값을 사용해보십시오. 그것은 다음과 같습니다 있도록

struct foo { 
    unsigned long bar; 
    void * baz; 
}; 

를 수정 : -이 그것은 기본적으로 어떻게되는지 당신이 어떤 struct이 있다고 가정하면 struct를 초기화하면

struct foo { 
    unsigned long canary1; 
    unsigned long bar; 
    void * baz; 
    unsigned long canary2; 
}; 

canary1canary2에 어떤 임의의 값을 넣어. struct에서 일부 작업을 수행 할 때마다 값이 동일하게 유지되는지 확인하십시오. 이렇게하면 버퍼 오버 플로우 나 스택 스매싱이 발생하면이를 감지 할 수 있습니다. 자동 변수를 사용하여 동일한 내부 함수를 수행 할 수 있습니다.

int foo(int bar) { 
     unsigned long canary1 = 0xDEADBABE; 
     char baz[20]; 
     unsigned long canary2 = 0xBAD0C0DE; 
     ... 
} 

등등. return 전에 값이 동일하게 유지되는지 확인하는 것을 잊지 마십시오. 또한 코드가 일관되게 같은 위치로 점프 할 수 있다면 코드 (또는 중단 점)를 넣고 스택 추적을 얻으십시오.

GCC는 이러한 카나리아 값을 추가하는 방법을 알고 있지만 컴파일러가이를 수행 할 수 있는지 여부는 알지 못합니다. 그러나 당신은 여전히 ​​그것을 수동으로 할 수 있습니다.

+0

우리는 데이터의 끝에 "마스터"카나리아 값을 배치하고 bss (스택은 마지막에서 뒤로 자랍니다)와 비슷한 것을합니다. 시작시 값을 초기화하고 스택 오버플로 또는 임의 쓰기의 경우 지속적으로 값을 확인합니다. – shenles

2

STM32에서 IAR EWARM을 사용하여 비슷한 문제가 발생했습니다. 메모리 덤프, 해체, 카나리아, 모두 아무것도 나타나지 않았다. 마지막으로 EWARM의 이전 버전으로 롤백되고 문제가 사라졌습니다. IAR 지원팀에 메시지를 보냈지 만 회신을받지 못했습니다. 이 버전의 EWARM 버전을 기억하지 못해 죄송합니다. 몇 가지 프로젝트가있었습니다.

저는 메모리 창을 열어두고 카나리아 테스트를 먼저 시도합니다. 코드 공간에서 임의로 점프하는 경우 이전 버전의 EWARM을 설치하십시오.

1

내가 추가 할 수있는 한 가지 사항은 ARM 칩을 사용하면 BX 또는 BLX 대신 BL을 사용하여 칩을 잘못된 Thumb/ARM 모드로 전환시킬 수 있다는 것입니다. 나중의 칩과 마찬가지로 일반적이지는 않지만 여전히 ...

아무 곳에도 점프를 찾지 못하면 잘못된 함수 포인터 테이블, 모든 인터럽트 벡터 테이블 덮어 쓰기 및 테스트하기 가장 쉬운 스택 오버플로를 찾습니다. 알려진 바이트 값을 스택 영역에 놓고 충돌이 발생하면 디버거로 남아있는 스택의 양을 확인하십시오. 아무도 없다면 거기에 가세요.

나는 또한 표준을 사용하여 마지막 X 일간에 변경된 사항을 확인하여 문제를 찾아냅니다. 마지막으로 코드에서 printf를 실행하여 잘못된 점프가 발생하는 곳을 좁히십시오. 함수 또는 두 개로 줄일 수 있다면 어셈블러를 추적하여 컴파일러 문제, 메모리 문제 또는 인터럽트 문제가 있는지 신속하게 확인할 수 있습니다. 행운을 빕니다!