[dev] Re: Fmask [c posix]

From: Mattias Andrée <maandree_AT_kth.se>
Date: Thu, 31 Dec 2015 02:20:01 +0100

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 <marc.collin7_AT_gmail.com> 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,
> <stanio_AT_cs.tu-berlin.de> wrote:
> > meta-meta
> >
> > * Hiltjo Posthuma 2015-12-30 12:21
> >> What's next? Linking interesting tweets?
> >
> > https://twitter.com/ggreenwald/status/682187313644998656
> >
>
>
Received on Thu Dec 31 2015 - 02:20:01 CET

This archive was generated by hypermail 2.3.0 : Thu Dec 31 2015 - 02:24:10 CET