#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
#include <sys/stat.h>
#include "dm.h"
#include "syntax.h"
#include "mtable.h"
/* options avaliable */
#define ASSERT_ON
#define __EXIT_ABBORT
#include "assert.h"
/*****************************************************************************/
int ast2tb( ast_root *ast, mt_table *mt )
{
AS_NULL(ast)
AS_NULL(mt)
int i,j,k;
ast_range *arng = NULL;
mt_range *mrng = NULL;
for (i=0;i<ast->total_tokens;i++)
{
arng = (ast_range *)ast->range[i];
AS_NULL(arng)
//AS_NULL(arng->val)
//AS_NULL(arng->iff)
if (arng->val != NULL)
if (arng->iff == NULL)
{
mrng = malloc(sizeof(mt_range));
AS_NULL(mrng)
memset(mrng,0,sizeof(mt_range));
mrng->start = arng->start;
mrng->end = arng->end;
mrng->val = arng->val->note;
mrng->val_sz = arng->val->size;
mt_add( mt, mrng );
}
if (arng->iff == NULL) continue;
for (j=0;j<arng->size_iff;j++)
{
unsigned char *cmp=NULL;
if (arng->iff[j]->expr->size_cmp > 0)
{
mrng = malloc(sizeof(mt_range));
AS_NULL(mrng)
memset(mrng,0,sizeof(mt_range));
//set start end positions
mrng->start = arng->start;
mrng->end = arng->end;
cmp = malloc(arng->iff[j]->expr->size_cmp);
AS_NULL(cmp)
for (k=0;k<arng->iff[j]->expr->size_cmp;k++)
cmp[k] = arng->iff[j]->expr->cmp[k]->val;
mrng->cmp = cmp;
mrng->cmp_sz = arng->iff[j]->expr->size_cmp;
if (arng->iff[j]->val != NULL)
{
mrng->val = arng->iff[j]->val->note;
mrng->val_sz = arng->iff[j]->val->size;
}
mt_add( mt, mrng );
}
}
}
return 0;
}
/*****************************************************************************/
/* primitive matchin for loop, get table sorted then more advanced solution
* maycome */
int match( mt_table *mt, char *buf, size_t size )
{
AS_NULL(mt)
AS_NULL(buf)
//anonymouse function
int pr(char *str, int sz)
{
int i;
for (i=0;i<sz;i++)
printf("%c", str[i]);
}
int i;
mt_range *rng = NULL;
for ( i=0; i<mt_size(mt); i++ )
{
rng = mt_get(mt,i);
if (rng == NULL) continue;
if (rng->start >= 0 && rng->start < size)
{
if ( rng->cmp_sz == 0)
{
printf("Byte %d match ", rng->start);
pr(rng->val,rng->val_sz);
printf("\n");
} else if (rng->cmp_sz == 1)
{
if (buf[rng->start] == ((unsigned char*)rng->cmp)[0])
{
printf("Byte %d match ", rng->start);
pr(rng->val,rng->val_sz);
printf("\n");
}
} else
{
printf("Cmp %d size not yet supported\n",rng->cmp_sz);
}
}
}
return 0;
}
/*****************************************************************************/
void helper( char *progname )
{
printf("Usage: %s [OPTS] <filename>\n\n"
"-f [BINFILE]\n"
"-m [DATAMACHFILE]\n"
"Version: %s \n"
"Example: %s -f bin.bin -m test/one_byte.md\n"
, progname, __VER__, progname);
}
/*****************************************************************************/
void version()
{
printf("Datamatch Version: %s \n", __VER__);
}
/*****************************************************************************/
int main(int argc, char **argv)
{
FILE *fin = NULL;
FILE *fdm = NULL;
struct stat st;
token_list *tl = NULL;
mt_table *mt = NULL;
ast_root *ast = NULL;
int c;
char *input_file = NULL;
char *datamach_file = NULL;
char *buf = NULL;
char *binbuf = NULL;
ssize_t binbuf_size = 0;
/*get cmd args and set options */
while ( (c = getopt(argc, argv, "f:m:v")) != -1 )
{
switch(c)
{
case 'f':
input_file = optarg;
break;
case 'm':
datamach_file = optarg;
break;
case 'v':
version();
exit(1);
break;
default:
helper( argv[0] );
exit(1);
}
}
if ((datamach_file == NULL) || (input_file == NULL))
{
printf("Should be set -f and -m\n");
return -1;
}
if ( stat( datamach_file, &st) )
{
printf("Cannot stat file %s\n", datamach_file );
return -1;
}
if ( stat( input_file, &st) )
{
printf("Cannot stat file %s\n", input_file );
return -1;
}
tl = tl_create();
mt = mt_create();
if (mt == NULL)
{
printf("Cannot create table\n");
return -1;
}
fdm = fopen( datamach_file, "r" );
if ( fdm )
{
fseek( fdm, 0, SEEK_SET );
stat( datamach_file, &st );
buf = malloc( st.st_size+1 ); memset( buf, 0, st.st_size+1 );
size_t r_size = fread( buf, 1, st.st_size, fdm );
if ( r_size > 0 )
{
int ret = parse_dm( tl, buf );
//printf("Datamatch %d %d bytes\n", ret, r_size );
} else
{
printf("ERR: while reading file %s [%d]\n", argv[1], r_size);
}
fclose( fdm );
} else
{
printf("ERR: Cannot open file\n");
return -1;
}
fin = fopen( input_file, "r" );
if (fin)
{
fseek( fin, 0, SEEK_SET );
stat( input_file, &st );
binbuf = malloc( st.st_size );
memset( binbuf, 0, st.st_size );
binbuf_size = fread( binbuf, 1, st.st_size, fin );
fclose( fin );
} else
{
printf("ERR:Cannot open binary file\n\n");
return -1;
}
/* print tokens */
//printf("print token_list\n");
//tl_str( tl );
//printf("end token_list\n");
ast = ast_syntax( tl );
//printf("ast = 0x%08x\n", ast);
//print_ast( ast );
ast2tb( ast, mt );
//mt_print( mt );
match( mt, binbuf, binbuf_size );
//ast_destroy( ast );
tl_destroy( tl );
mt_destroy( mt );
if ( buf ) free( buf );
if ( binbuf ) free( binbuf );
return 0;
}