--- /dev/null
+Copyright (c) 2016, OpenFortress Digital signatures,
+ http://openfortress.nl
+ All rights reserved.
+
+Redistribution and use in source and binary forms, with or with‐
+out modification, are permitted provided that the following con‐
+ditions are met:
+
+1. Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copy‐
+right notice, this list of conditions and the following dis‐
+claimer in the documentation and/or other materials provided with
+the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBU‐
+TORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DI‐
+RECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS IN‐
+TERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLI‐
+GENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-all: inputter outputter devio llcio pcscio
+PREFIX ?= /usr/local
+DESTDIR ?=
+
+TARGETS=hexin hexout devio llcio pcscio
+LITERAL=derdump
+
+all: $(TARGETS)
+
+CC=gcc -Wall
PCSCFLAGS=-D_THREAD_SAFE -I/usr/local/include/PCSC/ -L/usr/local/lib -L/usr/local/lib/pth -ggdb3 -pthread
-inputter: inputter.c
- $(CC) $(CFLAGS) -o inputter inputter.c
+hexin: hexin.c
+ $(CC) $(CFLAGS) -o hexin hexin.c
-outputter: outputter.c
- $(CC) $(CFLAGS) -o outputter outputter.c
+hexout: hexout.c
+ $(CC) $(CFLAGS) -o hexout hexout.c
devio: devio.c
$(CC) $(CFLAGS) -o devio devio.c
$(CC) $(CFLAGS) -o llcio llcio.c
pcscio: pcscio.c
- $(CC) $(CFLAGS) $(PCSCFLAGS) -o pcscio pcscio.c -lpcsclite
+ $(CC) -I /usr/include/PCSC $(CFLAGS) $(PCSCFLAGS) -o pcscio pcscio.c -lpcsclite
+
+install: all
+ install $(TARGETS) $(LITERAL) "$(DESTDIR)$(PREFIX)/sbin"
+
+uninstall:
+ cd "$(DESTDIR)$(PREFIX)/sbin" ; rm -f $(TARGETS)
clean:
+ rm -f $(TARGETS)
very:
- rm inputter outputter
veryclean: very clean
--- /dev/null
+# Package Description: hexio
+
+This is a very simple package of developer utilities. They are targeted
+at binary/hexadecimal interaction with low-down parts of a system, so
+ideal for various reverse engineering tasks. In spite of their utter
+simplicity, they can be true life savers.
+
+ * **hexin** reads hexadecimal input on `stdin` and outputs it in binary
+ on `stdout`; it will prompt with an address (or input offset) printed
+ in hexadecimal on the tty
+ * **hexout** reads binary input on `stdin` and outputs it in hexadecimal
+ form on `stdout`
+ * **devio** reads from `stdin` and passes what it finds to a given device;
+ anything returned by the device is passed on to `stdout`
+ * **llcio** reads from `stdin` and passes what it finds to a networked
+ device over LLC; anything returned over that LLC channel is passed on
+ to `stdout`
+ * **pcscio** uses the PC/SC smart card interface to pass what it finds
+ on `stdin` to a smart card as PDU codes; anything returned by that
+ smart card is passed on to `stdout`
+ * **derdump** parses DER structures (distinguished ASN.1 encoding) from
+ a file and shows the structure in great detail on `stdout`. Special
+ about this utility is that it will work hard to print input that is
+ full of errors; the utility will complain loudly, but continue instead
+ of failing fatally; this makes it a very useful developer tool.
+
--- /dev/null
+#!/bin/sh
+echo 'Configuration is not needed, just run "make all"'
--- /dev/null
+#!/usr/bin/python
+
+import sys
+
+if len (sys.argv) != 2:
+ print 'Usage: ' + sys.argv [0] + 'file.der'
+ sys.exit (1)
+
+der = open (sys.argv [1], 'r').read (65537)
+ofs = 0
+
+def eof ():
+ global ofs, der
+ return ofs >= len (der)
+
+def read1 ():
+ global ofs, der
+ if eof ():
+ print 'ATTEMPTED READ BEYOND EOF (RETURNING 0x00)'
+ return 0
+ else:
+ ofs = ofs + 1
+ return ord (der [ofs-1])
+
+nesting = []
+
+class2str = {
+ 0: 'Universal',
+ 1: 'Application',
+ 2: 'Contextual',
+ 3: 'Private'
+}
+
+pc2str = {
+ 0: 'Primitive',
+ 1: 'Constructed'
+}
+
+universal2str = {
+ 0: 'End-Of-Content',
+ 1: 'BOOLEAN',
+ 2: 'INTEGER',
+ 3: 'BITSTRING',
+ 4: 'OCTETSTRING',
+ 5: 'NULL',
+ 6: 'OID',
+ 7: 'Object-Descriptor',
+ 8: 'EXTERNAL',
+ 9: 'REAL',
+ 10: 'ENUMERATED',
+ 11: 'EMBEDDED PDV',
+ 12: 'UTF8String',
+ 13: 'RELATIVE-OID',
+ 14: '*****',
+ 15: '*****',
+ 16: 'SEQUENCE (OF)',
+ 17: 'SET (OF)',
+ 18: 'NumericString',
+ 19: 'PrintableString',
+ 20: 'T61String',
+ 21: 'VideotexString',
+ 22: 'IA5String',
+ 23: 'UTCTime',
+ 24: 'GeneralizedTime',
+ 25: 'GraphicString',
+ 26: 'VisibleString',
+ 27: 'GeneralString',
+ 28: 'UniversalString',
+ 29: 'CHARACTER STRING',
+ 30: 'BMPString',
+ 31: '*****'
+}
+
+while not eof ():
+
+ while nesting != [] and ofs >= nesting [-1]:
+ if ofs > nesting [-1]:
+ print 'READ OFFSET %d EXCEEDS ENCAPSULATION %d (RETURNING)' % (ofs, nesting [-1])
+ ofs = nesting.pop ()
+
+ tag = read1 ()
+ tag_class = (tag & 0xc0) >> 6
+ tag_pc = (tag & 0x20) != 0
+ tag_num = tag & 0x1f
+
+ lenlen = read1 ()
+ if lenlen & 0x80 == 0:
+ leng = lenlen
+ lenlen = 1
+ else:
+ lenlen = lenlen - 0x80 + 1
+ leng = 0
+ i = 1
+ while i < lenlen:
+ leng <<= 8
+ leng = leng + read1 ()
+ i = i + 1
+
+ if tag_class == 0:
+ meaning = universal2str [tag_num]
+ elif tag_class == 1:
+ meaning = '[APPLICATION ' + str (tag_num) + ']'
+ elif tag_class == 2:
+ meaning = '[' + str (tag_num) + ']'
+ else:
+ meaning = '[PRIVATE ' + str (tag_num) + ']'
+
+ print '%s%s: tag 0x%02x %s%d @%d ^%d, %s, %s' % (
+ ' ' * len (nesting),
+ meaning, tag,
+ '#' * lenlen, leng,
+ ofs - lenlen - 1,
+ len (nesting),
+ class2str [tag_class],
+ pc2str [tag_pc] )
+
+ if tag_pc == 0 and leng > 0:
+ print ' ' * ( len (nesting) + 1 ),
+ cstr = '"'
+ ival = 0
+ ostr = ''
+ oval = None
+ while leng > 0:
+ ch = read1 ()
+ print '%02x' % ch,
+ if 32 <= ch < 127:
+ cstr = cstr + chr (ch)
+ else:
+ cstr = cstr + '.'
+ ival = (ival << 8) | ch
+ if oval is None:
+ ostr = str (ch / 40) + '.' + str (ch % 40)
+ oval = 0
+ else:
+ oval = (oval << 7) | (ch & 0x7f)
+ if ch & 0x80 == 0:
+ ostr = ostr + '.' + str (oval)
+ oval = 0
+ leng = leng - 1
+ cstr = cstr + '"'
+ if tag == 0x06:
+ cstr = ostr
+ elif tag == 0x02:
+ cstr = str (ival)
+ print '==', cstr
+
+ if tag_pc != 0:
+ # print 'Now at', ofs, 'adding', leng, 'pushing', ofs + leng
+ nesting.append (ofs + leng)
+
+while nesting != []:
+ if ofs != nesting [-1]:
+ print 'NESTING NOT ENDED CORRECTLY, OFFSET IS %d INSTEAD OF %d (CONTINUING)' % (ofs, nesting [-1])
+ nesting.pop ()
+
+++ /dev/null
-#!/usr/bin/python
-
-import sys
-
-if len (sys.argv) != 2:
- print 'Usage: ' + sys.argv [0] + 'file.der'
- sys.exit (1)
-
-der = open (sys.argv [1], 'r').read (65537)
-ofs = 0
-
-def eof ():
- global ofs, der
- return ofs >= len (der)
-
-def read1 ():
- global ofs, der
- if eof ():
- print 'ATTEMPTED READ BEYOND EOF (RETURNING 0x00)'
- return 0
- else:
- ofs = ofs + 1
- return ord (der [ofs-1])
-
-nesting = []
-
-class2str = {
- 0: 'Universal',
- 1: 'Application',
- 2: 'Contextual',
- 3: 'Private'
-}
-
-pc2str = {
- 0: 'Primitive',
- 1: 'Constructed'
-}
-
-universal2str = {
- 0: 'End-Of-Content',
- 1: 'BOOLEAN',
- 2: 'INTEGER',
- 3: 'BITSTRING',
- 4: 'OCTETSTRING',
- 5: 'NULL',
- 6: 'OID',
- 7: 'Object-Descriptor',
- 8: 'EXTERNAL',
- 9: 'REAL',
- 10: 'ENUMERATED',
- 11: 'EMBEDDED PDV',
- 12: 'UTF8String',
- 13: 'RELATIVE-OID',
- 14: '*****',
- 15: '*****',
- 16: 'SEQUENCE (OF)',
- 17: 'SET (OF)',
- 18: 'NumericString',
- 19: 'PrintableString',
- 20: 'T61String',
- 21: 'VideotexString',
- 22: 'IA5String',
- 23: 'UTCTime',
- 24: 'GeneralizedTime',
- 25: 'GraphicString',
- 26: 'VisibleString',
- 27: 'GeneralString',
- 28: 'UniversalString',
- 29: 'CHARACTER STRING',
- 30: 'BMPString',
- 31: '*****'
-}
-
-while not eof ():
-
- while nesting != [] and ofs >= nesting [-1]:
- if ofs > nesting [-1]:
- print 'READ OFFSET %d EXCEEDS ENCAPSULATION %d (RETURNING)' % (ofs, nesting [-1])
- ofs = nesting.pop ()
-
- tag = read1 ()
- tag_class = (tag & 0xc0) >> 6
- tag_pc = (tag & 0x20) != 0
- tag_num = tag & 0x1f
-
- lenlen = read1 ()
- if lenlen & 0x80 == 0:
- leng = lenlen
- lenlen = 1
- else:
- lenlen = lenlen - 0x80 + 1
- leng = 0
- i = 1
- while i < lenlen:
- leng <<= 8
- leng = leng + read1 ()
- i = i + 1
-
- if tag_class == 0:
- meaning = universal2str [tag_num]
- elif tag_class == 1:
- meaning = '[APPLICATION ' + str (tag_num) + ']'
- elif tag_class == 2:
- meaning = '[' + str (tag_num) + ']'
- else:
- meaning = '[PRIVATE ' + str (tag_num) + ']'
-
- print '%s%s: tag 0x%02x %s%d @%d ^%d, %s, %s' % (
- ' ' * len (nesting),
- meaning, tag,
- '#' * lenlen, leng,
- ofs - lenlen - 1,
- len (nesting),
- class2str [tag_class],
- pc2str [tag_pc] )
-
- if tag_pc == 0 and leng > 0:
- print ' ' * ( len (nesting) + 1 ),
- cstr = '"'
- ival = 0
- ostr = ''
- oval = None
- while leng > 0:
- ch = read1 ()
- print '%02x' % ch,
- if 32 <= ch < 127:
- cstr = cstr + chr (ch)
- else:
- cstr = cstr + '.'
- ival = (ival << 8) | ch
- if oval is None:
- ostr = str (ch / 40) + '.' + str (ch % 40)
- oval = 0
- else:
- oval = (oval << 7) | (ch & 0x7f)
- if ch & 0x80 == 0:
- ostr = ostr + '.' + str (oval)
- oval = 0
- leng = leng - 1
- cstr = cstr + '"'
- if tag == 0x06:
- cstr = ostr
- elif tag == 0x02:
- cstr = str (ival)
- print '==', cstr
-
- if tag_pc != 0:
- # print 'Now at', ofs, 'adding', leng, 'pushing', ofs + leng
- nesting.append (ofs + leng)
-
-while nesting != []:
- if ofs != nesting [-1]:
- print 'NESTING NOT ENDED CORRECTLY, OFFSET IS %d INSTEAD OF %d (CONTINUING)' % (ofs, nesting [-1])
- nesting.pop ()
-
}
close (fd);
+ return 0;
}
--- /dev/null
+#include <unistd.h>
+#include <stdio.h>
+#include <ctype.h>
+
+#define BYTES_PER_LINE 35
+
+enum status { normal, endline, error, endfile };
+enum status status = normal;
+
+void ch2hex (unsigned char *output, int ch) {
+ if ((ch >= '0') && (ch <= '9')) {
+ *output <<= 4;
+ *output += ch - '0';
+ } else {
+ ch = toupper (ch);
+ if ((ch < 'A') || (ch > 'F')) {
+ fprintf (stderr, "Illegal char '%c'\n", ch);
+ status = error;
+ } else {
+ *output <<= 4;
+ *output += ch - 'A' + 10;
+ }
+ }
+}
+
+int getbyte (unsigned char *output) {
+ int ch;
+
+ *output = 0;
+
+ if (status == error) {
+ return 0;
+ }
+
+ do {
+ if ((ch = getchar ()) < 0) {
+ status = endfile;
+ return 0;
+ }
+ if (ch == '\n') {
+ status = endline;
+ return 0;
+ }
+ } while ((ch == ' ') || (ch == ':'));
+
+ if (status == normal) {
+ ch2hex (output, ch);
+ ch = getchar ();
+ ch2hex (output, ch);
+ }
+
+ return (status == normal);
+}
+
+int main (int argc, char *argv []) {
+ size_t offset = 0;
+ size_t len;
+ unsigned char buf [BYTES_PER_LINE];
+ char ch;
+
+ while (status != endfile) {
+ if (status == endline) {
+ status = normal;
+ }
+ usleep (1000000L); // Yield to others -- better prompt printing
+ fprintf (stderr, "%08lx>", offset);
+ fflush (stderr);
+ len = 0;
+ while ((len < BYTES_PER_LINE) && (status == normal)) {
+ if (getbyte (&buf [len])) {
+ len++;
+ offset++;
+ }
+ }
+ write (1, buf, len);
+ if (status == error) {
+ while (ch = getchar (), (ch >=0) && (ch!='\n')) {
+ ;
+ }
+ fprintf (stderr, "*** skipped remainder of line ***\n");
+ status = normal;
+ }
+ }
+ return 0;
+}
--- /dev/null
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/time.h>
+#include <signal.h>
+#include <errno.h>
+
+
+/* Outputter reads input from stdin and prints it in hex on stdout.
+ * It will collect lines of one character plus anything that arrives
+ * within a second after that first character, limited to a maximum
+ * number of characters that just fits on a 80-char wide display.
+ */
+
+
+#define BYTES_PER_LINE 24
+
+unsigned long timersofar = 123;
+
+void tick (int signal) {
+ timersofar++;
+}
+
+struct itimerval tickival = { { 0, 0 } , { 1, 0 } };
+struct itimerval stopival = { { 0, 0 } , { 0, 0 } };
+
+int main (int argc, char *argv []) {
+ unsigned char buf [BYTES_PER_LINE];
+/*
+ unsigned long timer;
+*/
+ size_t len;
+ size_t offset = 0;
+ if (signal (SIGALRM, tick) == SIG_ERR) {
+ perror ("Failed to install interval handler");
+ exit (1);
+ }
+ system ("stty raw -echo");
+ printf ("*** outputter starts -- in hex mode ***\r\n");
+ fflush (stdout);
+/*
+ while (timersofar = timer,
+ len = read (0, buf, BYTES_PER_LINE),
+ (len > 0) || ( errno == SIGALRM ) ) {
+*/
+ while (len = read (0, buf, 1), len > 0) {
+ size_t i;
+ int len2;
+ /* Set a timeout before reading more; ignore problems */
+ setitimer (ITIMER_REAL, &tickival, NULL);
+ len2 = read (0, buf + 1, BYTES_PER_LINE - 1);
+ setitimer (ITIMER_REAL, &stopival, NULL);
+ if ((len2 == -1) && (errno == EINTR)) {
+ len2 = 0;
+ }
+ if (len2 >= 0) {
+ len += len2;
+ }
+ printf ("%08lx", offset);
+ offset += len;
+ for (i=0; i<len; i++) {
+ printf (" %02x", buf [i]);
+ }
+ printf ("\r\n");
+ fflush (stdout);
+ if (len2 < 0) {
+ len = -1;
+ break;
+ }
+ }
+ if (len < 0) {
+ perror ("read(2) failed");
+ } else {
+ printf ("*** outputter ends ***\r\n");
+ }
+ system ("stty cooked echo");
+ return 0;
+}
+++ /dev/null
-#include <unistd.h>
-#include <stdio.h>
-#include <ctype.h>
-
-#define BYTES_PER_LINE 35
-
-enum status { normal, endline, error, endfile };
-enum status status = normal;
-
-void ch2hex (char *output, int ch) {
- if ((ch >= '0') && (ch <= '9')) {
- *output <<= 4;
- *output += ch - '0';
- } else {
- ch = toupper (ch);
- if ((ch < 'A') || (ch > 'F')) {
- fprintf (stderr, "Illegal char '%c'\n", ch);
- status = error;
- } else {
- *output <<= 4;
- *output += ch - 'A' + 10;
- }
- }
-}
-
-int getbyte (char *output) {
- int ch;
-
- *output = 0;
-
- if (status == error) {
- return 0;
- }
-
- do {
- if ((ch = getchar ()) < 0) {
- status = endfile;
- return 0;
- }
- if (ch == '\n') {
- status = endline;
- return 0;
- }
- } while ((ch == ' ') || (ch == ':'));
-
- if (status == normal) {
- ch2hex (output, ch);
- ch = getchar ();
- ch2hex (output, ch);
- }
-
- return (status == normal);
-}
-
-int main (int argc, char *argv []) {
- size_t offset = 0;
- size_t len;
- unsigned char buf [BYTES_PER_LINE];
- char ch;
-
- while (status != endfile) {
- if (status == endline) {
- status = normal;
- }
- usleep (1000000L); // Yield to others -- better prompt printing
- fprintf (stderr, "%08x>", offset);
- fflush (stderr);
- len = 0;
- while ((len < BYTES_PER_LINE) && (status == normal)) {
- if (getbyte (&buf [len])) {
- len++;
- offset++;
- }
- }
- write (1, buf, len);
- if (status == error) {
- while (ch = getchar (), (ch >=0) && (ch!='\n')) {
- ;
- }
- fprintf (stderr, "*** skipped remainder of line ***\n");
- status = normal;
- }
- }
-}
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
+#include <unistd.h>
#include <net/if.h>
#include <net/if_arp.h>
+++ /dev/null
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <sys/time.h>
-#include <signal.h>
-#include <errno.h>
-
-
-/* Outputter reads input from stdin and prints it in hex on stdout.
- * It will collect lines of one character plus anything that arrives
- * within a second after that first character, limited to a maximum
- * number of characters that just fits on a 80-char wide display.
- */
-
-
-#define BYTES_PER_LINE 24
-
-unsigned long timersofar = 123;
-
-void tick (int signal) {
- timersofar++;
-}
-
-struct itimerval tickival = { { 0, 0 } , { 1, 0 } };
-struct itimerval stopival = { { 0, 0 } , { 0, 0 } };
-
-int main (int argc, char *argv []) {
- unsigned char buf [BYTES_PER_LINE];
- unsigned long timer;
- size_t len;
- size_t offset = 0;
- if (signal (SIGALRM, tick) == SIG_ERR) {
- perror ("Failed to install interval handler");
- exit (1);
- }
- system ("stty raw -echo");
- printf ("*** outputter starts -- in hex mode ***\r\n");
- fflush (stdout);
-/*
- while (timersofar = timer,
- len = read (0, buf, BYTES_PER_LINE),
- (len > 0) || ( errno == SIGALRM ) ) {
-*/
- while (len = read (0, buf, 1), len > 0) {
- size_t i;
- int len2;
- /* Set a timeout before reading more; ignore problems */
- setitimer (ITIMER_REAL, &tickival, NULL);
- len2 = read (0, buf + 1, BYTES_PER_LINE - 1);
- setitimer (ITIMER_REAL, &stopival, NULL);
- if ((len2 == -1) && (errno == EINTR)) {
- len2 = 0;
- }
- if (len2 >= 0) {
- len += len2;
- }
- printf ("%08x", offset);
- offset += len;
- for (i=0; i<len; i++) {
- printf (" %02x", buf [i]);
- }
- printf ("\r\n");
- fflush (stdout);
- if (len2 < 0) {
- len = -1;
- break;
- }
- }
- if (len < 0) {
- perror ("read(2) failed");
- } else {
- printf ("*** outputter ends ***\r\n");
- }
- system ("stty cooked echo");
- return 0;
-}
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
+#include <string.h>
#include <sys/types.h>
#include <sys/select.h>
}
}
SCardReleaseContext (ctx);
+ return 0;
}