From: iceman1001 <iceman@iuse.se>
Date: Wed, 16 Dec 2015 10:01:46 +0000 (+0100)
Subject: ADD: @marshmellow42 's fixes for Q5, t55xx, fskclock,
X-Git-Url: https://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/commitdiff_plain/9332b857ffeee343334064d3ca53048f59c55e50?hp=2b1f4228c2987459445d30443f92038f9ea080c6

ADD: @marshmellow42 's fixes for Q5, t55xx, fskclock,

ADD:  got tired of always writing wrong "hf 14a list",  so I hooked it back up to call the "hf list" with argument. Things becomes smoother that way.
---

diff --git a/armsrc/lfops.c b/armsrc/lfops.c
index 85931aa3..22173059 100644
--- a/armsrc/lfops.c
+++ b/armsrc/lfops.c
@@ -400,7 +400,7 @@ void SimulateTagLowFrequency(int period, int gap, int ledcontrol)
 	for(;;) {
 		//wait until SSC_CLK goes HIGH
 		while(!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK)) {
-			if(BUTTON_PRESS() || usb_poll_validate_length() ) {
+			if(BUTTON_PRESS() || !usb_poll_validate_length() ) {
 				DbpString("Stopped");
 				return;
 			}
@@ -417,7 +417,7 @@ void SimulateTagLowFrequency(int period, int gap, int ledcontrol)
 		
 		//wait until SSC_CLK goes LOW
 		while(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK) {
-			if( BUTTON_PRESS() || usb_poll_validate_length() ) {
+			if( BUTTON_PRESS() || !usb_poll_validate_length() ) {
 				DbpString("Stopped");
 				return;
 			}
diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c
index a77a2dd3..91aa7218 100644
--- a/armsrc/mifarecmd.c
+++ b/armsrc/mifarecmd.c
@@ -1043,7 +1043,7 @@ void MifareEMemClr(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain)
 
 void MifareEMemSet(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){
 	FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
-	//emlSetMem(datain, arg0, arg1); // data, block num, blocks count	 
+	if (arg2==0) arg2 = 16; // backwards compat... default bytewidth
 	emlSetMem_xt(datain, arg0, arg1, arg2); // data, block num, blocks count, block byte width
 }
 
@@ -1187,8 +1187,8 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain){
 		if(!iso14443a_select_card(uid, NULL, &cuid, true, 0)) {
 			if (MF_DBGLEVEL >= MF_DBG_ERROR)	Dbprintf("Can't select card");
 			OnErrorMagic(MAGIC_UID);
-		};
-	};
+		}
+	}
 	
 	// wipe tag, fill it with zeros
 	if (workFlags & MAGIC_WIPE){
@@ -1196,14 +1196,14 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain){
 		if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
 			if (MF_DBGLEVEL >= MF_DBG_ERROR)	Dbprintf("wupC1 error");
 			OnErrorMagic(MAGIC_WIPE);
-		};
+		}
 
 		ReaderTransmit(wipeC, sizeof(wipeC), NULL);
 		if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
 			if (MF_DBGLEVEL >= MF_DBG_ERROR)	Dbprintf("wipeC error");
 			OnErrorMagic(MAGIC_WIPE);
-		};
-	};	
+		}
+	}	
 
 	// write block
 	if (workFlags & MAGIC_WUPC) {
@@ -1211,19 +1211,19 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain){
 		if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
 			if (MF_DBGLEVEL >= MF_DBG_ERROR)	Dbprintf("wupC1 error");
 			OnErrorMagic(MAGIC_WUPC);
-		};
+		}
 
 		ReaderTransmit(wupC2, sizeof(wupC2), NULL);
 		if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
 			if (MF_DBGLEVEL >= MF_DBG_ERROR)	Dbprintf("wupC2 error");
 			OnErrorMagic(MAGIC_WUPC);
-		};
+		}
 	}
 
 	if ((mifare_sendcmd_short(NULL, 0, ISO14443A_CMD_WRITEBLOCK, blockNo, receivedAnswer, receivedAnswerPar, NULL) != 1) || (receivedAnswer[0] != 0x0a)) {
 		if (MF_DBGLEVEL >= MF_DBG_ERROR)	Dbprintf("write block send command error");
 		OnErrorMagic(4);
-	};
+	}
 	
 	memcpy(data, datain, 16);
 	AppendCrc14443a(data, 16);
@@ -1232,7 +1232,7 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain){
 	if ((ReaderReceive(receivedAnswer, receivedAnswerPar) != 1) || (receivedAnswer[0] != 0x0a)) {
 		if (MF_DBGLEVEL >= MF_DBG_ERROR)	Dbprintf("write block send data error");
 		OnErrorMagic(0);
-	};	
+	}	
 	
 	if (workFlags & MAGIC_OFF) 
 		mifare_classic_halt_ex(NULL);
@@ -1271,20 +1271,20 @@ void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain){
 		if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
 			if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("wupC1 error");
 			OnErrorMagic(MAGIC_WUPC);
-		};
+		}
 
 		ReaderTransmit(wupC2, sizeof(wupC2), NULL);
 		if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
 			if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("wupC2 error");
 			OnErrorMagic(MAGIC_WUPC);
-		};
+		}
 	}
 
 	// read block		
 	if ((mifare_sendcmd_short(NULL, 0, ISO14443A_CMD_READBLOCK, blockNo, receivedAnswer, receivedAnswerPar, NULL) != 18)) {
 		if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("read block send command error");
 		OnErrorMagic(0);
-	};
+	}
 	
 	memcpy(data, receivedAnswer, sizeof(data));
 	
@@ -1309,19 +1309,19 @@ void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain){
 void MifareCIdent(){
 	
 	// variables
-	byte_t isOK = 1;	
+	bool isOK = true;	
 	uint8_t receivedAnswer[1];
 	uint8_t receivedAnswerPar[1];
 
 	ReaderTransmitBitsPar(wupC1,7,0, NULL);
 	if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
-		isOK = 0;
-	};
+		isOK = false;
+	}
 
 	ReaderTransmit(wupC2, sizeof(wupC2), NULL);
 	if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
-		isOK = 0;
-	};
+		isOK = false;
+	}
 
 	// removed the if,  since some magic tags misbehavies and send an answer to it.
 	mifare_classic_halt(NULL, 0);
diff --git a/client/cmddata.c b/client/cmddata.c
index 67e5b810..ad86f45f 100644
--- a/client/cmddata.c
+++ b/client/cmddata.c
@@ -947,11 +947,10 @@ int FSKrawDemod(const char *Cmd, bool verbose)
 
 	//set defaults
 	//set options from parameters entered with the command
-	rfLen = param_get8ex(Cmd, 0, 0, 10);
-	invert = param_get8ex(Cmd, 1, 0, 10);
-	fchigh = param_get8ex(Cmd, 2, 0, 10);
-	fclow = param_get8ex(Cmd, 3, 0, 10);
-	
+	rfLen = param_get8(Cmd, 0);
+	invert = param_get8(Cmd, 1);
+	fchigh = param_get8(Cmd, 2);
+	fclow = param_get8(Cmd, 3);
 	if (strlen(Cmd)>0 && strlen(Cmd)<=2) {
 		 if (rfLen==1){
 			invert = 1;   //if invert option only is used
@@ -963,16 +962,16 @@ int FSKrawDemod(const char *Cmd, bool verbose)
 	size_t BitLen = getFromGraphBuf(BitStream);
 	if (BitLen==0) return 0;
 	//get field clock lengths
-	uint16_t fcs=0;
+	uint8_t fc1=0, fc2=0, rf1=0;
 	if (!fchigh || !fclow) {
-		fcs = countFC(BitStream, BitLen, 1);
-		if (!fcs) {
-			fchigh = 10;
-			fclow = 8;
-		} else {
-			fchigh = (fcs >> 8) & 0x00FF;
-			fclow = fcs & 0x00FF;
+		uint8_t ans = fskClocks(&fc1, &fc2, &rf1, false);
+		if (ans == 0) {
+			if (g_debugMode) PrintAndLog("\nError: cannot detect valid fsk field clocks");			
+			return 0; // can't detect field clock
 		}
+		fchigh = fc1;
+		fclow = fc2;
+		if (rfLen == 0) rfLen = rf1;
 	}
 	//get bit clock length
 	if (!rfLen){
diff --git a/client/cmdhf14a.c b/client/cmdhf14a.c
index f94296c0..8d15f731 100644
--- a/client/cmdhf14a.c
+++ b/client/cmdhf14a.c
@@ -25,6 +25,7 @@
 #include "mifare.h"
 #include "cmdhfmfu.h"
 #include "nonce2key/nonce2key.h"
+#include "cmdhf.h"
 
 #define llx PRIx64
 
@@ -171,7 +172,8 @@ int usage_hf_14a_raw(void){
 
 int CmdHF14AList(const char *Cmd)
 {
-	PrintAndLog("Deprecated command, use 'hf list 14a' instead");
+	//PrintAndLog("Deprecated command, use 'hf list 14a' instead");
+	CmdHFList("14a");
 	return 0;
 }
 
diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c
index 7f0779b6..577baa54 100644
--- a/client/cmdhficlass.c
+++ b/client/cmdhficlass.c
@@ -32,6 +32,7 @@
 #include "protocols.h"
 #include "usb_cmd.h"
 #include "cmdhfmfu.h"
+#include "cmdhf.h"
 
 #define llX PRIx64
 
@@ -62,7 +63,8 @@ int xorbits_8(uint8_t val) {
 }
 
 int CmdHFiClassList(const char *Cmd) {
-	PrintAndLog("Deprecated command, use 'hf list iclass' instead");
+	//PrintAndLog("Deprecated command, use 'hf list iclass' instead");
+	CmdHFList("iclass");
 	return 0;
 }
 
diff --git a/client/cmdhfmfu.c b/client/cmdhfmfu.c
index 82289d5b..d1b810a5 100644
--- a/client/cmdhfmfu.c
+++ b/client/cmdhfmfu.c
@@ -1252,24 +1252,26 @@ int usage_hf_mfu_eload(void) {
 	PrintAndLog("Usage:  hf mfu eload u <file name w/o `.eml`> [numblocks]");
 	PrintAndLog("  Options:");
 	PrintAndLog("    h          : this help");	
-	PrintAndLog("    u          : UL");
-	PrintAndLog("    numblocks  : number of blocks to load from eml file");		
+	PrintAndLog("    u          : UL (required)");
+	PrintAndLog("    [filename] : without `.eml` (required)");	
+	PrintAndLog("    numblocks  : number of blocks to load from eml file (optional)");
 	PrintAndLog("");
 	PrintAndLog("  sample: hf mfu eload u filename");
 	PrintAndLog("          hf mfu eload u filename 57");
-	return 0;
+			return 0;
 }
 
 int usage_hf_mfu_sim(void) {
 	PrintAndLog("\nEmulating Ultralight tag from emulator memory\n");
 	PrintAndLog("\nBe sure to load the emulator memory first!\n");
 	PrintAndLog("Usage: hf mfu sim t 7 u <uid>");
-	PrintAndLog("  Options : ");
-	PrintAndLog("    h     : this help");
-	PrintAndLog("    t     : 7 = NTAG or Ultralight sim");
-	PrintAndLog("    u     : 4 or 7 byte UID");
+	PrintAndLog("  Options:");
+	PrintAndLog("    h       : this help");
+	PrintAndLog("    t 7     : 7 = NTAG or Ultralight sim (required)");
+	PrintAndLog("    u <uid> : 4 or 7 byte UID (optional)");
 	PrintAndLog("\n   sample : hf mfu sim t 7");
 	PrintAndLog("          : hf mfu sim t 7 u 1122344556677\n");
+	
 	return 0;
 }
 
@@ -1469,12 +1471,6 @@ int CmdHF14AMfUDump(const char *Cmd){
 
 	// add keys to block dump
 	if (hasAuthKey) {
-		if (!swapEndian){
-			authKeyPtr = SwapEndian64(authenticationkey, dataLen, (dataLen == 16) ? 8 : 4);
-		} else {
-			authKeyPtr = authenticationkey;
-		}
-
 		if (tagtype & UL_C){ //add 4 pages
 			memcpy(data + Pages*4, authKeyPtr, dataLen);
 			Pages += dataLen/4;  
@@ -1486,7 +1482,7 @@ int CmdHF14AMfUDump(const char *Cmd){
 	uint8_t	get_pack[] = {0,0};
 	iso14a_card_select_t card;
 	//attempt to read pack
-	if (!ul_auth_select( &card, tagtype, true, authKeyPtr, get_pack, sizeof(get_pack))) {
+	if (!ul_auth_select( &card, tagtype, hasAuthKey, authKeyPtr, get_pack, sizeof(get_pack))) {
 		//reset pack
 		get_pack[0]=0;
 		get_pack[1]=0;
@@ -1537,7 +1533,7 @@ int CmdHF14AMfUDump(const char *Cmd){
 	PrintAndLog("GetVer-2| %s|   | %.4s", sprint_hex(dump_file_data+4, 4), dump_file_data+4);
 	PrintAndLog("TBD     | 00 00       |   | ");
 	PrintAndLog("Tearing |    %s|   | %.3s", sprint_hex(dump_file_data+10, 3), dump_file_data+10);
-	PrintAndLog("Pack    |    %s   |    | %.2s", sprint_hex(dump_file_data+13, 2), dump_file_data+13);
+	PrintAndLog("Pack    |    %s   |   | %.2s", sprint_hex(dump_file_data+13, 2), dump_file_data+13);
 	PrintAndLog("TBD     |          00 |   | ");
 	PrintAndLog("Sig-1   | %s|   | %.4s", sprint_hex(dump_file_data+16, 4), dump_file_data+16);
 	PrintAndLog("Sig-2   | %s|   | %.4s", sprint_hex(dump_file_data+20, 4), dump_file_data+20);
@@ -1619,7 +1615,7 @@ int CmdHF14AMfUDump(const char *Cmd){
 	fwrite( dump_file_data, 1, Pages*4 + DUMP_PREFIX_LENGTH, fout );
 	fclose(fout);
 	
-	PrintAndLog("Dumped %d pages, wrote %d bytes to %s", Pages+12, (Pages+12)*4, filename);
+	PrintAndLog("Dumped %d pages, wrote %d bytes to %s", Pages+(DUMP_PREFIX_LENGTH/4), Pages*4 + DUMP_PREFIX_LENGTH, filename);
 	return 0;
 }
 
@@ -1776,14 +1772,13 @@ int CmdHF14AMfucSetPwd(const char *Cmd){
 
 	UsbCommand resp;
 	if (WaitForResponseTimeout(CMD_ACK,&resp,1500) ) {
-		if ( (resp.arg[0] & 0xff) == 1)
+		if ( (resp.arg[0] & 0xff) == 1) {
 			PrintAndLog("Ultralight-C new password: %s", sprint_hex(pwd,16));
-		else{
+		} else {
 			PrintAndLog("Failed writing at block %d", resp.arg[1] & 0xff);
 			return 1;
 		}
-	}
-	else {
+	} else {
 		PrintAndLog("command execution time out");
 		return 1;
 	}	
diff --git a/client/cmdhftopaz.c b/client/cmdhftopaz.c
index 4e9d5380..aab1d248 100644
--- a/client/cmdhftopaz.c
+++ b/client/cmdhftopaz.c
@@ -21,6 +21,7 @@
 #include "proxmark3.h"
 #include "iso14443crc.h"
 #include "protocols.h"
+#include "cmdhf.h"
 
 #define TOPAZ_MAX_MEMORY	2048
 
@@ -33,7 +34,6 @@ static struct {
 	uint8_t *dynamic_reserved_areas;
 } topaz_tag;
 
-
 static void topaz_switch_on_field(void)
 {
 	UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_CONNECT | ISO14A_NO_SELECT | ISO14A_NO_DISCONNECT | ISO14A_TOPAZMODE, 0, 0}};
@@ -252,8 +252,7 @@ static void topaz_print_NDEF(uint8_t *data)
 }
 
 	
-int CmdHFTopazReader(const char *Cmd)
-{
+int CmdHFTopazReader(const char *Cmd) {
 	int status;
 	uint8_t atqa[2];
 	uint8_t rid_response[8];
@@ -367,24 +366,23 @@ int CmdHFTopazReader(const char *Cmd)
 	return 0;
 }
 
-
-int CmdHFTopazSim(const char *Cmd)
-{
+int CmdHFTopazSim(const char *Cmd) {
 	PrintAndLog("not yet implemented");
 	return 0;
 }
 
-
-int CmdHFTopazCmdRaw(const char *Cmd)
-{
+int CmdHFTopazCmdRaw(const char *Cmd) {
 	PrintAndLog("not yet implemented");
 	return 0;
 }
 
+int CmdHFTopazList(const char *Cmd) {
+	CmdHFList("topaz");
+	return 0;
+}
 
 static int CmdHelp(const char *Cmd);
 
-
 static command_t CommandTable[] = 
 {
 	{"help",	CmdHelp,			1, "This help"},
@@ -392,10 +390,10 @@ static command_t CommandTable[] =
 	{"sim",		CmdHFTopazSim,		0, "<UID> -- Simulate Topaz tag"},
 	{"sniff",	CmdHF14ASniff,		0, "Sniff Topaz reader-tag communication"},
 	{"raw",		CmdHFTopazCmdRaw,	0, "Send raw hex data to tag"},
+	{"list",	CmdHFTopazList,		0, "[Deprecated] List Topaz history"},
 	{NULL,		NULL,				0, NULL}
 };
 
-
 int CmdHFTopaz(const char *Cmd) {
 	// flush
 	WaitForResponseTimeout(CMD_ACK,NULL,100);
diff --git a/client/cmdhftopaz.h b/client/cmdhftopaz.h
index 8d5428dd..afb000dd 100644
--- a/client/cmdhftopaz.h
+++ b/client/cmdhftopaz.h
@@ -12,5 +12,9 @@
 #define CMDHFTOPAZ_H__
 
 int CmdHFTopaz(const char *Cmd);
+int CmdHFTopazReader(const char *Cmd);
+int CmdHFTopazSim(const char *Cmd);
+int CmdHFTopazCmdRaw(const char *Cmd);
+int CmdHFTopazList(const char *Cmd);
 
 #endif
diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c
index de0ade28..75c1a1f8 100644
--- a/client/cmdlft55xx.c
+++ b/client/cmdlft55xx.c
@@ -150,12 +150,14 @@ int usage_t55xx_wakup(){
 	return 0;
 }
 int usage_t55xx_bruteforce(){
-    PrintAndLog("Usage: lf t55xx bruteforce <start password> <end password> [i <*.dic>]");
-    PrintAndLog("       password must be 4 bytes (8 hex symbols)");
 	PrintAndLog("This command uses A) bruteforce to scan a number range");
 	PrintAndLog("                  B) a dictionary attack");
+    PrintAndLog("Usage: lf t55xx bruteforce <start password> <end password> [i <*.dic>]");
+    PrintAndLog("       password must be 4 bytes (8 hex symbols)");
 	PrintAndLog("Options:");
 	PrintAndLog("     h			- this help");
+	PrintAndLog("     <start_pwd> - 4 byte hex value to start pwd search at");
+	PrintAndLog("     <end_pwd>   - 4 byte hex value to end pwd search at");
     PrintAndLog("     i <*.dic>	- loads a default keys dictionary file <*.dic>");
     PrintAndLog("");
     PrintAndLog("Examples:");
@@ -181,7 +183,6 @@ int CmdT55xxSetConfig(const char *Cmd) {
 	uint8_t bitRate = 0;
 	uint8_t rates[9] = {8,16,32,40,50,64,100,128,0};
 	uint8_t cmdp = 0;
-	config.Q5 = FALSE;
 	bool errors = FALSE;
 	while(param_getchar(Cmd, cmdp) != 0x00 && !errors)
 	{
@@ -384,11 +385,12 @@ bool DecodeT55xxBlock(){
 			ans = ASKDemod(cmdStr, FALSE, FALSE, 1);
 			break;
 		case DEMOD_PSK1:
-			// skip first 16 samples to allow antenna to settle in (psk gets inverted occasionally otherwise)
+			// skip first 160 samples to allow antenna to settle in (psk gets inverted occasionally otherwise)
 			save_restoreGB(1);
 			CmdLtrim("160");
 			snprintf(cmdStr, sizeof(buf),"%d %d 6", bitRate[config.bitrate], config.inverted );
 			ans = PSKDemod(cmdStr, FALSE);
+			//undo trim samples
 			save_restoreGB(0);
 			break;
 		case DEMOD_PSK2: //inverted won't affect this
@@ -399,7 +401,8 @@ bool DecodeT55xxBlock(){
 			snprintf(cmdStr, sizeof(buf),"%d 0 6", bitRate[config.bitrate] );
 			ans = PSKDemod(cmdStr, FALSE);
 			psk1TOpsk2(DemodBuffer, DemodBufferLen);
-			save_restoreGB(1);
+			//undo trim samples
+			save_restoreGB(0);
 			break;
 		case DEMOD_NRZ:
 			snprintf(cmdStr, sizeof(buf),"%d %d 1", bitRate[config.bitrate], config.inverted );
@@ -417,7 +420,6 @@ bool DecodeT55xxBlock(){
 }
 
 int CmdT55xxDetect(const char *Cmd){
-
 	bool errors = FALSE;
 	bool useGB = FALSE;
 	bool usepwd = FALSE;
@@ -465,7 +467,6 @@ bool tryDetectModulation(){
 	t55xx_conf_block_t tests[15];
 	int bitRate=0;
 	uint8_t fc1 = 0, fc2 = 0, clk=0;
-	save_restoreGB(1);
 	
 	if (GetFskClock("", FALSE, FALSE)){ 
 		fskClocks(&fc1, &fc2, &clk, FALSE);
@@ -486,7 +487,6 @@ bool tryDetectModulation(){
 				tests[hits].modulation = DEMOD_FSK1;
 			else if (fc1 == 10 && fc2 == 8)
 				tests[hits].modulation = DEMOD_FSK2a;
-
 			tests[hits].bitrate = bitRate;
 			tests[hits].inverted = TRUE;
 			tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);
@@ -525,7 +525,7 @@ bool tryDetectModulation(){
 			}
 		}
 		//undo trim from ask
-		save_restoreGB(0);
+		//save_restoreGB(0);
 		clk = GetNrzClock("", FALSE, FALSE);
 		if (clk>0) {
 			if ( NRZrawDemod("0 0 1", FALSE)  && test(DEMOD_NRZ, &tests[hits].offset, &bitRate, clk, &tests[hits].Q5)) {
@@ -545,9 +545,9 @@ bool tryDetectModulation(){
 			}
 		}
 		
-		//undo trim from nrz
-		save_restoreGB(0);
+		// allow undo
 		// skip first 160 samples to allow antenna to settle in (psk gets inverted occasionally otherwise)
+		save_restoreGB(1);
 		CmdLtrim("160");
 		clk = GetPskClock("", FALSE, FALSE);
 		if (clk>0) {
@@ -588,14 +588,16 @@ bool tryDetectModulation(){
 				}
 			} // inverse waves does not affect this demod
 		}
+		//undo trim samples
+		save_restoreGB(0);
 	}		
-	save_restoreGB(0);	
 	if ( hits == 1) {
 		config.modulation = tests[0].modulation;
 		config.bitrate = tests[0].bitrate;
 		config.inverted = tests[0].inverted;
 		config.offset = tests[0].offset;
 		config.block0 = tests[0].block0;
+		config.Q5 = tests[0].Q5;
 		printConfiguration( config );
 		return TRUE;
 	}
@@ -671,6 +673,15 @@ bool testQ5Modulation(uint8_t	mode, uint8_t	modread){
 	return FALSE;
 }
 
+int convertQ5bitRate(uint8_t bitRateRead) {
+	uint8_t expected[] = {8, 16, 32, 40, 50, 64, 100, 128};
+	for (int i=0; i<8; i++)
+		if (expected[i] == bitRateRead)
+			return i;
+
+	return -1;
+}
+
 bool testQ5(uint8_t mode, uint8_t *offset, int *fndBitRate, uint8_t	clk){
 
 	if ( DemodBufferLen < 64 ) return FALSE;
@@ -682,12 +693,12 @@ bool testQ5(uint8_t mode, uint8_t *offset, int *fndBitRate, uint8_t	clk){
 		uint8_t safer     = PackBits(si, 4, DemodBuffer); si += 4;     //master key
 		uint8_t resv      = PackBits(si, 8, DemodBuffer); si += 8;
 		// 2nibble must be zeroed.
-		if (safer != 0x6) continue;
+		if (safer != 0x6 && safer != 0x9) continue;
 		if ( resv > 0x00) continue;
 		//uint8_t	pageSel   = PackBits(si, 1, DemodBuffer); si += 1;
 		//uint8_t fastWrite = PackBits(si, 1, DemodBuffer); si += 1;
 		si += 1+1;
-		int bitRate       = PackBits(si, 5, DemodBuffer)*2 + 2; si += 5;     //bit rate
+		int bitRate       = PackBits(si, 6, DemodBuffer)*2 + 2; si += 6;     //bit rate
 		if (bitRate > 128 || bitRate < 8) continue;
 
 		//uint8_t AOR       = PackBits(si, 1, DemodBuffer); si += 1;   
@@ -702,7 +713,8 @@ bool testQ5(uint8_t mode, uint8_t *offset, int *fndBitRate, uint8_t	clk){
 		//test modulation
 		if (!testQ5Modulation(mode, modread)) continue;
 		if (bitRate != clk) continue;
-		*fndBitRate = bitRate;
+		*fndBitRate = convertQ5bitRate(bitRate);
+		if (*fndBitRate < 0) continue;
 		*offset = idx;
 
 		return TRUE;
@@ -1117,35 +1129,16 @@ char * GetBitRateStr(uint32_t id){
 
 	char *retStr = buf;
 		switch (id){
-		case 0: 
-			snprintf(retStr,sizeof(buf),"%d - RF/8",id);
-			break;
-		case 1:
-			snprintf(retStr,sizeof(buf),"%d - RF/16",id);
-			break;
-		case 2:		
-			snprintf(retStr,sizeof(buf),"%d - RF/32",id);
-			break;
-		case 3:
-			snprintf(retStr,sizeof(buf),"%d - RF/40",id);
-			break;
-		case 4:
-			snprintf(retStr,sizeof(buf),"%d - RF/50",id);
-			break;
-		case 5:
-			snprintf(retStr,sizeof(buf),"%d - RF/64",id);
-			break;
-		case 6:
-			snprintf(retStr,sizeof(buf),"%d - RF/100",id);
-			break;
-		case 7:
-			snprintf(retStr,sizeof(buf),"%d - RF/128",id);
-			break;
-		default:
-			snprintf(retStr,sizeof(buf),"%d - (Unknown)",id);
-			break;
+		case 0:   snprintf(retStr,sizeof(buf),"%d - RF/8",id);   break;
+		case 1:   snprintf(retStr,sizeof(buf),"%d - RF/16",id);  break;
+		case 2:   snprintf(retStr,sizeof(buf),"%d - RF/32",id);  break;
+		case 3:   snprintf(retStr,sizeof(buf),"%d - RF/40",id);  break;
+		case 4:   snprintf(retStr,sizeof(buf),"%d - RF/50",id);  break;
+		case 5:   snprintf(retStr,sizeof(buf),"%d - RF/64",id);  break;
+		case 6:   snprintf(retStr,sizeof(buf),"%d - RF/100",id); break;
+		case 7:   snprintf(retStr,sizeof(buf),"%d - RF/128",id); break;
+		default:  snprintf(retStr,sizeof(buf),"%d - (Unknown)",id); break;
 		}
-
 	return buf;
 }
 
@@ -1476,7 +1469,7 @@ int CmdT55xxBruteForce(const char *Cmd) {
 
 static command_t CommandTable[] = {
 	{"help",		CmdHelp,           1, "This help"},
-	{"bruteforce",	CmdT55xxBruteForce,0, "Simple bruteforce attack to find password"},
+	{"bruteforce",CmdT55xxBruteForce,0, "<start password> <end password> [i <*.dic>] Simple bruteforce attack to find password"},
 	{"config",		CmdT55xxSetConfig, 1, "Set/Get T55XX configuration (modulation, inverted, offset, rate)"},
 	{"detect",		CmdT55xxDetect,    1, "[1] Try detecting the tag modulation from reading the configuration block."},
 	{"dump",		CmdT55xxDump,      0, "[password] [o] Dump T55xx card block 0-7. Optional [password], [override]"},
diff --git a/client/util.c b/client/util.c
index de1cbe94..159929b5 100644
--- a/client/util.c
+++ b/client/util.c
@@ -140,7 +140,7 @@ char *sprint_bin_break(const uint8_t *data, const size_t len, const uint8_t brea
 	for (size_t out_index=0; out_index < max_len; out_index++) {
 		// set character
 		sprintf(tmp++, "%u", data[in_index]);
-		// check if a line break is needed
+		// check if a line break is needed and we have room to print it in our array
 		if ( (breaks > 0) && !((in_index+1) % breaks) && (out_index+1 != max_len) ) {
 			// increment and print line break
 			out_index++;
@@ -195,7 +195,6 @@ void num_to_bytebits(uint64_t	n, size_t len, uint8_t *dest) {
 // up to 64 bytes or 512 bits
 uint8_t *SwapEndian64(const uint8_t *src, const size_t len, const uint8_t blockSize){
 	static uint8_t buf[64];
-	//uint8_t buf[64];
 	memset(buf, 0x00, 64);
 	uint8_t *tmp = buf;
 	for (uint8_t block=0; block < (uint8_t)(len/blockSize); block++){