Linux에서 문자열 명령을 사용하는 방법


리눅스에서 ‘strings’ 명령어 사용법: 바이너리 파일 속 텍스트 추출하기

바이너리 파일이나 데이터 파일 내부의 숨겨진 텍스트를 찾아보고 싶으신가요? 리눅스의 `strings` 명령어는 이러한 텍스트 조각들을 마치 실타래처럼 뽑아내어 보여줍니다.

리눅스에는 문제 해결을 위한 다양한 명령어가 존재하며, `strings` 명령어 역시 그중 하나입니다. 이 명령어의 주된 목적은 무엇일까요? 바이너리 파일 내부에서 사람이 읽을 수 있는 문자열들을 추출하는 데 과연 의미가 있을까요?

잠시 생각해 봅시다. 프로그램 파일과 같은 바이너리 파일에는 종종 사람이 읽을 수 있는 텍스트 문자열들이 포함되어 있습니다. 하지만 이러한 문자열들을 어떻게 확인할 수 있을까요? `cat`과 같은 명령어를 사용하면 터미널 창이 깨져 보이는 경험을 할 수 있습니다. 텍스트 파일에 최적화된 프로그램은 인쇄 불가능한 문자를 마주하게 되면 제대로 작동하지 못합니다.

바이너리 파일 내부의 대부분 바이트는 사람이 읽을 수 없으며, 터미널 창에 의미 있게 출력할 수 없습니다. 알파벳, 구두점, 공백과 같은 ‘인쇄 가능한’ 문자와 달리, 인쇄 불가능한 문자는 표준 기호로 표현되지 않습니다. 이런 이유로, 바이너리 파일에서 텍스트 문자열을 확인하거나 검색하는 것은 쉽지 않습니다.

바로 이럴 때 `strings` 명령어가 필요합니다. 파일에서 인쇄 가능한 문자열을 추출하여, 다른 명령어가 처리할 수 없는 문자에 대한 걱정 없이 문자열을 다룰 수 있게 해줍니다.

`strings` 명령어의 기본 사용법

`strings` 명령어는 매우 간단하며, 기본적인 사용법은 다음과 같습니다. 명령줄에서 `strings` 뒤에 검색하고자 하는 파일 이름을 입력하기만 하면 됩니다.

예를 들어, “jibber”라는 실행 파일에서 문자열을 찾아보겠습니다. 터미널에 `strings jibber`를 입력하고 엔터 키를 누르면 됩니다.

strings jibber

그러면 파일에서 추출된 문자열들이 터미널 창에 나열됩니다.

최소 문자열 길이 설정하기

기본적으로 `strings` 명령어는 4자 이상의 문자열을 찾아냅니다. 최소 문자열 길이를 변경하고 싶다면 `-n` 옵션을 사용하면 됩니다. 예를 들어, 최소 길이를 2로 설정하려면 `strings -n 2 jibber`와 같이 입력합니다.

최소 길이가 짧을수록 더 많은 노이즈(쓸모없는 문자열)가 포함될 가능성이 높습니다. 일부 바이너리 값은 인쇄 가능한 문자를 나타내는 값과 동일한 숫자 값을 가질 수 있습니다. 이러한 값이 연달아 나타나고 최소 길이를 2로 설정하면 문자열처럼 인식될 수 있습니다.

strings -n 2 jibber

결과를 보면 두 글자 문자열이 포함되어 있으며, 공백도 인쇄 가능한 문자로 간주된다는 것을 알 수 있습니다.

`less`를 이용한 출력 제어

`strings` 명령어의 출력량이 많은 경우, `less`와 파이프를 연결하여 출력을 제어하는 것이 좋습니다. 이를 통해 화면을 스크롤하면서 원하는 텍스트를 쉽게 찾을 수 있습니다.

strings jibber | less

이제 출력이 `less`를 통해 표시되어 목록의 시작 부분부터 확인이 가능합니다.

객체 파일과 `strings` 명령어

일반적으로 프로그램 소스 코드는 객체 파일로 컴파일됩니다. 이 객체 파일들은 라이브러리 파일과 결합되어 최종 실행 파일을 생성합니다. “jibber” 객체 파일 내부를 살펴보겠습니다. 확장자가 `.o`인 파일에 주목해주세요.

strings jibber.o | less

첫 번째 문자열 세트는 모두 8자 이상이므로 8번째 열에서 줄이 바뀌어 표시됩니다. 여기서 “H” 문자는 9번째 열에 위치합니다. 이러한 문자열들은 SQL 문으로 보일 수 있습니다.

출력을 스크롤하다 보면 이러한 형식이 파일 전체에 적용되지 않는다는 것을 알 수 있습니다.

객체 파일과 최종 실행 파일 간의 텍스트 문자열 차이를 비교해 보는 것은 매우 흥미로운 경험입니다.

파일의 특정 영역에서 검색하기

컴파일된 프로그램에는 텍스트를 저장하는 데 사용되는 여러 영역이 있습니다. 기본적으로 `strings` 명령어는 파일 전체를 검색하여 텍스트를 찾습니다. 이는 `-a` (all) 옵션을 사용한 것과 동일합니다. 파일의 초기화되고 로드된 데이터 섹션에서만 문자열을 검색하려면 `-d` (data) 옵션을 사용합니다.

strings -d jibber | less

특별한 이유가 없다면 기본 설정을 사용하여 파일 전체를 검색하는 것이 좋습니다.

문자열 오프셋 출력하기

`strings` 명령어는 각 문자열이 파일 내에서 시작되는 오프셋을 출력할 수도 있습니다. 이를 위해서는 `-o` (offset) 옵션을 사용합니다.

strings -o parse_phrases | less

오프셋은 8진수로 표시됩니다.

오프셋을 10진수나 16진수와 같은 다른 숫자 체계로 표시하려면 `-t` (radix) 옵션을 사용합니다. `radix` 옵션 뒤에는 `d`(십진수), `x`(16진수), 또는 `o`(8진수)를 지정합니다. `-to`를 사용하는 것은 `-o`를 사용하는 것과 같습니다.

strings -t d parse_phrases | less

이제 오프셋이 십진수로 출력됩니다.

strings -t x parse_phrases | less

이번에는 오프셋이 16진수로 출력됩니다.

공백 처리하기

`strings` 명령어는 탭 및 공백 문자를 문자열의 일부로 간주합니다. 반면, 줄 바꿈 및 캐리지 리턴과 같은 다른 공백 문자는 문자열의 일부로 처리되지 않습니다. `-w` (whitespace) 옵션을 사용하면 모든 공백 문자를 문자열의 일부로 처리할 수 있습니다.

strings -w add_data | less

출력 결과를 보면 빈 줄이 포함되어 있는 것을 볼 수 있습니다. 이는 캐리지 리턴과 다음 줄의 줄 바꿈 문자 때문입니다.

파일에만 국한되지 않는 `strings`

`strings` 명령어는 바이트 스트림이나 생성 가능한 모든 것과 함께 사용할 수 있습니다.

예를 들어, 아래 명령어를 사용하면 컴퓨터의 RAM (랜덤 액세스 메모리) 내용을 분석할 수 있습니다.

`/dev/mem`에 접근해야 하므로 `sudo`를 사용해야 합니다. `/dev/mem`은 컴퓨터의 메인 메모리 이미지를 담고 있는 캐릭터 장치 파일입니다.

sudo strings /dev/mem | less

출력되는 목록이 RAM의 전체 내용은 아닙니다. 단지 추출할 수 있는 문자열일 뿐입니다.

다수의 파일에서 검색하기

와일드카드를 사용하여 검색할 파일 그룹을 지정할 수 있습니다. `*` 문자는 여러 문자를 나타내고, `?` 문자는 단일 문자를 나타냅니다. 명령줄에 여러 파일 이름을 직접 나열할 수도 있습니다.

와일드카드를 사용하여 `/bin` 디렉토리의 모든 실행 파일에서 검색해 보겠습니다. 결과가 많으므로 `-f` (file name) 옵션을 사용하여 각 줄의 시작 부분에 파일 이름을 출력합니다. 이렇게 하면 각 문자열이 어떤 파일에서 발견되었는지 알 수 있습니다.

그런 다음 `grep`을 사용하여 “Copyright”라는 단어가 포함된 문자열을 검색합니다.

strings -f /bin/* | grep Copyright

이제 `/bin` 디렉토리의 각 파일에 대한 저작권 정보가 파일 이름과 함께 표시됩니다.

`strings` 명령어의 활용

`strings` 명령어는 숨겨진 비밀이 있는 복잡한 명령어가 아닙니다. 아주 구체적인 작업을 수행하며, 그 일을 매우 효과적으로 처리합니다.

이 명령어는 리눅스 환경에서 다른 명령어들과 함께 사용할 때 그 진가를 발휘합니다. 바이너리 파일과 `grep`과 같은 다른 유틸리티 사이에 어떻게 위치하는지를 살펴보면, 이 간결한 명령어가 얼마나 강력한 기능을 제공하는지 이해할 수 있습니다.