static USHORT Unpack_Track(UCHAR *b1, UCHAR *b2, USHORT pklen2, USHORT unpklen, UCHAR cmode, UCHAR flags, USHORT number, USHORT pklen1, USHORT usum1, int enc) { USHORT r, err = NO_PROBLEM; static USHORT pass; int maybeencrypted; int pwrounds; UCHAR *tmp; USHORT prevpass = 0; if (passfound) { if (number != 80) dms_decrypt(b1, pklen1, b1); r = Unpack_Track_2(b1, b2, pklen2, unpklen, cmode, flags); if (r == NO_PROBLEM) { if (usum1 == dms_Calc_CheckSum(b2,(ULONG)unpklen)) return NO_PROBLEM; } log_error(number); if (passretries <= 0) return ERR_CSUM; } passretries--; pwrounds = 0; maybeencrypted = 0; tmp = (unsigned char*)malloc (pklen1); memcpy (tmp, b1, pklen1); memset(b2, 0, unpklen); for (;;) { r = Unpack_Track_2(b1, b2, pklen2, unpklen, cmode, flags); if (r == NO_PROBLEM) { if (usum1 == dms_Calc_CheckSum(b2,(ULONG)unpklen)) { passfound = maybeencrypted; if (passfound) write_log (L"DMS: decryption key = 0x%04X\n", prevpass); err = NO_PROBLEM; pass = prevpass; break; } } if (number == 80 || !enc) { err = ERR_CSUM; break; } maybeencrypted = 1; prevpass = pass; PWDCRC = pass; pass++; dms_decrypt(b1, pklen1, tmp); pwrounds++; if (pwrounds == 65536) { err = ERR_CSUM; passfound = 0; break; } } free (tmp); return err; }
static USHORT Process_Track(struct zfile *fi, struct zfile *fo, UCHAR *b1, UCHAR *b2, USHORT cmd, USHORT opt, USHORT pwd){ USHORT hcrc, dcrc, usum, number, pklen1, pklen2, unpklen, l, r; UCHAR cmode, flags; l = (USHORT)zfile_fread(b1,1,THLEN,fi); if (l != THLEN) { if (l==0) return DMS_FILE_END; else return ERR_SREAD; } /* "TR" identifies a Track Header */ if ((b1[0] != 'T')||(b1[1] != 'R')) return ERR_NOTTRACK; /* Track Header CRC */ hcrc = (USHORT)((b1[THLEN-2] << 8) | b1[THLEN-1]); if (CreateCRC(b1,(ULONG)(THLEN-2)) != hcrc) return ERR_THCRC; number = (USHORT)((b1[2] << 8) | b1[3]); /* Number of track */ pklen1 = (USHORT)((b1[6] << 8) | b1[7]); /* Length of packed track data as in archive */ pklen2 = (USHORT)((b1[8] << 8) | b1[9]); /* Length of data after first unpacking */ unpklen = (USHORT)((b1[10] << 8) | b1[11]); /* Length of data after subsequent rle unpacking */ flags = b1[12]; /* control flags */ cmode = b1[13]; /* compression mode used */ usum = (USHORT)((b1[14] << 8) | b1[15]); /* Track Data CheckSum AFTER unpacking */ dcrc = (USHORT)((b1[16] << 8) | b1[17]); /* Track Data CRC BEFORE unpacking */ if (cmd == CMD_VIEWFULL) { if (number==80) write_log (" FileID "); else if (number==0xffff) write_log (" Banner "); else if ((number==0) && (unpklen==1024)) write_log (" FakeBB "); else write_log (" %2d ",(short)number); write_log ("%5d %5d %s %04X %04X %04X %0d\n", pklen1, unpklen, modes[cmode], usum, hcrc, dcrc, flags); } if ((pklen1 > TRACK_BUFFER_LEN) || (pklen2 >TRACK_BUFFER_LEN) || (unpklen > TRACK_BUFFER_LEN)) return ERR_BIGTRACK; if (zfile_fread(b1,1,(size_t)pklen1,fi) != pklen1) return ERR_SREAD; if (CreateCRC(b1,(ULONG)pklen1) != dcrc) return ERR_TDCRC; /* track 80 is FILEID.DIZ, track 0xffff (-1) is Banner */ /* and track 0 with 1024 bytes only is a fake boot block with more advertising */ /* FILE_ID.DIZ is never encrypted */ if (pwd && (number!=80)) dms_decrypt(b1,pklen1); if ((cmd == CMD_UNPACK) && (number<80) && (unpklen>2048)) { r = Unpack_Track(b1, b2, pklen2, unpklen, cmode, flags); if (r != NO_PROBLEM) if (pwd) return ERR_BADPASSWD; else return r; if (usum != Calc_CheckSum(b2,(ULONG)unpklen)) if (pwd) return ERR_BADPASSWD; else return ERR_CSUM; if (zfile_fwrite(b2,1,(size_t)unpklen,fo) != unpklen) return ERR_CANTWRITE; } if ((cmd == CMD_SHOWBANNER) && (number == 0xffff)){ r = Unpack_Track(b1, b2, pklen2, unpklen, cmode, flags); if (r != NO_PROBLEM) if (pwd) return ERR_BADPASSWD; else return r; if (usum != Calc_CheckSum(b2,(ULONG)unpklen)) if (pwd) return ERR_BADPASSWD; else return ERR_CSUM; printbandiz(b2,unpklen); } if ((cmd == CMD_SHOWDIZ) && (number == 80)) { r = Unpack_Track(b1, b2, pklen2, unpklen, cmode, flags); if (r != NO_PROBLEM) return r; if (usum != Calc_CheckSum(b2,(ULONG)unpklen)) return ERR_CSUM; printbandiz(b2,unpklen); } return NO_PROBLEM; }