1package ndr 2 3import ( 4 "encoding/binary" 5 "fmt" 6) 7 8/* 9Serialization Version 1 10https://msdn.microsoft.com/en-us/library/cc243563.aspx 11 12Common Header - https://msdn.microsoft.com/en-us/library/cc243890.aspx 138 bytes in total: 14- First byte - Version: Must equal 1 15- Second byte - 1st 4 bits: Endianess (0=Big; 1=Little); 2nd 4 bits: Character Encoding (0=ASCII; 1=EBCDIC) 16- 3rd - Floating point representation (This does not seem to be the case in examples for Microsoft test sources) 17- 4th - Common Header Length: Must equal 8 18- 5th - 8th - Filler: MUST be set to 0xcccccccc on marshaling, and SHOULD be ignored during unmarshaling. 19 20Private Header - https://msdn.microsoft.com/en-us/library/cc243919.aspx 218 bytes in total: 22- First 4 bytes - Indicates the length of a serialized top-level type in the octet stream. It MUST include the padding length and exclude the header itself. 23- Second 4 bytes - Filler: MUST be set to 0 (zero) during marshaling, and SHOULD be ignored during unmarshaling. 24*/ 25 26const ( 27 protocolVersion uint8 = 1 28 commonHeaderBytes uint16 = 8 29 bigEndian = 0 30 littleEndian = 1 31 ascii uint8 = 0 32 ebcdic uint8 = 1 33 ieee uint8 = 0 34 vax uint8 = 1 35 cray uint8 = 2 36 ibm uint8 = 3 37) 38 39// CommonHeader implements the NDR common header: https://msdn.microsoft.com/en-us/library/cc243889.aspx 40type CommonHeader struct { 41 Version uint8 42 Endianness binary.ByteOrder 43 CharacterEncoding uint8 44 FloatRepresentation uint8 45 HeaderLength uint16 46 Filler []byte 47} 48 49// PrivateHeader implements the NDR private header: https://msdn.microsoft.com/en-us/library/cc243919.aspx 50type PrivateHeader struct { 51 ObjectBufferLength uint32 52 Filler []byte 53} 54 55func (dec *Decoder) readCommonHeader() error { 56 // Version 57 vb, err := dec.r.ReadByte() 58 if err != nil { 59 return Malformed{EText: "could not read first byte of common header for version"} 60 } 61 dec.ch.Version = uint8(vb) 62 if dec.ch.Version != protocolVersion { 63 return Malformed{EText: fmt.Sprintf("byte stream does not indicate a RPC Type serialization of version %v", protocolVersion)} 64 } 65 // Read Endianness & Character Encoding 66 eb, err := dec.r.ReadByte() 67 if err != nil { 68 return Malformed{EText: "could not read second byte of common header for endianness"} 69 } 70 endian := int(eb >> 4 & 0xF) 71 if endian != 0 && endian != 1 { 72 return Malformed{EText: "common header does not indicate a valid endianness"} 73 } 74 dec.ch.CharacterEncoding = uint8(vb & 0xF) 75 if dec.ch.CharacterEncoding != 0 && dec.ch.CharacterEncoding != 1 { 76 return Malformed{EText: "common header does not indicate a valid character encoding"} 77 } 78 switch endian { 79 case littleEndian: 80 dec.ch.Endianness = binary.LittleEndian 81 case bigEndian: 82 dec.ch.Endianness = binary.BigEndian 83 } 84 // Common header length 85 lb, err := dec.readBytes(2) 86 if err != nil { 87 return Malformed{EText: fmt.Sprintf("could not read common header length: %v", err)} 88 } 89 dec.ch.HeaderLength = dec.ch.Endianness.Uint16(lb) 90 if dec.ch.HeaderLength != commonHeaderBytes { 91 return Malformed{EText: "common header does not indicate a valid length"} 92 } 93 // Filler bytes 94 dec.ch.Filler, err = dec.readBytes(4) 95 if err != nil { 96 return Malformed{EText: fmt.Sprintf("could not read common header filler: %v", err)} 97 } 98 return nil 99} 100 101func (dec *Decoder) readPrivateHeader() error { 102 // The next 8 bytes after the common header comprise the RPC type marshalling private header for constructed types. 103 err := binary.Read(dec.r, dec.ch.Endianness, &dec.ph.ObjectBufferLength) 104 if err != nil { 105 return Malformed{EText: "could not read private header object buffer length"} 106 } 107 if dec.ph.ObjectBufferLength%8 != 0 { 108 return Malformed{EText: "object buffer length not a multiple of 8"} 109 } 110 // Filler bytes 111 dec.ph.Filler, err = dec.readBytes(4) 112 if err != nil { 113 return Malformed{EText: fmt.Sprintf("could not read private header filler: %v", err)} 114 } 115 return nil 116} 117