버퍼 오버 플로우가 덮어 쓰고있는 변수의 데이터 유형을 변경합니까? [닫은]


8

C 문자 배열이 있다고 가정 해보십시오 char buf[15]. variable int set_me = 0의 데이터가 바로 뒤에 메모리 위치에 저장되어 있다고 가정 해보십시오 char buf[15]. 나는이 초과하면 buf문자열로 "aaabbbcccdddeee\xef\xbe\xad\xde", 것 set_me문자 배열의 정수에서의 데이터 형식 변경을?


3
누가 데이터를 해석하고 있는지에 따라 다릅니다. 마침내 모든 것이 이진입니다. 그래서 당신이 그것을 해석하는 방식으로, 그것은 유효한 정수 값이거나 캐스트 에러를 일으킬 수 있습니다
Ganesh R.

답변:


33

아니.

변수의 "데이터 유형"은 소스 코드와 관련이 있으며 심지어 일부 언어에서만 관련이 있습니다. 변수를 처리하는 방법을 컴파일러에 알려줍니다.

이러한 고급 데이터 유형은 컴파일 된 (네이티브) 코드에 존재하지 않습니다. 컴파일러가 생성하는 명령어에 영향을 줄 수 있지만, 명령어 자체는 데이터가 문자 또는 숫자를 나타내는 지 상관하지 않습니다.


하드웨어에 변수가 없습니다. 하드웨어에는 메모리 위치와 그에 대한 지침이 있습니다.

변수 는 메모리 위치에서 데이터 의 보기 로 볼 수 있습니다 . 같은 메모리를 약간 다르게 보았을 때 (같은 위치를 참조하는 다른 유형의 다른 변수) 동일한 이진 값이 다른 의미를 가질 수 있습니다 .

예를 들어 바이트 0x41은 UTF-8로 인코딩 된 문자로 해석 될 수 있습니다 A. 단일 바이트 integer로 해석 될 수도 있습니다 65. 또한 멀티 바이트 정수 또는 부동 소수점 숫자의 1 바이트 또는 멀티 바이트 문자 인코딩의 1 바이트로 해석 될 수도 있습니다. 비트 셋일 수 있습니다 0b1000001. 동일한 메모리 위치의 동일한 바이트에서 모두. C 언어에서는 이러한 다른 유형 으로 캐스트 하여이 효과를 볼 수 있습니다.

"버퍼 오버플로"가 발생하면 컴파일러 또는 언어가 기대할 수있는 범위를 벗어나는 작업을 수행하는 것입니다. 그러나 하드웨어에 관한 한 1 은 메모리 위치에 바이트 (단일 또는 다중)를 쓰고 있습니다. 메모리 위치에는 "유형"이 없습니다. 실제로 하드웨어는 특정 바이트 세트가 코드에서 배열이나 버퍼를 만든다는 사실조차 알지 못합니다.

다음에 코드에서 해당 메모리 위치에 액세스 할 때마다 지침이 원래 정의 된대로 실행됩니다. 그들이 거기에 숫자를 기대한다면 예를 들어, 그들은 바이트의 데이터를 어떤 조치를 취할 것 처럼 그들은 수 있었다.


예제를 사용하려면 int부호있는 4 바이트 (32 비트) 정수 라고 가정합니다 .

+-------------+--------------------------------------------+-----------+
| Source code |                  char[15]                  |    int    |
+-------------+--------------------------------------------------------+
| Memory      |61|61|61|62|62|62|63|63|63|64|64|64|65|65|65|EF|BE|AD|DE|
+-------------+--------------------------------------------------------+

이제 빅 엔디안 시스템 2를 가정하여 int메모리의 메모리 위치에 포함되어 있음을 알 수 있습니다 . 부호있는 32 비트 int 입니다. 이제 부호없는 int ( ) 와 동일한 메모리를 해석하면 대신 메모리 가 됩니다. 메모리에서 정확히 동일한 데이터의 의미는 전적으로 데이터를 보는 방법에 따라 다릅니다.0xEFBEADDE-272716322uint4022250974


1 보호 된 메모리 영역에 쓰지 못하게하는 메커니즘이 있으며, 그렇게하면 프로그램이 중단됩니다.

2 x86은 실제로 리틀 엔디안이므로 바이트 값을 크게 구성하는 바이트를 해석합니다. 따라서 x86 0xDEADBEEF에서는 대신 부호있는 -559038737또는 부호없는 것을 제공 3735928559합니다.


그래서 0xdeadbeef,에 x86 아키텍처에, 그 진수 대응보다는 메모리에 공간을 적게 걸릴 것 3735928559?
Darien Springer

2
@DarienSpringer 둘 다 4 바이트의 메모리를 사용합니다. 동일한 4 바이트 시퀀스입니다. 그것들은 메모리에서 동일합니다. 원하는 경우 메모리의 기본 2 (이진)로 간주 할 수 있습니다. 그런 다음 표시 할 때 (출력을 위해 문자열로 변환) 표시 할 기준을 선택할 수 있습니다. 16 진은 16 진, 10 진은 10 진입니다. 스트링 표현은 다른 메모리 위치에 저장되며 다른 양을 사용할 수 있습니다 메모리 (각 문자가 별도의 바이트이므로) 문자열 0xDEADBEEF 로 메모리에 저장됩니다 0x30 0x78 0x44 0x45 0x41 0x44 0x42 0x45 0x45 0x46.
Bob

5
@DarienSpringer 달리 말하면, 숫자는 기본이 무엇이든 관계없이 같은 숫자입니다. 16 진수는 이진수를 보는 편리한 (정밀한) 방법입니다. 물리적으로 이진입니다. 10 진수와 같은 사람은 숫자를 10 진수로 표시하는 경우가 더 많습니다. 그러나 디스플레이 단계에 도달 할 때까지 모든 수치 연산 (더하기, 빼기, 곱하기 등)은 메모리의 동일한 이진 데이터에서 작동합니다.
Bob

1
"당신은 INT의 메모리 위치가 지금 0xEFBEADDE 것을 볼 수있다" 나는 당신이 의도하지 않은 알고 있지만 INT가있는 말을하는지처럼 소리 : Nitpick 에서 메모리 위치 0xEFBEADDE. 아마도 그 말을 조금 바꿔보십시오. 그렇지 않으면 이것은 훌륭한 답변입니다-나는 특히 "보기"비유와 "가려운"아이디어를 좋아합니다 :)
궤도에서 가벼움 경주

@LightnessRacesinOrbit 좋은 지적입니다. 편집했습니다.
Bob

2

C의 관점에서 대답은 "누가 아는가? 정의되지 않은 행동"입니다.

유형은 하드웨어가 아니라 C 개념입니다. 그러나 프로그램에 정의되지 않은 동작이있는 경우 C 규칙이 적용되지 않습니다. 이는 C 표준에서 정의되지 않은 동작의 문자 적 ​​의미입니다. 버퍼 오버플로는 그 중 하나입니다.

나는 처음에 "C 규칙은 더 이상 적용되지 않는다"라고 썼지 만, 실제로 정의되지 않은 행동은 소급 적입니다. C 규칙은 향후에 정의되지 않은 동작이있는 프로그램에는 적용되지 않습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.