For the life of me I cannot understand when this would be useful. Why was this written?
On Wed, 30 Dec 2015 22:54:40 -0200 Marc Collin <[email protected]> wrote: > Hiltjo, I'm sorry, that was really unthoughtful from me. > Not sure if this email conversation is still able to be > saved, but here goes the the author's documentation I > mentioned. In the future I'll remember to make better > emails. > > fmask -- apply masks to files. > > Table of Contents > ================= > 1 Where did the name come from? > 2 I want to compile this! > 3 HOWTO use fmask > 4 principles of the mask programs (HOWTO add your own) > 5 How powerful is this? > > > 1 Where did the name come from? > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > Gmask. [http://homepage3.nifty.com/furumizo/gmaskd_e.htm] > > 2 I want to compile this! > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > > !UNIX ONLY! Just chmod and run compile.sh dummy !UNIX > ONLY! > > 3 HOWTO use fmask > ~~~~~~~~~~~~~~~~~~ > > fmask is simple. You specify the operations you want to > perform to the file, in the arguments, and the file > itself in the last argument. I've implemented three > operations: reverse, swap and xor. The last one is just > xor'ing the file with a byte or a passphrase. If it's a > three or less digit number, it xors with the bytes value, > else it treats it as a string. To pass arguments to those > operations you use the : character to separate their name > from their arguments. Example use: > > ./fmask xor:15 example-file > > will xor example-file with the byte 0x0F. The output of > fmask will be the arguments you need to pass to fmask in > order to get the original file back from the new file > (fmask will modify example-file, it won't create a new > file with the result). In this example, fmask will output: > > xor:15 example-file > > since xor is an inverse operation of itself. I've written > two more programs, reverse and swap, which are > generalizations of simpler operations. For reverse, with > no arguments it simply reverses a file. If the content of > example-file is 123456, with > > ./fmask reverse example-file > > example-file will contain 654321. How can this be > generalized? By adding an argument, say x, which shows > how many bytes will be treated as a single block. In case > of no arguments, x is 1 (note reverse is also an inverse > operation of itself). Here's how to visualize this > > block 1 block 2 block 2 block 1 > +--------+--------+ +--------+--------+ > +---+---+---+---+ reverse:2 +---+---+---+---+ > | A | B | C | D | =========> | C | D | A | B | > +---+---+---+---+ +---+---+---+---+ > > The last operation, swap, is merely exchanging odd-offset > blocks with even blocks for a block of size 1: > > ABCDEF becomes BADCFE > > for blocks of larger size, it joins them. Suppose the > block size is 3: > > ABCDEF becomes DAEBFC > > Here's a way to visualize this: > > block 1 block 2 > +------------|------------+ > +---+---+---+---+---+---+ > | A | B | C | D | E | F | > +---+---+---+---+---+---+ > > block 1 > +---+---+---+ > | A | B | C | > +---+---+---+ \ > block 2 join these DA - EB - FC > +---+---+---+ / > | D | E | F | > +---+---+---+ > > D is picked first (first from block 2). Then A is picked > second (first from block 1). E is picked third, and B is > picked fourth, et cetera (this is a generalization of the > odd/even exchange). > > This operation is not the inverse of itself. I have > written another program, called rswap (which you don't > need to use by yourself; it's useful only for fmask), > which is the inverse of swap. Here's an example: > > printf 123456 > example-file > ./fmask swap:3 example-file > > output is rswap:3 example-file. That tells you with the > argument 'rswap:3 example-file', fmask will create the > original file back from the new file just created. > > There's one thing to mention left: padding. Because > reverse and swap operate on blocks of arbitrary size, > sometimes the block size does not perfectly divide the > file size into blocks; when this occurs, fmask will add > padding bytes of random values to the end of the file > before it calls the operations. As such, you'll also need > to crop these random bytes out. That is why fmask also > provides the 'resize' operation, which you should not use > by yourself because you will lose your data. Here's an > illustration of what I'm talking about > > printf 123456 > example-file > ./fmask reverse:4 swap:5 example-file > > Since example-file is only 6 bytes long, 2 bytes must be > added in order for 4 to perfectly divide the size of the > file. These two random bytes are added. Then reverse is > performed. Then comes the time of swap, which has a block > size of 5. The file is 8 bytes long, and 2 bytes must be > added in order for 5 to perfectly divide the file size. > These bytes are added, then swap is performed. Clearly, > the reverse operations will have to remove those bytes in > every step. The return string of fmask demonstrates this: > > rswap:5 resize:8 reverse:4 resize:6 foo > > notice the file is resized twice. > > 4 principles of the mask programs (HOWTO add your own) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > 1) must have an inverse program > 2) must print the number of bytes added to the file in > case of padding -- the inverse program must get those > bytes to be the last in the file (this will be fixed in > the next version of fmask and the program won't have to > do this dirty job -- fmask will do it). 3) the last > argument argv[argc-1] is the file operating on, passed by > fmask. It's handy because of 'file = argv[--argc];' > > Here's an example, the simple_xor.c program: > > > int main(int argc, char **argv) > { > FILE *fp; > fpos_t fpos; > int c; > // we want 2 arguments, byte to xor and the filename > if(argc != 3) return 0; > if((fp = fopen(argv[argc - 1], "r+b")) == NULL) return 0; > fgetpos(fp, &pos); > while((c = getc(fp)) != EOF) { > fsetpos(fp, &pos); // go back 1 byte to write the new byte > putc(c ^ argv[1][0], fp); > fgetpos(fp, &pos); > } > fclose(fp) > puts("0"); // we did not modify the file size; print 0 to > indicate // 0 bytes were added to the file. > return 0; > } > > Compile and put the binary in the fmask directory. Run > > ./fmask simple_xor:A example-file > > to XOR example-file bytes with the byte A. > If your operation has an inverse different than itself, > you must add the alias to the cmds[] struct in fmask.c. > swap is one such operation; rswap is its inverse (and > swap is the inverse of rswap -- struct works both ways). > > 5 How powerful is this? > ~~~~~~~~~~~~~~~~~~~~~~~~ > > Really powerful! Or at least the author thinks so. The > operations reverse and swap are the only operations > you'll probably ever need, but you can add your own, and > they don't have to operate on same-sized blocks (for > example, their size might be an arithmetic progression or > really anything that you have in mind). Here's an example > of how well it hides the original content of the file. > example-file contains the alphabet and a newline. > > $ cat example-file > ABCDEFGHIJKLMNOPQRSTUVWXYZ > $ ./fmask reverse:3 reverse:5 swap:7 reverse:11 swap > reverse example-file reverse rswap reverse:11 resize:42 > rswap:7 resize:30 reverse:5 resize:27 reverse:3 > example-file $ hd -C example-file | uniq > 00000000 d3 4c e4 4b 41 4a 43 41 42 46 4d 45 52 50 51 55 > |.L.KAJCABFMERPQU| 00000010 48 54 44 53 49 47 57 21 56 cf > 58 7e 4f 0a 4e 5a |HTDSIGW!V.X~O.NZ| 00000020 d3 59 5a e4 > 71 4f cf 7e f4 21 d3 f4 |.YZ.qO.~.!..| 0000002c > > Recognize anything? If you run the decryption string > returned by fmask you get the original file back again, > with the alphabet > > > Here's another example of adding rc4 functionality using > OpenSSLs tools. > > In this example, I'll show you how to add OpenSSL's > blowfish encryption to fmask, without writing any C code. > First how to use the openssl(1) utility for blowfish > encryption and decryption: > > -in (the source file) > -out (the encrypted file) > -k (password) > -d (decrypt) > > first argument should be the algorithm we want to use, > which is bf (sort for blowfish). There'll be two shell > scripts, for encryption and decryption. Here is > rc4_enc.sh: > > > if [ $# -eq 2 ]; then > openssl rc4 -in $2 -out "$2.temp" -k $1 > mv "$2.temp" $2 > echo 0 > fi > > Notice I print 0 since the algorithm doesn't add any > padding to the filesize; after decryption, it'll be back > to its original size, and not some padded one. rc4_dec.sh > is similar except there's a -d added in the argument list > to denote decryption. If you don't want to type the .sh > part when you invoke fmask, use symbolic links like so: > > ln -s rc4_enc.sh rc4 > ln -s rc4_dec.sh rc4_dec > > and don't forget to add "rc4" and "rc4_dec" in the cmds > struct in fmask.c > > On Wed, Dec 30, 2015 at 6:50 PM, > <[email protected]> wrote: > > meta-meta > > > > * Hiltjo Posthuma 2015-12-30 12:21 > >> What's next? Linking interesting tweets? > > > > https://twitter.com/ggreenwald/status/682187313644998656 > > > >
