2014-11-07 3 views
-1

내가 원하는 것은 파일 범위 변수 (내 프로그램에서)를 파일 외부에서 수정할 수 없도록 보장하는 것입니다. 그래서 저는 외부 연결을 배제하기 위해 그것들을 '정적'이라고 선언합니다. 그러나이 변수가 포인터를 통해 수정할 수 없도록하고 싶습니다. C에서 주소를 계산할 수없는 파일 범위 개체를 만들 수 있습니까?

나는를 사용하여 (명시 적으로 중, 계산 될 수 없다 저장소 클래스 지정 레지스터로 선언 된 객체의 어떤 부분의

주소의 '등록'저장 클래스와 비슷한 뭔가를 원하는 단항 & 연산자) 또는 암시 적으로 (배열 이름을 포인터로 변환하여).

'register'키워드의 제한없이 (파일 범위 변수에는 사용할 수 없으며 레지스터로 선언 된 배열은 인덱싱 할 수 없습니다). 이다

,

<new-keyword> int array[SIZE] = {0}; 

int a = array[0]; /* should be valid */ 
int *p = array; /* should be INVALID */ 
p = &array[3]; /* should be INVALID */ 

이 목표를 달성 대해 갈 수있는 가장 좋은 방법은 무엇입니까

?

왜 그런 기능이 필요합니까?
사용 시나리오는 모든 수정 사항을 개인적으로 검토 할 수없는 경우에도 나중에 많은 사람들이이 파일을 수정한다는 것입니다. 나는 가능한 한 많은 잠재적 인 버그를 배제하고 싶다. 이 경우 모듈에 대한 '비공개'변수가 문서 및/또는 규율에만 의존하지 않고 그대로 유지되도록하려는 것입니다.

+3

그냥 'const'를 사용하십시오. –

+0

당신이 저장하는 어떤 것도 주소를 가지고 있다고 생각하지 않습니다. 그러나 주소를 "숨길"수 있습니다. 일종의 가상 주소를 만들거나 마스크를 적용하여 "실제"주소를 가져올 수 있습니다. – Coconop

+0

IMO : 배열에 대한 포인터를 만들 수 있으면 배열의 주소를 계산할 수 있습니다. 이는 array [0]이 (배열의 주소) + (0 * sizeof (int))에 정수의 내용을 실제로 요청하고 있기 때문입니다. – user3629249

답변

2

아니요, 그렇게 생각하지 않습니다. 적어도 깔끔하게. 그러나 귀하의 사용 사례를 완전히 이해하지 못했습니다.

개체가 static 인 경우 아무도 모듈 외부에 이름을 알지 못합니다. 따라서 아무도 &을 사용하여 주소를 알 수 없습니다.

static int array[SIZE]; 

const int * get_array(void) 
{ 
    return array; 
} 

그런 다음 경고와 함께 컴파일 :

당신이 상수 포인터로 노출하는 기능을 쓰기에 노출하고, 그것을 수정 프로그램의 다른 부분을 원하지 않는 필요한 경우

. 누군가가 const을 던지면 문제가됩니다. 당신을 가정

+0

나는'const int * arrayAlias ​​= array; '가 노출되면 트릭을 수행 할 수 있다고 생각한다. – HuStmpHrrr

+1

@HuStmpHrrr 물론, 함수는 모듈을 통해 공유되는 전역 변수보다 깨끗합니다. – unwind

+0

나는 그것을 공개하고 싶지 않다. 사실, foreign 모듈이 'my'모듈에 속한 데이터를 변경할 수있는 방법이 절대적으로 없도록하고 싶다. 외부 모듈은이 모듈의 데이터를 'extern'을 통해 액세스 할 수 있거나 b) 변수에 대한 포인터 (함수 매개 변수로 수신)를 통해 액세스 할 수있는 경우이 모듈의 데이터를 변경할 수 있습니다. 키워드 'static'을 사용하여 (a)를 배제하지만 (b)를 배제 할 수는 없습니다. 나는 문서화 된 팀 규율에 의해서만 그것을 피할 수있다. –

1

이 보안 문제에 관심을, 여기에 몇 가지 고려해야 할 :

  1. register 키워드의 목적은이 집중 될 수있는 바와 같이, 레지스터에 그 변수를 유지하기 위해 컴파일러를 추천했다 익숙한. 레지스터에 메모리 주소가 없으므로 레지스터를 가져올 수 없습니다 (키워드의 주 목적이 아니지만 단순히 부작용 임). 컴파일러가 효율적인 코드를 생성하는 데 더 낫게됨에 따라 더 이상 필요하지 않습니다.

  2. 코드에있는 모든 객체를 "주소 추가가 불가능"(주소를 가져올 수 없음)로 만들 수있는 경우에도 프로그램은 여전히 ​​100 % 안전하지 않습니다. 이러한 객체는 여전히 메모리에 저장되어 있으며 여전히 볼 수 있습니다. 바이너리 파일을 분석하고, 디버거를 사용하고, 메모리 맵을 분석하는 등의 작업을 통해 이러한 메모리 주소를 찾아 낼 수 있습니다.

  3. 이것은 좋지 않습니다. 모듈에서 객체의 변수를 가져 오려면 해당 객체가 전역이어야하며 이는 나쁘다. 그래서 여러분은 글로벌 변수가 있는지 걱정해야합니다. Here 전역 범위에 변수가 포함 된 이유에 대한 자세한 내용을 찾을 수 있습니다.

  4. "문제"의 준 해결책으로 정적으로 선언 할 수 있습니다. 모듈 외부에서 액세스 할 수 없으며 아무런 결과가 발생하지 않으면 아무도 자신의 가치를 변경할 수 없습니다.

+0

나는 고의적으로 악의적 인 해커로부터 보안을 찾고 있지 않으며,이 모듈을 유지 보수하는 사람들이 부주의 한 실수로부터 보호하기를 바라고 있습니다. –

+0

이 경우 좋은 코딩 표준을 사용해야합니다. 코드를 올바르게 모듈화하고 모듈을 직각으로 만들면 몇 가지 "추가 보호"가 필요하지 않습니다. – Paul92

관련 문제