본문 바로가기
OS

[TIL 53] 텍스트 파일과 바이너리 파일 탐지(구분)하는 법

by 진득한진드기 2025. 4. 25.

파일의 분류

이번에 파일 분석 작업을 진행하면서 텍스트 파일과 바이너리 파일을 구분하는 로직을 짜야되는 상황이 와서 여기저기 자료를 좀 찾아보는데 해당 자료는 비지니스 로직인 경우가 많아서 이론적인 내용밖에 얻을 수 없었다.

 

먼저 내가 생각한 파일 타입 감지는 단순해 보이지만 실제로는 여러 단계의 세밀한 검증이 필요한 작업이었다.

 

그냥 대충 ascii코드나 utf-8 인지 검사하면 된다고 생각하지만 실제로는 그렇게 검사하면 애초에 비효율적이다. 코어 로직에 넣는다고 하면 최대한 적게 검사하는게 이득이기 때문에....

 

그렇다고 무조건적으로 이 방법을 써야하는건 아니다. 대충 인터넷을 뒤져도 완벽하게 구분할수있다고 단정지어 말하는 사람이 없다. 나 또한 그렇게 판단했다. 만약에 완벽한 방법이 있으면 댓글에 방법을 달아줬으면 좋겠다.

 

파일 시그니처(매직 넘버) 기반 1차 분류

먼저 파일의 시작 부분에 있는 시그니처(매직 넘버)를 확인한다. 이 방법은 많은 바이너리 파일 형식이 파일 시작 부분에 고유한 바이트 시퀀스를 포함하고 있다는 특성을 활용한다.

직업 특성상 이런걸 볼일이 없는사람이 더 많겠지만 tmi를 펼치자면 예를 들어 유명한 파일 시그니처는 아래와 같다. 

 

특정 시그니처 유명한것들은 찾아보면 엄청 많이 나오니까 찾아볼거면 찾아보는 것도......

  • PNG 파일: 89 50 4E 47 0D 0A 1A 0A
  • PDF 파일: 25 50 44 46
  • ZIP 파일: 50 4B 03 04
  • ELF 파일: 7F 45 4C 46

 

예를들어 위 사진과 같이 ELF 시그니처가 확인되는 걸 볼 수 있다.

 

이러한 시그니처는 매우 신뢰할 수 있는 파일 타입 지표가 된다. 그래서 해당 시그니처가 발견되면 바로 바이너리로 체크한다.

 

근데 진짜 문제인건 바이너리 데이터와 텍스트 데이터가 함께 있는 파일들이 있다는게 문제이다.

 

파일 구성자체는 linux 게열상 엄청 자유롭게 커스터마이징이 가능하기 때문에 업체마다 사용하는 파일 시스템 종류가 다를수도 있다.

 

그래서 무조건 시그니처로 판단하는 것 보다 더 확률 높은 필터링을 넣어야한다...--> 무조건 그렇다는건 아니고 그러는게 좋을 것 같다는 생각이다. 

 

확률적 분석을 통한 2차 분류

 

시그니처 검사에서 파일 타입이 명확하게 식별되지 않는 경우, 파일의 처음 대략적으로 2KB정도의 데이터를 샘플링하여 확률적 분석을 수행한다.

  1. NULL 바이트 검사: 텍스트 파일에는 일반적으로 NULL 바이트(0x00)가 거의 없다. NULL 바이트의 빈도가 특정 임계값을 초과하면 바이너리 파일로 분류한다.
  2. 제어 문자 분석: ASCII 범위 0x00-0x1F의 제어 문자 중 일반 텍스트에서는 개행(0x0A), 캐리지 리턴(0x0D), 탭(0x09) 정도만 자주 등장한다는 특징을 이용해서 분류한다. 다른 제어 문자가 많이 발견되면 바이너리 파일일 가능성이 높다.
  3. 바이트 분포 분석: 텍스트 파일은 특정 문자(알파벳, 숫자, 공백)의 분포가 자연어 패턴을 따르는 경향이 있습니다. 바이트 분포가 균일하거나 비정상적인 패턴을 보이면 바이너리 파일로 분류한다.
  4. 엔트로피 계산: 데이터의 무작위성을 측정하는 엔트로피 값이 높으면 압축 또는 암호화된 바이너리 파일일 가능성이 높다.

이러한 여러 지표를 종합적으로 고려하여 파일 유형을 판별하는 확률적 점수를 계산하고, 특정 임계값을 넘으면 바이너리 파일로 분류한다.

이 접근 방식이 단순히 파일 확장자에 의존하는 것보다 훨씬 정확하고, 특히 확장자가 없거나 잘못된 확장자를 가진 파일을 처리할 때 유용하다.