summaryrefslogtreecommitdiff
path: root/src/magic_block_scan.c
diff options
context:
space:
mode:
authorrobi <robi>2010-09-16 17:22:29 +0000
committerrobi <robi>2010-09-16 17:22:29 +0000
commitd90aa9c825e6c2dda92c65238afc782c99f9f0b2 (patch)
tree0f81ad6d93e26446afbf38f39d13baebf44cdb94 /src/magic_block_scan.c
parent6512ac6340cc34ed778505293943b664e4ec1b4c (diff)
magic functions part3 (inactiv)
Diffstat (limited to 'src/magic_block_scan.c')
-rw-r--r--src/magic_block_scan.c632
1 files changed, 584 insertions, 48 deletions
diff --git a/src/magic_block_scan.c b/src/magic_block_scan.c
index 76792e7..979d7d9 100644
--- a/src/magic_block_scan.c
+++ b/src/magic_block_scan.c
@@ -27,70 +27,606 @@
#include <string.h>
#include "util.h"
+#include "inode.h"
#include "magic.h"
-extern ext2_filsys current_fs ;
+#define MAX_RANGE 16
+extern ext2_filsys current_fs ;
ext2fs_block_bitmap d_bmap = NULL ;
-void magic_block_scan(char* des_dir, __u32 t_after){
- int retval;
- blk_t blk, o_blk;
- int ret, load_db;
- struct ext2fs_struct_loc_generic_bitmap *ds_bmap;
- char *block_buf = NULL;
- magic_t cookie;
- int m_result;
+__u32 get_block_len(char *buf){
+ int len = current_fs->blocksize -1;
- cookie = magic_open(MAGIC_NO_CHECK_COMPRESS | MAGIC_NO_CHECK_ELF | MAGIC_NO_CHECK_TAR);
- if ((cookie) && (! magic_load(cookie, NULL))){
+ while ((len >= 0) && (!(*(buf + len))))
+ len--;
+ return ++len;
+}
- retval = init_block_bitmap_list(&d_bmap, t_after);
- while (retval){
- retval = next_block_bitmap(d_bmap);
- if (retval == 2 )
- continue;
- if (d_bmap && retval ){
-
- ds_bmap = (struct ext2fs_struct_loc_generic_bitmap *) d_bmap;
- block_buf = malloc(current_fs->blocksize);
- if (block_buf){
- for (blk = ds_bmap->start; blk <ds_bmap->real_end; blk++){
- if (! (blk & 0x7)){
- o_blk = blk >> 3;
- while ((! *(ds_bmap->bitmap + o_blk)) && (o_blk <= (ds_bmap->real_end >> 3)))
- o_blk ++;
- blk = o_blk << 3;
- }
- if (blk >= ds_bmap->real_end)
- break;
-//FIXME in work
- if (ext2fs_test_block_bitmap ( d_bmap, blk) && (! ext2fs_test_block_bitmap( bmap, blk))){
- printf(" read block : %u\n",blk);
- ret = io_channel_read_blk ( current_fs->io, blk, 1, block_buf );
- if (ret){
- fprintf(stderr,"ERROR: while read block %10u\n",blk);
- }
- m_result = magic_check_block(block_buf,cookie,current_fs->blocksize,blk);
- }
- }
- free(block_buf);
+struct found_data_t* free_file_data(struct found_data_t* old){
+ if(old->inode) free(old->inode);
+ if(old->scan_result) free(old->scan_result);
+ if(old->name) free(old->name);
+ free(old);
+ old = NULL;
+ return old;
+}
+
+
+
+struct found_data_t* new_file_data(blk_t blk,__u32 scan,char *magic_buf, char* buf, __u32 *f){
+ struct found_data_t *new;
+ int str_len;
+ __u32 name_len;
+ char *c;
+ int def_len = 20;
+
+ new = malloc(sizeof(struct found_data_t));
+ if (!new) return NULL;
+
+ new->first = blk;
+ new->last = blk;
+ new->leng = 0;
+ new->scan = scan;
+ new->size = 0;
+ new->func = NULL;
+ if ( ident_file(new,&scan,magic_buf,buf)){
+ new->type = scan;
+ str_len = strlen(magic_buf) + 1;
+ c = strpbrk(magic_buf,";:, ");
+ if (c)
+ name_len = c - magic_buf + def_len;
+ else
+ name_len = str_len + def_len;
+
+ new->scan_result = malloc(str_len);
+ new->name = malloc(name_len);
+ new->inode = new_inode();
+ if((!new->scan_result) || (!new->name) || (!new->inode)){
+ new = free_file_data(new);
+ fprintf(stderr,"ERROR; while allocate memory for found file struct\n");
+ }
+ else{
+ strcpy(new->scan_result,magic_buf);
+ strncpy(new->name, magic_buf , name_len - 20);
+ sprintf(new->name + name_len - 20,"/%010u",blk);
+ get_file_property(new);
+ new->func(buf,&name_len,scan,2,new);
+ }
+}
+ *f++;
+return new;
+}
+
+
+
+
+struct found_data_t* recover_file_data(char *des_dir, struct found_data_t* this, __u32 *follow){
+ recover_file(des_dir,"MAGIC_3",this->name,(struct ext2_inode*)this->inode, 0 , 1);
+ free_file_data(this);
+ *follow = 0;
+ return NULL;
+}
+
+
+
+
+struct found_data_t* forget_file_data(struct found_data_t* this, __u32 *p_follow){
+ printf("TRASH : %s : leng %lu : begin %lu\n", this->name, this->inode->i_size , this->first);
+ free_file_data(this);
+ *p_follow = 0;
+ return NULL;
+}
+
+
+
+
+__u32 add_file_data(struct found_data_t* this, blk_t blk, __u32 scan ,__u32 *f){
+ __u32 retval = 0;
+
+ if (inode_add_block(this->inode , blk , current_fs->blocksize)){
+ this->leng++;
+ this->last = blk;
+ *f++ ;
+ }
+return *f ;
+}
+
+
+
+int file_data_correct_size(struct found_data_t* this, int size){
+ unsigned long long i_size;
+ int flag=0;
+
+ if (size <= current_fs->blocksize){
+ flag = 1;
+ i_size = (((unsigned long long)this->inode->i_size_high) << 32) + this->inode->i_size;
+ i_size -= (current_fs->blocksize - size);
+ this->inode->i_size = i_size & 0xffffffff ;
+ this->inode->i_size_high = i_size >> 32 ;
+ }
+ return flag;
+}
+
+
+
+int check_file_data_end(struct found_data_t* this,char *buf){
+ int size;
+ int ret = 0;
+
+ size = get_block_len(buf);
+ ret = this->func(buf, &size ,this->scan ,0 , this);
+
+ if (ret)
+ ret = file_data_correct_size(this,size);
+ return ret;
+}
+
+
+
+
+//?????
+int check_data_passage(char *a_buf, char *b_buf){
+ int i, blocksize;
+ int sum[4][2];
+
+
+
+}
+
+
+//FIXME obsolete: must switch to FLAG=1 of func() of the filetype
+int check_file_data_possible(struct found_data_t* this, __u32 scan ,char *buf, __u32 follow){
+ int ret = 0;
+ switch (this->scan & M_IS_FILE){
+// case (M_TXT | M_APPLI) :
+ case M_TXT :
+ if (scan & M_TXT) ret = 1;
+ break;
+ case M_VIDEO :
+ case M_AUDIO :
+ case M_IMAGE :
+ if (!(scan & M_IS_META)) ret = 1;
+ break;
+ case M_APPLI :
+ if (!(scan & M_IS_META)) ret = 1;
+ break;
+ }
+ if (!(this->scan & M_IS_FILE))
+ ret = 1;
+ return ret;
+}
+
+
+
+
+int add_ext3_file_meta_data(struct found_data_t* this, char *buf, blk_t blk){
+ blk_t next_meta;
+ blk_t last_data = 0;
+ next_meta = inode_add_meta_block(this->inode , blk, &last_data, buf );
+ this->last = last_data;
+
+ if (next_meta > 10 && (ext2fs_test_block_bitmap ( d_bmap, next_meta) && (! ext2fs_test_block_bitmap( bmap, next_meta)))){
+ io_channel_read_blk ( current_fs->io, next_meta, 1, buf );
+
+ if (check_meta3_block(buf, blk, get_block_len(buf))){
+ next_meta = inode_add_meta_block(this->inode , next_meta , &last_data, buf );
+ this->last = last_data;
+
+ if (next_meta > 10 && (ext2fs_test_block_bitmap ( d_bmap, next_meta) && (! ext2fs_test_block_bitmap( bmap, next_meta)))){
+ io_channel_read_blk ( current_fs->io, next_meta, 1, buf );
+
+ if (check_meta3_block(buf, blk, get_block_len(buf))){
+ next_meta = inode_add_meta_block(this->inode , next_meta , &last_data, buf );
+ this->last = last_data;
}
- else
- printf("can't allocate memory for blocksearch\n");
+ }
+ }
+ }
+return (next_meta) ? 0 : 1 ;
+}
+
+
+
+blk_t check_indirect_meta3(char *block_buf,blk_t blk, __u32 blocksize){
+ blk_t *pb_block;
+ blk_t last;
+ int i = blocksize/sizeof(blk_t);
+ int count=0;
+
+ pb_block = (blk_t*)block_buf;
+ last = ext2fs_le32_to_cpu(*pb_block);
+ while (i && last ) {
+ pb_block++;
+ i--;
+ if ((ext2fs_le32_to_cpu(*pb_block) -1) == last)
+ count++;
+ if (ext2fs_le32_to_cpu(*pb_block))
+ last = ext2fs_le32_to_cpu(*pb_block);
+ else
+ break;
+ }
+ return (count>3) ? last : blk ;
+}
+
+
+
+int check_meta3_block(char *block_buf, blk_t blk, __u32 size){
+ blk_t block, *pb_block;
+ int i,j ;
+
+ size = (size + 3) & 0xFFFFFC ;
+ if (! size ) return 0;
+
+ for (i = size-4 ; i>=0 ; i -= 4){
+ pb_block = (blk_t*)(block_buf+i);
+ block = ext2fs_le32_to_cpu(*pb_block);
+ if( block && (block < current_fs->super->s_blocks_count) &&
+ (ext2fs_test_block_bitmap( d_bmap, block)) && (!ext2fs_test_block_bitmap(bmap,block))){
+ if (i) {
+ for (j = i - 4 ; j >= 0 ;j -= 4){
+ if (block == ext2fs_le32_to_cpu(*((blk_t*)(block_buf+j))))
+ return 0;
+ }
+ }
+ else {
+ if (block == blk+1)
+ return 1;
}
- clear_block_bitmap_list(d_bmap);
+
}
- if(cookie) magic_close(cookie);
+ else
+ return 0;
}
-//FIXME only if needed
-if(d_bmap)
- ext2fs_free_block_bitmap(d_bmap);
+}
+
+
+int check_meta4_block(char *block_buf, blk_t blk, __u32 size){
+ __u16 *p_h16;
+ __u16 h16;
+
+ if(!((block_buf[0] == (char)0x0a) && (block_buf[1] == (char)0xf3)))
+ return 0;
+ p_h16 = (__u16*)block_buf+2;
+ h16 = ext2fs_le16_to_cpu(*p_h16);
+ p_h16 = (__u16*)block_buf+4;
+ if (ext2fs_le16_to_cpu(*p_h16) != (__u16)((current_fs->blocksize -12)/ 12))
+ return 0;
+ if ((!h16) || (h16 > ext2fs_le16_to_cpu(*p_h16)))
+ return 0;
+
+ return 1 ;
}
+
+
+
+
+int check_dir_block(char *block_buf, blk_t blk, __u32 size){
+ struct ext2_dir_entry_2 *dir_entry;
+ ext2_ino_t inode_nr;
+ __u16 len;
+
+ dir_entry = (struct ext2_dir_entry_2*)block_buf;
+
+ inode_nr = ext2fs_le32_to_cpu(dir_entry->inode);
+ if ((inode_nr && (inode_nr < EXT2_GOOD_OLD_FIRST_INO)) || (inode_nr > current_fs->super->s_inodes_count))
+ return 0;
+ len = ext2fs_le16_to_cpu(dir_entry->rec_len);
+ if ((len < 8) || (len % 4) || (len > current_fs->blocksize) ||(len < (((unsigned)dir_entry->name_len + 11) & ~3 )))
+ return 0;
+ if ((dir_entry->name_len & 0x01) && dir_entry->name[(unsigned)dir_entry->name_len])
+ return 0;
+ if (len < current_fs->blocksize - 12){
+ dir_entry = (struct ext2_dir_entry_2*) (block_buf + len);
+ len = ext2fs_le16_to_cpu(dir_entry->rec_len);
+ if ((len < 8) || (len % 4) || (len > current_fs->blocksize) ||(len < (((unsigned)dir_entry->name_len + 11) & ~3 )))
+ return 0;
+ if ((dir_entry->name_len & 0x01) && dir_entry->name[(unsigned)dir_entry->name_len])
+ return 0;
+ }
+ return 1;
+}
+
+
+// skip not of interest blocks : return 1 if skiped
+static int skip_block(blk_t *p_blk ,struct ext2fs_struct_loc_generic_bitmap *ds_bmap ){
+ struct ext2fs_struct_loc_generic_bitmap *p_bmap;
+ blk_t o_blk;
+ int flag = 0;
+
+ o_blk = (*p_blk) >> 3;
+ p_bmap = (struct ext2fs_struct_loc_generic_bitmap *) bmap;
+ while (((! *(ds_bmap->bitmap + o_blk)) || (*(ds_bmap->bitmap + o_blk) == 0xff)) && (o_blk < (ds_bmap->real_end >> 3))){
+ o_blk ++;
+ flag = 1;
+ }
+ *p_blk = o_blk << 3 ;
+
+return flag;
+}
+
+
+//magic scanner
+int magic_check_block(char* buf,magic_t cookie , magic_t cookie_f, char *magic_buf, __u32 size, blk_t blk){
+ int count = size-1;
+ int *i , len;
+ char text[100];
+ char *p_search;
+ __u32 retval = 0;
+ char searchstr[] = "7-zip cpio image Image filesystem CD-ROM MPEG 9660 Targa Kernel boot Linux x86 ";
+ char token[10];
+
+ strncpy(text,magic_buffer(cookie_f,buf , size),99);
+ strncpy(magic_buf, magic_buffer(cookie , buf , size),99);
+ while (count >= 0 && (*(buf+count) == 0)) count-- ;
+
+ printf("Scan Result : %s %d\n", magic_buf , count+1) ;
+ printf("RESULT : %s \n",text);
+
+
+ if (!strncmp(text,"data",4)){
+ if (count == -1) {
+ retval |= M_BLANK;
+ goto out;
+ }
+ }
+
+ if((strstr(magic_buf,"text/")) && (strstr(text,"text"))){
+ retval |= M_TXT ;
+ }
+
+ if (strstr(magic_buf,"charset=binary")){
+ retval |= M_BINARY ;
+ }
+
+ if (!(retval & M_TXT) && (strstr(magic_buf,"application/octet-stream")) && (!(strncmp(text,"data",4)))){
+ retval |= M_DATA;
+ }
+
+ if ((retval & M_DATA) || (count < 32) || (ext2fs_le32_to_cpu(*(blk_t*)buf) == blk +1)) {
+ if (check_meta3_block(buf, blk, count+1)){
+ retval = M_EXT3_META ;
+ goto out;
+ }
+ if (check_meta4_block(buf, blk, count+1)){
+ retval = M_EXT4_META ;
+ goto out;
+ }
+ if (check_dir_block(buf, blk, count+1)){
+ retval = M_DIR ;
+ goto out;
+ }
+ }
+
+ if (retval & M_DATA)
+ goto out;
+
+ if (retval & M_TXT){
+ if (strstr(magic_buf,"ascii")){
+ retval |= M_ASCII ;
+ }
+
+ if(strstr(magic_buf,"iso")){
+ retval |= M_ASCII ;
+ }
+
+ if(strstr(magic_buf,"utf")){
+ retval |= M_UTF ;
+ }
+ goto out;
+ }
+
+
+ if (strstr(magic_buf,"application/octet-stream")){
+ p_search = searchstr;
+ while (*p_search){
+ len=0;
+ while((*p_search) != 0x20){
+ token[len] = *p_search;
+ p_search++;
+ len++;
+ }
+ token[len] = 0;
+ if (strstr(text,token)){
+ strncpy(magic_buf,text,99);
+ retval |= (M_APPLI | M_ARCHIV);
+ break;
+ }
+ p_search++;
+ }
+ goto out;
+ }
+
+ if (strstr(magic_buf,"application/")){
+ retval |= M_APPLI;
+ goto out;
+ }
+
+ if (strstr(magic_buf,"image/")){
+ retval |= M_IMAGE;
+ goto out;
+ }
+
+ if (strstr(magic_buf,"audio/")){
+ retval |= M_AUDIO;
+ goto out;
+ }
+
+ if (strstr(magic_buf,"video/")){
+ retval |= M_VIDEO;
+ goto out;
+ }
+
+ if (strstr(magic_buf,"message/")){
+ retval |= M_MESSAGE;
+ goto out;
+ }
+
+ if (strstr(magic_buf,"model/")){
+ retval |= M_MODEL;
+ goto out;
+ }
+
+out:
+ printf("BLOCK_SCAN : 0x%08x\n",retval & 0xffffe000);
+ blockhex(stdout,buf,0,(count < (64)) ? count : 64 );
+
+ retval |= (count+1);
+
+ return retval;
+}
+
+
+
+
+struct found_data_t* soft_border(char *des_dir, char *buf, struct found_data_t* file_data, __u32* follow, blk_t blk){
+ if ( check_file_data_end(file_data, buf ))
+ file_data = recover_file_data(des_dir, file_data, follow);
+ else{
+ file_data = forget_file_data(file_data, follow);
+// printf("Don't recover this file, current block %d \n",blk);
+ }
+return file_data;
+}
+
+
+int get_range(blk_t* p_blk ,struct ext2fs_struct_loc_generic_bitmap *ds_bmap, char* buf){
+ blk_t begin;
+ blk_t end;
+ int count=1;
+ for (begin = *p_blk; begin < ds_bmap->real_end ; begin++){
+ if((!(begin & 0x7)) && skip_block(&begin, ds_bmap))
+ printf("jump to %d \n",begin);
+
+ if (ext2fs_test_block_bitmap ( d_bmap, begin) && (! ext2fs_test_block_bitmap( bmap, begin)))
+ break;
+ }
+ *p_blk = begin;
+ if (begin >= ds_bmap->real_end)
+ return 0;
+
+ for (end = begin,count=1 ; count < MAX_RANGE ; ){
+ if (ext2fs_test_block_bitmap(d_bmap, end+1) && (! ext2fs_test_block_bitmap( bmap, end+1))){
+ end++;
+ count++;
+ }
+ else break;
+
+ }
+ *(p_blk+1) = end;
+ if (io_channel_read_blk ( current_fs->io, begin , count, buf )){
+ fprintf(stderr,"ERROR: while read block %10u + %d\n",begin,count);
+ return 0;
+ }
+return count;
+}
+
+
+
+//magic_block_scan_main
+int magic_block_scan(char* des_dir, __u32 t_after){
+magic_t cookie = 0;
+magic_t cookie_f = 0;
+struct ext2fs_struct_loc_generic_bitmap *ds_bmap;
+struct found_data_t *file_data = NULL;
+blk_t blk[2] ;
+blk_t j;
+char *buf = NULL;
+char *magic_buf = NULL;
+char *tmp_buf = NULL;
+int blocksize, ds_retval,count,i;// step;
+__u32 scan,follow;
+
+
+blocksize = current_fs->blocksize ;
+count = 0;
+blk[0] = 0;
+cookie = magic_open(MAGIC_MIME | MAGIC_NO_CHECK_COMPRESS | MAGIC_NO_CHECK_ELF );
+cookie_f = magic_open(MAGIC_NO_CHECK_COMPRESS | MAGIC_NO_CHECK_ELF );
+if ((! cookie) || magic_load(cookie, NULL) || (! cookie_f) || magic_load(cookie_f, NULL)){
+ fprintf(stderr,"ERROR: can't find libmagic\n");
+ goto errout;
+}
+buf = malloc(blocksize * MAX_RANGE);
+tmp_buf = malloc(blocksize);
+magic_buf = malloc(200);
+if ((! buf) || (! magic_buf) || (! tmp_buf)){
+ fprintf(stderr,"ERROR: can't allocate memory\n");
+ goto errout;
+}
+
+ds_retval = init_block_bitmap_list(&d_bmap, t_after);
+while (ds_retval){
+ ds_retval = next_block_bitmap(d_bmap);
+ if (ds_retval == 2 )
+ continue;
+
+ if (d_bmap && ds_retval ){
+ ds_bmap = (struct ext2fs_struct_loc_generic_bitmap *) d_bmap;
+
+ count = get_range(blk ,ds_bmap, buf);
+
+ while (count){
+ printf(" %d %d %d\n", blk[0],blk[1],count);
+ for (i = 0; i< ((count>12) ? MAX_RANGE - 12 : count) ;i++){
+ scan = magic_check_block(buf+(i*blocksize), cookie, cookie_f , magic_buf , blocksize ,blk[0]+i);
+ if(scan & (M_DATA | M_BLANK | M_IS_META))
+ continue;
+
+ printf("SCAN %d : %09x : %s\n",blk[0]+i,scan,magic_buf);
+ if (((count -i) > 12) && (ext2fs_le32_to_cpu(*(__u32*)(buf +((i+12)*blocksize))) == blk[0] + i +1 + 12)){
+ follow = 0;
+ file_data = new_file_data(blk[0]+i,scan,magic_buf,buf+(i*blocksize),&follow);
+ for(j=blk[0]+i; j<(blk[0]+i+12);j++)
+ add_file_data(file_data, j, scan ,&follow);
+ scan = magic_check_block(buf+((i+12)*blocksize), cookie, cookie_f , magic_buf , blocksize ,blk[0]+i+12);
+ if (scan & M_EXT3_META){
+ if (add_ext3_file_meta_data(file_data, buf+((i+12)*blocksize), j)){
+ io_channel_read_blk (current_fs->io, file_data->last, 1, tmp_buf);
+ file_data = soft_border(des_dir, tmp_buf, file_data, &follow, j);
+ break;
+ }
+ else
+ file_data = forget_file_data(file_data, &follow);
+ }
+ else
+ file_data = forget_file_data(file_data, &follow);
+ }
+ else{
+ // no matches
+ // In the first step we are taking nothing
+
+// printf(" %d not matches %d == %d \n\n\n", blk[0]+i, ext2fs_le32_to_cpu(*(buf +((i+12)*blocksize))), blk[0] + i + 12+1);
+ }
+ }
+
+
+
+
+ blk[0] += (i)?i:1;
+ count = get_range(blk ,ds_bmap,buf);
+
+ }
+
+
+ }//operation
+} //while transactions
+
+
+errout:
+clear_block_bitmap_list(d_bmap);
+if (file_data) free_file_data(file_data);
+if (buf) free(buf);
+if (tmp_buf) free(tmp_buf);
+if (magic_buf) free(magic_buf);
+if (cookie) magic_close(cookie);
+if (cookie_f) magic_close(cookie_f);
+} //end
+