바이너리 데이터에서 렉서 / 파서를 사용하는 것이 왜 그렇게 잘못 되었습니까?


13

나는 종종 파서 결합기 와 달리 lexer / parsers 와 함께 일하고 파싱에서 수업을 한 적이없는 사람들을보고 바이너리 데이터 파싱에 대해 묻습니다. 일반적으로 데이터는 이진일뿐만 아니라 상황에 따라 다릅니다. 이것은 기본적으로 한 유형의 토큰, 바이트 토큰 만 갖습니다.

누군가 파싱 수업을 듣지 않고 이론에 기반을 둔 CS 학생에게 충분한 명확성으로 렉서 / 파서로 이진 데이터를 구문 분석하는 것이 왜 그렇게 잘못되었는지 설명 할 수 있습니까?


내 생각에 어휘 분석기는 아마도 바이트 / 워드보다 작은 토큰을 찾지 못할 것이다. 필요한 경우 Erlang은 바이너리 구문 분석에 대한 탁월한 지원을 제공합니다. user.it.uu.se/~pergu/papers/JFP_06.pdf
Dave Clarke

3
나는 당신의 가정이 사실이라고 생각하지 않습니다. 분명히, 문맥이없는 데이터는 문제를 야기하지만 (이는 종종 우회 될 수 있음) 이진 단어에 대한 문법을 ​​제공 할 수 있습니다 . 으로 당신은 아마, 인기 파서 생성기를 사용할 수 없습니다 사람들은 텍스트 입력을 가정합니다. 그러나 그것은 또 다른 문제입니다.
Raphael

@GuyCoder : 문법에 대한 많은 고전적인 예는 이진 알파벳을 사용합니다 (예 : . S0S10S
Raphael

1
28

5
@GuyCoder : 다른 프로그램에서 생성 된 모든 데이터는 문법으로 설명 할 수 있습니다. 그러나 상황에 맞는 것이 아닐 수도 있습니다.
Raphael

답변:


10

원칙적으로 아무런 문제가 없습니다.

실제로,

  • 내가 아는 대부분의 텍스트가 아닌 데이터 형식은 컨텍스트가 없으므로 일반적인 파서 생성기에 적합하지 않습니다. 가장 일반적인 이유는 프로덕션이 필요한 횟수를 제공하는 길이 필드가 있기 때문입니다.

    문맥에 맞지 않는 언어를 사용하더라도 파서 생성기의 사용을 막을 수는 없습니다. 언어의 수퍼 세트를 구문 분석 한 후 의미 규칙 을 사용하여 원하는 언어 로 줄입니다. 결과가 결정적이라면 텍스트가 아닌 형식에이 방법을 사용할 수 있습니다. 문제는 대부분의 이진 형식이 임의의 데이터를 포함 할 수 있으므로 동기화 할 수있는 것 이외의 것을 찾는 것입니다. 길이 필드는 그것이 얼마인지 알려줍니다.

    그런 다음 수동으로 작성된 어휘 분석기를 파서의 피드백으로 처리 할 수있는 것과 같은 트릭을 시작할 수 있습니다 (예를 들어 C의 lex / yacc 처리는 typedef를 처리하는 데 그러한 트릭을 사용합니다). 그러나 우리는 두 번째 요점에 도달합니다.

  • 텍스트가 아닌 데이터 형식은 컨텍스트가없는 경우에도 매우 간단합니다. 위에서 언급 한 수를 무시하면 언어는 규칙적이고 최악의 경우 LL1이므로 수동 구문 분석 기술에 적합합니다. 또한 재귀 강하와 같은 수동 구문 분석 기술에서는 처리 횟수가 쉽습니다.


"언어는 규칙적이다"만약 이진 데이터가 문법이라는 것을 의미하기 위해 "하지만 문맥에 민감하다"를 취했다면, 나는 그 답을 명확하게 설명 할 것이다. 파서 언급
Guy Coder

7

데이터를 사람이 읽을 수있는 데이터 (일반적으로 책, 프로그램에 따라 다름), 컴퓨터 및 기타 데이터 (이미지 또는 사운드 구문 분석)가 읽을 수있는 데이터의 세 가지 범주로 분류 해 보겠습니다.

첫 번째 범주의 경우 컴퓨터에서 사용할 수있는 것으로 처리해야합니다. 사람이 사용하는 언어는 일반적으로 파서에 의해 상대적으로 잘 이해 될 수 있으므로 일반적으로 파서를 사용합니다.

세 번째 범주의 데이터 예는 텍스트에서 구문 분석하려는 책에서 페이지의 스캔 이미지입니다. 이 범주의 경우 거의 항상 입력에 대한 매우 구체적인 지식이 필요하므로이를 분석하려면 특정 프로그램이 필요합니다. 표준 파싱 기술은 여기서 멀지 않습니다.

귀하의 질문은 두 번째 범주에 관한 것입니다. 이진 데이터가있는 경우 거의 항상 다른 컴퓨터 프로그램을위한 컴퓨터 프로그램의 제품입니다. 이것은 또한 데이터의 형식이 데이터 생성을 담당하는 프로그램에 의해 선택됨을 의미합니다.

컴퓨터 프로그램은 거의 항상 명확한 구조의 형식으로 데이터를 생성합니다. 입력을 구문 분석 하면 입력 의 구조 를 파악하려고합니다 . 이진 데이터를 사용하면이 구조는 일반적으로 컴퓨터로 매우 간단하고 구문 분석하기 쉽습니다.

다시 말해, 일반적으로 구조를 이미 알고있는 입력 구조를 파악하는 것은 약간의 낭비입니다. 구문 분석이 자유롭지 않기 때문에 (시간이 걸리고 프로그램이 복잡 해짐) 바이너리 데이터에 렉서 / 파서를 사용하는 것이 '너무 잘못'한 이유입니다.


2
이것은 좋은 관점이지만 질문에 대답하지 않는 것 같습니다.
Raphael

LANGSEC: Language-theoretic Security흥미로운 관점을 제공합니다. 기사 중 하나는 "이상한 기계"에 대해 이야기합니다 : 시스템 의 입력 처리 기능을 구성 하는 알려진 형식의 임시 파서 . 실제로 의도 한대로 작동하지 않을 수 있습니다. 잘못된 가정으로 인해 결함이있는 기계는 특별히 제작 된 입력이 주어지면 예상치 못한 상태 전이를 수행하여 불가능한 계산을 수행합니다. 이것은 공격 벡터를 생성합니다. 공식적인 문법을 사용하면 올바른 알고리즘을 얻을 수 있습니다.
Matheus Moreira

0

a+b×(cd)+e(+ a (* b (- c d)) e)a b c d - * + e +. 일반적인 수학적 표기법은 Lisp (더 많은 괄호가 필요하지만 무료로 가변적 인 특성을 가지므로 큰 특성을 사용하여 식을 표현하기 위해 더 적은 기호가 필요함) 또는 RPL (괄호가 필요하지 않음)보다 중복성이 더 높습니다. 이러한 중복성은 컴퓨터에 거의 유용하지 않으며 데이터에 오류가있을 수있는 경우 오류 정정 논리는 일반적으로 임의의 데이터에 적용되는 오류 수정 코드를 사용하여 데이터의 기능적 의미와 별도로 유지됩니다. 바이트 시퀀스는 무엇을 나타내는 지에 관계없이.

이진 형식은 일반적으로 압축되도록 설계되었으므로 문맥없는 문법으로 표현할 수있는 균형 괄호와 같은 간단한 언어 기능이 거의 없습니다. 또한, 데이터의 이진 표현이 표준적인 것, 즉 각 객체의 단일 표현을 갖는 것이 종종 유용하다. 이것은 괄호와 같은 중복 기능을 배제합니다. 중복성이 줄어듦에 따라 칭찬 할 수없는 또 다른 결과는 모든 입력이 구문 적으로 정확하면 오류 검사를 줄입니다.

이진 데이터에 대한 사소한 파서의 또 다른 요인은 많은 이진 형식이 오버 헤드가 거의없는 일정한 메모리에서 작동하는 것을 선호하는 저수준 코드로 구문 분석되도록 설계되었다는 것입니다. 적용 가능한 경우 요소의 임의 반복을 허용하기 위해 고정 된 크기가 선호됩니다. 왼쪽에서 오른쪽으로 구문 분석기가 오브젝트에 적합한 양의 메모리를 먼저 할당 한 다음 오브젝트의 표현을 읽을 수있게하는 TLV 와 같은 형식 입니다. 왼쪽에서 오른쪽으로 구문 분석하면 중간 버퍼없이 데이터를 그대로 처리 할 수 ​​있으므로 이점이 있습니다.


처음 두 단락의 요점은 무엇입니까? 중복성이없는 경우에도 파서가 필요합니다. 또한, 첫 번째 단락이 잘못 :이 모든 단어가 허용되는 예입니다하지만 당신은 얻을 구문 분석 구조 (RNA의 예를 들면 이차 구조 예측을).
Raphael

@Raphael 사소한 파서는 일반적으로 중복성을 의미합니다 (예, 지적한대로 예외가 있습니다). 인간이나 컴퓨터를 위해 설계된 언어는 고려하지 않았습니다. 이것은 흥미로운 예입니다. 처음 두 단락은 이진 형식과 사람이 읽을 수있는 형식의 일반적인 차이점에 대해 설명합니다 (예외를 찾으면 예외를 찾을 수 있음).
Gilles 'SO- 악마 중지'
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.