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

diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c
index 28149eff..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 };
@@ -150,6 +129,7 @@ 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("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:");
@@ -166,6 +146,7 @@ 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)");
@@ -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) {
@@ -674,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;
 }
 
@@ -864,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){
 		
@@ -993,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;
 	}
@@ -1263,20 +1279,22 @@ int AquireData( uint8_t page, uint8_t block, bool pwdmode, uint32_t password ){
 	// 	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;
 }
@@ -1392,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;
 	}
@@ -1419,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");
 	
@@ -1438,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') {
@@ -1463,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");
@@ -1514,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;
 			}
@@ -1526,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.");
@@ -1566,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;
 		}
@@ -1599,13 +1631,14 @@ int CmdT55xxBruteForce(const char *Cmd) {
 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) {
@@ -1615,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
@@ -1638,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
@@ -1647,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
@@ -1667,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)