C 문자 배열이 있다고 가정 해보십시오 char buf[15]
. variable int set_me = 0
의 데이터가 바로 뒤에 메모리 위치에 저장되어 있다고 가정 해보십시오 char buf[15]
. 나는이 초과하면 buf
문자열로 "aaabbbcccdddeee\xef\xbe\xad\xde"
, 것 set_me
문자 배열의 정수에서의 데이터 형식 변경을?
답변
아니.
변수의 “데이터 유형”은 소스 코드와 관련이 있으며 심지어 일부 언어에서만 관련이 있습니다. 변수를 처리하는 방법을 컴파일러에 알려줍니다.
이러한 고급 데이터 유형은 컴파일 된 (네이티브) 코드에 존재하지 않습니다. 컴파일러가 생성하는 명령어에 영향을 줄 수 있지만, 명령어 자체는 데이터가 문자 또는 숫자를 나타내는 지 상관하지 않습니다.
하드웨어에 변수가 없습니다. 하드웨어에는 메모리 위치와 그에 대한 지침이 있습니다.
변수 는 메모리 위치에서 데이터 의 보기 로 볼 수 있습니다 . 같은 메모리를 약간 다르게 보았을 때 (같은 위치를 참조하는 다른 유형의 다른 변수) 동일한 이진 값이 다른 의미를 가질 수 있습니다 .
예를 들어 바이트 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
-272716322
uint
4022250974
1 보호 된 메모리 영역에 쓰지 못하게하는 메커니즘이 있으며, 그렇게하면 프로그램이 중단됩니다.
2 x86은 실제로 리틀 엔디안이므로 바이트 값을 크게 구성하는 바이트를 해석합니다. 따라서 x86 0xDEADBEEF
에서는 대신 부호있는 -559038737
또는 부호없는 것을 제공 3735928559
합니다.
답변
C의 관점에서 대답은 “누가 아는가? 정의되지 않은 행동”입니다.
유형은 하드웨어가 아니라 C 개념입니다. 그러나 프로그램에 정의되지 않은 동작이있는 경우 C 규칙이 적용되지 않습니다. 이는 C 표준에서 정의되지 않은 동작의 문자 적 의미입니다. 버퍼 오버플로는 그 중 하나입니다.
나는 처음에 “C 규칙은 더 이상 적용되지 않는다”라고 썼지 만, 실제로 정의되지 않은 행동은 소급 적입니다. C 규칙은 향후에 정의되지 않은 동작이있는 프로그램에는 적용되지 않습니다.