X-Git-Url: http://cvs.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/ab74872d40cf1f6b91344909e307ae788a3f8497..c631b1a216099f929a15193ec5841d980e8be8d0:/client/cmdlft55xx.c

diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c
index f0a6fe94..1b005d96 100644
--- a/client/cmdlft55xx.c
+++ b/client/cmdlft55xx.c
@@ -6,28 +6,7 @@
 //-----------------------------------------------------------------------------
 // Low frequency T55xx commands
 //-----------------------------------------------------------------------------
-
-#include <stdio.h>
-#include <string.h>
-#include <inttypes.h>
-#include "proxmark3.h"
-#include "ui.h"
-#include "graph.h"
-#include "cmdmain.h"
-#include "cmdparser.h"
-#include "cmddata.h"
-#include "cmdlf.h"
 #include "cmdlft55xx.h"
-#include "util.h"
-#include "data.h"
-#include "lfdemod.h"
-#include "cmdhf14a.h" //for getTagInfo
-
-#define T55x7_CONFIGURATION_BLOCK 0x00
-#define T55x7_PAGE0 0x00
-#define T55x7_PAGE1 0x01
-#define T55x7_PWD	0x00000010
-#define REGULAR_READ_MODE_BLOCK 0xFF
 
 // Default configuration
 t55xx_conf_block_t config = { .modulation = DEMOD_ASK, .inverted = FALSE, .offset = 0x00, .block0 = 0x00, .Q5 = FALSE };
@@ -42,13 +21,13 @@ void Set_t55xx_Config(t55xx_conf_block_t conf){
 int usage_t55xx_config(){
 	PrintAndLog("Usage: lf t55xx config [d <demodulation>] [i 1] [o <offset>] [Q5]");
 	PrintAndLog("Options:");
-	PrintAndLog("       h                        This help");
-	PrintAndLog("       b <8|16|32|40|50|64|100|128>     Set bitrate");
-	PrintAndLog("       d <FSK|FSK1|FSK1a|FSK2|FSK2a|ASK|PSK1|PSK2|NRZ|BI|BIa>  Set demodulation FSK / ASK / PSK / NRZ / Biphase / Biphase A");
-	PrintAndLog("       i [1]                            Invert data signal, defaults to normal");
-	PrintAndLog("       o [offset]                       Set offset, where data should start decode in bitstream");
-	PrintAndLog("       Q5                            Set as Q5(T5555) chip instead of T55x7");
-	PrintAndLog("       ST                            Set Sequence Terminator on");
+	PrintAndLog("       h                                - This help");
+	PrintAndLog("       b <8|16|32|40|50|64|100|128>     - Set bitrate");
+	PrintAndLog("       d <FSK|FSK1|FSK1a|FSK2|FSK2a|ASK|PSK1|PSK2|NRZ|BI|BIa>  - Set demodulation FSK / ASK / PSK / NRZ / Biphase / Biphase A");
+	PrintAndLog("       i [1]                            - Invert data signal, defaults to normal");
+	PrintAndLog("       o [offset]                       - Set offset, where data should start decode in bitstream");
+	PrintAndLog("       Q5                               - Set as Q5(T5555) chip instead of T55x7");
+	PrintAndLog("       ST                               - Set Sequence Terminator on");
 	PrintAndLog("");
 	PrintAndLog("Examples:");
 	PrintAndLog("      lf t55xx config d FSK          - FSK demodulation");
@@ -92,7 +71,7 @@ int usage_t55xx_write(){
 int usage_t55xx_trace() {
 	PrintAndLog("Usage:  lf t55xx trace [1]");
 	PrintAndLog("Options:");
-	PrintAndLog("     [graph buffer data]  - if set, use Graphbuffer otherwise read data from tag.");
+	PrintAndLog("     1             - if set, use Graphbuffer otherwise read data from tag.");
 	PrintAndLog("");
 	PrintAndLog("Examples:");
 	PrintAndLog("      lf t55xx trace");
@@ -103,7 +82,7 @@ int usage_t55xx_trace() {
 int usage_t55xx_info() {
 	PrintAndLog("Usage:  lf t55xx info [1]");
 	PrintAndLog("Options:");
-	PrintAndLog("     [graph buffer data]  - if set, use Graphbuffer otherwise read data from tag.");
+	PrintAndLog("     1             - if set, use Graphbuffer otherwise read data from tag.");
 	PrintAndLog("");
 	PrintAndLog("Examples:");
 	PrintAndLog("      lf t55xx info");
@@ -150,7 +129,8 @@ int usage_t55xx_wakup(){
 int usage_t55xx_bruteforce(){
 	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("press 'enter' to cancel the command");
+    PrintAndLog("Usage: lf t55xx bruteforce [h] <start password> <end password> [i <*.dic>]");
     PrintAndLog("       password must be 4 bytes (8 hex symbols)");
 	PrintAndLog("Options:");
 	PrintAndLog("     h			- this help");
@@ -166,13 +146,14 @@ int usage_t55xx_bruteforce(){
 }
 int usage_t55xx_recoverpw(){
 	PrintAndLog("This command uses a few tricks to try to recover mangled password");
+	PrintAndLog("press 'enter' to cancel the command");
 	PrintAndLog("WARNING: this may brick non-password protected chips!");
 	PrintAndLog("Usage: lf t55xx recoverpw [password]");
 	PrintAndLog("       password must be 4 bytes (8 hex symbols)");
 	PrintAndLog("       default password is 51243648, used by many cloners");
 	PrintAndLog("Options:");
 	PrintAndLog("     h           - this help");
-	PrintAndLog("     [password] - 4 byte hex value of password written by cloner");
+	PrintAndLog("     [password]  - 4 byte hex value of password written by cloner");
 	PrintAndLog("");
 	PrintAndLog("Examples:");
 	PrintAndLog("       lf t55xx recoverpw");
@@ -195,8 +176,8 @@ static int CmdHelp(const char *Cmd);
 
 void printT5xxHeader(uint8_t page){
 	PrintAndLog("Reading Page %d:", page);	
-	PrintAndLog("blk | hex data | binary");
-	PrintAndLog("----+----------+---------------------------------");	
+	PrintAndLog("blk | hex data | binary                           | ascii");
+	PrintAndLog("----+----------+----------------------------------+-------");	
 }
 
 int CmdT55xxSetConfig(const char *Cmd) {
@@ -547,6 +528,11 @@ bool tryDetectModulation(){
 		clk = GetAskClock("", FALSE, FALSE);
 		if (clk>0) {
 			tests[hits].ST = TRUE;
+			// "0 0 1 " == clock auto, invert false, maxError 1.
+			// false = no verbose
+			// false = no emSearch
+			// 1 = Ask/Man
+			// st = true
 			if ( ASKDemod_ext("0 0 1", FALSE, FALSE, 1, &tests[hits].ST) && test(DEMOD_ASK, &tests[hits].offset, &bitRate, clk, &tests[hits].Q5)) {
 				tests[hits].modulation = DEMOD_ASK;
 				tests[hits].bitrate = bitRate;
@@ -555,6 +541,11 @@ bool tryDetectModulation(){
 				++hits;
 			}
 			tests[hits].ST = TRUE;
+			// "0 0 1 " == clock auto, invert true, maxError 1.
+			// false = no verbose
+			// false = no emSearch
+			// 1 = Ask/Man
+			// st = true
 			if ( ASKDemod_ext("0 1 1", FALSE, FALSE, 1, &tests[hits].ST)  && test(DEMOD_ASK, &tests[hits].offset, &bitRate, clk, &tests[hits].Q5)) {
 				tests[hits].modulation = DEMOD_ASK;
 				tests[hits].bitrate = bitRate;
@@ -664,13 +655,46 @@ bool tryDetectModulation(){
 		return TRUE;
 	}
 	
+	bool retval = FALSE;
 	if ( hits > 1) {
 		PrintAndLog("Found [%d] possible matches for modulation.",hits);
 		for(int i=0; i<hits; ++i){
-			PrintAndLog("--[%d]---------------", i+1);
+			retval = testKnownConfigBlock(tests[i].block0);
+			if ( retval ) {				
+				PrintAndLog("--[%d]--------------- << selected this", i+1);
+				config.modulation = tests[i].modulation;
+				config.bitrate = tests[i].bitrate;
+				config.inverted = tests[i].inverted;
+				config.offset = tests[i].offset;
+				config.block0 = tests[i].block0;
+				config.Q5 = tests[i].Q5;
+				config.ST = tests[i].ST;
+			} else {
+				PrintAndLog("--[%d]---------------", i+1);
+			}
 			printConfiguration( tests[i] );
 		}
 	}
+	return retval;
+}
+
+bool testKnownConfigBlock(uint32_t block0) {
+	switch(block0){
+		case T55X7_DEFAULT_CONFIG_BLOCK:
+		case T55X7_RAW_CONFIG_BLOCK:
+		case T55X7_EM_UNIQUE_CONFIG_BLOCK:
+		case T55X7_FDXB_CONFIG_BLOCK:
+		case T55X7_HID_26_CONFIG_BLOCK:
+		case T55X7_PYRAMID_CONFIG_BLOCK:
+		case T55X7_INDALA_64_CONFIG_BLOCK:
+		case T55X7_INDALA_224_CONFIG_BLOCK:
+		case T55X7_GUARDPROXII_CONFIG_BLOCK:
+		case T55X7_VIKING_CONFIG_BLOCK:
+		case T55X7_NORALYS_CONFIG_BLOCK:
+		case T55X7_IOPROX_CONFIG_BLOCK:
+		case T55X7_PRESCO_CONFIG_BLOCK:
+			return TRUE;
+	}
 	return FALSE;
 }
 
@@ -854,16 +878,18 @@ void printT55xxBlock(const char *blockNum){
 		bits[i - config.offset] = DemodBuffer[i];
 
 	blockData = PackBits(0, 32, bits);
+	uint8_t bytes[4] = {0};
+	num_to_bytes(blockData, 4, bytes);
 
-	PrintAndLog(" %s | %08X | %s", blockNum, blockData, sprint_bin(bits,32));
+	PrintAndLog(" %s | %08X | %s | %s", blockNum, blockData, sprint_bin(bits,32), sprint_ascii(bytes,4));
 }
 
 int special(const char *Cmd) {
 	uint32_t blockData = 0;
 	uint8_t bits[32] = {0x00};
 
-	PrintAndLog("OFFSET | DATA  | BINARY");
-	PrintAndLog("----------------------------------------------------");
+	PrintAndLog("OFFSET | DATA  | BINARY                              | ASCII");
+	PrintAndLog("-------+-------+-------------------------------------+------");
 	int i,j = 0;
 	for (; j < 64; ++j){
 		
@@ -983,7 +1009,7 @@ int CmdT55xxWriteBlock(const char *Cmd) {
 	}
 	clearCommandBuffer();
 	SendCommand(&c);
-	if (!WaitForResponseTimeout(CMD_ACK, &resp, 1000)){
+	if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)){
 		PrintAndLog("Error occurred, device did not ACK write operation. (May be due to old firmware)");
 		return 0;
 	}
@@ -1249,21 +1275,26 @@ int CmdT55xxDump(const char *Cmd){
 
 int AquireData( uint8_t page, uint8_t block, bool pwdmode, uint32_t password ){
 	// arg0 bitmodes:
-	// bit0 = pwdmode
-	// bit1 = page to read from
+	// 	bit0 = pwdmode
+	// 	bit1 = page to read from
+	// arg1: which block to read
+	// arg2: password
 	uint8_t arg0 = (page<<1) | pwdmode;
 	UsbCommand c = {CMD_T55XX_READ_BLOCK, {arg0, block, password}};
-	
 	clearCommandBuffer();
 	SendCommand(&c);
-	if ( !WaitForResponseTimeout(CMD_ACK,NULL,2500) ) {
+	if ( !WaitForResponseTimeout(CMD_ACK, NULL, 2500) ) {
 		PrintAndLog("command execution time out");
 		return 0;
 	}
 
-	uint8_t got[12000];
-	GetFromBigBuf(got,sizeof(got),0);
-	WaitForResponse(CMD_ACK,NULL);
+	//uint8_t got[12288];
+	uint8_t got[7679];
+	GetFromBigBuf(got, sizeof(got), 0);
+	if ( !WaitForResponseTimeout(CMD_ACK, NULL, 8000) ) {
+		PrintAndLog("command execution time out");
+		return 0;
+	}
 	setGraphBuf(got, sizeof(got));
 	return 1;
 }
@@ -1379,10 +1410,9 @@ void t55x7_create_config_block( int tagtype ){
 
 int CmdResetRead(const char *Cmd) {
 	UsbCommand c = {CMD_T55XX_RESET_READ, {0,0,0}};
-
 	clearCommandBuffer();
 	SendCommand(&c);
-	if ( !WaitForResponseTimeout(CMD_ACK,NULL,2500) ) {
+	if ( !WaitForResponseTimeout(CMD_ACK, NULL, 2500) ) {
 		PrintAndLog("command execution time out");
 		return 0;
 	}
@@ -1406,11 +1436,10 @@ int CmdT55xxWipe(const char *Cmd) {
 	// With a pwd should work even if pwd bit not set
 	PrintAndLog("\nBeginning Wipe of a T55xx tag (assuming the tag is not password protected)\n");
 		
-	if ( Q5 ){
+	if ( Q5 )
 		snprintf(ptrData,sizeof(writeData),"b 0 d 6001F004 p 0");
-	} else {
+	else
 		snprintf(ptrData,sizeof(writeData),"b 0 d 000880E0 p 0");
-	}
 	
 	if (!CmdT55xxWriteBlock(ptrData)) PrintAndLog("Error writing blk 0");
 	
@@ -1425,23 +1454,34 @@ int CmdT55xxWipe(const char *Cmd) {
 	return 0;
 }
 
+bool IsCancelled(void) {
+	if (ukbhit()) {
+		int ch = getchar();
+		(void)ch;
+		printf("\naborted via keyboard!\n");
+		return TRUE;
+	}
+	return FALSE;
+}
+
 int CmdT55xxBruteForce(const char *Cmd) {
 	
 	// load a default pwd file.
-	char buf[9];
+	char line[9];
 	char filename[FILE_PATH_SIZE]={0};
 	int	keycnt = 0;
-	int ch;
 	uint8_t stKeyBlock = 20;
 	uint8_t *keyBlock = NULL, *p = NULL;
     uint32_t start_password = 0x00000000; //start password
     uint32_t end_password   = 0xFFFFFFFF; //end   password
     bool found = false;
 
+	memset(line, 0, sizeof(line));
+	
     char cmdp = param_getchar(Cmd, 0);
 	if (cmdp == 'h' || cmdp == 'H') return usage_t55xx_bruteforce();
 
-	keyBlock = calloc(stKeyBlock, 6);
+	keyBlock = calloc(stKeyBlock, 4);
 	if (keyBlock == NULL) return 1;
 
 	if (cmdp == 'i' || cmdp == 'I') {
@@ -1450,46 +1490,52 @@ int CmdT55xxBruteForce(const char *Cmd) {
 		if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE;
 		memcpy(filename, Cmd+2, len);
 	
-		FILE * f = fopen( filename , "r");
-		
+		FILE * f = fopen( filename , "r");		
 		if ( !f ) {
 			PrintAndLog("File: %s: not found or locked.", filename);
 			free(keyBlock);
 			return 1;
 		}			
-			
-		while( fgets(buf, sizeof(buf), f) ){
-			if (strlen(buf) < 8 || buf[7] == '\n') continue;
 		
-			while (fgetc(f) != '\n' && !feof(f)) ;  //goto next line
-			
+		while( fgets(line, sizeof(line), f) ){
+			if (strlen(line) < 8 || line[7] == '\n') continue;
+		
+			//goto next line
+			while (fgetc(f) != '\n' && !feof(f)) ;
+		
 			//The line start with # is comment, skip
-			if( buf[0]=='#' ) continue;
+			if( line[0]=='#' ) continue;
 
-			if (!isxdigit(buf[0])){
-				PrintAndLog("File content error. '%s' must include 8 HEX symbols", buf);
+			if (!isxdigit(line[0])) {
+				PrintAndLog("File content error. '%s' must include 8 HEX symbols", line);
 				continue;
 			}
 			
-			buf[8] = 0;
-
+			line[8] = 0;		
+			
+			// realloc keyblock array size.
 			if ( stKeyBlock - keycnt < 2) {
-				p = realloc(keyBlock, 6*(stKeyBlock+=10));
+				p = realloc(keyBlock, 4 * (stKeyBlock += 10));
 				if (!p) {
 					PrintAndLog("Cannot allocate memory for defaultKeys");
 					free(keyBlock);
-					fclose(f);
+					if (f)
+						fclose(f);
 					return 2;
 				}
 				keyBlock = p;
 			}
+			// clear mem
 			memset(keyBlock + 4 * keycnt, 0, 4);
-			num_to_bytes(strtoll(buf, NULL, 16), 4, keyBlock + 4*keycnt);
-			PrintAndLog("chk custom pwd[%2d] %08X", keycnt, bytes_to_num(keyBlock + 4*keycnt, 4));
-			keycnt++;
-			memset(buf, 0, sizeof(buf));
+			
+			num_to_bytes( strtoll(line, NULL, 16), 4, keyBlock + 4*keycnt);
+			
+			PrintAndLog("chk custom pwd[%2d] %08X", keycnt, bytes_to_num(keyBlock + 4 * keycnt, 4) );			
+			keycnt++;			
+			memset(line, 0, sizeof(line));
 		}		
-		fclose(f);
+		if (f)
+			fclose(f);
 		
 		if (keycnt == 0) {
 			PrintAndLog("No keys found in file");
@@ -1501,11 +1547,14 @@ int CmdT55xxBruteForce(const char *Cmd) {
 		// loop
 		uint64_t testpwd = 0x00;
 		for (uint16_t c = 0; c < keycnt; ++c ) {
-	
-			if (ukbhit()) {
-				ch = getchar();
-				(void)ch;
-				printf("\naborted via keyboard!\n");
+
+			if ( offline ) {
+				printf("Device offline\n");
+				free(keyBlock);
+				return  2;
+			}
+		
+			if (IsCancelled()) {
 				free(keyBlock);
 				return 0;
 			}
@@ -1513,20 +1562,18 @@ int CmdT55xxBruteForce(const char *Cmd) {
 			testpwd = bytes_to_num(keyBlock + 4*c, 4);
 
 			PrintAndLog("Testing %08X", testpwd);
-			
-			
+						
 			if ( !AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, TRUE, testpwd)) {
-				PrintAndLog("Aquireing data from device failed. Quitting");
+				PrintAndLog("Acquire data from device failed. Quitting");
 				free(keyBlock);
 				return 0;
 			}
 			
 			found = tryDetectModulation();
-
 			if ( found ) {
 				PrintAndLog("Found valid password: [%08X]", testpwd);
-				free(keyBlock);
-				return 0;
+				//free(keyBlock);
+				//return 0;
 			} 
 		}
 		PrintAndLog("Password NOT found.");
@@ -1553,16 +1600,14 @@ int CmdT55xxBruteForce(const char *Cmd) {
 
 		printf(".");
 		fflush(stdout);
-		if (ukbhit()) {
-			ch = getchar();
-			(void)ch;
-			printf("\naborted via keyboard!\n");
+		
+		if (IsCancelled()) {
 			free(keyBlock);
 			return 0;
 		}
 			
 		if (!AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, TRUE, i)) {
-			PrintAndLog("Aquireing data from device failed. Quitting");
+			PrintAndLog("Acquire data from device failed. Quitting");
 			free(keyBlock);
 			return 0;
 		}
@@ -1583,17 +1628,17 @@ int CmdT55xxBruteForce(const char *Cmd) {
     return 0;
 }
 
-int tryOnePassword(uint32_t password)
-{
+int tryOnePassword(uint32_t password) {
 	PrintAndLog("Trying password %08x", password);
 	if (!AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, TRUE, password)) {
-		PrintAndLog("Aquireing data from device failed. Quitting");
+		PrintAndLog("Acquire data from device failed. Quitting");
 		return -1;
 	}
 
 	if (tryDetectModulation())
 		return 1;
-	else return 0;
+	else 
+		return 0;
 }
 
 int CmdT55xxRecoverPW(const char *Cmd) {
@@ -1603,21 +1648,19 @@ int CmdT55xxRecoverPW(const char *Cmd) {
 	uint32_t prev_password = 0xffffffff;
 	uint32_t mask = 0x0;
 	int found = 0;
-
 	char cmdp = param_getchar(Cmd, 0);
 	if (cmdp == 'h' || cmdp == 'H') return usage_t55xx_recoverpw();
 
 	orig_password = param_get32ex(Cmd, 0, 0x51243648, 16); //password used by handheld cloners
 
 	// first try fliping each bit in the expected password
-	while ((found != 1) && (bit < 32)) {
+	while (bit < 32) {
 		curr_password = orig_password ^ ( 1 << bit );
 		found = tryOnePassword(curr_password);
-		if (found == 1)
-			goto done;
-		else if (found == -1)
-			return 0;
+		if (found == -1) return 0;
 		bit++;
+		
+		if (IsCancelled()) return 0;
 	}
 
 	// now try to use partial original password, since block 7 should have been completely
@@ -1626,7 +1669,7 @@ int CmdT55xxRecoverPW(const char *Cmd) {
 	// not sure from which end the bit bits are written, so try from both ends 
 	// from low bit to high bit
 	bit = 0;
-	while ((found != 1) && (bit < 32)) {
+	while (bit < 32) {
 		mask += ( 1 << bit );
 		curr_password = orig_password & mask;
 		// if updated mask didn't change the password, don't try it again
@@ -1635,18 +1678,17 @@ int CmdT55xxRecoverPW(const char *Cmd) {
 			continue;
 		}
 		found = tryOnePassword(curr_password);
-		if (found == 1)
-			goto done;
-		else if (found == -1)
-			return 0;
+		if (found == -1) return 0;
 		bit++;
-		prev_password=curr_password;
+		prev_password = curr_password;
+		
+		if (IsCancelled()) return 0;
 	}
 
 	// from high bit to low
 	bit = 0;
 	mask = 0xffffffff;
-	while ((found != 1) && (bit < 32)) {
+	while (bit < 32) {
 		mask -= ( 1 << bit );
 		curr_password = orig_password & mask;
 		// if updated mask didn't change the password, don't try it again
@@ -1655,14 +1697,14 @@ int CmdT55xxRecoverPW(const char *Cmd) {
 			continue;
 		}
 		found = tryOnePassword(curr_password);
-		if (found == 1)
-			goto done;
-		else if (found == -1)
+		if (found == -1)
 			return 0;
 		bit++;
-		prev_password=curr_password;
+		prev_password = curr_password;
+		
+		if (IsCancelled()) return 0;
 	}
-done:
+
 	PrintAndLog("");
 
 	if (found == 1)