#include #include #include "attack.h" ULONG NtFrsMajor = NTFRS_MAJOR; ULONG NtFrsCommMinor = NTFRS_COMM_MINOR_7; // // Note: When using COMM_DECODE_VAR_LEN_BLOB you must also use COMM_SZ_NULL // in the table below so that no length check is made when the field is decoded. // This allows the field size to grow. Down level members must be able to // handle this by ignoring var len field components they do not understand. // // // The Communication packet element table below is used to construct and // decode comm packet data sent between members. // *** WARNING *** - the order of the rows in the table must match the // the order of the elements in the COMM_TYPE enum. See comments for COMM_TYPE // enum for restrictions on adding new elements to the table. // // Data Element Type DisplayText Size Decode Type Offset to Native Cmd Packet // COMM_PACKET_ELEMENT CommPacketTable[COMM_MAX] = { {COMM_NONE, "NONE" , COMM_SZ_NULL, COMM_DECODE_NONE, 0 }, {COMM_BOP, "BOP" , COMM_SZ_UL, COMM_DECODE_ULONG, RsOffsetSkip }, {COMM_COMMAND, "COMMAND" , COMM_SZ_UL, COMM_DECODE_ULONG_TO_USHORT, OFFSET(COMMAND_PACKET, Command)}, {COMM_TO, "TO" , COMM_SZ_NULL, COMM_DECODE_GNAME, RsOffset(To) }, {COMM_FROM, "FROM" , COMM_SZ_NULL, COMM_DECODE_GNAME, RsOffset(From) }, {COMM_REPLICA, "REPLICA" , COMM_SZ_NULL, COMM_DECODE_GNAME, RsOffset(ReplicaName) }, {COMM_JOIN_GUID, "JOIN_GUID" , COMM_SZ_GUL, COMM_DECODE_BLOB, RsOffset(JoinGuid) }, {COMM_VVECTOR, "VVECTOR" , COMM_SZ_GVSN, COMM_DECODE_VVECTOR, RsOffset(VVector) }, {COMM_CXTION, "CXTION" , COMM_SZ_NULL, COMM_DECODE_GNAME, RsOffset(Cxtion) }, {COMM_BLOCK, "BLOCK" , COMM_SZ_NULL, COMM_DECODE_BLOB, RsOffset(Block) }, {COMM_BLOCK_SIZE, "BLOCK_SIZE" , COMM_SZ_ULL, COMM_DECODE_ULONGLONG, RsOffset(BlockSize) }, {COMM_FILE_SIZE, "FILE_SIZE" , COMM_SZ_ULL, COMM_DECODE_ULONGLONG, RsOffset(FileSize) }, {COMM_FILE_OFFSET, "FILE_OFFSET" , COMM_SZ_ULL, COMM_DECODE_ULONGLONG, RsOffset(FileOffset) }, {COMM_REMOTE_CO, "REMOTE_CO" , COMM_SZ_COC, COMM_DECODE_REMOTE_CO, RsOffset(PartnerChangeOrderCommand)}, {COMM_GVSN, "GVSN" , COMM_SZ_GVSN, COMM_DECODE_BLOB, RsOffset(GVsn) }, {COMM_CO_GUID, "CO_GUID" , COMM_SZ_GUL, COMM_DECODE_BLOB, RsOffset(ChangeOrderGuid) }, {COMM_CO_SEQUENCE_NUMBER, "CO_SEQUENCE_NUMBER" , COMM_SZ_UL, COMM_DECODE_ULONG, RsOffset(ChangeOrderSequenceNumber)}, {COMM_JOIN_TIME, "JOIN_TIME" , COMM_SZ_JTIME, COMM_DECODE_BLOB, RsOffset(JoinTime) }, {COMM_LAST_JOIN_TIME, "LAST_JOIN_TIME" , COMM_SZ_ULL, COMM_DECODE_ULONGLONG, RsOffset(LastJoinTime) }, {COMM_EOP, "EOP" , COMM_SZ_UL, COMM_DECODE_ULONG, RsOffsetSkip }, {COMM_REPLICA_VERSION_GUID, "REPLICA_VERSION_GUID", COMM_SZ_GUL, COMM_DECODE_BLOB, RsOffset(ReplicaVersionGuid)}, {COMM_MD5_DIGEST, "MD5_DIGEST" , COMM_SZ_MD5, COMM_DECODE_BLOB, RsOffset(Md5Digest) }, {COMM_CO_EXT_WIN2K, "CO_EXT_WIN2K" , COMM_SZ_COEXT_W2K,COMM_DECODE_BLOB, RsOffset(PartnerChangeOrderCommandExt)}, {COMM_CO_EXTENSION_2, "CO_EXTENSION_2" , COMM_SZ_NULL, COMM_DECODE_VAR_LEN_BLOB, RsOffset(PartnerChangeOrderCommandExt)}, {COMM_COMPRESSION_GUID, "COMPRESSION_GUID" , COMM_SZ_GUID, COMM_DECODE_GUID, RsOffset(CompressionTable)} }; VOID CommCopyMemory( IN PCOMM_PACKET CommPkt, IN PUCHAR Src, IN ULONG Len ) /*++ Routine Description: Copy memory into a comm packet, extending as necessary Arguments: CommPkt Src Len Return Value: None. --*/ { #undef DEBSUB #define DEBSUB "CommCopyMemory:" ULONG MemLeft; PUCHAR NewPkt; // // Adjust size of comm packet if necessary // // PERF: How many allocs get done to send a CO??? This looks expensive. MemLeft = CommPkt->MemLen - CommPkt->PktLen; if (Len > MemLeft) { // // Just filling memory; extend memory, tacking on a little extra // CommPkt->MemLen = (((CommPkt->MemLen + Len) + (COMM_MEM_SIZE - 1)) / COMM_MEM_SIZE) * COMM_MEM_SIZE; NewPkt = MALLOC(CommPkt->MemLen); CopyMemory(NewPkt, CommPkt->Pkt, CommPkt->PktLen); FREE(CommPkt->Pkt); CommPkt->Pkt = NewPkt; } // // Copy into the packet // if (Src != NULL) { CopyMemory(CommPkt->Pkt + CommPkt->PktLen, Src, Len); } else { ZeroMemory(CommPkt->Pkt + CommPkt->PktLen, Len); } CommPkt->PktLen += Len; } VOID CommPackULong( IN PCOMM_PACKET CommPkt, IN COMM_TYPE Type, IN ULONG Data ) /*++ Routine Description: Copy a header and a ulong into the comm packet. Arguments: CommPkt Type Data Return Value: None. --*/ { #undef DEBSUB #define DEBSUB "CommPackULong:" ULONG Len = sizeof(ULONG); USHORT CommType = (USHORT)Type; CommCopyMemory(CommPkt, (PUCHAR)&CommType, sizeof(USHORT)); printf("Packed CommType.\n"); CommCopyMemory(CommPkt, (PUCHAR)&Len, sizeof(ULONG)); printf("Packed Len.\n"); CommCopyMemory(CommPkt, (PUCHAR)&Data, sizeof(ULONG)); printf("Packed Data.\n"); } PCOMM_PACKET CommStartCommPkt( IN PWCHAR Name ) /*++ Routine Description: Allocate a comm packet. Arguments: Name Return Value: Address of a comm packet. --*/ { #undef DEBSUB #define DEBSUB "CommStartCommPkt:" ULONG Size; PCOMM_PACKET CommPkt; // // We can create a comm packet in a file or in memory // CommPkt = MALLOC(sizeof(COMM_PACKET)); Size = COMM_MEM_SIZE; CommPkt->Pkt = MALLOC(Size); CommPkt->MemLen = Size; CommPkt->Major = NtFrsMajor; CommPkt->Minor = NtFrsCommMinor; printf("CommPkt initialized. Getting ready to add BOP\n"); // // Pack the beginning-of-packet // CommPackULong(CommPkt, COMM_BOP, 0); return CommPkt; } PCOMM_PACKET BuildCommPktFromDescriptorList( IN PCOMM_PKT_DESCRIPTOR pListHead, IN ULONG ActualPktSize, IN OPTIONAL ULONG *Major, IN OPTIONAL ULONG *Minor, IN OPTIONAL ULONG *CsId, IN OPTIONAL ULONG *MemLen, IN OPTIONAL ULONG *PktLen, IN OPTIONAL ULONG *UpkLen ) /*++ Routine Description: Allocate a comm packet and fill it acording to the parameters specified.. Arguments: pListHead - Address of the pListEntry of a COMM_PKT_DESCRIPTOR. We walk the list of descriptors to build the Pkt. ActualPktSize - Amount of memory to allocate for the Pkt. Major Minor CsId MemLen PktLen UpkLen - These parameters correspond to the fields in a COMM_PACKET. If they are NULL, the default value is used. Return Value: Address of a comm packet. --*/ { PCOMM_PKT_DESCRIPTOR pDescriptor = pListHead; PCOMM_PACKET CommPkt = NULL; // // Allocate the CommPkt struct // CommPkt = MALLOC(sizeof(COMM_PACKET)); // // Allocate the Pkt // CommPkt->Pkt = MALLOC(ActualPktSize); // // Set struct values. Use defaults if parameters are not specified. // CommPkt->MemLen = (MemLen?*MemLen:COMM_MEM_SIZE); CommPkt->Major = (Major?*Major:NtFrsMajor); CommPkt->Minor = (Minor?*Minor:NtFrsCommMinor); CommPkt->CsId = (CsId?*CsId:CS_RS); CommPkt->UpkLen = (UpkLen?*UpkLen:0); // // PktLen must be 0 for now so that CommCopyMemory will work correctly. // We'll set it to the provided value later. // CommPkt->PktLen = 0; while(pDescriptor != NULL) { CommCopyMemory(CommPkt, (PUCHAR)&(pDescriptor->CommType), sizeof(USHORT)); CommCopyMemory(CommPkt, (PUCHAR)&(pDescriptor->CommDataLength), sizeof(ULONG)); CommCopyMemory(CommPkt, (PUCHAR)(pDescriptor->Data), pDescriptor->ActualDataLength ); pDescriptor = pDescriptor->Next; }; // // We're done building the packet. // Now we can set PktLen tot he supplied value. // CommPkt->PktLen = (PktLen?*PktLen:CommPkt->PktLen); return CommPkt; }