changeset 129:597143ba1c37

miscellaneous C programs moved out of the top level directory
author Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
date Sun, 06 Apr 2014 20:20:39 +0000
parents 03f8a618689e
children 87b82398a08b
files .hgignore Makefile atsc.c factdiff.c imeibrute.c miscprog/Makefile miscprog/atsc.c miscprog/factdiff.c miscprog/imeibrute.c miscprog/mokosrec2bin.c miscprog/pirimei.c miscprog/rfcap-grep.c mokosrec2bin.c pirimei.c rfcap-grep.c
diffstat 15 files changed, 666 insertions(+), 666 deletions(-) [+]
line wrap: on
line diff
--- a/.hgignore	Sat Apr 05 20:21:55 2014 +0000
+++ b/.hgignore	Sun Apr 06 20:20:39 2014 +0000
@@ -2,13 +2,6 @@
 
 \.[oa]$
 
-^atsc$
-^factdiff$
-^imeibrute$
-^mokosrec2bin$
-^pirimei$
-^rfcap-grep$
-
 ^arm7dis/armdis$
 ^arm7dis/thumbdis$
 
@@ -17,6 +10,13 @@
 ^compal/c156-boot\.
 ^compal/osmovoodoo
 
+^miscprog/atsc$
+^miscprog/factdiff$
+^miscprog/imeibrute$
+^miscprog/mokosrec2bin$
+^miscprog/pirimei$
+^miscprog/rfcap-grep$
+
 ^mpffs/mpffs-cat$
 ^mpffs/mpffs-dbgls$
 ^mpffs/mpffs-ls$
--- a/Makefile	Sat Apr 05 20:21:55 2014 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,23 +0,0 @@
-CC=	gcc
-CFLAGS=	-O2
-STD=	atsc factdiff mokosrec2bin rfcap-grep
-CRYPTO=	imeibrute pirimei
-PROGS=	${STD} ${CRYPTO}
-
-all:	${PROGS}
-
-${STD}:
-	${CC} ${CFLAGS} -o $@ $@.c
-
-${CRYPTO}:
-	${CC} ${CFLAGS} -o $@ $@.c -lcrypto
-
-atsc:		atsc.c
-factdiff:	factdiff.c
-imeibrute:	imeibrute.c
-mokosrec2bin:	mokosrec2bin.c
-pirimei:	pirimei.c
-rfcap-grep:	rfcap-grep.c
-
-clean:
-	rm -f ${PROGS} *.o *errs *.out
--- a/atsc.c	Sat Apr 05 20:21:55 2014 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,58 +0,0 @@
-/*
- * It is known that some GSM devices have undocumented AT commands for
- * changing the IMEI.  There is no standard syntax for such an AT command
- * (by the "proper rules" one is not supposed to exist at all), and instead
- * there seem to be several different ad hoc syntaxes.  This source file,
- * found on a Chinese site, implements one of these numerous ad hoc
- * IMEI-changing AT commands:
- *
- * ftp://ftp.ifctf.org/pub/GSM/TI_src/ati_sc.c
- *
- * Notice that this particular incarnation of the "set IMEI" AT command
- * is called AT@SC; there just happens to be an identically-named AT@SC
- * command on Openmoko's GSM modems.  Might it perchance be the same
- * IMEI changing command?
- *
- * This program constructs what should be a valid input to the decoding
- * logic in the ati_sc.c source above, for the purpose of testing whether
- * or not such a command would indeed effect an IMEI change on a GTA02 modem.
- */
-
-#include <stdio.h>
-#include <ctype.h>
-#include <string.h>
-#include <strings.h>
-#include <stdlib.h>
-
-static char hexdigits[] = "0123456789abcdef";
-
-main(argc, argv)
-	char **argv;
-{
-	char hexout[16];
-	unsigned n1, n2, cksum;
-	int i, c;
-
-	if (argc != 2) {
-usage:		fprintf(stderr, "usage: %s 15-IMEI-digits\n", argv[0]);
-		exit(1);
-	}
-	if (strlen(argv[1]) != 15)
-		goto usage;
-	n1 = n2 = 0;
-	for (i = 0; i < 15; i++) {
-		c = argv[1][i];
-		if (!isdigit(c))
-			goto usage;
-		c -= '0';
-		hexout[i] = hexdigits[c ^ 5];
-		if (i < 7)
-			n1 = n1 * 10 + c;
-		else
-			n2 = n2 * 10 + c;
-	}
-	hexout[15] = '\0';
-	cksum = (n1 + n2) % 1973;
-	printf("AT@SC=\"%s%04u\"\n", hexout, cksum);
-	exit(0);
-}
--- a/factdiff.c	Sat Apr 05 20:21:55 2014 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,85 +0,0 @@
-/*
- * The 64 KiB "factory block" at the end of the 2nd flash chip select on
- * Pirelli DP-L10 phones is believed to contain juicy info (IMEI and RF
- * calibration data), but the format is yet to be cracked.
- *
- * This program compares Pirelli factory block images that have been read
- * out of several phones, seeking to determine which bytes are always the
- * same and which bytes change from specimen to specimen.
- *
- * Written by Spacefalcon the Outlaw.
- */
-
-#include <sys/types.h>
-#include <sys/file.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-u_char specimen0[65536];
-char is_diff[65536];
-
-read_specimen_file(filename, buf)
-	char *filename;
-	u_char *buf;
-{
-	int fd, cc;
-
-	fd = open(filename, O_RDONLY);
-	if (fd < 0) {
-		perror(filename);
-		exit(1);
-	}
-	cc = read(fd, buf, 65536);
-	close(fd);
-	if (cc != 65536) {
-		fprintf(stderr, "%s: unable to read 64 KiB\n", filename);
-		exit(1);
-	}
-}
-
-process_comp_specimen(filename)
-	char *filename;
-{
-	u_char this_spec[65536];
-	int i;
-
-	read_specimen_file(filename, this_spec);
-	for (i = 0; i < 65536; i++)
-		if (this_spec[i] != specimen0[i])
-			is_diff[i] = 1;
-}
-
-output()
-{
-	int off, state, cstart, num;
-
-	for (off = 0; off < 65536; ) {
-		state = is_diff[off];
-		cstart = off;
-		while (off < 65536 && is_diff[off] == state)
-			off++;
-		printf("%04X-%04X: %s", cstart, off-1,
-			state ? "varying" : "constant");
-		if (state) {
-			num = off - cstart;
-			printf(" (%d byte%s)", num, num != 1 ? "s" : "");
-		}
-		putchar('\n');
-	}
-}
-
-main(argc, argv)
-	char **argv;
-{
-	char **ap;
-
-	if (argc < 3) {
-		fprintf(stderr, "usage: %s specimen0 specimen1 ...\n", argv[0]);
-		exit(1);
-	}
-	read_specimen_file(argv[1], specimen0);
-	for (ap = argv + 2; *ap; ap++)
-		process_comp_specimen(*ap);
-	output();
-	exit(0);
-}
--- a/imeibrute.c	Sat Apr 05 20:21:55 2014 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,99 +0,0 @@
-/*
- * The IMEI "protection" implemented by TI for Calypso (as opposed to Calypso+
- * or LoCosto) platforms for those device manufs who desired to obfuscate their
- * IMEIs (not everyone did - Openmoko opted out, for example), as seen in
- * g23m/condat/com/src/comlib/cl_imei.c in the Leonardo semi-src by Sotovik,
- * encrypts the IMEI using plain DES, using a key derived from the Calypso die
- * ID.  However, only 28 effective key bits are used, and the key is then also
- * encrypted with itself and stored right after the encrypted IMEI, and is used
- * by the decryption & verification routine.  Per TI's source, the 16-byte
- * encrypted IMEI record is to be stored in FFS in /gsm/imei.enc; the DP-L10
- * phone by Pirelli/Foxconn has been found to use the same scheme, but store
- * the 16-byte record in question in their "factory block" instead, at absolute
- * address 0x027F0504 as seen by the ARM7 CPU.
- *
- * The encryption scheme seems so weak to me (28 effective key bits and an easy
- * hit detection criterion for a brute force cracker) that I decided to see,
- * just for fun, how long it would take to crack that encryption by brute force
- * alone, and using a totally non-optimized program to do that.
- */
-
-#include <sys/types.h>
-#include <openssl/des.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-DES_cblock ciphertext[2], dieid_key, decrypted[2];
-DES_key_schedule keysched;
-
-read_ciphertext(filename, offset_arg)
-	char *filename, *offset_arg;
-{
-	FILE *f;
-	u_long offset_val;
-
-	f = fopen(filename, "r");
-	if (!f) {
-		perror(filename);
-		exit(1);
-	}
-	if (offset_arg) {
-		offset_val = strtoul(offset_arg, 0, 16);
-		fseek(f, offset_val, 0);
-	}
-	fread(ciphertext, 8, 2, f);
-	fclose(f);
-}
-
-print_des_cblock(msg, blk)
-	char *msg;
-	DES_cblock blk;
-{
-	printf("%s: %02X %02X %02X %02X %02X %02X %02X %02X\n", msg,
-		blk[0], blk[1], blk[2], blk[3], blk[4], blk[5], blk[6], blk[7]);
-}
-
-try()
-{
-	DES_set_key_unchecked(&dieid_key, &keysched);
-	DES_ecb_encrypt(&ciphertext[1], &decrypted[1], &keysched, DES_DECRYPT);
-	if (decrypted[1][0] & 0xFE != dieid_key[0])
-		return;
-	if (decrypted[1][1])
-		return;
-	if (decrypted[1][2] & 0xFE != dieid_key[2])
-		return;
-	if (decrypted[1][3])
-		return;
-	if (decrypted[1][4] & 0xFE != dieid_key[4])
-		return;
-	if (decrypted[1][5])
-		return;
-	if (decrypted[1][6] & 0xFE != dieid_key[6])
-		return;
-	if (decrypted[1][7])
-		return;
-	print_des_cblock("Hit", &decrypted[1]);
-	DES_ecb_encrypt(&ciphertext[0], &decrypted[0], &keysched, DES_DECRYPT);
-	print_des_cblock("IMEI", &decrypted[0]);
-}
-
-main(argc, argv)
-	char **argv;
-{
-	if (argc < 2 || argc > 3) {
-		fprintf(stderr, "usage: %s binfile [offset]\n", argv[0]);
-		exit(1);
-	}
-	read_ciphertext(argv[1], argv[2]);
-	dieid_key[1] = 0;
-	dieid_key[3] = 0;
-	dieid_key[5] = 0;
-	dieid_key[7] = 0;
-	for (dieid_key[0] = 0; dieid_key[0] <= 0xFE; dieid_key[0] += 2)
-	  for (dieid_key[2] = 0; dieid_key[2] <= 0xFE; dieid_key[2] += 2)
-	    for (dieid_key[4] = 0; dieid_key[4] <= 0xFE; dieid_key[4] += 2)
-	      for (dieid_key[6] = 0; dieid_key[6] <= 0xFE; dieid_key[6] += 2)
-		try();
-	exit(0);
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/miscprog/Makefile	Sun Apr 06 20:20:39 2014 +0000
@@ -0,0 +1,23 @@
+CC=	gcc
+CFLAGS=	-O2
+STD=	atsc factdiff mokosrec2bin rfcap-grep
+CRYPTO=	imeibrute pirimei
+PROGS=	${STD} ${CRYPTO}
+
+all:	${PROGS}
+
+${STD}:
+	${CC} ${CFLAGS} -o $@ $@.c
+
+${CRYPTO}:
+	${CC} ${CFLAGS} -o $@ $@.c -lcrypto
+
+atsc:		atsc.c
+factdiff:	factdiff.c
+imeibrute:	imeibrute.c
+mokosrec2bin:	mokosrec2bin.c
+pirimei:	pirimei.c
+rfcap-grep:	rfcap-grep.c
+
+clean:
+	rm -f ${PROGS} *.o *errs *.out
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/miscprog/atsc.c	Sun Apr 06 20:20:39 2014 +0000
@@ -0,0 +1,58 @@
+/*
+ * It is known that some GSM devices have undocumented AT commands for
+ * changing the IMEI.  There is no standard syntax for such an AT command
+ * (by the "proper rules" one is not supposed to exist at all), and instead
+ * there seem to be several different ad hoc syntaxes.  This source file,
+ * found on a Chinese site, implements one of these numerous ad hoc
+ * IMEI-changing AT commands:
+ *
+ * ftp://ftp.ifctf.org/pub/GSM/TI_src/ati_sc.c
+ *
+ * Notice that this particular incarnation of the "set IMEI" AT command
+ * is called AT@SC; there just happens to be an identically-named AT@SC
+ * command on Openmoko's GSM modems.  Might it perchance be the same
+ * IMEI changing command?
+ *
+ * This program constructs what should be a valid input to the decoding
+ * logic in the ati_sc.c source above, for the purpose of testing whether
+ * or not such a command would indeed effect an IMEI change on a GTA02 modem.
+ */
+
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+#include <strings.h>
+#include <stdlib.h>
+
+static char hexdigits[] = "0123456789abcdef";
+
+main(argc, argv)
+	char **argv;
+{
+	char hexout[16];
+	unsigned n1, n2, cksum;
+	int i, c;
+
+	if (argc != 2) {
+usage:		fprintf(stderr, "usage: %s 15-IMEI-digits\n", argv[0]);
+		exit(1);
+	}
+	if (strlen(argv[1]) != 15)
+		goto usage;
+	n1 = n2 = 0;
+	for (i = 0; i < 15; i++) {
+		c = argv[1][i];
+		if (!isdigit(c))
+			goto usage;
+		c -= '0';
+		hexout[i] = hexdigits[c ^ 5];
+		if (i < 7)
+			n1 = n1 * 10 + c;
+		else
+			n2 = n2 * 10 + c;
+	}
+	hexout[15] = '\0';
+	cksum = (n1 + n2) % 1973;
+	printf("AT@SC=\"%s%04u\"\n", hexout, cksum);
+	exit(0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/miscprog/factdiff.c	Sun Apr 06 20:20:39 2014 +0000
@@ -0,0 +1,85 @@
+/*
+ * The 64 KiB "factory block" at the end of the 2nd flash chip select on
+ * Pirelli DP-L10 phones is believed to contain juicy info (IMEI and RF
+ * calibration data), but the format is yet to be cracked.
+ *
+ * This program compares Pirelli factory block images that have been read
+ * out of several phones, seeking to determine which bytes are always the
+ * same and which bytes change from specimen to specimen.
+ *
+ * Written by Spacefalcon the Outlaw.
+ */
+
+#include <sys/types.h>
+#include <sys/file.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+u_char specimen0[65536];
+char is_diff[65536];
+
+read_specimen_file(filename, buf)
+	char *filename;
+	u_char *buf;
+{
+	int fd, cc;
+
+	fd = open(filename, O_RDONLY);
+	if (fd < 0) {
+		perror(filename);
+		exit(1);
+	}
+	cc = read(fd, buf, 65536);
+	close(fd);
+	if (cc != 65536) {
+		fprintf(stderr, "%s: unable to read 64 KiB\n", filename);
+		exit(1);
+	}
+}
+
+process_comp_specimen(filename)
+	char *filename;
+{
+	u_char this_spec[65536];
+	int i;
+
+	read_specimen_file(filename, this_spec);
+	for (i = 0; i < 65536; i++)
+		if (this_spec[i] != specimen0[i])
+			is_diff[i] = 1;
+}
+
+output()
+{
+	int off, state, cstart, num;
+
+	for (off = 0; off < 65536; ) {
+		state = is_diff[off];
+		cstart = off;
+		while (off < 65536 && is_diff[off] == state)
+			off++;
+		printf("%04X-%04X: %s", cstart, off-1,
+			state ? "varying" : "constant");
+		if (state) {
+			num = off - cstart;
+			printf(" (%d byte%s)", num, num != 1 ? "s" : "");
+		}
+		putchar('\n');
+	}
+}
+
+main(argc, argv)
+	char **argv;
+{
+	char **ap;
+
+	if (argc < 3) {
+		fprintf(stderr, "usage: %s specimen0 specimen1 ...\n", argv[0]);
+		exit(1);
+	}
+	read_specimen_file(argv[1], specimen0);
+	for (ap = argv + 2; *ap; ap++)
+		process_comp_specimen(*ap);
+	output();
+	exit(0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/miscprog/imeibrute.c	Sun Apr 06 20:20:39 2014 +0000
@@ -0,0 +1,99 @@
+/*
+ * The IMEI "protection" implemented by TI for Calypso (as opposed to Calypso+
+ * or LoCosto) platforms for those device manufs who desired to obfuscate their
+ * IMEIs (not everyone did - Openmoko opted out, for example), as seen in
+ * g23m/condat/com/src/comlib/cl_imei.c in the Leonardo semi-src by Sotovik,
+ * encrypts the IMEI using plain DES, using a key derived from the Calypso die
+ * ID.  However, only 28 effective key bits are used, and the key is then also
+ * encrypted with itself and stored right after the encrypted IMEI, and is used
+ * by the decryption & verification routine.  Per TI's source, the 16-byte
+ * encrypted IMEI record is to be stored in FFS in /gsm/imei.enc; the DP-L10
+ * phone by Pirelli/Foxconn has been found to use the same scheme, but store
+ * the 16-byte record in question in their "factory block" instead, at absolute
+ * address 0x027F0504 as seen by the ARM7 CPU.
+ *
+ * The encryption scheme seems so weak to me (28 effective key bits and an easy
+ * hit detection criterion for a brute force cracker) that I decided to see,
+ * just for fun, how long it would take to crack that encryption by brute force
+ * alone, and using a totally non-optimized program to do that.
+ */
+
+#include <sys/types.h>
+#include <openssl/des.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+DES_cblock ciphertext[2], dieid_key, decrypted[2];
+DES_key_schedule keysched;
+
+read_ciphertext(filename, offset_arg)
+	char *filename, *offset_arg;
+{
+	FILE *f;
+	u_long offset_val;
+
+	f = fopen(filename, "r");
+	if (!f) {
+		perror(filename);
+		exit(1);
+	}
+	if (offset_arg) {
+		offset_val = strtoul(offset_arg, 0, 16);
+		fseek(f, offset_val, 0);
+	}
+	fread(ciphertext, 8, 2, f);
+	fclose(f);
+}
+
+print_des_cblock(msg, blk)
+	char *msg;
+	DES_cblock blk;
+{
+	printf("%s: %02X %02X %02X %02X %02X %02X %02X %02X\n", msg,
+		blk[0], blk[1], blk[2], blk[3], blk[4], blk[5], blk[6], blk[7]);
+}
+
+try()
+{
+	DES_set_key_unchecked(&dieid_key, &keysched);
+	DES_ecb_encrypt(&ciphertext[1], &decrypted[1], &keysched, DES_DECRYPT);
+	if (decrypted[1][0] & 0xFE != dieid_key[0])
+		return;
+	if (decrypted[1][1])
+		return;
+	if (decrypted[1][2] & 0xFE != dieid_key[2])
+		return;
+	if (decrypted[1][3])
+		return;
+	if (decrypted[1][4] & 0xFE != dieid_key[4])
+		return;
+	if (decrypted[1][5])
+		return;
+	if (decrypted[1][6] & 0xFE != dieid_key[6])
+		return;
+	if (decrypted[1][7])
+		return;
+	print_des_cblock("Hit", &decrypted[1]);
+	DES_ecb_encrypt(&ciphertext[0], &decrypted[0], &keysched, DES_DECRYPT);
+	print_des_cblock("IMEI", &decrypted[0]);
+}
+
+main(argc, argv)
+	char **argv;
+{
+	if (argc < 2 || argc > 3) {
+		fprintf(stderr, "usage: %s binfile [offset]\n", argv[0]);
+		exit(1);
+	}
+	read_ciphertext(argv[1], argv[2]);
+	dieid_key[1] = 0;
+	dieid_key[3] = 0;
+	dieid_key[5] = 0;
+	dieid_key[7] = 0;
+	for (dieid_key[0] = 0; dieid_key[0] <= 0xFE; dieid_key[0] += 2)
+	  for (dieid_key[2] = 0; dieid_key[2] <= 0xFE; dieid_key[2] += 2)
+	    for (dieid_key[4] = 0; dieid_key[4] <= 0xFE; dieid_key[4] += 2)
+	      for (dieid_key[6] = 0; dieid_key[6] <= 0xFE; dieid_key[6] += 2)
+		try();
+	exit(0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/miscprog/mokosrec2bin.c	Sun Apr 06 20:20:39 2014 +0000
@@ -0,0 +1,226 @@
+/*
+ * The *.m0 format in which the Closedmoko firmware images have been
+ * distributed is a form of SREC, but further examination quickly
+ * reveals that the data bytes are swapped: the byte order is neither
+ * the natural little-endian ARM one of the Calypso, nor a word-wise
+ * ARM BE; instead the upper and lower bytes of each 16-bit shortword
+ * are swapped relative to the natural byte/word order of the Calypso
+ * ARM processor.
+ *
+ * Before this Closedmoko firmware can be examined with any of the
+ * standard reverse eng tools (ARM disassemblers or even the good old
+ * strings), it needs to be converted from the weird byte-swapped SREC
+ * format to straight binary in the natural byte order.  The present
+ * utility accomplishes that conversion.
+ *
+ * Written by Spacefalcon the Outlaw.
+ */
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <strings.h>
+
+char *infname;
+FILE *inf, *outf;
+u_char fillbyte;
+char srecbuf[80];
+u_char srecbin[40];
+int lineno, state;
+u_long lastaddr;
+
+u_char header[6] = {0x06, 0x00, 0x00, 'H', 'D', 'R'};
+
+decode_hex_byte(s)
+	char *s;
+{
+	register int u, l;
+
+	if (!isxdigit(s[0]) || !isxdigit(s[1]))
+		return(-1);
+	if (isdigit(s[0]))
+		u = s[0] - '0';
+	else if (isupper(s[0]))
+		u = s[0] - 'A' + 10;
+	else
+		u = s[0] - 'a' + 10;
+	if (isdigit(s[1]))
+		l = s[1] - '0';
+	else if (isupper(s[1]))
+		l = s[1] - 'A' + 10;
+	else
+		l = s[1] - 'a' + 10;
+	return((u << 4) | l);
+}
+
+srec2bin()
+{
+	register int i, l, b;
+
+	l = decode_hex_byte(srecbuf + 2);
+	if (l < 1) {
+		fprintf(stderr, "%s line %d: S-record length octet is bad\n",
+			infname, lineno);
+		exit(1);
+	}
+	srecbin[0] = l;
+	if (l > 35) {
+		fprintf(stderr,
+			"%s line %d: S-record is longer than expected\n",
+			infname, lineno);
+		exit(1);
+	}
+	for (i = 1; i <= l; i++) {
+		b = decode_hex_byte(srecbuf + i*2 + 2);
+		if (b < 0) {
+			fprintf(stderr, "%s line %d: hex decode error\n",
+				infname, lineno);
+			exit(1);
+		}
+		srecbin[i] = b;
+	}
+	return(0);
+}
+
+srec_cksum()
+{
+	u_char accum;
+	register int i, len;
+
+	len = srecbin[0] + 1;
+	accum = 0;
+	for (i = 0; i < len; i++)
+		accum += srecbin[i];
+	if (accum != 0xFF) {
+		fprintf(stderr, "%s line %d: bad checksum\n", infname, lineno);
+		exit(1);
+	}
+	return(0);
+}
+
+main(argc, argv)
+	char **argv;
+{
+	register int i;
+	u_long curaddr;
+	int datalen;
+
+	if (argc < 3 || argc > 4) {
+usage:		fprintf(stderr, "usage: %s input.m0 output.bin [fill-byte]\n",
+			argv[0]);
+		exit(1);
+	}
+	infname = argv[1];
+	inf = fopen(infname, "r");
+	if (!inf) {
+		perror(infname);
+		exit(1);
+	}
+	if (argc > 3) {
+		i = decode_hex_byte(argv[3]);
+		if (i >= 0)
+			fillbyte = i;
+		else
+			goto usage;
+	} else
+		fillbyte = 0;
+
+	state = 0;
+	for (lineno = 1; ; lineno++) {
+		if (!fgets(srecbuf, sizeof srecbuf, inf)) {
+			fprintf(stderr, "%s: premature EOF\n", infname);
+			exit(1);
+		}
+		if (srecbuf[0] != 'S') {
+			fprintf(stderr, "%s line %d: not an S-record\n",
+				infname, lineno);
+			exit(1);
+		}
+		switch (srecbuf[1]) {
+		case '0':
+			if (state == 0)
+				break;
+			else
+				goto badtype;
+		case '3':
+			if (state == 0)
+				goto badtype;
+			else
+				break;
+		case '7':
+			if (state == 2)
+				break;
+			else
+				goto badtype;
+		default:
+		badtype:
+			fprintf(stderr,
+				"%s line %d: S-record type unexpected\n",
+				infname, lineno);
+			exit(1);
+		}
+		srec2bin();
+		srec_cksum();
+		if (state == 0) {
+			if (bcmp(srecbin, header, 6)) {
+				fprintf(stderr, "%s: expected header missing\n",
+					infname);
+				exit(1);
+			}
+			state = 1;
+			continue;
+		}
+		switch (srecbuf[1]) {
+		case '3':
+			if (srecbin[0] < 6) {
+				fprintf(stderr,
+					"%s line %d: S3 record is too short\n",
+					infname, lineno);
+				exit(1);
+			}
+			curaddr = (srecbin[1] << 24) | (srecbin[2] << 16) |
+				  (srecbin[3] << 8) | srecbin[4];
+			if (curaddr & 1) {
+				fprintf(stderr, "%s line %d: odd address\n",
+					infname, lineno);
+				exit(1);
+			}
+			datalen = srecbin[0] - 5;
+			if (datalen & 1) {
+				fprintf(stderr, "%s line %d: odd data length\n",
+					infname, lineno);
+				exit(1);
+			}
+			if (state < 2) {
+				outf = fopen(argv[2], "w");
+				if (!outf) {
+					perror(argv[2]);
+					exit(1);
+				}
+				state = 2;
+				lastaddr = 0;
+			}
+			if (curaddr < lastaddr) {
+				fprintf(stderr,
+					"%s line %d: address going backwards\n",
+					infname, lineno);
+				exit(1);
+			}
+			while (lastaddr < curaddr) {
+				putc(fillbyte, outf);
+				lastaddr++;
+			}
+			for (i = 0; i < datalen; i += 2) {
+				putc(srecbin[i + 6], outf);
+				putc(srecbin[i + 5], outf);
+			}
+			lastaddr = curaddr + datalen;
+			continue;
+		case '7':
+			fclose(outf);
+			exit(0);
+		default:
+			abort();
+		}
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/miscprog/pirimei.c	Sun Apr 06 20:20:39 2014 +0000
@@ -0,0 +1,103 @@
+/*
+ * This program recovers the IMEI of a Pirelli DP-L10 phone from a dump of
+ * its factory block (last 64 KiB sector of the 2nd flash chip select) and
+ * the corresponding dieid file as written by fc-loadtool.
+ *
+ * The location of the 16-byte encrypted IMEI record within the factory block
+ * (at offset 0x504) has been figured out with the help of the factdiff.c
+ * program, and the magic decryption & verification algorithm has been found in
+ * g23m/condat/com/src/comlib/cl_imei.c in the Leonardo semi-src by Sotovik.
+ */
+
+#include <sys/types.h>
+#include <openssl/des.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+DES_cblock ciphertext[2], dieid_key, decrypted[2];
+DES_key_schedule keysched;
+
+read_ciphertext(filename)
+	char *filename;
+{
+	FILE *f;
+
+	f = fopen(filename, "r");
+	if (!f) {
+		perror(filename);
+		exit(1);
+	}
+	fseek(f, 0x504L, 0);
+	fread(ciphertext, 8, 2, f);
+	fclose(f);
+}
+
+decode_hexdigit(ch)
+{
+	if (isdigit(ch))
+		return(ch - '0');
+	else if (isalpha(ch))
+		return(ch - 'A' + 10);
+	else
+		return(ch - 'a' + 10);
+}
+
+read_dieid_file(filename)
+	char *filename;
+{
+	FILE *f;
+	int i;
+	char lb[64];
+
+	f = fopen(filename, "r");
+	if (!f) {
+		perror(filename);
+		exit(1);
+	}
+	for (i = 0; i < 4; i++) {
+		fgets(lb, sizeof lb, f);
+		if (!isxdigit(lb[0]) || !isxdigit(lb[1]) || !isxdigit(lb[2]) ||
+		    !isxdigit(lb[3]) || !isxdigit(lb[4]) || !isxdigit(lb[5]) ||
+		    !isxdigit(lb[6]) || !isxdigit(lb[7]) ||
+		    lb[8] != ':' || lb[9] != ' ' ||
+		    !isxdigit(lb[10]) || !isxdigit(lb[11]) ||
+		    !isxdigit(lb[12]) || !isxdigit(lb[13]) || lb[14] != '\n') {
+			fprintf(stderr, "%s, line %d: differs from expected\n",
+				filename, i + 1);
+			exit(1);
+		}
+		dieid_key[i*2] = (decode_hexdigit(lb[12]) << 4) |
+					decode_hexdigit(lb[13]);
+		dieid_key[i*2+1] = 0;
+	}
+	fclose(f);
+}
+
+print_des_cblock(msg, blk)
+	char *msg;
+	DES_cblock blk;
+{
+	printf("%s: %02X %02X %02X %02X %02X %02X %02X %02X\n", msg,
+		blk[0], blk[1], blk[2], blk[3], blk[4], blk[5], blk[6], blk[7]);
+}
+
+main(argc, argv)
+	char **argv;
+{
+	if (argc != 3) {
+		fprintf(stderr, "usage: %s fact.bin dieid\n", argv[0]);
+		exit(1);
+	}
+	read_ciphertext(argv[1]);
+	read_dieid_file(argv[2]);
+	print_des_cblock("Key derived from die ID", &dieid_key);
+	print_des_cblock("Ciphertext block 1", &ciphertext[0]);
+	print_des_cblock("Ciphertext block 2", &ciphertext[1]);
+	DES_set_key_unchecked(&dieid_key, &keysched);
+	DES_ecb_encrypt(&ciphertext[0], &decrypted[0], &keysched, DES_DECRYPT);
+	print_des_cblock("1st decrypted block", &decrypted[0]);
+	DES_ecb_encrypt(&ciphertext[1], &decrypted[1], &keysched, DES_DECRYPT);
+	print_des_cblock("2nd decrypted block", &decrypted[1]);
+	exit(0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/miscprog/rfcap-grep.c	Sun Apr 06 20:20:39 2014 +0000
@@ -0,0 +1,65 @@
+/*
+ * This utility performs a memmem() binary "grep", checking to see if a given
+ * binary file (mokoN firmware image) contains a particular binary "string"
+ * of 16 bytes: namely, the 16 bytes found in the "standard" /gsm/com/rfcap
+ * file on GTA0x modems.
+ */
+
+#define	_GNU_SOURCE
+#include <sys/types.h>
+#include <sys/file.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+u_char needle[16] = {0x00, 0x1F, 0x41, 0x14, 0x00, 0x00, 0x00, 0x00,
+		     0x50, 0x00, 0x00, 0xA5, 0x05, 0x00, 0xC0, 0x00};
+u_char *haystack;
+size_t haystack_size;
+
+read_file(filename)
+	char *filename;
+{
+	int fd;
+	struct stat st;
+
+	fd = open(filename, O_RDONLY);
+	if (fd < 0) {
+		perror(filename);
+		exit(1);
+	}
+	fstat(fd, &st);
+	if (!S_ISREG(st.st_mode)) {
+		fprintf(stderr, "error: %s is not a regular file\n", filename);
+		exit(1);
+	}
+	haystack_size = st.st_size;
+	haystack = malloc(haystack_size);
+	if (!haystack) {
+		fprintf(stderr, "unable to malloc buffer for %s\n", filename);
+		exit(1);
+	}
+	read(fd, haystack, haystack_size);
+	close(fd);
+}
+
+main(argc, argv)
+	char **argv;
+{
+	u_char *result;
+
+	if (argc != 2) {
+		fprintf(stderr, "usage: %s mokoN.bin\n", argv[0]);
+		exit(1);
+	}
+	read_file(argv[1]);
+	result = memmem(haystack, haystack_size, needle, sizeof needle);
+	if (result)
+		printf("Found the rfcap bytes at offset 0x%x\n",
+			result - haystack);
+	else
+		printf("rfcap bytes not found in this image\n");
+	exit(0);
+}
--- a/mokosrec2bin.c	Sat Apr 05 20:21:55 2014 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,226 +0,0 @@
-/*
- * The *.m0 format in which the Closedmoko firmware images have been
- * distributed is a form of SREC, but further examination quickly
- * reveals that the data bytes are swapped: the byte order is neither
- * the natural little-endian ARM one of the Calypso, nor a word-wise
- * ARM BE; instead the upper and lower bytes of each 16-bit shortword
- * are swapped relative to the natural byte/word order of the Calypso
- * ARM processor.
- *
- * Before this Closedmoko firmware can be examined with any of the
- * standard reverse eng tools (ARM disassemblers or even the good old
- * strings), it needs to be converted from the weird byte-swapped SREC
- * format to straight binary in the natural byte order.  The present
- * utility accomplishes that conversion.
- *
- * Written by Spacefalcon the Outlaw.
- */
-
-#include <sys/types.h>
-#include <stdio.h>
-#include <ctype.h>
-#include <strings.h>
-
-char *infname;
-FILE *inf, *outf;
-u_char fillbyte;
-char srecbuf[80];
-u_char srecbin[40];
-int lineno, state;
-u_long lastaddr;
-
-u_char header[6] = {0x06, 0x00, 0x00, 'H', 'D', 'R'};
-
-decode_hex_byte(s)
-	char *s;
-{
-	register int u, l;
-
-	if (!isxdigit(s[0]) || !isxdigit(s[1]))
-		return(-1);
-	if (isdigit(s[0]))
-		u = s[0] - '0';
-	else if (isupper(s[0]))
-		u = s[0] - 'A' + 10;
-	else
-		u = s[0] - 'a' + 10;
-	if (isdigit(s[1]))
-		l = s[1] - '0';
-	else if (isupper(s[1]))
-		l = s[1] - 'A' + 10;
-	else
-		l = s[1] - 'a' + 10;
-	return((u << 4) | l);
-}
-
-srec2bin()
-{
-	register int i, l, b;
-
-	l = decode_hex_byte(srecbuf + 2);
-	if (l < 1) {
-		fprintf(stderr, "%s line %d: S-record length octet is bad\n",
-			infname, lineno);
-		exit(1);
-	}
-	srecbin[0] = l;
-	if (l > 35) {
-		fprintf(stderr,
-			"%s line %d: S-record is longer than expected\n",
-			infname, lineno);
-		exit(1);
-	}
-	for (i = 1; i <= l; i++) {
-		b = decode_hex_byte(srecbuf + i*2 + 2);
-		if (b < 0) {
-			fprintf(stderr, "%s line %d: hex decode error\n",
-				infname, lineno);
-			exit(1);
-		}
-		srecbin[i] = b;
-	}
-	return(0);
-}
-
-srec_cksum()
-{
-	u_char accum;
-	register int i, len;
-
-	len = srecbin[0] + 1;
-	accum = 0;
-	for (i = 0; i < len; i++)
-		accum += srecbin[i];
-	if (accum != 0xFF) {
-		fprintf(stderr, "%s line %d: bad checksum\n", infname, lineno);
-		exit(1);
-	}
-	return(0);
-}
-
-main(argc, argv)
-	char **argv;
-{
-	register int i;
-	u_long curaddr;
-	int datalen;
-
-	if (argc < 3 || argc > 4) {
-usage:		fprintf(stderr, "usage: %s input.m0 output.bin [fill-byte]\n",
-			argv[0]);
-		exit(1);
-	}
-	infname = argv[1];
-	inf = fopen(infname, "r");
-	if (!inf) {
-		perror(infname);
-		exit(1);
-	}
-	if (argc > 3) {
-		i = decode_hex_byte(argv[3]);
-		if (i >= 0)
-			fillbyte = i;
-		else
-			goto usage;
-	} else
-		fillbyte = 0;
-
-	state = 0;
-	for (lineno = 1; ; lineno++) {
-		if (!fgets(srecbuf, sizeof srecbuf, inf)) {
-			fprintf(stderr, "%s: premature EOF\n", infname);
-			exit(1);
-		}
-		if (srecbuf[0] != 'S') {
-			fprintf(stderr, "%s line %d: not an S-record\n",
-				infname, lineno);
-			exit(1);
-		}
-		switch (srecbuf[1]) {
-		case '0':
-			if (state == 0)
-				break;
-			else
-				goto badtype;
-		case '3':
-			if (state == 0)
-				goto badtype;
-			else
-				break;
-		case '7':
-			if (state == 2)
-				break;
-			else
-				goto badtype;
-		default:
-		badtype:
-			fprintf(stderr,
-				"%s line %d: S-record type unexpected\n",
-				infname, lineno);
-			exit(1);
-		}
-		srec2bin();
-		srec_cksum();
-		if (state == 0) {
-			if (bcmp(srecbin, header, 6)) {
-				fprintf(stderr, "%s: expected header missing\n",
-					infname);
-				exit(1);
-			}
-			state = 1;
-			continue;
-		}
-		switch (srecbuf[1]) {
-		case '3':
-			if (srecbin[0] < 6) {
-				fprintf(stderr,
-					"%s line %d: S3 record is too short\n",
-					infname, lineno);
-				exit(1);
-			}
-			curaddr = (srecbin[1] << 24) | (srecbin[2] << 16) |
-				  (srecbin[3] << 8) | srecbin[4];
-			if (curaddr & 1) {
-				fprintf(stderr, "%s line %d: odd address\n",
-					infname, lineno);
-				exit(1);
-			}
-			datalen = srecbin[0] - 5;
-			if (datalen & 1) {
-				fprintf(stderr, "%s line %d: odd data length\n",
-					infname, lineno);
-				exit(1);
-			}
-			if (state < 2) {
-				outf = fopen(argv[2], "w");
-				if (!outf) {
-					perror(argv[2]);
-					exit(1);
-				}
-				state = 2;
-				lastaddr = 0;
-			}
-			if (curaddr < lastaddr) {
-				fprintf(stderr,
-					"%s line %d: address going backwards\n",
-					infname, lineno);
-				exit(1);
-			}
-			while (lastaddr < curaddr) {
-				putc(fillbyte, outf);
-				lastaddr++;
-			}
-			for (i = 0; i < datalen; i += 2) {
-				putc(srecbin[i + 6], outf);
-				putc(srecbin[i + 5], outf);
-			}
-			lastaddr = curaddr + datalen;
-			continue;
-		case '7':
-			fclose(outf);
-			exit(0);
-		default:
-			abort();
-		}
-	}
-}
--- a/pirimei.c	Sat Apr 05 20:21:55 2014 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,103 +0,0 @@
-/*
- * This program recovers the IMEI of a Pirelli DP-L10 phone from a dump of
- * its factory block (last 64 KiB sector of the 2nd flash chip select) and
- * the corresponding dieid file as written by fc-loadtool.
- *
- * The location of the 16-byte encrypted IMEI record within the factory block
- * (at offset 0x504) has been figured out with the help of the factdiff.c
- * program, and the magic decryption & verification algorithm has been found in
- * g23m/condat/com/src/comlib/cl_imei.c in the Leonardo semi-src by Sotovik.
- */
-
-#include <sys/types.h>
-#include <openssl/des.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-DES_cblock ciphertext[2], dieid_key, decrypted[2];
-DES_key_schedule keysched;
-
-read_ciphertext(filename)
-	char *filename;
-{
-	FILE *f;
-
-	f = fopen(filename, "r");
-	if (!f) {
-		perror(filename);
-		exit(1);
-	}
-	fseek(f, 0x504L, 0);
-	fread(ciphertext, 8, 2, f);
-	fclose(f);
-}
-
-decode_hexdigit(ch)
-{
-	if (isdigit(ch))
-		return(ch - '0');
-	else if (isalpha(ch))
-		return(ch - 'A' + 10);
-	else
-		return(ch - 'a' + 10);
-}
-
-read_dieid_file(filename)
-	char *filename;
-{
-	FILE *f;
-	int i;
-	char lb[64];
-
-	f = fopen(filename, "r");
-	if (!f) {
-		perror(filename);
-		exit(1);
-	}
-	for (i = 0; i < 4; i++) {
-		fgets(lb, sizeof lb, f);
-		if (!isxdigit(lb[0]) || !isxdigit(lb[1]) || !isxdigit(lb[2]) ||
-		    !isxdigit(lb[3]) || !isxdigit(lb[4]) || !isxdigit(lb[5]) ||
-		    !isxdigit(lb[6]) || !isxdigit(lb[7]) ||
-		    lb[8] != ':' || lb[9] != ' ' ||
-		    !isxdigit(lb[10]) || !isxdigit(lb[11]) ||
-		    !isxdigit(lb[12]) || !isxdigit(lb[13]) || lb[14] != '\n') {
-			fprintf(stderr, "%s, line %d: differs from expected\n",
-				filename, i + 1);
-			exit(1);
-		}
-		dieid_key[i*2] = (decode_hexdigit(lb[12]) << 4) |
-					decode_hexdigit(lb[13]);
-		dieid_key[i*2+1] = 0;
-	}
-	fclose(f);
-}
-
-print_des_cblock(msg, blk)
-	char *msg;
-	DES_cblock blk;
-{
-	printf("%s: %02X %02X %02X %02X %02X %02X %02X %02X\n", msg,
-		blk[0], blk[1], blk[2], blk[3], blk[4], blk[5], blk[6], blk[7]);
-}
-
-main(argc, argv)
-	char **argv;
-{
-	if (argc != 3) {
-		fprintf(stderr, "usage: %s fact.bin dieid\n", argv[0]);
-		exit(1);
-	}
-	read_ciphertext(argv[1]);
-	read_dieid_file(argv[2]);
-	print_des_cblock("Key derived from die ID", &dieid_key);
-	print_des_cblock("Ciphertext block 1", &ciphertext[0]);
-	print_des_cblock("Ciphertext block 2", &ciphertext[1]);
-	DES_set_key_unchecked(&dieid_key, &keysched);
-	DES_ecb_encrypt(&ciphertext[0], &decrypted[0], &keysched, DES_DECRYPT);
-	print_des_cblock("1st decrypted block", &decrypted[0]);
-	DES_ecb_encrypt(&ciphertext[1], &decrypted[1], &keysched, DES_DECRYPT);
-	print_des_cblock("2nd decrypted block", &decrypted[1]);
-	exit(0);
-}
--- a/rfcap-grep.c	Sat Apr 05 20:21:55 2014 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,65 +0,0 @@
-/*
- * This utility performs a memmem() binary "grep", checking to see if a given
- * binary file (mokoN firmware image) contains a particular binary "string"
- * of 16 bytes: namely, the 16 bytes found in the "standard" /gsm/com/rfcap
- * file on GTA0x modems.
- */
-
-#define	_GNU_SOURCE
-#include <sys/types.h>
-#include <sys/file.h>
-#include <sys/stat.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-u_char needle[16] = {0x00, 0x1F, 0x41, 0x14, 0x00, 0x00, 0x00, 0x00,
-		     0x50, 0x00, 0x00, 0xA5, 0x05, 0x00, 0xC0, 0x00};
-u_char *haystack;
-size_t haystack_size;
-
-read_file(filename)
-	char *filename;
-{
-	int fd;
-	struct stat st;
-
-	fd = open(filename, O_RDONLY);
-	if (fd < 0) {
-		perror(filename);
-		exit(1);
-	}
-	fstat(fd, &st);
-	if (!S_ISREG(st.st_mode)) {
-		fprintf(stderr, "error: %s is not a regular file\n", filename);
-		exit(1);
-	}
-	haystack_size = st.st_size;
-	haystack = malloc(haystack_size);
-	if (!haystack) {
-		fprintf(stderr, "unable to malloc buffer for %s\n", filename);
-		exit(1);
-	}
-	read(fd, haystack, haystack_size);
-	close(fd);
-}
-
-main(argc, argv)
-	char **argv;
-{
-	u_char *result;
-
-	if (argc != 2) {
-		fprintf(stderr, "usage: %s mokoN.bin\n", argv[0]);
-		exit(1);
-	}
-	read_file(argv[1]);
-	result = memmem(haystack, haystack_size, needle, sizeof needle);
-	if (result)
-		printf("Found the rfcap bytes at offset 0x%x\n",
-			result - haystack);
-	else
-		printf("rfcap bytes not found in this image\n");
-	exit(0);
-}