header.go 3.9 KB

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