2017-04-30 11 views
2

새 프로토콜을 Scapy에 추가하고 구체적인 필드에 어려움이 있습니다. 이 필드는 패키지 페이로드의 길이를 지정합니다. 필드는 페이로드의 길이에 따라 1, 2, 3 또는 4 바이트가 될 수 있습니다. 또한 인코딩됩니다. 필드의 크기가 1, 2, 3 또는 4 바이트인지 확인하기 위해 찾은 방법은 값의 첫 번째 바이트를 가져오고 127보다 작 으면 필드가 1 바이트로 표시됩니다. 127이고 x보다 작 으면 2 바이트로 표시됩니다 (인코딩 알고리즘 때문입니다).Scapy - 동적 길이가있는 새 필드 추가

그래서 문제는 첫 번째 바이트의 값에 따라이 필드 길이를 동적으로 정의 할 수 없다는 것입니다. 내가 시도한 첫 번째 일은 ConditionalFields으로이 문제를 처리하는 것이지만 잘못된 경로와 같은 느낌입니다.

ConditionalField(ByteField("length",1), lambda pkt:pkt.length <= 127), 
    ConditionalField(ShortField("length",None), lambda pkt:pkt.length > 127),] 

나는이 솔루션은 새로운 Scapy 필드를 정의하는 것입니다 생각하지만, 그에 따라 첫 번째 바이트 및 설치 길이에 액세스하는 방법을 모르겠어요. 모든 제안을 부탁드립니다. 미리 감사드립니다.

디코딩 알고리즘 : 당신은 구현해야

def test(encoded_byte): 
    if((encoded_byte & 128) != 0): 
     return True 
    else: 
     return False 


def decoding(bytes): 
    multiplier = 1 
    value = 0 
    offset = 0 
    condition = True 

    while condition: 
     encoded_byte = bytes[offset] 
     value += (encoded_byte & 127) * multiplier 
     multiplier *= 128 
     if multiplier > 128 ** 3: 
      raise Exception('Malformed Remaining Length') 
     offset += 1 
     condition = test(encoded_byte) 

    return value 
+0

제시하고자하는 코드가 있습니까? –

+0

필드 값에 대해 프로그래밍 한 조건부 필드와 디코딩 알고리즘이 있습니다. – somarhs

답변

1

자신의 특정 .addfield().getfield() 방법과 여기에 field. 귀하의 예를 바탕으로, 여기에 작동합니다 예입니다

class NewLayer(Packet): 
    fields_desc = [ 
     VariableFieldLenField("length", None, length_of="data"), 
     StrLenField("data", "", length_from=lambda pkt: pkt.length), 
    ] 

:

class VariableFieldLenField(FieldLenField): 
    def addfield(self, pkt, s, val): 
     val = self.i2m(pkt, val) 
     data = [] 
     while val: 
      if val > 127: 
       data.append(val & 127) 
       val /= 127 
      else: 
       data.append(val) 
       lastoffset = len(data) - 1 
       data = "".join(chr(val | (0 if i == lastoffset else 128)) 
           for i, val in enumerate(data)) 
       return s + data 
      if len(data) > 3: 
       raise Scapy_Exception("%s: malformed length field" % 
             self.__class__.__name__) 
    def getfield(self, pkt, s): 
     value = 0 
     for offset, curbyte in enumerate(s): 
      curbyte = ord(curbyte) 
      value += (curbyte & 127) * (128 ** offset) 
      if curbyte & 128 == 0: 
       return s[offset + 1:], value 
      if offset > 2: 
       raise Scapy_Exception("%s: malformed length field" % 
             self.__class__.__name__) 

이제 작업의 가장 어려운 부분이 완료되었습니다, 당신은 단지 VariableFieldLenField 필드를 사용하여 레이어를 생성해야 이제 모든 것을 검사하는 일부 검사는 예상대로 작동합니다.

NewLayer('\x01x') 
str(_) 
NewLayer(_) 
NewLayer(data='x') 
str(_) 
NewLayer(_) 
NewLayer(data='x' * 128) 
str(_) 
NewLayer(_) 
str(NewLayer(data='x' * 16385))[:10] 
NewLayer(str(NewLayer(data='x' * 16385))).length