corrupt: upload the corruption bits
... These were supposed to be uploaded a while ago
This commit is contained in:
parent
3d1830ca66
commit
7868b86e48
113
src/corrupt.c
Normal file
113
src/corrupt.c
Normal 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
10
src/corrupt.h
Normal 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 */
|
Loading…
Reference in a new issue