Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon. Entire thread

Fmask [c posix]

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\n"
"fmask [operation_1 ... operation_k] <file>\n"
"operation may be: reverse, swap, xor, aes, "
"blowfish or rc4\n", 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;
}

Name: Anonymous 2014-05-03 7:13

cool, post the rest

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\n", 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", 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;
}

Name: Rob `Commander' Pike 2014-05-03 9:06

The don't implement your own crypto police are going to get you!

Name: 1 2014-05-03 11:00

I like this code because it's a small example of something that does lots!

Name: Anonymous 2014-05-05 9:02

Bump for code review! Don't you like it? I can post docs if you want...

Name: Anonymous 2014-05-05 17:08

>>6
Please post the docs.

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

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.

Name: Anonymous 2014-05-08 22:18

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

Name: Anonymous 2014-05-09 1:10

Stop fishing for compliments. Just post this shit on reddit.

Name: Anonymous 2014-05-09 3:03

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

*downvotes >>11-sama*

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.

Name: Anonymous 2014-05-09 13:44

Name: Cocklover 2014-05-09 14:50

I love cocks

Name: Anonymous 2014-05-09 14:52

I'm so happy for >>11-san

Name: Anonymous 2014-05-09 20:44

I'm so happy for >>15 san.

Name: Anonymous 2014-05-09 21:11

>>14
STAY ON REDDIT, PLEASE.

Name: >>18 2014-05-10 11:26

And after a few weeks, come back and show us the brilliant and amusing memes of reddit!

Name: Anonymous 2015-12-30 2:30

bampu pantsu

Name: Anonymous 2015-12-30 3:27

>>22
nice ducks

Name: Anonymous 2015-12-30 6:21

>>21
Suck a dick, dubsfaggot.

Name: Anonymous 2015-12-30 6:53

>>22
quack

Name: Anonymous 2015-12-30 16:37

Holy shit that some nice dubs !!

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.

Name: Anonymous 2015-12-31 3:41

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

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.

Name: Anonymous 2016-01-01 11:55

>>26
Critics need not practise their subject, and it is often detrimental to do so. Ever seen a chef who is also a food critic? The only music critics-turned-musicians were the Pet Shop Boys, and that's not exactly top-of-the-line material. Program reviewers need not also present a program of their own as a license to pass comment.
Point is, >>26, you should just stick to today's special.

Newer Posts
Don't change these.
Name: Email:
Entire Thread Thread List