summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--src/file_type.c795
-rw-r--r--src/magic_block_scan.c60
-rw-r--r--src/util.c22
-rw-r--r--src/util.h1
5 files changed, 780 insertions, 103 deletions
diff --git a/ChangeLog b/ChangeLog
index e4202b0..dca13d2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,7 @@
-
+ new : function for RPM and XCF(Gimp)
+ change : DEB; ZIP; TTF; some Perl and Python files
+ Optimization for text based files (not completed yet)
+
0.3.0-pv0 new : the first experimental version of the magic-functions for ext4
disabled : the magic-function for ext3 is switched off in this version
diff --git a/src/file_type.c b/src/file_type.c
index 760149f..5640149 100644
--- a/src/file_type.c
+++ b/src/file_type.c
@@ -53,9 +53,9 @@ int ident_file(struct found_data_t *new, __u32 *scan, char *magic_buf, char *buf
char messagestr[] ="news rfc822 ";
char modelstr[] ="vrml x3d ";
char applistr[] ="dicom mac-binhex40 msword octet-stream ogg pdf pgp pgp-encrypted pgp-keys pgp-signature postscript unknown+zip vnd.google-earth.kml+xml vnd.google-earth.kmz vnd.lotus-wordpro vnd.ms-cab-compressed vnd.ms-excel vnd.ms-tnef vnd.oasis.opendocument. vnd.rn-realmedia vnd.symbian.install x-123 x-adrift x-archive x-arc x-arj x-bittorrent x-bzip2 x-compress x-coredump x-cpio x-dbf x-dbm x-debian-package x-dosexec x-dvi x-eet x-elc x-executable x-gdbm x-gnucash x-gnumeric x-gnupg-keyring x-gzip x-hdf x-hwp x-ichitaro4 x-ichitaro5 x-ichitaro6 x-iso9660-image x-java-applet x-java-jce-keystore x-java-keystore x-java-pack200 x-kdelnk x-lha x-lharc x-lzip x-mif xml xml-sitemap x-msaccess x-ms-reader x-object x-pgp-keyring x-quark-xpress-3 x-quicktime-player x-rar x-rpm x-sc x-setupscript x-sharedlib x-shockwave-flash x-stuffit x-svr4-package x-tar x-tex-tfm x-tokyocabinet-btree x-tokyocabinet-fixed x-tokyocabinet-hash x-tokyocabinet-table x-xz x-zoo zip x-font-ttf x-7z-compressed ";
- char textstr[] = "html PGP rtf texmacs troff vnd.graphviz x-awk x-diff x-fortran x-gawk x-info x-lisp x-lua x-msdos-batch x-nawk x-perl x-php x-shellscript x-texinfo x-tex x-vcard x-xmcd plain x-pascal x-c++ x-c x-mail x-makefile x-asm x-python x-java text ";
+ char textstr[] = "html PGP rtf texmacs troff vnd.graphviz x-awk x-diff x-fortran x-gawk x-info x-lisp x-lua x-msdos-batch x-nawk x-perl x-php x-shellscript x-texinfo x-tex x-vcard x-xmcd plain x-pascal x-c++ x-c x-mail x-makefile x-asm x-python x-java PEM SGML libtool M3U tcl POD PPD configure ruby sed expect ssh text ";
//Files not found as mime-type
- char undefstr[] ="MPEG Targa 7-zip cpio CD-ROM DVD 9660 Kernel boot ext2 ext3 ext4 Image CDF SQLite OpenOffice.org Microsoft VMWare3 VMware4 JPEG ART PCX RIFF DIF IFF ATSC ScreamTracker EBML LZMA Audio=Visual Sample=Vision ISO=Media Linux filesystem x86 LUKS ";
+ char undefstr[] ="MPEG Targa 7-zip cpio CD-ROM DVD 9660 Kernel boot ext2 ext3 ext4 Image CDF SQLite OpenOffice.org Microsoft VMWare3 VMware4 JPEG ART PCX RIFF DIF IFF ATSC ScreamTracker EBML LZMA Audio=Visual Sample=Vision ISO=Media Linux filesystem x86 LUKS python ";
//-----------------------------------------------------------------------------------
char* p_search;
char token[30];
@@ -161,7 +161,7 @@ static int analysis_ret1(char* typename, struct found_data_t* f_data, int ret ,
break;
case 2 :
f_data->scantype |= DATA_READY;
- (f_data->buf_length)++;
+ if(offset % current_fs->blocksize)(f_data->buf_length)++;
break;
case 3 :
f_data->scantype = 0;
@@ -521,7 +521,11 @@ int file_bin_txt(unsigned char *buf, int *size, __u32 scan , int flag, struct fo
}
-static int follow_zip(unsigned char *buf, __u16 blockcount, __u32 *offset, __u32 *last_match, int flag){
+struct zip_priv_t{
+ int flag;
+ __u32 count;};
+
+static int follow_zip(unsigned char *buf, __u16 blockcount, __u32 *offset, __u32 *last_match, struct zip_priv_t * priv){
#define ZIP_CENTRAL_DIR 0x02014B50
#define ZIP_FILE_ENTRY 0x04034B50
#define ZIP_SIGNATURE 0x05054B50
@@ -534,63 +538,91 @@ static int follow_zip(unsigned char *buf, __u16 blockcount, __u32 *offset, __u32
__u32 i=*offset;
int ret = 1;
__u32 header;
+ __u32 end = (blockcount * current_fs->blocksize)-30;
__u16 *p_16;
__u32 *p_32;
- while ((ret == 1 )&& ( i < (blockcount * current_fs->blocksize)-30)){
- header = ext2fs_le32_to_cpu(*(__u32*)(buf+i));
- switch (header){
- case ZIP_CENTRAL_DIR :
- *last_match = i +1;
- p_16 = (__u16*)(buf+i+28);
- i += ext2fs_le16_to_cpu(*p_16);
- p_16++;
- i += ext2fs_le16_to_cpu(*p_16) + 46;
- p_16++;
- i += ext2fs_le16_to_cpu(*p_16);
- break;
- case ZIP_FILE_ENTRY :
- *last_match = i+1;
- p_32 = (__u32*)(buf+i+18);
- if (! ext2fs_le32_to_cpu(*p_32)){
- ret = 3;
+ while ((ret == 1 )&& ( i < end )){
+ if (priv->flag){
+ while ((i < end) && (!((buf[i] == 0x50) && (buf[i+1] ==0x4B) && (buf[i+2] ==0x07)&& (buf[i+3] ==0x08)))){
+ (priv->count)++;
+ i++;
+ if (priv->count > 4194304){ // only 4MB then we give up
+ ret = 3;
+ break;
+ }
+ }
+ if ((i == end)||(ret == 3))
break;
+ p_32 = (__u32*)(buf+i+8);
+ if (ext2fs_le32_to_cpu(*p_32) == priv->count){
+ priv->flag = 0;
+ *last_match = i+1;
}
- p_16 = (__u16*)(buf+i+26);
- i += ext2fs_le32_to_cpu(*p_32) + ext2fs_le16_to_cpu(*p_16);
- p_16++;
- i += ext2fs_le16_to_cpu(*p_16) + 30;
- break;
- case ZIP_SIGNATURE :
- *last_match = i +1;
- p_16 = (__u16*)(buf+i+4);
- i += ext2fs_le16_to_cpu(*p_16) + 6;
- break;
- case ZIP_END_CENTRAL_DIR :
- *last_match = i +1;
- p_16 = (__u16*)(buf+i+20);
- i += ext2fs_le16_to_cpu(*p_16) + 22;
- ret = 2;
- break;
-
- //I think the follow is never needed
- case ZIP_EXTRA_DATA :
- // p_32 = (__u32*)(buf+i+4);
- // i += ext2fs_le32_to_cpu(*p_16) + 8;
- //break;
- case ZIP_CENTRAL_DIR64 :
- // i + 12 ;
- // ret = 2 ;
- //break;
- case ZIP_END_CENTRAL_DIR64 :
- case ZIP_DATA_DESCRIPTOR :
- *last_match = i +1;
- ret = 3;
- break;
- default :
- ret = 0 ;
- break;
- }
+ else{
+ ret = 0;
+ break;
+ }
+ }
+ else{
+ header = ext2fs_le32_to_cpu(*(__u32*)(buf+i));
+ switch (header){
+ case ZIP_CENTRAL_DIR :
+ *last_match = i +1;
+ p_16 = (__u16*)(buf+i+28);
+ i += ext2fs_le16_to_cpu(*p_16);
+ p_16++;
+ i += ext2fs_le16_to_cpu(*p_16) + 46;
+ p_16++;
+ i += ext2fs_le16_to_cpu(*p_16);
+ break;
+ case ZIP_FILE_ENTRY :
+ *last_match = i+1;
+ p_32 = (__u32*)(buf+i+18);
+ if (! ext2fs_le32_to_cpu(*p_32)){
+ if ( (buf[i+6] & 0x08) ){
+ priv->flag = 1;
+ priv->count = 0;
+ }
+ }
+ p_16 = (__u16*)(buf+i+26);
+ i += ext2fs_le32_to_cpu(*p_32) + ext2fs_le16_to_cpu(*p_16);
+ p_16++;
+ i += ext2fs_le16_to_cpu(*p_16) + 30;
+ break;
+ case ZIP_SIGNATURE :
+ *last_match = i +1;
+ p_16 = (__u16*)(buf+i+4);
+ i += ext2fs_le16_to_cpu(*p_16) + 6;
+ break;
+ case ZIP_END_CENTRAL_DIR :
+ *last_match = i +1;
+ p_16 = (__u16*)(buf+i+20);
+ i += ext2fs_le16_to_cpu(*p_16) + 22;
+ ret = 2;
+ break;
+
+ //I think the follow is never needed
+ case ZIP_EXTRA_DATA :
+ // p_32 = (__u32*)(buf+i+4);
+ // i += ext2fs_le32_to_cpu(*p_16) + 8;
+ //break;
+ case ZIP_CENTRAL_DIR64 :
+ // i + 12 ;
+ // ret = 2 ;
+ //break;
+ case ZIP_END_CENTRAL_DIR64 :
+ case ZIP_DATA_DESCRIPTOR :
+ *last_match = i +1;
+ i+=16;
+ if (buf[i] != 0x50)
+ ret = 3;
+ break;
+ default :
+ ret = 0 ;
+ break;
+ }
+ }
}
*offset = i;
return ret;
@@ -647,6 +679,7 @@ return 0;
}
+
static int follow_zlib(unsigned char *buf, __u16 blockcount, __u32 *offset, __u32 *last_match, struct priv_zlib_t *priv){
int ret = 1; //priv->flag: Bit0=initialize2 ; Bit1=initialize ; Bit2=check maxout; Bit3=crc32 ; Bit15=Init
int z_ret = 0; //0x0b = initialize for gzip , or use 0x06 for z
@@ -921,24 +954,21 @@ int file_bzip2(unsigned char *buf, int *size, __u32 scan , int flag, struct foun
//zip
int file_zip(unsigned char *buf, int *size, __u32 scan , int flag, struct found_data_t* f_data){
- int ret = 0;
- int j,i, b_count;
+ int ret = 0;
+ int j,i, b_count;
unsigned char token[5];
- __u32 last_match = 0;
- __u32 offset;
+ __u32 last_match = 0;
+ struct zip_priv_t *z_priv = NULL;
+ __u32 offset;
sprintf(token,"%c%c%c%c",0x50,0x4b,0x05,0x06);
switch (flag){
case 0 :if(f_data->scantype & DATA_READY){
- *size = (f_data->next_offset)?f_data->next_offset : *size;
+ *size = (f_data->next_offset)?f_data->next_offset : current_fs->blocksize ;
ret = 1;
}
else{
- //if((!(f_data->inode->i_flags & EXT4_EXTENTS_FL))&&(f_data->size < (12 * current_fs->blocksize))){
- // f_data->inode->i_size = (f_data->size + current_fs->blocksize -1) & ~(current_fs->blocksize-1);
- // *size = f_data->size % current_fs->blocksize;
- //}
if((*size) > 22){
j = strlen(token) -1;
i = (*size -12);
@@ -954,8 +984,10 @@ int file_zip(unsigned char *buf, int *size, __u32 scan , int flag, struct found_
ret =1;
}
}
- else
+ else{
+ *size += 4;
ret = 2;
+ }
}
break;
case 1 :
@@ -963,15 +995,27 @@ int file_zip(unsigned char *buf, int *size, __u32 scan , int flag, struct found_
break;
case 2 :
offset = 0;
+ z_priv = malloc(sizeof(struct zip_priv_t));
+ if (!z_priv){
+ f_data->first = 0;
+ return 0;
+ }
+ z_priv->flag = 0;
+ z_priv->count = 0;
+ f_data->priv = z_priv;
b_count = (f_data->buf_length > 12) ? 12 : f_data->buf_length ;
- ret = follow_zip(buf, b_count, &offset, &last_match,0);
+ ret = follow_zip(buf, b_count, &offset, &last_match,f_data->priv);
ret = analysis_ret1("ZIP", f_data, ret , b_count, offset, last_match);
break;
case 3 :
offset = f_data->next_offset ;
- ret = follow_zip(buf, f_data->buf_length, &offset, &last_match,0);
+ ret = follow_zip(buf, f_data->buf_length, &offset, &last_match,f_data->priv);
ret = analysis_ret2("ZIP", f_data, ret, offset, last_match);
break;
+ case 4 :
+ if (f_data->priv)
+ free(f_data->priv);
+ break;
}
return ret;
}
@@ -1008,13 +1052,146 @@ int file_lzw(unsigned char *buf, int *size, __u32 scan , int flag, struct found_
return ret;
}
+//rpm
+int file_rpm(unsigned char *buf, int *size, __u32 scan , int flag, struct found_data_t* f_data){
+#define GZ_FTEXT 1
+#define GZ_FHCRC 2
+#define GZ_FEXTRA 4
+#define GZ_FNAME 8
+#define GZ_FCOMMENT 0x10
+
+ int i, z_flags, b_count, ret = 0;
+ __u32 offset;
+ __u32 last_match = 0;
+ struct priv_zlib_t *priv = NULL;
+ __u32 h_count,h_size;
+ __u32 p_size = 0;
+
+
+ switch (flag){
+ case 0 :
+ if(f_data->scantype & DATA_READY){
+ *size = (f_data->next_offset)?f_data->next_offset : *size;
+ ret = 1;
+ }
+ else{
+ if (f_data->scantype & DATA_LENGTH) {
+ if (f_data->inode->i_size < f_data->size)
+ ret = 0;
+ else{
+ p_size = ((f_data->size-1) % current_fs->blocksize)+1;
+ if (*size < p_size)
+ *size = p_size;
+ ret = 1;
+ }
+ }
+ else{
+ if(*size < (current_fs->blocksize -8))
+ ret = 1 ;
+ else {
+ if(*size < (current_fs->blocksize -4))
+ ret = 2 ;
+ }
+ *size += 2;
+ }
+ }
+ break;
+ case 1 :
+ return ((scan & (M_IS_META | M_CLASS_1 | M_BLANK | M_TXT))||(f_data->scantype & DATA_READY)) ? 0 :1 ;
+ break;
+ case 2 :
+ if (!((buf[0]==0xed)&&(buf[1]==0xab)&&(buf[2]==0xee)&&(buf[3]==0xdb)&&(buf[4]==0x03))){
+ f_data->func = file_default ;
+ return 0;
+ }
+ if (buf[7] == 1){
+ f_data->name[strlen(f_data->name)-3] = 0 ;
+ strncat(f_data->name,"srpm",6);
+ }
+ offset=96;
+ if ((buf[offset]== 0x8e)&&(buf[offset+1]== 0xad)&&(buf[offset+2]== 0xe8)) {
+ h_count=((buf[offset+8]<<24)|(buf[offset+9]<<16)|(buf[offset+10]<<8)|(buf[offset+11]));
+ h_size=((buf[offset+12]<<24)|(buf[offset+13]<<16)|(buf[offset+14]<<8)|(buf[offset+15]));
+ for (i=0;i<h_count;i++){
+ if((buf[offset+18+(i*16)]==0x03) && (buf[offset+19+(i*16)]==0xe8) && (buf[offset+23+(i*16)]==0x04)){
+ p_size =((buf[offset+24+(i*16)]<<24)|(buf[offset+25+(i*16)]<<16)|
+ (buf[offset+26+(i*16)]<<8)|(buf[offset+27+(i*16)]))+1;
+ break;
+ }
+ }
+ offset += (++h_count * 16);
+ if (p_size)
+ p_size = (buf[offset+p_size-1]<<24)|(buf[offset+p_size]<<16)|
+ (buf[offset+p_size+1]<<8)|(buf[offset+p_size+2]);
+ offset += ((h_size + 7) & ~7);
+ if (p_size)
+ p_size += offset;
+
+ if ((offset < 1024) && (buf[offset]== 0x8e)&&(buf[offset+1]== 0xad)&&(buf[offset+2]== 0xe8)) {
+ h_count=((buf[offset+8]<<24)|(buf[offset+9]<<16)|(buf[offset+10]<<8)|(buf[offset+11]));
+ h_size=((buf[offset+12]<<24)|(buf[offset+13]<<16)|(buf[offset+14]<<8)|(buf[offset+15]));
+ offset += ((++h_count * 16) + h_size);
+ }
+ }
+ b_count = (f_data->buf_length > 12) ? 12 : f_data->buf_length ;
+ if (((offset+12) > (b_count *current_fs->blocksize)) || (buf[offset]!=0x1F)||(buf[offset+1]!=0x8B)||
+ (buf[offset+2]!=0x08)||((buf[offset+3]&0xe0)!=0) || (init_priv_zlib(f_data))){
+ f_data->size = p_size ;
+ f_data->scantype = DATA_LENGTH ;
+ ret = 1;
+ break;
+ }
+ else {
+ ((struct priv_zlib_t*)(f_data->priv))->flag = 0xb;
+
+ if (!follow_zlib(NULL,0,NULL,NULL,(struct priv_zlib_t *)f_data->priv)){
+ z_flags=buf[offset+3];
+ offset += 10;
+ if((z_flags&GZ_FEXTRA)!=0){
+ offset += (buf[offset]|(buf[offset+1]<<8));
+ offset += 2;
+ }
+ if((z_flags&GZ_FNAME)!=0){
+ while( (offset < 256) && (buf[offset++]!='\0')){
+ }
+ }
+ if((z_flags&GZ_FCOMMENT)!=0){
+ while((offset<1024) && (buf[offset++]!='\0')){
+ }
+ }
+ if((z_flags&GZ_FHCRC)!=0){
+ offset+=2;
+ }
+ ret = follow_zlib(buf, b_count, &offset, &last_match,(struct priv_zlib_t *)f_data->priv);
+ ret = analysis_ret1("RPM", f_data, ret , b_count, offset, last_match);
+ }
+ else
+ f_data->first = 0;
+ }
+ break;
+ case 3 :
+ offset = f_data->next_offset ;
+ ret = follow_zlib(buf, f_data->buf_length, &offset, &last_match,(struct priv_zlib_t *)f_data->priv);
+ ret = analysis_ret2("RPM", f_data, ret, offset, last_match);
+ break;
+ case 4:
+ if (f_data->priv){
+ if (((struct priv_zlib_t*)(f_data->priv))->flag)
+ inflateEnd( &((struct priv_zlib_t*)(f_data->priv))->z_strm);
+ free(f_data->priv);
+ }
+ break;
+ }
+ return ret;
+}
//ttf
int file_ttf(unsigned char *buf, int *size, __u32 scan , int flag, struct found_data_t* f_data){
- int i,j,ret = 0;
+ __u32 table_id[9] = {0x70616d63,0x66796c67,0x64616568,0x61656868,0x78746d68,0x61636f6c,0x7078616d,0x656d616e,0x74736f70};
+ int i,j,id_count,ret = 0;
__u16 tables, s_range, shift;
- __u32 *p, tmp;
+ __u32 *p, id, tmp;
unsigned char *c;
switch (flag){
@@ -1025,23 +1202,26 @@ int file_ttf(unsigned char *buf, int *size, __u32 scan , int flag, struct found_
}
else {
*size = ((*size ) + 3) & ~3 ;
- ret = 4;
+ ret = 2;
}
break;
case 1 :return (scan & (M_IS_META | M_CLASS_1 | M_BLANK)) ? 0 :1 ;
break;
case 2 :
+ id_count = 0;
tables = (buf[4]<<8) + buf[5];
- s_range = (buf[6]<<8) + buf[7];
- shift = (buf[10]<<8) + buf[11];
- if ((!tables) || (((tables * 16) - s_range) != shift)){
- f_data->func = NULL;
- return 0;
- }
c = (unsigned char*) buf + 12;
for (i = 0; i< tables; i++){
+ p = (__u32*)c;
+ id = ext2fs_le32_to_cpu(*p);
+ for (j=0;j<9;j++){
+ if (id == table_id[j]){
+ id_count++;
+ break;
+ }
+ }
for (j=0;j<4;j++){
- if (( *c < 32) || (*c > 126)){
+ if (( *c < 32) || ((*c > 126) && (*c != 0xa9))){
f_data->func = NULL;
return 0;
}
@@ -1055,9 +1235,15 @@ int file_ttf(unsigned char *buf, int *size, __u32 scan , int flag, struct found_
f_data->size = tmp;
c+=12;
}
- f_data->size = (f_data->size +3) & ~3 ;
- f_data->scantype = DATA_LENGTH ;
- ret = 1;
+ if(id_count < 5){
+ f_data->func = NULL;
+ ret = 0;
+ }
+ else {
+ f_data->size = (f_data->size +3) & ~3 ;
+ f_data->scantype = DATA_LENGTH ;
+ ret = 1;
+ }
break;
}
return ret;
@@ -2747,7 +2933,33 @@ int file_binary(unsigned char *buf, int *size, __u32 scan , int flag, struct fou
return ret;
}
-
+
+
+//bin-raw
+int file_bin_raw(unsigned char *buf, int *size, __u32 scan , int flag, struct found_data_t* f_data){
+ int ret = 0;
+ switch (flag){
+ case 0 :
+ if(f_data->scantype & DATA_METABLOCK){
+ ret = 1;
+ break;
+ }
+ else{
+ if (*size < (current_fs->blocksize -8))
+ ret = 2;
+
+ if (*size < (current_fs->blocksize -16))
+ ret = 1;
+ }
+ break;
+ case 1 :
+ return (scan & (M_IS_META | M_CLASS_1)) ? 0 :1 ;
+ break;
+ }
+ return ret;
+}
+
+
int file_tfm(unsigned char *buf, int *size, __u32 scan , int flag, struct found_data_t* f_data){
int i,ret = 0;
@@ -3243,7 +3455,7 @@ int file_gif(unsigned char *buf, int *size, __u32 scan , int flag, struct found_
break;
case 2 :
f_data->scantype |= DATA_READY;
- (f_data->buf_length)++;
+ if(offset % current_fs->blocksize)(f_data->buf_length)++;
break;
}
@@ -3716,6 +3928,342 @@ return ret;
}
+struct xcf_priv_t {
+ int flag ;
+ __u32 width ;
+ __u32 height ;
+ int byte_p_pix ;
+ int s_count ;
+ int compress;
+ __u32 b_stream ;
+ __u32 l_offset ;
+};
+
+static int follow_xcf(unsigned char *buf, __u16 blockcount, __u32 *offset, __u32 *last_match, void *priv){
+ int i;
+ int ret = 1;
+ __u32 f_offset = *offset;
+ __u32 *p1, *p2;
+ __u32 type, pl, pointer;
+ __u32 end = (blockcount * current_fs->blocksize)-30;
+ struct xcf_priv_t *p_data = (struct xcf_priv_t*) priv;
+
+ while ( (ret == 1) && (f_offset < (end-1))){
+ switch (p_data->flag){
+ case 0://Master image structure
+ if ((!f_offset) &&(! p_data->b_stream)){
+ f_offset += 26;
+ p1 = (__u32*) (buf+14);
+ p_data->width = ext2fs_be32_to_cpu(*p1);
+ p1++;
+ p_data->height = ext2fs_be32_to_cpu(*p1);
+ }
+ do{ //Image properties
+ p1 = (__u32*) (buf+f_offset);
+ p2 = p1 +1;
+ type = ext2fs_be32_to_cpu(*p1);
+ pl = ext2fs_be32_to_cpu(*p2);
+ if ((type == 17) && (pl == 1))
+ p_data->compress = buf[f_offset+8];
+ if (type)
+ f_offset += (pl + 8);
+ }while(type && (type <28) && (f_offset < end));
+ if((!pl) && (!type)) {
+ f_offset += 8;
+ p_data->flag = 1;
+ }
+ if (type > 27)
+ ret = 0;
+ break;
+ case 1 : //Pointer to the layer structure
+ do{
+ p1 = (__u32*) (buf+f_offset);
+ pointer = ext2fs_be32_to_cpu(*p1);
+ if (p_data->l_offset < pointer)
+ p_data->l_offset = pointer;
+ if((p_data->s_count)++ > 256)
+ ret = 0;
+ f_offset += 4;
+ }while (ret && pointer && (f_offset < end));
+ if(ret && (f_offset < end)){
+ p_data->flag = 2;
+ p_data->s_count = 0;
+ }
+ break;
+ case 2 : //Pointer to the channel structure
+ do{
+ p1 = (__u32*) (buf+f_offset);
+ pointer = ext2fs_be32_to_cpu(*p1);
+ if (p_data->l_offset < pointer){
+ p_data->l_offset = pointer;
+ p_data->flag = 5; //FIXME
+ }
+ if((p_data->s_count)++ > 64)
+ ret = 0;
+ f_offset += 4;
+ }while (ret && pointer && (f_offset < end));
+ if(ret && (f_offset < end)){
+ (p_data->flag)++; //FIXME
+ f_offset = (p_data->l_offset - (p_data->b_stream - *offset));
+ }
+ break;
+ case 3 : //Layer structure
+ p1 = (__u32*) (buf+f_offset);
+ p_data->width = ext2fs_be32_to_cpu(*p1);
+ p1++;
+ p_data->height = ext2fs_be32_to_cpu(*p1);
+ p1++;
+ switch (ext2fs_be32_to_cpu(*p1)){
+ case 0 : p_data->byte_p_pix = 3 ; break;
+ case 1 : p_data->byte_p_pix = 4 ; break;
+ case 2 :
+ case 4 : p_data->byte_p_pix = 1 ; break;
+ case 3 :
+ case 5 : p_data->byte_p_pix = 2 ; break;
+ default : p_data->byte_p_pix = 0;
+ }
+ if (p_data->width && p_data->height && p_data->byte_p_pix){
+ p1++; //Layer name
+ pl = ext2fs_be32_to_cpu(*p1);
+ if ((f_offset + 20 + pl) < end){
+ f_offset += 16;
+ if (pl){
+ for (i=0; i < (pl-1); i++){
+ if (! isprint(buf[f_offset+i])){
+ if (! is_unicode(buf+f_offset+i))
+ ret = 0;
+ break;
+ }
+ }
+ }
+ if (ret && (!buf[f_offset + pl -1])){
+ *last_match = f_offset;
+ f_offset += pl;
+ p_data->flag = 4;
+ }
+ }
+ else {
+ end = f_offset;
+ break;
+ }
+ }
+ if (p_data->flag != 4)
+ ret = 0;
+ break;
+ case 7 : //Channel or Mask properties
+ case 4 : //Layer properties
+ do{
+ p1 = (__u32*) (buf+f_offset);
+ p2 = p1 +1;
+ type = ext2fs_be32_to_cpu(*p1);
+ pl = ext2fs_be32_to_cpu(*p2);
+ if (type)
+ f_offset += (pl + 8);
+ }while(type && (type <28) && (f_offset < end));
+ if((!pl) && (!type)) {
+ f_offset += 8;
+ (p_data->flag)++;
+ }
+ if (type > 27)
+ ret = 0;
+ break;
+ case 5 : //Pointer to the hierarchy structure
+ p1 = (__u32*) (buf+f_offset);
+ pointer = ext2fs_be32_to_cpu(*p1);
+ if (p_data->l_offset < pointer){
+ p_data->l_offset = pointer;
+ p_data->flag = 9;
+ }
+ p1++; //Pointer to the layer mask (a channel structure)
+ pointer = ext2fs_be32_to_cpu(*p1);
+ if (pointer &&(p_data->l_offset < pointer)){
+ p_data->l_offset = pointer;
+ p_data->flag = 6;
+ }
+ f_offset += 8;
+ if (p_data->flag == 5)
+ ret = 0;
+ else {
+ *last_match = f_offset;
+ if (p_data->l_offset < ((p_data->b_stream - *offset) + f_offset)){
+ ret = 3;
+ break;
+ }
+ else
+ f_offset = (p_data->l_offset - (p_data->b_stream - *offset));
+ }
+ break;
+ case 6 : //Channel structure (layer masks or from the master image structure)
+ p1 = (__u32*) (buf+f_offset);
+ p2 = p1 +1;
+ if ((p_data->width == ext2fs_be32_to_cpu(*p1)) && (p_data->height == ext2fs_be32_to_cpu(*p2))){
+ p2++; //Channel or Mask name
+ pl = ext2fs_be32_to_cpu(*p2);
+ if ((f_offset + 20 + pl) < end){
+ f_offset += 12;
+ if (pl){
+ for (i=0; i < (pl-1); i++){
+ if (! isprint(buf[f_offset +i])){
+ if (! is_unicode(buf+f_offset+i))
+ ret = 0;
+ break;
+ }
+ }
+ }
+ if (ret && (!buf[f_offset + pl -1])){
+ *last_match = f_offset;
+ f_offset += pl;
+ p_data->flag = 7;
+ }
+ }
+ else {
+ end = f_offset;
+ break;
+ }
+ }
+ if (p_data->flag == 6)
+ ret = 0;
+ else {
+ *last_match = f_offset;
+ }
+ break;
+ case 8 : //Pointer to the hierarchy structure
+ p1 = (__u32*) (buf+f_offset);
+ pointer = ext2fs_be32_to_cpu(*p1);
+ if (p_data->l_offset < pointer){
+ p_data->l_offset = pointer;
+ p_data->flag = 9;
+ }
+ f_offset += 4;
+ if (p_data->flag == 8)
+ ret = 0;
+ else {
+ *last_match = f_offset;
+ if (p_data->l_offset < ((p_data->b_stream - *offset) + f_offset)){
+ ret = 3;
+ break;
+ }
+ else
+ f_offset = (p_data->l_offset - (p_data->b_stream - *offset));
+ }
+ break;
+ case 9 : //hierarchy structure
+ p1 = (__u32*) (buf+f_offset);
+ p2 = p1 +1;
+ if ((p_data->width == ext2fs_be32_to_cpu(*p1)) && (p_data->height == ext2fs_be32_to_cpu(*p2))){
+ p2 += 3;
+ p_data->l_offset = ext2fs_be32_to_cpu(*p2);
+ if ((p_data->l_offset)&& (p_data->l_offset > ((p_data->b_stream - *offset) + f_offset))){
+ *last_match = f_offset;
+ f_offset = (p_data->l_offset - (p_data->b_stream - *offset));
+ p_data->flag = 10;
+ }
+ else{
+ ret = 3;
+ break;
+ }
+ }
+ if (p_data->flag == 9)
+ ret = 0;
+ break;
+ case 10 ://Pointer to unused level structure
+ if (f_offset < (end -120)){
+ do {
+ p1 = (__u32*) (buf+f_offset);
+ p2 = p1 +1;
+ p_data->width >>= 1;
+ p_data->height >>= 1;
+ if (!((p_data->width == ext2fs_be32_to_cpu(*p1)) && (p_data->height == ext2fs_be32_to_cpu(*p2)))){
+ ret = 0;
+ }
+ else {
+ f_offset += 12;
+ }
+ }while ((p_data->width > 64) || (p_data->height > 64));
+ if (ret)
+ ret = 2;
+ }
+ else
+ end = f_offset;
+ break;
+ }
+ }
+ p_data->b_stream += (f_offset - *offset);
+ *offset = f_offset;
+
+return ret;
+}
+
+
+//xcf
+int file_xcf(unsigned char *buf, int *size, __u32 scan , int flag, struct found_data_t* f_data){
+ int i,ret = 0;
+ struct xcf_priv_t *priv;
+ __u32 offset;
+ __u32 last_match = 0;
+ __u32 b_count;
+
+
+ switch (flag){
+ case 0 :
+ if(f_data->scantype & DATA_READY){
+ *size = (f_data->next_offset)?f_data->next_offset : *size;
+ ret = 1 ;
+ }
+ else {
+ __u32 *p1;
+ __u32 e[4];
+ if (*size > 16){
+ p1 = (__u32*) (buf + *size -4);
+ for (i = 0; i<4; i++){
+ e[i] = ext2fs_be32_to_cpu(*p1);
+ p1--;
+ }
+ if((e[0]<65) && ((!e[1])||(!e[2])) && ((e[3] & ~1) == (e[0]<<1))){
+ ret = 1;
+ *size += 4;
+ break;
+ }
+ }
+ if (*size < (current_fs->blocksize - 8))
+ ret = 2;
+ if (*size < (current_fs->blocksize - 12))
+ ret = 1;
+ *size += 4;
+ }
+ break;
+ case 1 :return ((scan & (M_IS_META | M_CLASS_1 | M_BLANK ))||(f_data->scantype & DATA_READY)) ? 0 :1 ;
+ break;
+ case 2 :
+ if ((buf[8]==0x20) && (!buf[13]) && (!buf[22]) && (!buf[23]) && (!buf[24]) && (buf[25]<4)
+ && (f_data->priv = malloc(sizeof(struct xcf_priv_t)))){
+
+ f_data->priv_len = sizeof(struct xcf_priv_t);
+ memset(f_data->priv,0,sizeof(struct xcf_priv_t));
+ f_data->last_match_blk =1;
+ } else{
+ f_data->first = 0;
+ return 0;
+ }
+ offset = 0;
+ b_count = (f_data->buf_length > 12) ? 12 : f_data->buf_length ;
+ ret = follow_xcf(buf,b_count, &offset, &last_match,f_data->priv);
+ ret = analysis_ret1("XCF", f_data, ret , b_count, offset, last_match);
+ break;
+ case 3 :
+ offset = f_data->next_offset ;
+ ret = follow_xcf(buf, f_data->buf_length, &offset, &last_match,f_data->priv);
+ ret = analysis_ret2("XCF", f_data, ret, offset, last_match);
+ break;
+ case 4:
+ if (f_data->priv)
+ free(f_data->priv);
+ break;
+ }
+return ret;
+}
+
+
//ico
int file_ico(unsigned char *buf, int *size, __u32 scan , int flag, struct found_data_t* f_data){
@@ -4750,7 +5298,7 @@ static const unsigned char token1[4]= {0x00,0x00,0x01,0xb7};
break;
case 2 :
f_data->scantype |= DATA_READY;
- (f_data->buf_length)++;
+ if(offset % current_fs->blocksize)(f_data->buf_length)++;
break;
case 3:
// fprintf(stderr,"MPEG-CHECK: mpeg-sequence found, H_F-Carving on\n");
@@ -6364,7 +6912,7 @@ switch (flag){
case 2 :
if (offset){
f_data->scantype |= DATA_READY;
- (f_data->buf_length)++;
+ if(offset % current_fs->blocksize)(f_data->buf_length)++;
}
else {
f_data->func = NULL;
@@ -6612,7 +7160,7 @@ void get_file_property(struct found_data_t* this){
break;
case 0x0120 : //x-dbf
- // this->func = file_x-dbf ;
+//FIXME this->func = file_dbf ;
strncat(this->name,".dbf",7);
break;
@@ -6622,7 +7170,7 @@ void get_file_property(struct found_data_t* this){
break;
case 0x0122 : //x-debian-package
- // this->func = file_x-debian-package ;
+ this->func = file_archive;
strncat(this->name,".deb",7);
break;
@@ -6797,7 +7345,7 @@ void get_file_property(struct found_data_t* this){
break;
case 0x0145 : //x-rpm
- // this->func = file_x-rpm ;
+ this->func = file_rpm ;
strncat(this->name,".rpm",7);
break;
@@ -7076,7 +7624,7 @@ void get_file_property(struct found_data_t* this){
break;
case 0x0317 : //x-xcf
- // this->func = file_x-xcf;
+ this->func = file_xcf;
strncat(this->name,".xcf",7);
break;
@@ -7226,7 +7774,7 @@ void get_file_property(struct found_data_t* this){
case 0x0618 : //x-pascal (often c files)
this->func = file_txt ;
- strncat(this->name,".c",7);
+ strncat(this->name,".pas",7);
break;
case 0x0619 : //c++
@@ -7264,7 +7812,67 @@ void get_file_property(struct found_data_t* this){
strncat(this->name,".jar",7);
break;
- case 0x0620 : //text (for all unknown)
+ case 0x0620 : //PEM
+ this->func = file_txt ;
+ strncat(this->name,".pem",7);
+ break;
+
+ case 0x0621 : //SGML
+ this->func = file_txt ;
+ strncat(this->name,".rc",7);
+ break;
+
+ case 0x0622 : //libtool
+ this->func = file_txt ;
+ strncat(this->name,".la",7);
+ break;
+
+ case 0x0623 : //M3U
+ this->func = file_txt ;
+ strncat(this->name,".m3u",7);
+ break;
+
+ case 0x0624 : //tcl
+ this->func = file_txt ;
+ strncat(this->name,".tcl",7);
+ break;
+
+ case 0x0625 : //POD
+ this->func = file_txt ;
+ strncat(this->name,".pod",7);
+ break;
+
+ case 0x0626 : //PPD
+ this->func = file_txt ;
+ strncat(this->name,".ppd",7);
+ break;
+
+ case 0x0627 : //configure
+ this->func = file_txt ;
+ strncat(this->name,".conf",7);
+ break;
+
+ case 0x0628 : //ruby
+ this->func = file_txt ;
+ strncat(this->name,".rb",7);
+ break;
+
+ case 0x0629 : //sed
+ this->func = file_txt ;
+ strncat(this->name,".sed",7);
+ break;
+
+ case 0x062a : //expect
+ this->func = file_txt ;
+// strncat(this->name,".expect",8);
+ break;
+
+ case 0x062b : //ssh
+ this->func = file_txt ;
+ strncat(this->name,".key",7);
+ break;
+
+ case 0x062c : //text (for all unknown)
this->func = file_txt ;
strncat(this->name,".txt",7);
break;
@@ -7552,6 +8160,11 @@ void get_file_property(struct found_data_t* this){
strncat(this->name,".luks",7);
break;
+ case 0x0825 : //python (binary)
+ this->func = file_bin_raw ;
+ strncat(this->name,".pyc",7);
+ break;
+
//----------------------------------------------------------------
default:
this->func = file_default ;
diff --git a/src/magic_block_scan.c b/src/magic_block_scan.c
index 1efacf3..948dcfe 100644
--- a/src/magic_block_scan.c
+++ b/src/magic_block_scan.c
@@ -554,8 +554,11 @@ static int magic_check_block(unsigned char* buf,magic_t cookie , magic_t cookie_
if (deep && count && (count > 60))// current_fs->blocksize))
strncpy(magic_buf, magic_buffer(cookie , buf , count-1),60);
}
-
+//loop:
if ((strstr(magic_buf,"text/plain"))||(strstr(magic_buf,"text/html"))){
+ char *type;
+ char searchstr[] = "bin/perl python PEM SGML OpenSSH libtool M3U Tcl=script Perl=POD module=source PPD make=config bin/make awk bin/ruby bin/sed bin/expect bash ";
+ char searchtype[] = "text/x-perl text/x-python text/PEM text/SGML text/ssh text/libtool text/M3U text/tcl text/POD text/x-perl text/PPD text/configure text/x-makefile text/x-awk text/ruby text/sed text/expect text/x-shellscript ";
if (deep && (count > 250) && (!strncmp(buf,"From ",5))){
p_search = buf + 6;
for (len = 0; (len < (count -7)) ; len++){
@@ -573,17 +576,52 @@ static int magic_check_block(unsigned char* buf,magic_t cookie , magic_t cookie_
}
}
if(!(strstr(magic_buf,"text/html"))){
- if(deep && (count < (current_fs->blocksize -2))) {
- p_search = buf + 6;
- for (len = 0; len < 15 ; len++)
- if( *(p_search++) == 0x20)
- break;
- if (len < 15){
- retval = M_TXT | M_CLASS_2 ;
- goto out;
+ if (deep){
+//FIXME
+ p_search = searchstr;
+ type = searchtype;
+ while (*p_search){
+ len=0;
+ while((*p_search) != 0x20){
+ token[len] = ((*p_search)==0x3d)? 0x20 : (*p_search);
+ p_search++;
+ len++;
+ }
+ token[len] = 0;
+ if (strstr(text,token)){
+ len = 0;
+ while (type[len] != 0x20){
+ magic_buf[len] = type[len];
+ len++;
+ }
+ magic_buf[len] = 0;
+ retval = (M_TXT | M_CLASS_1);
+ goto out;
+ }
+ p_search++;
+ while (type[0] != 0x20)
+ type++;
+ if (*type)
+ type++;
+ }
+
+ if((count < (current_fs->blocksize -2)) || (!buf[-1])){
+ p_search = buf + 6;
+ for (len = 0; len < 20 ; len++){
+ if((*p_search ==0x0a) || (*(p_search++) == 0x20))
+ break;
+ }
+ if (len < 20){
+ for (len = 6; len < 80 ; len++)
+ if( buf[len] == 0x0a)
+ break;
+ if (len <80){
+ retval = M_TXT | M_CLASS_2 ;
+ goto out;
+ }
+ }
}
}
-//FIXME
retval |= (M_DATA | M_TXT) ;
goto out;
}
@@ -653,7 +691,7 @@ static int magic_check_block(unsigned char* buf,magic_t cookie , magic_t cookie_
}
if (strstr(magic_buf,"application/octet-stream")){
- char searchstr[] = "7-zip cpio CD-ROM MPEG 9660 Targa Kernel boot SQLite OpenOffice.org VMWare3 VMware4 JPEG ART PCX IFF DIF RIFF ATSC ScreamTracker matroska LZMA Audio=Visual Sample=Vision ISO=Media ext2 ext3 ext4 LUKS ";
+ char searchstr[] = "7-zip cpio CD-ROM MPEG 9660 Targa Kernel boot SQLite OpenOffice.org VMWare3 VMware4 JPEG ART PCX IFF DIF RIFF ATSC ScreamTracker matroska LZMA Audio=Visual Sample=Vision ISO=Media ext2 ext3 ext4 LUKS python ";
p_search = searchstr;
while (*p_search){
len=0;
diff --git a/src/util.c b/src/util.c
index 4984794..c98a98a 100644
--- a/src/util.c
+++ b/src/util.c
@@ -660,3 +660,25 @@ int zero_space(unsigned char *buf, __u32 offset){
i++;
return (i == end ) ? 1 : 0 ;
}
+
+int is_unicode( unsigned char* buf){
+ int ret = 0;
+ unsigned char *p = buf;
+ unsigned char *p1 = buf +1;
+ if ((*p > 0xc1) && (*p < 0xf5) && (*p1 > 0x7f) && (*p1 < 0xc0)){
+ if (!(*p & 0x20))
+ ret = 2;
+ else{
+ p1++;
+ if ((!(*p & 0x10)) && (*p1 > 0x7f) && (*p1 < 0xc0))
+ ret = 3 ;
+ else{
+ p1++;
+ if ((!(*p & 0x08)) && (*p1 > 0x7f) && (*p1 < 0xc0))
+ ret = 4 ;
+ }
+ }
+ }
+ return ret;
+}
+
diff --git a/src/util.h b/src/util.h
index 7dc4033..1299f62 100644
--- a/src/util.h
+++ b/src/util.h
@@ -177,6 +177,7 @@ int check_fs_open(char*);
void reset_getopt(void);
unsigned long parse_ulong(const char* , const char* , const char* , int* );
int zero_space(unsigned char*, __u32 );
+int is_unicode( unsigned char* );
// public functions lookup_local.c
void list_dir(ext2_ino_t inode); //list dir (using normal functions from ext2fs)