Fmask [c posix]

1 Name: Anonymous 2014-05-03 7:06 This is the main code, resize.c, reverse.c, xor.c, swap.c, rswap.c will be posted you want to see them. Hope you like...



#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <sys/stat.h>

#include <unistd.h>



#define PROGRAM_VERSION "1.1"

#define BIN_PATH "bin/"



struct { const char *p, *s; } cmds[] = {

{ "swap", "rswap" },

{ "blowfish", "blowfish_dec" },

{ "rc4", "rc4_dec" },

{ "aes", "aes_dec" }

};



void help(void)

{

printf("fmask v. %s -- apply masks to files

"

"fmask [operation_1 ... operation_k] <file>

"

"operation may be: reverse, swap, xor, aes, "

"blowfish or rc4

", PROGRAM_VERSION);

}



char **push(char *p)

{

static char *s[128], **q = s + 1;

*q = malloc(strlen(p) + 1);

strcpy(*q, p);

return q++;

}



char *inversecmd(char *p)

{

static char r[128];

size_t i;

char *s = strchr(p, ' ');



if(s && s - p < sizeof r) {

strncpy(r, p, s - p);

r[s - p] = 0;

} else *r = 0;

for(i = 0; i < sizeof cmds / sizeof *cmds; i++)

if(strcmp(r, cmds[i].p) == 0) {

strcpy(r, cmds[i].s);

break;

} else if(strcmp(r, cmds[i].s) == 0) {

strcpy(r, cmds[i].p);

break;

}

return r;

}



char *cmd(char *p, char *s)

{

size_t i, j = strlen(p), k = strlen(s), n = strlen(BIN_PATH);

char *r;



if(r = malloc(j + k + n + 2)) {

strncpy(r, BIN_PATH, n);

r += n;

for(i = 0; i < j; i++)

r[i] = p[i] == ':' ? ' ' : p[i];

r[i] = ' ';

strcpy(r + i + 1, s);

}

return r ? r - n : 0;

}



int main(int argc, char **argv)

{

char *file, *p, *q, *qq, qqq[128], **stack = 0;

int i;

unsigned long lu = 0, b = 0;

struct stat s;

FILE *fp;



if(argc < 3) {

help();

return 0;

}

else file = argv[--argc];

if(stat(file, &s) == -1) return 0;

for(i = 1; i < argc; i++) {

p = cmd(argv[i], file);

if(p == NULL) return 0;

if(fp = popen(p, "r")) {

q = inversecmd(p + sizeof BIN_PATH - 1);

if(fscanf(fp, "%lu", &lu) == 1) {

b = 1;

qq = strchr(argv[i], ':');

if(lu)

sprintf(qqq, "%s%s resize:%lu", q, qq ? qq : "",

(s.st_size += lu) - lu), lu = 0;

else

sprintf(qqq, "%s%s", q, qq ? qq : "");

stack = push(qqq);

}

pclose(fp);

}

free(p);

}

while(stack && *stack) {

printf("%s ", *stack);

free(*stack--);

}

if(b) puts(file);

return 0;

}



2 Name: Anonymous 2014-05-03 7:13 cool, post the rest

3 Name: Anonymous 2014-05-03 7:18 resize.c



#include <unistd.h>



int main(int argc, char **argv)

{

if(argc != 3) return 0;

truncate(argv[2], strtoul(argv[1], NULL, 0));

puts("resize");

}



reverse.c



#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <sys/stat.h>

#include <sys/mman.h>

#include <fcntl.h>



int main(int argc, char **argv)

{

int fd;

struct stat s;

char *p, *pp, *file;

size_t i, nblock, padding, blocks;



if(argc < 2) return 0;

else if(argc == 2) nblock = 1, file = argv[1];

else nblock = atoi(argv[1]), file = argv[2];

if((fd = open(file, O_RDWR)) == -1) return 0;

if(fstat(fd, &s) == -1) return 0;

padding = (nblock - s.st_size % nblock) % nblock;

blocks = s.st_size / nblock + !!padding;

lseek(fd, 0, SEEK_END);

for(i = 0; i < padding; i++) write(fd, "A", 1);

fsync(fd);

if((p = mmap(NULL, s.st_size + padding, PROT_READ | PROT_WRITE,

MAP_SHARED, fd, 0)) == NULL) return 0;

if((pp = malloc(nblock)) == NULL) {

munmap(p, s.st_size + padding);

return 0;

}

srand(time(NULL));

for(i = 0; i < nblock - padding; i++)

pp[nblock - i - 1] = rand();

for(i = 0; i < blocks / 2; i++) {

memcpy(pp, p + (blocks - i - 1) * nblock,

(padding && !i) ? padding : nblock);

memcpy(p + (blocks - i - 1) * nblock, p + i * nblock, nblock);

memcpy(p + i * nblock, pp, nblock);

}

munmap(p, s.st_size + padding);

free(pp);

printf("%zu

", padding);

return 0;

}



rswap.c



#include <stdlib.h>

#include <string.h>

#include <unistd.h>



int main(int argc, char **argv)

{

char *p, *s[4] = { "swap", "-1" };



if(argc < 2) return 0;

else if(argc == 2)

s[2] = argv[1];

else {

if((p = malloc(strlen(argv[1]) + 2)) == NULL) return 0;

p[0] = '-';

strcpy(p + 1, argv[1]);

s[1] = p, s[2] = argv[2];

}

execv("swap", s);

return 0;

}



swap.c



#include <stdio.h>

#include <stdlib.h>



int main(int argc, char **argv)

{

int nblock, neg = 0;

const char *file;

char *p;

size_t n, i, j;

FILE *fp;

fpos_t pos;



if(argc < 2) return 0;

else if(argc == 2) nblock = 1, file = argv[1];

else {

nblock = atoi(argv[1]);

if(nblock < 0) nblock = -nblock, neg = 1;

file = argv[2];

}

srand(time(NULL));

if((fp = fopen(file, "r+b")) == NULL) return 0;

if((p = malloc(2*nblock)) == NULL) return 0;

for(j = 0; j == 0;) {

fgetpos(fp, &pos);

if((n = fread(p, 1, 2*nblock, fp)) == 0) break;

if(n != 2*nblock) {

for(i = 0; i + n < 2*nblock; i++)

p[i + n] = rand();

j = 1;

}

fsetpos(fp, &pos);

if(neg == 0)

for(i = 0; i < nblock; i++)

fputc(p[i + nblock], fp), fputc(p[i], fp);

else {

for(i = 1; i < 2*nblock; i += 2)

fputc(p[i], fp);

for(i = 0; i < 2*nblock; i += 2)

fputc(p[i], fp);

}

}

printf("%zu

", n ? 2*nblock - n : 0);

return 0;

}



xor.c



#include <stdio.h>

#include <string.h>

#include <ctype.h>



int main(int argc, char **argv)

{

int c;

size_t i, j;

char *s = 0;

unsigned char k;

FILE *fp;

fpos_t pos;



if(argc != 3) return 0;

if((j = strlen(argv[1])) < 4)

k = atoi(argv[1]);

else s = argv[1];

if((fp = fopen(argv[2], "r+b")) == NULL) return 0;

fgetpos(fp, &pos);

for(i = 0; (c = getc(fp)) != EOF; i++) {

if(i == j) i = 0;

fsetpos(fp, &pos);

if(s) putc(c ^ s[i], fp);

else putc(c ^ k, fp);

fgetpos(fp, &pos);

}

puts("0");

return 0;

}



4 Name: Rob `Commander' Pike 2014-05-03 9:06 The don't implement your own crypto police are going to get you!

5 Name: 1 2014-05-03 11:00 I like this code because it's a small example of something that does lots!

6 Name: Anonymous 2014-05-05 9:02 Bump for code review! Don't you like it? I can post docs if you want...

7 Name: Anonymous 2014-05-05 17:08 >>6

Please post the docs. Please post the docs.

8 Name: Anonymous 2014-05-06 2:51

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

Here's another example of adding rc4 functionality using OpenSSLs tools.

9 Name: Anonymous 2014-05-08 22:15 No comments? This is depressing. Please come down from the heavens and say something about my code Gods of prog.

10 Name: Anonymous 2014-05-08 22:18 >>8-9

Don't let the lack of replies discourage you. This is a cute program. Don't let the lack of replies discourage you. This is a cute program.

11 Name: Anonymous 2014-05-09 1:10 Stop fishing for compliments. Just post this shit on reddit.

12 Name: Anonymous 2014-05-09 3:03 >>11

reddit a shit. I like seeing code posted here. compliments or not.



*downvotes reddit a shit. I like seeing code posted here. compliments or not.*downvotes >>11- sama*

13 Name: Anonymous 2014-05-09 13:01 >>11

I ``fish'', if anything, for discussion and criticism, because I wrote it. I want others to take interest in something I worked on. I will post it on reddit. I ``fish'', if anything, for discussion and criticism, because I wrote it. I want others to take interest in something I worked on. I will post it on reddit.

15 Name: Cocklover 2014-05-09 14:50 I love cocks

16 Name: Anonymous 2014-05-09 14:52 I'm so happy for >>11- san

17 Name: Anonymous 2014-05-09 20:44 san. I'm so happy for >>15 san.

18 Name: Anonymous 2014-05-09 21:11 >>14

STAY ON REDDIT, PLEASE .

19 Name: >>18 2014-05-10 11:26 And after a few weeks, come back and show us the brilliant and amusing memes of reddit!

20 Name: Anonymous 2015-12-30 2:30 bampu pantsu

21 Name: Anonymous 2015-12-30 3:27 >>22

nice ducks nice ducks

22 Name: Anonymous 2015-12-30 6:21 >>21

Suck a dick, dubsfaggot. Suck a dick, dubsfaggot.

23 Name: Anonymous 2015-12-30 6:53 >>22

quack quack

24 Name: Anonymous 2015-12-30 16:37 Holy shit that some nice dubs !!

25 Name: Anonymous 2015-12-31 1:02 >>9

No comments? This is depressing.

Yes, it's very depressing to see the lack of comments in your code, you piece of shit. Nobody wants to look at that wall of uncommented single-character variable names.



It's not like smaller source code makes it run faster, you know. Yes, it's very depressing to see the lack of comments in your code, you piece of shit. Nobody wants to look at that wall of uncommented single-character variable names.It's not like smaller source code makes it run faster, you know.

26 Name: Anonymous 2015-12-31 3:41 >>25

Where is your program for inspection? - has written his already, but you have nothing but vitriol to show us. Where is your program for inspection? >>1 has written his already, but you have nothing but vitriol to show us.

27 Name: Anonymous 2015-12-31 4:31 >>26

Not for your eyes. Besides, the shittiness of uncommented, single-char variable code stands on its own judgment, and needs no exemplar to see how shit it is. Not for your eyes. Besides, the shittiness of uncommented, single-char variable code stands on its own judgment, and needs no exemplar to see how shit it is.