zzuf: add a -X flag for hexadecimal dumps.
This commit is contained in:
parent
2738d9bd9d
commit
eb8c73c57d
@ -174,7 +174,7 @@ considered by the \fB\-l\fR flag.
|
||||
\fB\-m\fR, \fB\-\-md5\fR
|
||||
Instead of displaying the program's \fIstandard output\fR, just print its MD5
|
||||
digest to \fBzzuf\fR's standard output. The standard error channel is left
|
||||
untouched.
|
||||
untouched. See also the \fB\-X\fR flag.
|
||||
.TP
|
||||
\fB\-M\fR, \fB\-\-max\-memory\fR=\fImebibytes\fR
|
||||
Specify the maximum amount of memory, in mebibytes (1 MiB = 1,048,576 bytes),
|
||||
@ -354,6 +354,10 @@ get run, their exit status, etc.
|
||||
Report processes that exit with a non-zero status. By default only processes
|
||||
that crash due to a signal are reported.
|
||||
.TP
|
||||
\fB\-X\fR, \fB\-\-hex\fR
|
||||
Convert the fuzzed program's \fIstandard output\fR to hexadecimal. The standard
|
||||
error channel is left untouched. See also the \fB\-m\fR flag.
|
||||
.TP
|
||||
\fB\-h\fR, \fB\-\-help\fR
|
||||
Display a short help message and exit.
|
||||
.TP
|
||||
|
||||
@ -181,6 +181,7 @@
|
||||
<ClInclude Include="..\src\opts.h" />
|
||||
<ClInclude Include="..\src\timer.h" />
|
||||
<ClInclude Include="..\src\util\getopt.h" />
|
||||
<ClInclude Include="..\src\util\hex.h" />
|
||||
<ClInclude Include="..\src\util\md5.h" />
|
||||
<ClInclude Include="..\src\util\mutex.h" />
|
||||
<ClInclude Include="..\src\util\regex.h" />
|
||||
@ -195,6 +196,7 @@
|
||||
<ClCompile Include="..\src\opts.c" />
|
||||
<ClCompile Include="..\src\timer.c" />
|
||||
<ClCompile Include="..\src\util\getopt.c" />
|
||||
<ClCompile Include="..\src\util\hex.c" />
|
||||
<ClCompile Include="..\src\util\md5.c" />
|
||||
<ClCompile Include="..\src\util\regex.cpp">
|
||||
<CompileAs>CompileAsCpp</CompileAs>
|
||||
|
||||
@ -4,7 +4,8 @@ pkglib_LTLIBRARIES = libzzuf.la
|
||||
|
||||
ZZUF = \
|
||||
zzuf.c opts.c opts.h timer.c timer.h myfork.c myfork.h \
|
||||
util/getopt.c util/getopt.h util/md5.c util/md5.h
|
||||
util/getopt.c util/getopt.h util/md5.c util/md5.h \
|
||||
util/hex.c util/hex.h
|
||||
|
||||
ZZAT = \
|
||||
zzat.c \
|
||||
|
||||
@ -43,6 +43,7 @@ void _zz_opts_init(struct opts *opts)
|
||||
|
||||
opts->b_quiet = 0;
|
||||
opts->b_md5 = 0;
|
||||
opts->b_hex = 0;
|
||||
opts->b_checkexit = 0;
|
||||
opts->b_verbose = 0;
|
||||
|
||||
|
||||
@ -36,6 +36,7 @@ struct opts
|
||||
double maxratio;
|
||||
|
||||
int b_md5;
|
||||
int b_hex;
|
||||
int b_checkexit;
|
||||
int b_verbose;
|
||||
int b_quiet;
|
||||
@ -71,6 +72,7 @@ struct opts
|
||||
double ratio;
|
||||
int64_t date;
|
||||
struct zz_md5 *md5;
|
||||
struct zz_hex *hex;
|
||||
char **newargv;
|
||||
} *child;
|
||||
};
|
||||
|
||||
116
src/util/hex.c
Normal file
116
src/util/hex.c
Normal file
@ -0,0 +1,116 @@
|
||||
/*
|
||||
* zzuf - general purpose fuzzer
|
||||
*
|
||||
* Copyright © 2002—2015 Sam Hocevar <sam@hocevar.net>
|
||||
*
|
||||
* This program is free software. It comes without any warranty, to
|
||||
* the extent permitted by applicable law. You can redistribute it
|
||||
* and/or modify it under the terms of the Do What the Fuck You Want
|
||||
* to Public License, Version 2, as published by the WTFPL Task Force.
|
||||
* See http://www.wtfpl.net/ for more details.
|
||||
*/
|
||||
|
||||
/*
|
||||
* hex.c: hexadecimal data dump
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#if defined HAVE_STDINT_H
|
||||
# include <stdint.h>
|
||||
#elif defined HAVE_INTTYPES_H
|
||||
# include <inttypes.h>
|
||||
#endif
|
||||
#if defined HAVE_ENDIAN_H
|
||||
# include <endian.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "util/hex.h"
|
||||
|
||||
struct zz_hex
|
||||
{
|
||||
/* Buffered line */
|
||||
uint8_t current_line[16];
|
||||
/* The previous line FIXME: not used yet */
|
||||
uint8_t prev_line[16];
|
||||
/* Number of bytes read so far */
|
||||
int64_t count;
|
||||
};
|
||||
|
||||
struct zz_hex *zz_hex_init(void)
|
||||
{
|
||||
struct zz_hex *ctx = malloc(sizeof(struct zz_hex));
|
||||
|
||||
ctx->count = 0;
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
static void print_hex(struct zz_hex *ctx, unsigned len)
|
||||
{
|
||||
uint8_t *buf = ctx->current_line;
|
||||
uint32_t address = (uint32_t)(ctx->count - len);
|
||||
|
||||
/* Create the hex dump */
|
||||
uint8_t hex[49] = " ";
|
||||
for (unsigned i = 0; i < len; ++i)
|
||||
{
|
||||
static char const *hex2char = "0123456789abcdef";
|
||||
hex[i * 3 + (i >= 8)] = hex2char[buf[i] >> 4];
|
||||
hex[i * 3 + (i >= 8) + 1] = hex2char[buf[i] & 0xf];
|
||||
}
|
||||
|
||||
/* Create the ASCII representation */
|
||||
uint8_t ascii[17] = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
|
||||
for (unsigned i = 0; i < len; ++i)
|
||||
{
|
||||
ascii[i] = (buf[i] >= 0x20 && buf[i] <= 0x7f) ? buf[i] : '.';
|
||||
}
|
||||
|
||||
printf("%08x %s |%s|\n", address, hex, ascii);
|
||||
}
|
||||
|
||||
void zz_hex_add(struct zz_hex *ctx, uint8_t *buf, unsigned len)
|
||||
{
|
||||
unsigned buffered_len = (unsigned)(ctx->count & 15);
|
||||
|
||||
while (len > 0)
|
||||
{
|
||||
/* Copy as many bytes as possible into our data buffer */
|
||||
unsigned to_copy = 16 - buffered_len;
|
||||
if (to_copy > len)
|
||||
to_copy = len;
|
||||
|
||||
memcpy(ctx->current_line + buffered_len, buf, to_copy);
|
||||
buffered_len += to_copy;
|
||||
buf += to_copy;
|
||||
len -= to_copy;
|
||||
ctx->count += to_copy;
|
||||
|
||||
/* If the buffer is full, print it */
|
||||
if (buffered_len == 16)
|
||||
{
|
||||
print_hex(ctx, 16);
|
||||
buffered_len = 0;
|
||||
}
|
||||
}
|
||||
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
void zz_hex_fini(struct zz_hex *ctx)
|
||||
{
|
||||
/* Print the last line, if non-empty */
|
||||
if (ctx->count & 15)
|
||||
print_hex(ctx, (unsigned)(ctx->count & 15));
|
||||
|
||||
/* Print the last offset */
|
||||
printf("%08x\n", (uint32_t)ctx->count);
|
||||
|
||||
free(ctx);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
20
src/util/hex.h
Normal file
20
src/util/hex.h
Normal file
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* zzuf - general purpose fuzzer
|
||||
*
|
||||
* Copyright © 2002—2015 Sam Hocevar <sam@hocevar.net>
|
||||
*
|
||||
* This program is free software. It comes without any warranty, to
|
||||
* the extent permitted by applicable law. You can redistribute it
|
||||
* and/or modify it under the terms of the Do What the Fuck You Want
|
||||
* to Public License, Version 2, as published by the WTFPL Task Force.
|
||||
* See http://www.wtfpl.net/ for more details.
|
||||
*/
|
||||
|
||||
/*
|
||||
* hex.h: hexadecimal data dump
|
||||
*/
|
||||
|
||||
extern struct zz_hex *zz_hex_init(void);
|
||||
extern void zz_hex_add(struct zz_hex *ctx, uint8_t *buf, unsigned len);
|
||||
extern void zz_hex_fini(struct zz_hex *ctx);
|
||||
|
||||
@ -14,8 +14,6 @@
|
||||
* md5.h: MD5 computation
|
||||
*/
|
||||
|
||||
struct md5;
|
||||
|
||||
extern struct zz_md5 *zz_md5_init(void);
|
||||
extern void zz_md5_add(struct zz_md5 *ctx, uint8_t *buf, unsigned len);
|
||||
extern void zz_md5_fini(uint8_t *digest, struct zz_md5 *ctx);
|
||||
|
||||
36
src/zzuf.c
36
src/zzuf.c
@ -66,6 +66,7 @@
|
||||
#include "timer.h"
|
||||
#include "util/getopt.h"
|
||||
#include "util/md5.h"
|
||||
#include "util/hex.h"
|
||||
|
||||
#if !defined SIGKILL
|
||||
# define SIGKILL 9
|
||||
@ -159,7 +160,7 @@ int main(int argc, char *argv[])
|
||||
# define OPTSTR_RLIMIT_CPU ""
|
||||
#endif
|
||||
#define OPTSTR "+" OPTSTR_REGEX OPTSTR_RLIMIT_MEM OPTSTR_RLIMIT_CPU \
|
||||
"a:Ab:B:C:dD:e:f:F:ij:l:mnO:p:P:qr:R:s:St:U:vxhV"
|
||||
"a:Ab:B:C:dD:e:f:F:ij:l:mnO:p:P:qr:R:s:St:U:vxXhV"
|
||||
#define MOREINFO "Try `%s --help' for more information.\n"
|
||||
int option_index = 0;
|
||||
static struct zz_option long_options[] =
|
||||
@ -201,6 +202,7 @@ int main(int argc, char *argv[])
|
||||
{ "max-usertime", 1, NULL, 'U' },
|
||||
{ "verbose", 0, NULL, 'v' },
|
||||
{ "check-exit", 0, NULL, 'x' },
|
||||
{ "hex", 0, NULL, 'X' },
|
||||
{ "help", 0, NULL, 'h' },
|
||||
{ "version", 0, NULL, 'V' },
|
||||
{ NULL, 0, NULL, 0 }
|
||||
@ -368,6 +370,9 @@ int main(int argc, char *argv[])
|
||||
case 'x': /* --check-exit */
|
||||
opts->b_checkexit = 1;
|
||||
break;
|
||||
case 'X': /* --hex */
|
||||
opts->b_hex = 1;
|
||||
break;
|
||||
case 'v': /* --verbose */
|
||||
opts->b_verbose = 1;
|
||||
break;
|
||||
@ -387,6 +392,15 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
}
|
||||
|
||||
if (opts->b_md5 && opts->b_hex)
|
||||
{
|
||||
fprintf(stderr, "%s: MD5 hash (-m) and hexadecimal dump (-X) are "
|
||||
"incompatible\n", argv[0]);
|
||||
printf(MOREINFO, argv[0]);
|
||||
_zz_opts_fini(opts);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (opts->ports && !b_network)
|
||||
{
|
||||
fprintf(stderr, "%s: port option (-p) requires network fuzzing (-n)\n",
|
||||
@ -565,9 +579,12 @@ int main(int argc, char *argv[])
|
||||
static void loop_stdin(struct opts *opts)
|
||||
{
|
||||
struct zz_md5 *md5 = NULL;
|
||||
struct zz_hex *hex = NULL;
|
||||
|
||||
if (opts->b_md5)
|
||||
md5 = zz_md5_init();
|
||||
else if (opts->b_hex)
|
||||
hex = zz_hex_init();
|
||||
|
||||
_zz_register(0);
|
||||
|
||||
@ -595,6 +612,8 @@ static void loop_stdin(struct opts *opts)
|
||||
|
||||
if (opts->b_md5)
|
||||
zz_md5_add(md5, buf, ret);
|
||||
else if (opts->b_hex)
|
||||
zz_hex_add(hex, buf, ret);
|
||||
else while (ret)
|
||||
{
|
||||
int nw = 0;
|
||||
@ -617,6 +636,10 @@ static void loop_stdin(struct opts *opts)
|
||||
md5sum[12], md5sum[13], md5sum[14], md5sum[15]);
|
||||
fflush(stdout);
|
||||
}
|
||||
else if (opts->b_hex)
|
||||
{
|
||||
zz_hex_fini(hex);
|
||||
}
|
||||
|
||||
_zz_unregister(0);
|
||||
}
|
||||
@ -773,6 +796,8 @@ static void spawn_children(struct opts *opts)
|
||||
opts->child[slot].status = STATUS_RUNNING;
|
||||
if (opts->b_md5)
|
||||
opts->child[slot].md5 = zz_md5_init();
|
||||
else if (opts->b_hex)
|
||||
opts->child[slot].hex = zz_hex_init();
|
||||
|
||||
if (opts->b_verbose)
|
||||
{
|
||||
@ -969,6 +994,10 @@ static void clean_children(struct opts *opts)
|
||||
md5sum[11], md5sum[12], md5sum[13], md5sum[14], md5sum[15]);
|
||||
fflush(stdout);
|
||||
}
|
||||
else if (opts->b_hex)
|
||||
{
|
||||
zz_hex_fini(opts->child[i].hex);
|
||||
}
|
||||
opts->child[i].status = STATUS_FREE;
|
||||
opts->nchild--;
|
||||
}
|
||||
@ -1014,6 +1043,8 @@ static void __stdcall read_child(DWORD err_code, DWORD nbr_of_bytes_transfered,
|
||||
|
||||
if (co->opts->b_md5 && co->fd_no == 2)
|
||||
zz_md5_add(co->opts->child[co->child_no].md5, co->buf, nbr_of_bytes_transfered);
|
||||
else if (co->opts->b_hex && co->fd_no == 2)
|
||||
zz_hex_add(co->opts->child[co->child_no].hex, co->buf, nbr_of_bytes_transfered);
|
||||
|
||||
free(co); /* clean up allocated data */
|
||||
}
|
||||
@ -1118,6 +1149,8 @@ static void read_children(struct opts *opts)
|
||||
|
||||
if (opts->b_md5 && j == 2)
|
||||
zz_md5_add(opts->child[i].md5, buf, ret);
|
||||
else if (opts->b_hex && j == 2)
|
||||
zz_hex_add(opts->child[i].hex, buf, ret);
|
||||
else if (!opts->b_quiet || j == 0)
|
||||
write((j < 2) ? STDERR_FILENO : STDOUT_FILENO, buf, ret);
|
||||
}
|
||||
@ -1266,6 +1299,7 @@ static void usage(void)
|
||||
printf(" -U, --max-usertime <n> kill children that run for more than <n> seconds\n");
|
||||
printf(" -v, --verbose print information during the run\n");
|
||||
printf(" -x, --check-exit report processes that exit with a non-zero status\n");
|
||||
printf(" -X, --hex convert program output to hexadecimal\n");
|
||||
printf(" -h, --help display this help and exit\n");
|
||||
printf(" -V, --version output version information and exit\n");
|
||||
printf("\n");
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user