SMB_Parameters主要包含用于管理Transaction消息的一些标志和设置信息,为服务端处理提供必要的上下文环境。以SMB_COM_TRANSACTION命令为例,其SMB_Parameters格式如下:
SMB_Parameters { UCHAR WordCount; Words { USHORT TotalParameterCount; USHORT TotalDataCount; USHORT MaxParameterCount; USHORT MaxDataCount; UCHAR MaxSetupCount; UCHAR Reserved1; USHORT Flags; ULONG Timeout; USHORT Reserved2; USHORT ParameterCount; USHORT ParameterOffset; USHORT DataCount; USHORT DataOffset; UCHAR SetupCount; UCHAR Reserved3; USHORT Setup[SetupCount]; //3种Transaction子命令的该字段略有不同 } }SMB_COM_TRANSACTION命令的Setup结构定义了其下属的子命令码、FID等设置信息:
Setup { USHORT Subcommand; USHORT FID; }在SMB_COM_TRANSACTION2命令中,Setup字段只存放2字节的子命令码,无其它设置信息。与前两种Transaction命令不同的是,SMB_COM_NT_TRANSACT中的SMB_Parameters部分将子命令码单独定义在Function字段,根据子命令码的不同定义不同的Setup内容:
SMB_Parameters { ...... UCHAR SetupCount; USHORT Function; USHORT Setup[SetupCount]; ...... }SMB_Data主要包含了用于服务端操作的参数和数据:
SMB_Data { USHORT ByteCount; Bytes { SMB_STRING Name; UCHAR Pad1[]; UCHAR Trans_Parameters[ParameterCount]; UCHAR Pad2[]; UCHAR Trans_Data[DataCount]; } }根据这些对SMB消息格式的描述可知,Transaction消息中包含Setup、Trans_Parameters和Trans_Data等可变大小的内容,分别提供客户端与服务端之间进行Transaction交互期间的配置、参数和数据。无论客户端发送给服务端的SMB请求,还是服务端发送给客户端的SMB响应,都包含这些可变内容。在SMB请求中,被称之为InSetup、InParameters和InData;在SMB响应中,被称之为OutSetup、OutParameters和OutData。这些内容在当前数据包中的长度、在整个Transaction交互的总长度、最大长度都在SMB_Prameters的部分字段体现:
缓冲区关联字段SMB_Prameters.Setup SetupCount、MaxSetupCount
SMB_Data.Trans_Parameters ParameterCount 、TotalParameterCount、MaxParameterCount
SMB_Data.Trans_Data DataCount、TotalDataCount、MaxDataCount
服务端会将从客户端接收的InSetup、InParameters和InData,同后续需要响应给客户端的OutSetup、OutParameters和OutData等内容存放在同一个缓冲区中,称之为Transaction data buffer。需要注意的是,这些数据之间不是单纯的前后顺序排列,很多都是重叠的。
同时,服务端还会定义一个TRANSACTION结构体,用于存放指向Transaction data buffer缓冲区中上述6种数据的指针,与之相关的*Count、Total*Count、Max*Count等字段,以及TID、PID、UID标识符等配置信息。
接下来介绍一下Windows SMB transaction的实现细节。
01 TRANSACTION结构体和Transaction data buffer总是分配在同一个缓冲区,在内存中它们是相邻的:
+-----------------+--------------------------------------------+ | TRANSACTION | transaction data buffer | +-----------------+--------------------------------------------+[译者注] TRANSACTION和Transaction data buffer共同组成了的缓冲区称之为Transaction buffer。
02 Transaction buffer位于分页内存池缓冲区中。
03 对于Size小于等于0×5000的Transaction buffer,Windows采用快表为其分配缓冲区,并且整个缓冲区的size将被设置为0×5000,即使起初申请的大小只有0×100;对于Size大于0×5000的Transaction buffer,Windows直接从分页内存池中为其分配缓冲区。如果SMB_COM_TRANSACTION命令的SetupCount字段被置为0,无论Size大小是多少,都会直接从分页内存池中分配。