From b56f6dfb708a91516c5060c3b057ef2adf21b753 Mon Sep 17 00:00:00 2001 From: pi-rho Date: Thu, 3 May 2012 20:25:20 -0500 Subject: [PATCH] * Added PDF document creation (groff -> ps2pdf) - renamed man pages * Added additional functionality to xor. This tool will be installed with several names to change its core action, while retaining its overall functionality. Currently, the following actions have been included: - xor - rot (bitwise rotate) - rol (bytewise rotate) - caesar (Caesar's cipher) * Added a summary man page (netre-tools.mdoc). This man page will be a sort of menu for users to find all of the tools included in the toolkit. Suggested by cashmoney. * Added additional code in Makefile.am to detect GCC and to handle debug --- ChangeLog | 9 ++- Makefile.am | 87 ++++++++++++++++------ NEWS | 13 ++++ autogen | 2 +- configure.ac | 3 +- man/{hdng.1 => hdng.mdoc} | 2 +- man/netre-tools.mdoc | 85 ++++++++++++++++++++++ man/{p4split.1 => p4split.mdoc} | 2 +- man/{pmerge.1 => pmerge.mdoc} | 2 +- man/{puniq.1 => puniq.mdoc} | 2 +- man/{repr.1 => repr.mdoc} | 2 +- man/{unhex.1 => unhex.mdoc} | 2 +- man/xor.1 | 78 -------------------- man/xor.mdoc | 109 ++++++++++++++++++++++++++++ src/xor.c | 124 ++++++++++++++++++++++---------- 15 files changed, 376 insertions(+), 146 deletions(-) rename man/{hdng.1 => hdng.mdoc} (98%) create mode 100644 man/netre-tools.mdoc rename man/{p4split.1 => p4split.mdoc} (97%) rename man/{pmerge.1 => pmerge.mdoc} (97%) rename man/{puniq.1 => puniq.mdoc} (97%) rename man/{repr.1 => repr.mdoc} (97%) rename man/{unhex.1 => unhex.mdoc} (97%) delete mode 100644 man/xor.1 create mode 100644 man/xor.mdoc diff --git a/ChangeLog b/ChangeLog index db736e6..b235987 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ -2012-02-12 PPA Maintainer +2012-05-01 pi-rho + + * Added netre-tools.7 + * Added additional actions to xor + * Added additional install commands to Makefile.am + * Added pdf document creation based on man pages + +2012-02-12 pi-rho * Added utilities from the fluffy project diff --git a/Makefile.am b/Makefile.am index b5748c9..983854c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,35 +1,76 @@ ACLOCAL_AMFLAGS = -I m4 -EXTRA_DIST = man + +bin_PROGRAMS = hdng unhex xor repr puniq pmerge p4split +dist_man1_MANS = man/hdng.mdoc man/unhex.mdoc man/xor.mdoc man/repr.mdoc \ + man/puniq.mdoc man/pmerge.mdoc man/p4split.mdoc +dist_man7_MANS = man/netre-tools.mdoc +MANPAGES = $(dist_man1_MANS) $(dist_man7_MANS) +PDFPAGES = ${MANPAGES:.mdoc=.pdf} + +AM_CFLAGS = +AM_CPPFLAGS = +if IS_GCC +AM_CFLAGS += -std=c99 +AM_CPPFLAGS += -D_GNU_SOURCE +if IS_DEBUG +AM_CFLAGS += -g -ggdb -O0 +AM_CFLAGS += -Wno-long-long -Wall -W -Wnested-externs -Wformat=2 +AM_CFLAGS += -Wstrict-prototypes +AM_CFLAGS += -Wwrite-strings -Wshadow -Wpointer-arith -Wsign-compare +AM_CFLAGS += -Wundef -Wbad-function-cast -Winline -Wcast-align -Wno-pointer-sign +endif +endif + +if IS_DEBUG +AM_CPPFLAGS += -DDEBUGSTMTS +endif noinst_LTLIBRARIES = libpcap.la libpcap_la_SOURCES = src/pcap.c src/pcap.h -noinst_HEADERS = src/netre.h +noinst_HEADERS = src/netre.h -bin_PROGRAMS = hdng unhex xor repr puniq pmerge p4split -hdng_SOURCES = src/hdng.c -unhex_SOURCES = src/unhex.c -xor_SOURCES = src/xor.c -repr_SOURCES = src/repr.c -puniq_SOURCES = src/puniq.c -puniq_LDADD = libpcap.la -pmerge_SOURCES = src/pmerge.c -pmerge_LDADD = libpcap.la -p4split_SOURCES = src/p4split.c -p4split_LDADD = libpcap.la - -man_MANS = man/hdng.1 man/unhex.1 man/xor.1 man/repr.1 man/puniq.1 \ - man/pmerge.1 man/p4split.1 - -docdir = $(datadir)/doc/@PACKAGE@ -doc_DATA = README AUTHORS TODO +hdng_SOURCES = src/hdng.c +unhex_SOURCES = src/unhex.c +xor_SOURCES = src/xor.c +repr_SOURCES = src/repr.c +puniq_SOURCES = src/puniq.c +puniq_LDADD = libpcap.la +pmerge_SOURCES = src/pmerge.c +pmerge_LDADD = libpcap.la +p4split_SOURCES = src/p4split.c +p4split_LDADD = libpcap.la MAINTAINERCLEANFILES = Makefile.in aclocal.m4 build-aux/compile \ - build-aux/config.guess build-aux/config.sub build-aux/depcomp \ - build-aux/install-sh build-aux/missing config.h.in \ - config.h.in~ configure build-aux/ltmain.sh m4/libtool.m4 \ - m4/lt~obsolete.m4 m4/ltoptions.m4 m4/ltsugar.m4 m4/ltversion.m4 + build-aux/config.guess build-aux/config.sub \ + build-aux/depcomp build-aux/install-sh build-aux/missing \ + config.h.in config.h.in~ configure build-aux/ltmain.sh \ + m4/libtool.m4 m4/lt~obsolete.m4 m4/ltoptions.m4 \ + m4/ltsugar.m4 m4/ltversion.m4 $(PDFPAGES) + +docdir = $(datadir)/doc/@PACKAGE@ +doc_DATA = README AUTHORS TODO $(PDFPAGES) + +SUFFIXES = .mdoc .pdf + +.mdoc.pdf: + groff -mdoc -t -Tps $< | ps2pdf - - >$@ maintainer-clean-local: rmdir build-aux rmdir m4 + +install-exec-hook: + (cd $(DESTDIR)$(bindir); \ + $(LN_S) xor rot; \ + $(LN_S) xor rol; \ + $(LN_S) xor caesar; ) + +install-data-hook: + (cd $(DESTDIR)$(man1dir); \ + $(LN_S) xor.1 rot.1; \ + $(LN_S) xor.1 rol.1; \ + $(LN_S) xor.1 caesar.1; ) + mv -f $(DESTDIR)$(docdir)/xor.pdf \ + $(DESTDIR)$(docdir)/transformer.pdf + diff --git a/NEWS b/NEWS index deee65b..608cb99 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,17 @@ 0.1337 The Middle + * Added PDF document creation (groff -> ps2pdf) + + * Added additional functionality to xor. This tool will be installed with + several names to change its core action, while retaining its overall + functionality. Currently, the following actions have been included: + - xor + - rot (bitwise rotate) + - rol (bytewise rotate) + - caesar (Caesar's cipher) + + * Added a summary man page (netre-tools.mdoc). This man page will be a sort of + menu for users to find all of the tools included in the toolkit. Suggested + by cashmoney. * In learning GNU autotools, the build cruft is now using libtool and creating a 'convenience' library out of pcap.c, which is used by the PCAP utils. diff --git a/autogen b/autogen index 00cbeef..6a0e54c 100755 --- a/autogen +++ b/autogen @@ -1,6 +1,6 @@ #!/bin/sh -e -[ ! -d "m4" ] && mkdir m4 +mkdir -p m4 autoreconf --install --force rm -rf autom4te.cache diff --git a/configure.ac b/configure.ac index 3f36a80..4bf4029 100644 --- a/configure.ac +++ b/configure.ac @@ -10,6 +10,7 @@ AC_CONFIG_MACRO_DIR([m4]) AM_INIT_AUTOMAKE([1.11 gnu check-news silent-rules subdir-objects -Wall -Werror]) AM_MAINTAINER_MODE AM_SILENT_RULES([yes]) +AC_SUBST([VERSION]) # Find programs... AC_PROG_CC @@ -30,7 +31,7 @@ AC_TYPE_UINT64_T AC_TYPE_UINT8_T # Checks for library functions. -AC_CHECK_FUNCS([memset strtol]) +AC_CHECK_FUNCS([memset strncasecmp strtol]) # debug stuff AC_ARG_ENABLE([debug], diff --git a/man/hdng.1 b/man/hdng.mdoc similarity index 98% rename from man/hdng.1 rename to man/hdng.mdoc index 968c4ed..b9afc2e 100644 --- a/man/hdng.1 +++ b/man/hdng.mdoc @@ -18,7 +18,7 @@ . .Dd March 3, 2012 .Dt HDNG 1 -.Os "network reverse engineering tools" +.Os "network reverse engineering toolkit" .Sh NAME .Nm hdng .Nd a hex dumper for the next generation diff --git a/man/netre-tools.mdoc b/man/netre-tools.mdoc new file mode 100644 index 0000000..d1b7d55 --- /dev/null +++ b/man/netre-tools.mdoc @@ -0,0 +1,85 @@ +.\" This manual is Copyright 2012 by pi-rho +.\" +.\" This program is free software: you can redistribute it and/or modify +.\" it under the terms of the GNU General Public License as published by +.\" the Free Software Foundation, either version 3 of the License, or +.\" (at your option) any later version. +.\" +.\" This package is distributed in the hope that it will be useful, +.\" but WITHOUT ANY WARRANTY; without even the implied warranty of +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +.\" GNU General Public License for more details. +.\" +.\" You should have received a copy of the GNU General Public License +.\" along with this program. If not, see . +.\" +.\" On Debian systems, the complete text of the GNU General +.\" Public License version 3 can be found in "/usr/share/common-licenses/GPL-3". +. +.Dd May 1, 2012 +.Dt NETRE-TOOLS 7 +.Os "Network Reverse Engineering Toolkit" +.Sh NAME +.Nm netre-tools +.Nd network reverse engineering toolkit +. +.Sh DESCRIPTION +Network reverse engineering describes an emerging specialty in the information +assurance industry. This specialty exists in the gray area between malware +reverse engineering and network forensics. Analysts in this specialty may process +a wide variety of data. This data may be encrypted, encoded, or embedded in +multiple layers of other data. +.Pp +This toolkit aims to provide simple utilities to aide the analyst in carving +through many potential layers in order to find information. This toolkit will +most likely never be a complete solution; however, the authors aim to fill in +the gaps left by more complex tools. +. +.Sh IMPLEMENTATION NOTES +The following tools are currently included in the toolkit: +.Ss Data Inspection and Manipulation +This subgroup aids in inspecting data and manipulating data. +.Pp +.Bl -tag -width caesar -compact +.It Nm hdng +Hex Dumper - Next Generation (also symbolically linked as +.Nm hd ) +.It Nm unhex +converts hexits to binary data (i.e. "61 62" \(rA "AB") +.It Nm xor +applies bytes to the pipeline using XOR +.It Nm rot +applies bytes to the pipeline using ROT (bitwise rotation) +.It Nm rol +applies bytes to the pipeline using ROL (bytewise rotation) +.It Nm caesar +applies bytes to the pipeline using Caesar's Cipher (alphabetic rotation) +.El +. +.Ss PCAP Manipulation +This subgroup allows frames in PCAP (packet capture) files to be manipulated +from the command line. +.Pp +.Bl -tag -width p4split -compact +.It Nm p4split +split a large PCAP file into smaller files, using a CIDR-notation filter +.It Nm pmerge +join PCAP files into a larger file while preserving date/time order +.It Nm puniq +drop duplicated packets from a PCAP +.El +. +.Sh SEE ALSO +.Xr hdng 1 , +.Xr unhex 1 , +.Xr xor 1 , +.Xr rot 1 , +.Xr rol 1 , +.Xr caesar 1 , +.Xr p4split 1 , +.Xr pmerge 1 , +.Xr puniq 1 +. +.Sh AUTHORS +.An Xephyr Aq Ad zephyr@dirtbags.net , +.An pi-rho Aq Ad pi-rho@tyr.cx diff --git a/man/p4split.1 b/man/p4split.mdoc similarity index 97% rename from man/p4split.1 rename to man/p4split.mdoc index dc4a7c7..f248a01 100644 --- a/man/p4split.1 +++ b/man/p4split.mdoc @@ -18,7 +18,7 @@ . .Dd March 3, 2012 .Dt P4SPLIT 1 -.Os "network reverse engineering tools" +.Os "Network Reverse Engineering Toolkit" .Sh NAME .Nm p4split .Nd split a PCAP based on CIDR filter diff --git a/man/pmerge.1 b/man/pmerge.mdoc similarity index 97% rename from man/pmerge.1 rename to man/pmerge.mdoc index 51a98f6..c47df6d 100644 --- a/man/pmerge.1 +++ b/man/pmerge.mdoc @@ -18,7 +18,7 @@ . .Dd March 3, 2012 .Dt PMERGE 1 -.Os "network reverse engineering tools" +.Os "Network Reverse Engineering Toolkit" .Sh NAME .Nm pmerge .Nd merge multiple PCAP files in timeline order diff --git a/man/puniq.1 b/man/puniq.mdoc similarity index 97% rename from man/puniq.1 rename to man/puniq.mdoc index eebe213..9a0e1e4 100644 --- a/man/puniq.1 +++ b/man/puniq.mdoc @@ -18,7 +18,7 @@ . .Dd March 3, 2012 .Dt PUNIQ 1 -.Os "network reverse engineering tools" +.Os "Network Reverse Engineering Toolkit" .Sh NAME .Nm puniq .Nd filter one to many PCAP files for unique frames diff --git a/man/repr.1 b/man/repr.mdoc similarity index 97% rename from man/repr.1 rename to man/repr.mdoc index 9a21a9d..d1c5e44 100644 --- a/man/repr.1 +++ b/man/repr.mdoc @@ -18,7 +18,7 @@ . .Dd March 3, 2012 .Dt REPR 1 -.Os "network reverse engineering tools" +.Os "Network Reverse Engineering Toolkit" . .Sh NAME .Nm repr diff --git a/man/unhex.1 b/man/unhex.mdoc similarity index 97% rename from man/unhex.1 rename to man/unhex.mdoc index c6af044..e6dabc5 100644 --- a/man/unhex.1 +++ b/man/unhex.mdoc @@ -18,7 +18,7 @@ . .Dd March 3, 2012 .Dt UNHEX 1 -.Os "network reverse engineering tools" +.Os "Network Reverse Engineering Toolkit" . .Sh NAME .Nm unhex diff --git a/man/xor.1 b/man/xor.1 deleted file mode 100644 index 47d88f1..0000000 --- a/man/xor.1 +++ /dev/null @@ -1,78 +0,0 @@ -.\" This manual is Copyright 2012 by pi-rho -.\" -.\" This program is free software: you can redistribute it and/or modify -.\" it under the terms of the GNU General Public License as published by -.\" the Free Software Foundation, either version 3 of the License, or -.\" (at your option) any later version. -.\" -.\" This package is distributed in the hope that it will be useful, -.\" but WITHOUT ANY WARRANTY; without even the implied warranty of -.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -.\" GNU General Public License for more details. -.\" -.\" You should have received a copy of the GNU General Public License -.\" along with this program. If not, see . -.\" -.\" On Debian systems, the complete text of the GNU General -.\" Public License version 3 can be found in "/usr/share/common-licenses/GPL-3". -. -.Dd March 3, 2012 -.Dt XOR 1 -.Os "network reverse engineering tools" -. -.Sh NAME -.Nm xor -.Nd apply mask bytes to a stream using XOR -. -.Sh SYNOPSIS -.Nm xor -.Op Fl h | Fl v -.Nm xor -.Op Fl x -.Ar MASKBYTE -.Op Ar MASKBYTE ... -.Nm xor -.Fl s -.Ar MASKSTRING -. -.Sh DESCRIPTION -The basic concept for this utility is to apply a set of mask bytes, repeatedly, -to a stream of input. The application of the mask bytes is accomplished using -the bitwise XOR operation. -. -.Sh USAGE -As a filter with the hexadecimal mask bytes -.Bq 20 , 2f -applied to the input stream (i.e. -.Bq 20 , 2f , 20 , 2f , ... Ns ) -.D1 ... | Nm xor Fl x Ar 20 Ar 2f | Li ... -As a filter with a string of characters used as a mask -.D1 ... | Nm xor Fl s Qo Ar " key " Qc | Li ... -. -.Sh OPTIONS -A summary of the options supported by -.Nm xor -is included below. -. -.Bl -tag -width Ds -.It Fl h -usage information -.It Fl v -the program's version -.It Fl x -explicity interpret mask bytes as hexadecimal digits -.It Fl s -use a string of characters as the mask -.It Ar MASKBYTE Op Ar MASKBYTE ... -a list of mask bytes to apply to the input stream -.It Ar MASKSTRING -a string of characters -.El -. -.Sh SEE ALSO -.Xr hdng 1 , -.Xr unhex 1 -. -.Sh AUTHORS -.An Zephyr Aq Ad zephyr@dirtbags.net , -.An pi-rho Aq Ad pi-rho@tyr.cx diff --git a/man/xor.mdoc b/man/xor.mdoc new file mode 100644 index 0000000..706db76 --- /dev/null +++ b/man/xor.mdoc @@ -0,0 +1,109 @@ +.\" This manual is Copyright 2012 by pi-rho +.\" +.\" This program is free software: you can redistribute it and/or modify +.\" it under the terms of the GNU General Public License as published by +.\" the Free Software Foundation, either version 3 of the License, or +.\" (at your option) any later version. +.\" +.\" This package is distributed in the hope that it will be useful, +.\" but WITHOUT ANY WARRANTY; without even the implied warranty of +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +.\" GNU General Public License for more details. +.\" +.\" You should have received a copy of the GNU General Public License +.\" along with this program. If not, see . +.\" +.\" On Debian systems, the complete text of the GNU General +.\" Public License version 3 can be found in "/usr/share/common-licenses/GPL-3". +. +.Dd May 1, 2012 +.Dt TRANSFORMER 1 +.Os "Network Reverse Engineering Toolkit" +. +.Sh NAME +.Nm xor +.Nd apply bytes to the pipeline using XOR +.br +.Nm rot +.Nd apply bytes to the pipeline using ROT +.br +.Nm rol +.Nd apply bytes to the pipeline using ROL +.br +.Nm caesar +.Nd apply bytes to the pipeline using Caesar's Cipher +. +.Sh SYNOPSIS +.Nm +.Op Fl h | Fl v +.Nm +.Op Fl u +.Op Fl x +.Ar BYTE +.Op Ar BYTE ... +.Nm +.Op Fl u +.Fl s +.Ar STRING +. +.Sh DESCRIPTION +The basic concept for this utility is to apply a set of bytes, repeatedly, to a +stream of input. +. +.Sh USAGE +As a filter with the hexadecimal bytes +.Bq 0x20 , 0x2f +applied to the input stream using +.Nm xor . +The bytes are applied repeatedly until the end-of-file (i.e. +.Bq 0x20 , 0x2f , 0x20 , 0x2f , ... Ns ) . +.D1 ... | Nm xor Fl x Ar 20 Ar 2f | Li ... +.Pp +As a filter with a string of characters used as a byte source (i.e. +.Bq 0x20 , 0x6b , 0x65 , 0x79 , 0x20 , ... Ns ) . +.D1 ... | Nm xor Fl s Qo Ar " key " Qc | Li ... +. +.Sh OPTIONS +A summary of the options is included below. +. +.Bl -tag -width Ds +.It Fl h +usage information +.It Fl v +the program's version +.It Fl x +explicity interpret bytes as hexadecimal digits +.It Fl s Ar STRING +use a string of characters as the byte source +.It Fl u +undo - reverse the transform (this is ignored for +.Nm xor ) +.It Ar BYTE Op Ar BYTE ... +a list of bytes to apply to the input stream +.El +. +.Sh IMPLEMENTATION NOTES +The application of the bytes is accomplished using one of the following +transforms: +. +.Bd -unfilled -offset indent +.TS +box tab(:); +l | l | l | l. +\fBTransform:Description:Bytes:Undo\fR +_:_:_:_ +xor:bitwise exclusive OR:integers [0-255]:- +rot:bitwise rotate left:integers [0-7]:bitwise rotate right +rol:bytewise rotate (-):integers [0-255]:bytewise rotate (+) +caesar:alphabet shift (+):integers [0-26]:alphabet shift (-) +.TE +.Ed +.Pp +. +.Sh SEE ALSO +.Xr hdng 1 , +.Xr unhex 1 +. +.Sh AUTHORS +.An Zephyr Aq Ad zephyr@dirtbags.net , +.An pi-rho Aq Ad pi-rho@tyr.cx diff --git a/src/xor.c b/src/xor.c index 43738c0..693eb5e 100644 --- a/src/xor.c +++ b/src/xor.c @@ -1,11 +1,11 @@ /* - * __ _ _ _ - * __ _____ _ __ / _(_) | |_ ___ _ __ - * \ \/ / _ \| '__| | |_| | | __/ _ \ '__| - * > < (_) | | | _| | | || __/ | - * /_/\_\___/|_| |_| |_|_|\__\___|_| + * _ __ + * | |_ _ __ __ _ _ __ ___ / _| ___ _ __ _ __ ___ ___ _ __ + * | __| '__/ _` | '_ \/ __| |_ / _ \| '__| '_ ` _ \ / _ \ '__| + * | |_| | | (_| | | | \__ \ _| (_) | | | | | | | | __/ | + * \__|_| \__,_|_| |_|___/_| \___/|_| |_| |_| |_|\___|_| * - * apply mask bytes to the pipeline + * apply bytes to the pipeline * */ @@ -19,60 +19,114 @@ #include #include "netre.h" -int version(bool error) { - fprintf(WHICHOUT(error), "xor v.%s - %s\n\n", PACKAGE_VERSION, - "apply mask bytes to the pipeline, using XOR"); +typedef enum transform { + xor, + rot, + rol, + caesar +} transform_t; + +static const char *ttoa(transform_t p) { + switch(p) { + case xor: return "xor"; break; + case rot: return "rot"; break; + case rol: return "rol"; break; + case caesar: return "caesar"; break; + default : return "---"; break; + } +} + +transform_t parse_tname(char *arg) { + char *t = basename(arg); + + if (!strncasecmp(t, "rot", 3)) return rot; + if (!strncasecmp(t, "rol", 3)) return rol; + if (!strncasecmp(t, "caesar", 6)) return caesar; + return xor; +} + +int version(bool error, transform_t t) { + fprintf(WHICHOUT(error), "%s v.%s - %s %s\n\n", ttoa(t), PACKAGE_VERSION, + "apply bytes to the pipeline, using", ttoa(t)); return error ? EX_USAGE : EX_OK; } -int usage(bool error, char *prog) { - int retval = version(error); - fprintf(WHICHOUT(error), "Usage:\t%s [-x] MASK [MASK]*\n", prog); - fprintf(WHICHOUT(error), "\t%s -s MASKSTRING\n", prog); - fprintf(WHICHOUT(error), "\t-x\tmask bytes are hexadecimal\n"); - fprintf(WHICHOUT(error), "\t-s\tuse a string of characters as a mask\n"); - fprintf(WHICHOUT(error), "\n\tMASK\t\ta mask byte\n"); - fprintf(WHICHOUT(error), "\tMASKSTRING\ta string of mask characters\n"); +int usage(bool error, transform_t t) { + int retval = version(error, t); + fprintf(WHICHOUT(error), "Usage:\t%s [-x] BYTE [BYTE]*\n", ttoa(t)); + fprintf(WHICHOUT(error), "\t%s -s BYTESTRING\n", ttoa(t)); + fprintf(WHICHOUT(error), "\t-s\tuse a string of characters as the byte source\n"); + fprintf(WHICHOUT(error), "\t-x\tbytes are hexadecimal\n"); + if (t != xor) + fprintf(WHICHOUT(error), "\t-u\tundo %s\n", ttoa(t)); return retval; } -void do_xor(uint8_t mask[], int len) { +#define XOR(c,s) (c ^ s) +#define ROTL(c,s) ((c >> (s%8)) | (c << (8-(s%8)))) & 0xFF +#define ROTR(c,s) ((c << (s%8)) | (c >> (8-(s%8)))) & 0xFF +#define ROT(d,c,s) (d ? ROTR(c,s) : ROTL(c,s)) +#define ROLL(c,s) (c - s) % 256 +#define ROLR(c,s) (c + s) % 256 +#define ROL(d,c,s) (d ? ROLR(c,s) : ROLL(c,s)) +#define CAESARE(c,s,a) ((c - a + s) % 26) + a +#define CAESARD(c,s,a) ((c - a - s) % 26) + a +#define CAESAR(d,c,s,a) (d ? CAESARD(c,s,a) : CAESARE(c,s,a)) + +int CAE(int undo, int c, uint8_t s) { + if (isupper(c)) return CAESAR(undo, c, s, 'A'); + if (islower(c)) return CAESAR(undo, c, s, 'a'); + return c; +} + +int action(transform_t t, uint8_t mask[], int len, bool undo) { int i = 0; while (true) { int c = getchar(); + if (c == EOF) break; - if (EOF == c) break; - - c ^= mask[i]; + switch(t) { + case rot: c = ROT(undo, c, mask[i]); break; + case rol: c = ROL(undo, c, mask[i]); break; + case caesar: c = CAE(undo, c, mask[i]); break; + default: c = XOR( c, mask[i]); break; + } putchar(c); i = (i + 1) % len; } + + return EX_OK; } int main(int argc, char *argv[]) { - int opt; - int masklen = 0; - int base = 0; int i; + int opt; + int masklen = 0; + int base = 0; + bool undo = false; + transform_t t = parse_tname(argv[0]); /* option parsing */ - while ((opt = getopt(argc, argv, "xsvh")) != -1) { + while ((opt = getopt(argc, argv, "uxsvh")) != -1) { switch (opt) { - case 'x': /* hex */ + case 'u': /* undo */ + if (t != xor) undo = true; + break; + case 'x': /* hex */ base = 16; break; - case 's': /* string */ + case 's': /* string */ base = -1; break; - case 'v': return version(false); - case 'h': return usage(false, argv[0]); - default: return usage(true, argv[0]); + case 'v': return version(false, t); + case 'h': return usage(false, t); + default: return usage(true, t); } } - if (optind >= argc) return usage(true, argv[0]); + if (optind >= argc) return usage(true, t); if (base != -1) { masklen = argc - optind; @@ -80,15 +134,13 @@ int main(int argc, char *argv[]) { for (i = optind; i < argc; i++) mask[i-optind] = (uint8_t)strtol(argv[i], NULL, base); - do_xor(mask, masklen); - } else { /* string */ + return action(t, mask, masklen, undo); + } else { /* string */ masklen = strlen(argv[optind]); uint8_t mask[masklen]; for (i = 0; i < masklen; i++) mask[i] = (uint8_t)argv[optind][i]; - do_xor(mask, masklen); + return action(t, mask, masklen, undo); } - - return EX_OK; }