2013-04-02 1 views
2

Linux에서 이진 환경 변수를 가지고 놀면서 일부 싱글 바이트가 좋지 않은 것으로 보이는 이상한 행동을 발견했습니다. 나는 그것을 더 가깝게 조사했고 setenv()에 주어질 때 특정 바이트가 항상 "변환"되는 것으로 보인다. 이것 좀 봐 :바이너리 환경 변수 및 setenv()

#include <stdio.h> 
#include <stdlib.h> 

int main(int argc, char **argv) 
{ 
    char array[256]; 

    int i; 
    for(i = 1; i < 256; i++) { 
     array[i] = i; 
    } 

    setenv("badenv", array, 1); 

    system("/bin/sh"); 

    return 0; 
} 

나는 echo $ badenv> test를 실행할 때; 16 진 덤프 시험은 내가 참조 :

0000000 0101 0302 0504 0706 2008 0c0b 0e0d 100f 
0000010 1211 1413 1615 1817 1a19 1c1b 1e1d 201f 
0000020 2221 2423 2625 2827 2a29 2c2b 2e2d 302f 
0000030 3231 3433 3635 3837 3a39 3c3b 3e3d 403f 

그 0 * 9는 0x20에 변환됩니다 것, 그리고 그 0xa는 다른 사람 사이에, 0xB로 변환됩니다.

나는 setenv()를 악용합니까, 아니면 일반적으로 일반적으로 환경 변수를 남용하고 있습니까? 맨 페이지를 살펴본 후 환경 변수가 바이너리 값을 처리 할 수 ​​있는지 여부를 알아보기 위해 일부를 검색했지만 확실하지 않습니다.

이 동작의 원인은 무엇이며, 환경 변수를 사용하면서 그 주위에 어떤 방법이 있습니까?

+0

env 변수에 들어갈 수있는 것에 대해 몇 가지 자동 제한이있는 것 같습니다. 'export a ='echo -e "\ t"'는 탭을 공백으로 대체하는 것과 같은 결과를 낳습니다. – elmo

+0

'setenv'는 변수 값으로 0으로 끝나는 문자열 (a.k.a.C 스타일 문자열)을 기대하므로 0 바이트를 제대로 처리하지 못하기 때문에 값은 임의의 2 진 데이터가 될 수 없습니다. 왜 0x9와 같은 제어 문자를 공백으로 변환하는지 모르겠습니다. 아마도 어떤 안전 조치 일 것입니다. – shakurov

답변

3

환경 변수는 $IFS의 값에 따라 "단어"로 분리되며 "단어"는 단일 구분 기호 (이 경우에는 일반 공백)로 결합됩니다. 따라서 시퀀스 "\x09\x0a" 또는 "\t\n",array의 내용을 해석 할 때 하나의 공백 ('\x20')으로 축소됩니다.

IFS - 확장 후 단어를 분할하고 read builtin 명령을 사용하여 줄을 단어로 분할하는 데 사용되는 내부 필드 구분 기호. 기본값은 ''space tab newline ''입니다.

(일시적으로) $IFS을 바꾸면 대체 할 수 있습니다.

참고 그러나

  • array[0]
  • array이 프로그램에서

을 0이 종료되지 않은 불확정 값을 가지고있다. 그걸 고쳐야 해.

+0

감사합니다. 그래도이 동작을하려면 $ IFS를 어떻게 설정해야합니까? 현재 $ IFS가 설정되지 않았으므로 내용없이 선언했습니다. – csstudent2233

+0

'IFS = ""'를 설정하면 공백의 (비어 있지 않은) 순서가 단일 공백으로 축소되지만 공백이 하나이므로 변경되지 않습니다. 하지만'IFS'가 설정되어 있다고 확신합니다.'echo -n "$ IFS"| xxd'는 무엇을 말할 것인가? (아마도 스페이스, 탭, 줄 바꿈, 그래서 xxd는'2009 0a'를보고 할 것입니다.) –

+0

네 말이 맞아. 다시 한 번 고마워, 그건 내 원래 장난감 프로그램에서 작동하도록 만드는 것 같다. 제가 여기에 붙여 넣은 프로그램은 일반적으로 "문제"를 보여주기위한 것입니다. – csstudent2233