Skip to content
Snippets Groups Projects
Unverified Commit 78ac29af authored by Richard Cordovano's avatar Richard Cordovano Committed by GitHub
Browse files

Merge pull request #2447 from APriestman/7690_detectTar

7690 Add detection for tar files
parents 30141013 1c063168
No related branches found
No related tags found
No related merge requests found
...@@ -16,15 +16,96 @@ ...@@ -16,15 +16,96 @@
* @return 1 if the signature is found, 0 otherwise * @return 1 if the signature is found, 0 otherwise
*/ */
int int
detectImageSignatureWithOffset(const char * signature, size_t signatureLen, size_t offset, const char * buf, size_t bufLen) {
if (signatureLen + offset > bufLen) {
return 0;
}
if (memcmp(signature, buf + offset, signatureLen) == 0) {
return 1;
}
return 0;
}
/**
* Compare the beginning of the buffer with the given signature.
*
* @return 1 if the signature is found, 0 otherwise
*/
int
detectImageSignature(const char * signature, size_t signatureLen, const char * buf, size_t bufLen) { detectImageSignature(const char * signature, size_t signatureLen, const char * buf, size_t bufLen) {
return detectImageSignatureWithOffset(signature, signatureLen, 0, buf, bufLen);
}
if (signatureLen >= bufLen) { /**
* Calculate the checksum on the first block to see if matches the tar format.
*
* @return 1 if the checksum is valid, 0 otherwise
*/
int
verifyTarChecksum(const char * buf, size_t bufLen) {
if (bufLen < 512) {
return 0; return 0;
} }
if (memcmp(signature, buf, signatureLen) == 0) { // Calculate checksum of first 512 bytes.
unsigned int cksum = 0;
const int cksumOffset = 148;
const int cksumLength = 8;
for (int i = 0; i < 512; i++) {
// Add each byte. For the checksum bytes, add a space.
if ((i < cksumOffset) || (i >= cksumOffset + cksumLength)) {
cksum += (unsigned char)buf[i];
}
else {
cksum += ' ';
}
}
// Convert the checksum field (octal) to a number
unsigned int savedCksum = 0;
// Skip leading spaces
int startingOffset = cksumOffset;
for (int i = 0; i < cksumLength; i++) {
unsigned char b = buf[cksumOffset + i];
if (b == ' ') {
startingOffset++;
}
else {
// Hit a non-space character
break;
}
}
// If the checksum is all spaces, it is not valid
if (startingOffset == cksumOffset + cksumLength) {
return 0;
}
// Convert octal digits
for (int offset = startingOffset; offset < cksumOffset + cksumLength; offset++) {
unsigned char b = buf[offset];
if (b == 0 || b == ' ') {
// We're done reading the checksum
break;
}
if (b < '0' || b > '7') {
// Found an illegal character
return 0;
}
// Add the next digit
savedCksum = savedCksum << 3 | (b - '0');
}
if (savedCksum == cksum) {
return 1; return 1;
} }
return 0; return 0;
} }
...@@ -36,14 +117,17 @@ detectImageSignature(const char * signature, size_t signatureLen, const char * b ...@@ -36,14 +117,17 @@ detectImageSignature(const char * signature, size_t signatureLen, const char * b
*/ */
char* detectUnsupportedImageType(TSK_IMG_INFO * img_info) { char* detectUnsupportedImageType(TSK_IMG_INFO * img_info) {
// Read the beginning of the image. There should be room for all the signature searches. // Read the beginning of the image. Try to read in enough bytes for all signatures.
size_t len = 32; // The tar checksum calculation requires 512 bytes.
char* buf = (char*)tsk_malloc(len); size_t maxLen = 512; // Bytes to read
size_t len; // The actual number of bytes read
char* buf = (char*)tsk_malloc(maxLen);
if (buf == NULL) { if (buf == NULL) {
return NULL; return NULL;
} }
if (tsk_img_read(img_info, 0, buf, len) != len) { len = tsk_img_read(img_info, 0, buf, maxLen);
if (len == 0) {
free(buf); free(buf);
return NULL; return NULL;
} }
...@@ -70,6 +154,9 @@ char* detectUnsupportedImageType(TSK_IMG_INFO * img_info) { ...@@ -70,6 +154,9 @@ char* detectUnsupportedImageType(TSK_IMG_INFO * img_info) {
else if (detectImageSignature("[Dumps]", 7, buf, len)) { else if (detectImageSignature("[Dumps]", 7, buf, len)) {
strcpy(result, "Cellebrite (UFD)"); strcpy(result, "Cellebrite (UFD)");
} }
else if (detectImageSignatureWithOffset("ustar", 5, 257, buf, len)) {
strcpy(result, "Tar Archive");
}
else if (detectImageSignature("PK\x03\x04", 4, buf, len) || detectImageSignature("PK\x05\x06", 4, buf, len) else if (detectImageSignature("PK\x03\x04", 4, buf, len) || detectImageSignature("PK\x05\x06", 4, buf, len)
|| (detectImageSignature("PK\x07\x08", 4, buf, len))) { || (detectImageSignature("PK\x07\x08", 4, buf, len))) {
strcpy(result, "Zip Archive"); strcpy(result, "Zip Archive");
...@@ -79,6 +166,9 @@ char* detectUnsupportedImageType(TSK_IMG_INFO * img_info) { ...@@ -79,6 +166,9 @@ char* detectUnsupportedImageType(TSK_IMG_INFO * img_info) {
} }
else if (detectImageSignature("\x1f\x8b", 2, buf, len)) { else if (detectImageSignature("\x1f\x8b", 2, buf, len)) {
strcpy(result, "Gzip Archive"); strcpy(result, "Gzip Archive");
}
else if (verifyTarChecksum(buf, len)) {
strcpy(result, "Tar Archive");
} }
free(buf); free(buf);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment