2013-10-25 3 views
4

glibceglibc은 쓰기 가능한 메모리 (정확하게 '암호화'가 아닌 'XOR')의 포인터를 암호화하는 PTR_MANGLE을가집니다.libc의 포인터 암호화에 대한 질문

필자는이 기능에 대한 정보를 많이 찾지 못했습니다. man -k PTR_MANGLE은 조회수를 반환하지 않으며 Google은 표면적 인 잡담을 되 돌리고 있습니다. 몇 가지 확실한 기사 중 하나는 Live Journal에 Drepper의 Pointer Encryption입니다.

그것에 대한 자세한 설명서가 있습니까? 사용자 공간 프로세스로 확장 할 수 있습니까, 아니면 런타임 라이브러리로 제한됩니까? 그렇다면이 기능을 사용하려면 컴파일러 스위치 또는 옵션이 무엇입니까? 런타임에 기능을 비활성화 할 수 있습니까?

+0

아무도 여기에 대답하지 않으면 http://security.stackexchange.com/을 시도하십시오 - 또한 대답에 관심이 있습니다. –

답변

4

PTR_MANGLE은 매크로를 기반으로하는 glibc의 내부 기능입니다. 어떤 식 으로든 컴파일러가 자동화하지는 않습니다. 응용 프로그램에서 똑같은 것을 복제 할 수도 있지만 수동으로해야합니다.

uintptr_t xor_key; // needs to be initialized with random "key" before use 
#define PTR_MANGLE(p) (1 ? (void *)((uintptr_t)(p)^xor_key) : p) 

이것은 glibc 구현과 완전히 다를 수 있습니다. 나는 오랫동안 그것을 보지 않고 단지 이것을 내 머리 꼭대기에서 썼다. 조건 연산자의 쓸모없는 사용은 표현식이 원본 포인터와 동일한 유형을 갖도록 강제적으로 사용하므로 직접 사용될 수 있습니다.

조작이 고유 한 역함수이므로 PTR_MANGLE을 "암호화"와 "암호 해독"에 모두 사용할 수 있습니다.

+0

흥미 롭습니다. 삼항 연산자 반환 유형에 대한 귀하의 의견에 의아해합니다. ISO/IEC 9899 : 2011 §6.5.15 ** 조건 연산자 ** ¶6은 말합니다 : ... _otherwise, 하나의 피연산자 은'void'에 대한 포인터이거나'void '의 정규화 된 버전입니다.이 경우 결과 유형은 a 적절한 형태의'void' 포인터 ._ 포인터 타입이'void *'인가? GCC (또는, 아마도 Clang)를 사용한다면'(typeof (p)) '를 사용하여 캐스트를 추가하고 조건부를 피할 수 있습니다. –

+0

@JonathanLeffler : 이전 조항 중 어느 것도 적용되지 않았습니까? 나는 그렇게 생각했다. –

+0

단락의 시작 부분은 다음과 같습니다. _ 두 번째 및 세 번째 피연산자가 모두 포인터이거나 하나가 널 포인터 상수이고 other가 포인터 인 경우 결과 유형은 모든 유형 한정자 으로 정규화 된 유형에 대한 포인터입니다. 두 피연산자에 의해 참조되는 타입. 또한 두 피연산자가 호환 가능 유형 또는 서로 다른 형식의 호환 가능 유형에 대한 포인터 인 경우 결과 유형은 복합 유형의 적절한 버전에 대한 포인터 인 입니다. 한 피연산자가 널 포인터 상수이면 결과에 다른 피연산자 유형이 있습니다. 그렇지 않으면 ... _ –