2011-04-20 2 views
0

가능한 중복은 : 버퍼 오버 플로우 (반환 주소)


how to skip a line doing a buffer overflow in c

내가 RHEL5에서 GDB를 사용하여 main() 기능을 분해. 기본적으로 코드의 다른 명령어로 리턴 주소를 변경하려고합니다.

시나리오 :

function(int a,int b) 
{ 
    char buffer[16]; 
    //some operations here.. 
} 

int main() 
{ 
    int x = 12; 
    int y =13; 
    int p ; 

    function(x,y); 

    p = 100; 

    printf("%d",p); 
} 

내가 P = 100을 건너 뛸와의 printf 호출에 이동합니다.! GDB에서 함수 호출의 주소를 검사합니다. > 0x080 ..... 뭔가 - main()function()의 주소의

something --> 0x0804827b 

범위.

그러나 프로그램에서 변수의 주소를 &a을 사용하여 얻으려고 할 때 16 진수 주소는 0xbfeca ...와 같습니다.

왜 그렇습니까? 나는 그 이유를 알지 못해서 반송 주소를 얻거나 반송 주소를 변경할 수조차 못했습니다. 어떻게해야합니까? 그 이유는 무엇일까요?

+0

아마도 ** [이 답변] (http://stackoverflow.com/questions/5280789/how-to-skip-a-line-doing-a-buffer-overflow-in-c/5571224#5571224) * * to * [c에서 버퍼 오버플로를 수행하는 행을 건너 뛰는 방법] (http://stackoverflow.com/q/5280789/203667) * 일부 사용이 가능할 수 있습니다. – jschmier

답변

1

a 변수가 스택에 배치됩니다. 이것은 기능하기위한 지역 변수입니다. 반송 주소도 스택에 저장됩니다.

주소 0xbf ...... 스택 및 주소 0x080에 일반적입니다 ..... 코드 섹션에 일반적입니다.

반송 주소를 바꾸려면 &a 부근의 메모리 (예 : gdb)를 검사하여 반송 주소 (0x080 .....와 같은 주소 여야 함)를 찾아야합니다. 그런 다음 그것을 대체 할 수 있습니다.

0

MSVC에서 건너 뛸 지침의 크기를 추가하여 반송 주소를 변경하는 데 사용할 수있는 _AddressOfReturnAddress (GCC 해당 사항 없음 *) 내장 함수가 있습니다. 그러나 이 cdecl 기능에 대해 실패하거나 순서가 재 지정되는 경우 실패합니다. 또한 당신의 경우에, p = 100;은 최적화 될 것입니다.

TBH와 같은 것은 매우 상황이 좋으며 아마도 '방문 사이트'에 맞춤 어셈블리를 작성해야 할 것입니다. 귀하의 경우 최선의 선택은 목표를 무조건적인 점프로 바꾸는 것입니다.

* 그러나 시스템 (ITS ABI)에 운영 및 사용하는 호출 규칙에 따라, 당신은 사용할 수 있습니다

void* pAddressOfReturn = (&a) - sizeof(void*); 

기능이 __stdcall 또는 __cdecl입니다.