1.1 --- a/Command.cpp Sun Jul 05 17:13:07 2009 -0400
1.2 +++ b/Command.cpp Tue Jul 07 18:08:44 2009 -0400
1.3 @@ -107,24 +107,10 @@
1.4 ifs.close();
1.5
1.6
1.7 - switch(command->mode)
1.8 - {
1.9 - case PRINT:
1.10 - command->printOperation();
1.11 - break;
1.12 - case XOR:
1.13 - command->xorOperation();
1.14 - break;
1.15 - case OR:
1.16 - command->orOperation();
1.17 - break;
1.18 - case AND:
1.19 - command->andOperation();
1.20 - break;
1.21 - case NOT:
1.22 - command->notOperation();
1.23 - break;
1.24 - };
1.25 + if(command->mode == PRINT)
1.26 + command->printOperation();
1.27 + else
1.28 + command->writeOperation();
1.29 }
1.30
1.31
1.32 @@ -238,8 +224,14 @@
1.33 }
1.34 }
1.35
1.36 -void Command::xorOperation()
1.37 +void Command::writeOperation()
1.38 {
1.39 + if(dataCount < 1 && mode != NOT)
1.40 + {
1.41 + printf("Need data bytes to perform operation with!\n");
1.42 + return;
1.43 + }
1.44 +
1.45 // create a stream to the file & verify its valid
1.46 std::ifstream ifs(filename, std::ifstream::in | std::ifstream::binary);
1.47
1.48 @@ -267,12 +259,29 @@
1.49
1.50 ifs.close();
1.51
1.52 - // apply xor to the buffer
1.53 + // apply operation to the buffer
1.54 // TODO: Possibly do this in parallel. Investigate GPU, SIMD, etc
1.55 int dataIndex = 0;
1.56 for(int i = 0; i < length; i++)
1.57 {
1.58 - buffer[i] ^= data[dataIndex];
1.59 + switch(mode)
1.60 + {
1.61 + case XOR:
1.62 + buffer[i] ^= data[dataIndex];
1.63 + break;
1.64 + case OR:
1.65 + buffer[i] |= data[dataIndex];
1.66 + break;
1.67 + case AND:
1.68 + buffer[i] &= data[dataIndex];
1.69 + break;
1.70 + case NOT:
1.71 + buffer[i] = ~buffer[i];
1.72 + break;
1.73 + default:
1.74 + break;
1.75 +
1.76 + };
1.77
1.78 // get the next element of data to operate with
1.79 if(++dataIndex >= dataCount)
1.80 @@ -284,6 +293,7 @@
1.81
1.82 if(output == 0)
1.83 {
1.84 +
1.85 printf("Error opening %s", filename);
1.86 return;
1.87 }
1.88 @@ -309,10 +319,6 @@
1.89
1.90 }
1.91
1.92 -void Command::orOperation(){}
1.93 -void Command::andOperation(){}
1.94 -void Command::notOperation(){}
1.95 -
1.96 bool checkCharacterBounds(char theChar)
1.97 {
1.98 if(theChar >= ' ' && theChar <= '~')
2.1 --- a/Command.h Sun Jul 05 17:13:07 2009 -0400
2.2 +++ b/Command.h Tue Jul 07 18:08:44 2009 -0400
2.3 @@ -27,11 +27,11 @@
2.4
2.5 void print();
2.6
2.7 - void printOperation();
2.8 - void xorOperation();
2.9 - void orOperation();
2.10 - void andOperation();
2.11 - void notOperation();
2.12 + void printOperation();
2.13 + void writeOperation();
2.14 +
2.15 + bool verbose;
2.16 +
2.17
2.18 };
2.19
3.1 --- a/CommandParser.l Sun Jul 05 17:13:07 2009 -0400
3.2 +++ b/CommandParser.l Tue Jul 07 18:08:44 2009 -0400
3.3 @@ -18,6 +18,10 @@
3.4 return;
3.5 }
3.6
3.7 +-v {
3.8 + return VERBOSEFLAG;
3.9 +}
3.10 +
3.11 -p {
3.12 return PRINTMODE;
3.13 }
3.14 @@ -48,6 +52,7 @@
3.15
3.16 0[xX][0-9a-fA-F]+ {
3.17 int retVal = sscanf(yytext, "%x",&(yylval.int_val));
3.18 +
3.19 if(retVal != 1)
3.20 return;
3.21 return NUMBER;
4.1 --- a/CommandParser.y Sun Jul 05 17:13:07 2009 -0400
4.2 +++ b/CommandParser.y Tue Jul 07 18:08:44 2009 -0400
4.3 @@ -1,7 +1,7 @@
4.4 // this file contains the yacc/bison parsing code
4.5
4.6
4.7 -%token PRINTMODE XORMODE ORMODE ANDMODE NOTMODE RANGEFLAG LENGTHFLAG
4.8 +%token PRINTMODE XORMODE ORMODE ANDMODE NOTMODE RANGEFLAG LENGTHFLAG VERBOSEFLAG
4.9
4.10 %union {
4.11 char *string_val;
4.12 @@ -18,6 +18,7 @@
4.13 void yyerror(const char*);
4.14
4.15 #include <stdio.h>
4.16 +#include <iostream>
4.17 #include <string.h>
4.18 #include "Command.h"
4.19
4.20 @@ -25,6 +26,9 @@
4.21 extern void yy_scan_string(char*);
4.22 extern "C" void configBuffer(char*);
4.23
4.24 +void printUsage();
4.25 +
4.26 +bool verbose;
4.27 int rangeStart, rangeEnd;
4.28
4.29 %}
4.30 @@ -38,7 +42,15 @@
4.31 ;
4.32
4.33 args:
4.34 - mode destination filename data
4.35 + verbosity mode destination filename data
4.36 +;
4.37 +
4.38 +verbosity:
4.39 + VERBOSEFLAG {
4.40 + theCommand->verbose = true;
4.41 + verbose = true;
4.42 + }
4.43 + |
4.44 ;
4.45
4.46 filename:
4.47 @@ -101,7 +113,7 @@
4.48
4.49 range:
4.50 RANGEFLAG NUMBER NUMBER {
4.51 - theCommand->range = true;
4.52 + theCommand->range = true;
4.53 theCommand->start = $2;
4.54 theCommand->end = $3;
4.55 }
4.56 @@ -111,12 +123,45 @@
4.57
4.58 void yyerror(const char * s)
4.59 {
4.60 - fprintf(stderr,"%s\n", s);
4.61 + printUsage();
4.62 }
4.63
4.64 void printUsage()
4.65 {
4.66 - printf("Usage\n");
4.67 + std::cout << "Usage: [-v] mode [[-r start end] [-l start distance]] filename [databytes]" << std::endl;
4.68 + if(theCommand->verbose == false)
4.69 + std::cout << "Use -v for more detailed information" << std::endl;
4.70 + else
4.71 + {
4.72 + std::cout << "Mode can be any (and must be one) of the following:" << std::endl;
4.73 + std::cout << " -x for XOR operations" << std::endl;
4.74 + std::cout << " -a for AND operations" << std::endl;
4.75 + std::cout << " -o for OR operations" << std::endl;
4.76 + std::cout << " -n for NOT operations" << std::endl;
4.77 + std::cout << " -p for PRINT operations" << std::endl;
4.78 + std::cout << "" << std::endl;
4.79 + std::cout << "To apply an operation over a range of bytes," << std::endl;
4.80 + std::cout << " use the -r flag and specify a start and end address." << std::endl;
4.81 + std::cout << " Note that the start is inclusive and end is exclusive." << std::endl;
4.82 + std::cout << "" << std::endl;
4.83 + std::cout << "To apply an operation over a certain length," << std::endl;
4.84 + std::cout << " use the -l flag and specify a start address and length" << std::endl;
4.85 + std::cout << "" << std::endl;
4.86 + std::cout << "filename is the file that will be operated on. It must exist." << std::endl;
4.87 + std::cout << "" << std::endl;
4.88 + std::cout << "databytes are the bytes of data that any operation requiring data " << std::endl;
4.89 + std::cout << "will use. They can be specified in either decimal or hexadecimal " << std::endl;
4.90 + std::cout << "by simply typing the number or prepending a 0x." << std::endl;
4.91 + std::cout << "If the range or length of the operation is greater than the " << std::endl;
4.92 + std::cout << "number of databytes supplied, the databytes will be looped over " << std::endl;
4.93 + std::cout << "until the operation has been completed." << std::endl;
4.94 + std::cout << "Note that the xor, or, and and operations REQUIRE data bytes." << std::endl;
4.95 + std::cout << "" << std::endl;
4.96 + std::cout << "Please make note of the endianness of your machine." << std::endl;
4.97 + std::cout << "Hexciting performs all operations on character sized elements, " << std::endl;
4.98 + std::cout << " so interpret the results properly, according to endianness." << std::endl;
4.99 +
4.100 + }
4.101 }
4.102
4.103 /*
4.104 @@ -127,7 +172,7 @@
4.105 Also, why is a char*** being used instead of a
4.106 char**? Needs to be invesitaged
4.107 */
4.108 -void parseArguments(int argc, char** argv)
4.109 +int parseArguments(int argc, char** argv)
4.110 {
4.111 int i;
4.112
4.113 @@ -139,7 +184,7 @@
4.114 }
4.115
4.116 if(sum <= 0)
4.117 - return;
4.118 + return 1;
4.119
4.120 // make us a buffer and zero it out
4.121 char tempBuffer[sum];
4.122 @@ -159,30 +204,34 @@
4.123 // give our arguments to lex for parsing
4.124 configBuffer(tempBuffer);
4.125
4.126 -
4.127 // use bison parsing
4.128 int returnVal = yyparse();
4.129 if(returnVal != 0)
4.130 {
4.131 - printf("yyparse failed!\n");
4.132 + return 1;
4.133 }
4.134
4.135 + return 0;
4.136
4.137 }
4.138
4.139 int main(int argc, char** argv)
4.140 {
4.141 + // initialise our global
4.142 + theCommand = new Command();
4.143 +
4.144 if(argc == 1)
4.145 {
4.146 printUsage();
4.147 return 0;
4.148 }
4.149
4.150 - // initialise our global
4.151 - theCommand = new Command();
4.152 -
4.153 // process our arguments
4.154 - parseArguments(argc, argv);
4.155 + if(parseArguments(argc, argv) != 0)
4.156 + {
4.157 + // something went wrong
4.158 + return 1;
4.159 + }
4.160
4.161 // process the command
4.162 processCommand(theCommand);