Compare commits

...

4 commits

Author SHA1 Message Date
snow flurry 7868b86e48 corrupt: upload the corruption bits
... These were supposed to be uploaded a while ago
2020-11-17 13:45:15 -08:00
snow flurry 3d1830ca66 gitignore: Add misc/
Being used for testing PC98 images which don't work well with git.
2020-11-17 13:44:26 -08:00
snow flurry 82157919e9 Add Makefile
This only works with BSD make. Not sure if I'm going to keep it
like that or convert it to a GNU Makefile.
2020-11-17 13:31:23 -08:00
snow flurry 02b23c4187 Add .gitignore 2020-11-17 13:30:46 -08:00
4 changed files with 150 additions and 0 deletions

4
.gitignore vendored Normal file
View file

@ -0,0 +1,4 @@
fk98
*.core
obj/
misc/

23
Makefile Normal file
View file

@ -0,0 +1,23 @@
CC := gcc
.ifdef DEBUG
CFLAGS := -DDEBUG -ggdb
.else
CFLAGS :=
.endif
.PHONY: all
all: config.o corrupt.o dosfs.o main.o
$(CC) $(CFLAGS) -o fk98 obj/config.o obj/corrupt.o obj/dosfs.o obj/main.o
.PHONY: clean
clean:
rm -r ${.CURDIR}/obj
rm ${.CURDIR}/fk98
.SUFFIXES: .o
.PATH: src
.c.o: obj
$(CC) $(CFLAGS) -o obj/${.TARGET} -c ${.IMPSRC}
obj:
mkdir obj

113
src/corrupt.c Normal file
View file

@ -0,0 +1,113 @@
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "config.h"
#include "corrupt.h"
#include "debug.h"
#include "dosfs.h"
static uint32_t xs_rand(uint32_t);
static uint32_t xs_randb(uint32_t *, uint32_t, uint32_t);
/*
* Finds the rule (if any) that matches the given file. If no rule
* matches, the function returns NULL.
*/
config_t *
match_rule(config_t *conf, dosfile_t *file)
{
config_t *cur;
int match;
for (cur = conf; cur != NULL; cur = cur->next) {
match = 0;
match += ((cur->filename[0] == '*' && cur->filename[1] == 0) ||
(!strncmp(cur->filename, file->fname, 8)));
match += ((cur->ext[0] == '*' && cur->ext[1] == 0) ||
(!strncmp(cur->ext, file->fext, 3)));
if (match >= 2)
return cur;
}
return NULL;
}
/*
* Corrupts the given dosfile_t according to conf.
*/
int
corrupt_file(dosfs_t *fsd, dosfile_t *file, config_t *conf, uint32_t *state)
{
uint32_t off;
int real_off;
unsigned char c;
struct conf_opts_t opts;
opts = conf->opts;
for (off = conf->start; (off < conf->end) && (off < file->ent.size);
off += xs_randb(state, conf->skip_a, conf->skip_b)) {
real_off = get_byte_offset(fsd, file, off);
if (real_off < 0) {
DPRINTF(("get_byte_offset returned %s", strerror(real_off * -1)));
return 0;
}
if (pread(fsd->ifd, &c, 1, real_off) == -1) {
perror("file read failed");
return 1;
}
/*
* The fun part! Originally the plan was to check for each
* function (i.e., "is it zero or not") before running the
* operations, but zero shift, add, and xor should be just as
* efficient as a bunch of if statements. Might be flawed
* logic, let me know if it is!
*/
c = c >> opts.shr;
c = c << opts.shl;
c += opts.add;
c ^= opts.bit_xor;
if (pwrite(fsd->ifd, &c, 1, real_off) == -1) {
perror("file write failed");
return 1;
}
}
return 0;
}
/*
* Generates a random number within two bounds.
*/
static uint32_t
xs_randb(uint32_t *state, uint32_t lower, uint32_t upper)
{
*state = xs_rand(*state);
/* if we're already between, just roll with it */
if (*state <= upper && *state >= lower) {
return *state;
}
return ((*state % (upper - lower)) + lower);
}
/*
* Implement xorshift for randomness
*/
static uint32_t
xs_rand(uint32_t in)
{
uint32_t out;
out = in;
out ^= in << 13;
out ^= out >> 17;
out ^= out << 5;
return out;
}

10
src/corrupt.h Normal file
View file

@ -0,0 +1,10 @@
#ifndef _CORRUPT_H
#define _CORRUPT_H
#include "config.h"
#include "dosfs.h"
config_t *match_rule(config_t *, dosfile_t *);
int corrupt_file(dosfs_t *, dosfile_t *, config_t *, uint32_t *);
#endif /* !_CORRUPT_H */