Merge pull request #143 from marshmellow42/master

lfops cleanup, t55xx additions/fixes, PCF7931 input cleanup
This commit is contained in:
Martin Holst Swende 2015-11-15 13:22:26 +01:00
commit 9983a92943
27 changed files with 1660 additions and 1393 deletions

View file

@ -637,6 +637,32 @@ int CmdG_Prox_II_Demod(const char *Cmd)
return 1;
}
//by marshmellow
//see ASKDemod for what args are accepted
int CmdVikingDemod(const char *Cmd)
{
if (!ASKDemod(Cmd, false, false, 1)) {
if (g_debugMode) PrintAndLog("ASKDemod failed");
return 0;
}
size_t size = DemodBufferLen;
//call lfdemod.c demod for gProxII
int ans = VikingDemod_AM(DemodBuffer, &size);
if (ans < 0) {
if (g_debugMode) PrintAndLog("Error Viking_Demod %d", ans);
return 0;
}
//got a good demod
uint32_t raw1 = bytebits_to_byte(DemodBuffer+ans, 32);
uint32_t raw2 = bytebits_to_byte(DemodBuffer+ans+32, 32);
uint32_t cardid = bytebits_to_byte(DemodBuffer+ans+24, 32);
uint8_t checksum = bytebits_to_byte(DemodBuffer+ans+32+24, 8);
PrintAndLog("Viking Tag Found: Card ID %08X, Checksum: %02X", cardid, checksum);
PrintAndLog("Raw: %08X%08X", raw1,raw2);
setDemodBuf(DemodBuffer+ans, 64, 0);
return 1;
}
//by marshmellow - see ASKDemod
int Cmdaskrawdemod(const char *Cmd)
{
@ -1130,8 +1156,6 @@ int CmdFSKdemodParadox(const char *Cmd)
//print ioprox ID and some format details
int CmdFSKdemodIO(const char *Cmd)
{
//raw fsk demod no manchester decoding no start bit finding just get binary from wave
//set defaults
int idx=0;
//something in graphbuffer?
if (GraphTraceLen < 65) {
@ -1220,11 +1244,6 @@ int CmdFSKdemodIO(const char *Cmd)
//print full AWID Prox ID and some bit format details if found
int CmdFSKdemodAWID(const char *Cmd)
{
//int verbose=1;
//sscanf(Cmd, "%i", &verbose);
//raw fsk demod no manchester decoding no start bit finding just get binary from wave
uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
size_t size = getFromGraphBuf(BitStream);
if (size==0) return 0;
@ -1423,7 +1442,6 @@ int CmdFSKdemodPyramid(const char *Cmd)
uint32_t fc = 0;
uint32_t cardnum = 0;
uint32_t code1 = 0;
//uint32_t code2 = 0;
if (fmtLen==26){
fc = bytebits_to_byte(BitStream+73, 8);
cardnum = bytebits_to_byte(BitStream+81, 16);
@ -1597,61 +1615,33 @@ int CmdIndalaDecode(const char *Cmd)
return 0;
}
uint8_t invert=0;
ans = indala26decode(DemodBuffer, &DemodBufferLen, &invert);
if (ans < 1) {
size_t size = DemodBufferLen;
size_t startIdx = indala26decode(DemodBuffer, &size, &invert);
if (startIdx < 1) {
if (g_debugMode==1)
PrintAndLog("Error2: %d",ans);
return -1;
}
char showbits[251]={0x00};
setDemodBuf(DemodBuffer, size, startIdx);
if (invert)
if (g_debugMode==1)
PrintAndLog("Had to invert bits");
PrintAndLog("BitLen: %d",DemodBufferLen);
//convert UID to HEX
uint32_t uid1, uid2, uid3, uid4, uid5, uid6, uid7;
int idx;
uid1=0;
uid2=0;
PrintAndLog("BitLen: %d",DemodBufferLen);
if (DemodBufferLen==64){
for( idx=0; idx<64; idx++) {
uid1=(uid1<<1)|(uid2>>31);
if (DemodBuffer[idx] == 0) {
uid2=(uid2<<1)|0;
showbits[idx]='0';
} else {
uid2=(uid2<<1)|1;
showbits[idx]='1';
}
}
showbits[idx]='\0';
PrintAndLog("Indala UID=%s (%x%08x)", showbits, uid1, uid2);
}
else {
uid3=0;
uid4=0;
uid5=0;
uid6=0;
uid7=0;
for( idx=0; idx<DemodBufferLen; idx++) {
uid1=(uid1<<1)|(uid2>>31);
uid2=(uid2<<1)|(uid3>>31);
uid3=(uid3<<1)|(uid4>>31);
uid4=(uid4<<1)|(uid5>>31);
uid5=(uid5<<1)|(uid6>>31);
uid6=(uid6<<1)|(uid7>>31);
if (DemodBuffer[idx] == 0) {
uid7=(uid7<<1)|0;
showbits[idx]='0';
}
else {
uid7=(uid7<<1)|1;
showbits[idx]='1';
}
}
showbits[idx]='\0';
PrintAndLog("Indala UID=%s (%x%08x%08x%08x%08x%08x%08x)", showbits, uid1, uid2, uid3, uid4, uid5, uid6, uid7);
uid1=bytebits_to_byte(DemodBuffer,32);
uid2=bytebits_to_byte(DemodBuffer+32,32);
if (DemodBufferLen==64) {
PrintAndLog("Indala UID=%s (%x%08x)", sprint_bin(DemodBuffer,DemodBufferLen), uid1, uid2);
} else {
uid3=bytebits_to_byte(DemodBuffer+64,32);
uid4=bytebits_to_byte(DemodBuffer+96,32);
uid5=bytebits_to_byte(DemodBuffer+128,32);
uid6=bytebits_to_byte(DemodBuffer+160,32);
uid7=bytebits_to_byte(DemodBuffer+192,32);
PrintAndLog("Indala UID=%s (%x%08x%08x%08x%08x%08x%08x)",
sprint_bin(DemodBuffer,DemodBufferLen), uid1, uid2, uid3, uid4, uid5, uid6, uid7);
}
if (g_debugMode){
PrintAndLog("DEBUG: printing demodbuffer:");
@ -2353,6 +2343,7 @@ static command_t CommandTable[] =
{"askedgedetect", CmdAskEdgeDetect, 1, "[threshold] Adjust Graph for manual ask demod using the length of sample differences to detect the edge of a wave (use 20-45, def:25)"},
{"askem410xdemod", CmdAskEM410xDemod, 1, "[clock] [invert<0|1>] [maxErr] -- Demodulate an EM410x tag from GraphBuffer (args optional)"},
{"askgproxiidemod", CmdG_Prox_II_Demod, 1, "Demodulate a G Prox II tag from GraphBuffer"},
{"askvikingdemod", CmdVikingDemod, 1, "Demodulate a Viking tag from GraphBuffer"},
{"autocorr", CmdAutoCorr, 1, "[window length] [g] -- Autocorrelation over window - g to save back to GraphBuffer (overwrite)"},
{"biphaserawdecode",CmdBiphaseDecodeRaw,1, "[offset] [invert<0|1>] [maxErr] -- Biphase decode bin stream in DemodBuffer (offset = 0|1 bits to shift the decode start)"},
{"bin2hex", Cmdbin2hex, 1, "bin2hex <digits> -- Converts binary to hexadecimal"},

View file

@ -17,6 +17,7 @@ int CmdData(const char *Cmd);
void printDemodBuff(void);
void setDemodBuf(uint8_t *buff, size_t size, size_t startIdx);
int CmdAskEM410xDemod(const char *Cmd);
int CmdVikingDemod(const char *Cmd);
int CmdG_Prox_II_Demod(const char *Cmd);
int Cmdaskrawdemod(const char *Cmd);
int Cmdaskmandemod(const char *Cmd);

View file

@ -33,17 +33,82 @@
static int CmdHelp(const char *Cmd);
int usage_lf_cmdread()
{
PrintAndLog("Usage: lf cmdread d <delay period> z <zero period> o <one period> c <cmdbytes> [H] ");
PrintAndLog("Options: ");
PrintAndLog(" h This help");
PrintAndLog(" L Low frequency (125 KHz)");
PrintAndLog(" H High frequency (134 KHz)");
PrintAndLog(" d <delay> delay OFF period");
PrintAndLog(" z <zero> time period ZERO");
PrintAndLog(" o <one> time period ONE");
PrintAndLog(" c <cmd> Command bytes");
PrintAndLog(" ************* All periods in microseconds");
PrintAndLog("Examples:");
PrintAndLog(" lf cmdread d 80 z 100 o 200 c 11000");
PrintAndLog(" lf cmdread d 80 z 100 o 100 c 11000 H");
return 0;
}
/* send a command before reading */
int CmdLFCommandRead(const char *Cmd)
{
static char dummy[3];
dummy[0]= ' ';
static char dummy[3] = {0x20,0x00,0x00};
UsbCommand c = {CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K};
sscanf(Cmd, "%"lli" %"lli" %"lli" %s %s", &c.arg[0], &c.arg[1], &c.arg[2],(char*)(&c.d.asBytes),(char*)(&dummy+1));
// in case they specified 'h'
bool errors = FALSE;
//uint8_t divisor = 95; //125khz
uint8_t cmdp = 0;
int strLength = 0;
while(param_getchar(Cmd, cmdp) != 0x00)
{
switch(param_getchar(Cmd, cmdp))
{
case 'h':
return usage_lf_cmdread();
case 'H':
//divisor = 88;
dummy[1]='h';
cmdp++;
break;
case 'L':
cmdp++;
break;
case 'c':
strLength = param_getstr(Cmd, cmdp+1, (char *)&c.d.asBytes);
cmdp+=2;
break;
case 'd':
c.arg[0] = param_get32ex(Cmd, cmdp+1, 0, 10);
cmdp+=2;
break;
case 'z':
c.arg[1] = param_get32ex(Cmd, cmdp+1, 0, 10);
cmdp+=2;
break;
case 'o':
c.arg[2] = param_get32ex(Cmd, cmdp+1, 0, 10);
cmdp+=2;
break;
default:
PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));
errors = 1;
break;
}
if(errors) break;
}
// No args
if(cmdp == 0) errors = 1;
//Validations
if(errors) return usage_lf_cmdread();
// in case they specified 'H'
strcpy((char *)&c.d.asBytes + strlen((char *)c.d.asBytes), dummy);
clearCommandBuffer();
SendCommand(&c);
return 0;
}
@ -493,7 +558,12 @@ int CmdLFRead(const char *Cmd)
//And ship it to device
UsbCommand c = {CMD_ACQUIRE_RAW_ADC_SAMPLES_125K, {arg1,0,0}};
SendCommand(&c);
WaitForResponse(CMD_ACK,NULL);
//WaitForResponse(CMD_ACK,NULL);
if ( !WaitForResponseTimeout(CMD_ACK,NULL,2500) ) {
PrintAndLog("command execution time out");
return 1;
}
return 0;
}
@ -1085,6 +1155,12 @@ int CmdLFfind(const char *Cmd)
return 1;
}
ans=CmdVikingDemod("");
if (ans>0) {
PrintAndLog("\nValid Viking ID Found!");
return 1;
}
ans=CmdPSKNexWatch("");
if (ans>0) {
PrintAndLog("\nValid NexWatch ID Found!");
@ -1126,13 +1202,17 @@ int CmdLFfind(const char *Cmd)
static command_t CommandTable[] =
{
{"help", CmdHelp, 1, "This help"},
{"cmdread", CmdLFCommandRead, 0, "<off period> <'0' period> <'1' period> <command> ['h'] -- Modulate LF reader field to send command before read (all periods in microseconds) (option 'h' for 134)"},
{"awid", CmdLFAWID, 1, "{ AWID RFIDs... }"},
{"em4x", CmdLFEM4X, 1, "{ EM4X RFIDs... }"},
{"hid", CmdLFHID, 1, "{ HID RFIDs... }"},
{"hitag", CmdLFHitag, 1, "{ Hitag tags and transponders... }"},
{"io", CmdLFIO, 1, "{ ioProx tags... }"},
{"pcf7931", CmdLFPCF7931, 1, "{ PCF7931 RFIDs... }"},
{"t55xx", CmdLFT55XX, 1, "{ T55xx RFIDs... }"},
{"ti", CmdLFTI, 1, "{ TI RFIDs... }"},
{"cmdread", CmdLFCommandRead, 0, "<d period> <z period> <o period> <c command> ['H'] -- Modulate LF reader field to send command before read (all periods in microseconds) (option 'H' for 134)"},
{"config", CmdLFSetConfig, 0, "Set config for LF sampling, bit/sample, decimation, frequency"},
{"flexdemod", CmdFlexdemod, 1, "Demodulate samples for FlexPass"},
{"hid", CmdLFHID, 1, "{ HID RFIDs... }"},
{"awid", CmdLFAWID, 1, "{ AWID RFIDs... }"},
{"io", CmdLFIO, 1, "{ ioProx tags... }"},
{"indalademod", CmdIndalaDemod, 1, "['224'] -- Demodulate samples for Indala 64 bit UID (option '224' for 224 bit)"},
{"indalaclone", CmdIndalaClone, 0, "<UID> ['l']-- Clone Indala to T55x7 (tag must be in antenna)(UID in HEX)(option 'l' for 224 UID"},
{"read", CmdLFRead, 0, "['s' silent] Read 125/134 kHz LF ID-only tag. Do 'lf read h' for help"},
@ -1143,11 +1223,7 @@ static command_t CommandTable[] =
{"simpsk", CmdLFpskSim, 0, "[1|2|3] [c <clock>] [i] [r <carrier>] [d <raw hex to sim>] -- Simulate LF PSK tag from demodbuffer or input"},
{"simbidir", CmdLFSimBidir, 0, "Simulate LF tag (with bidirectional data transmission between reader and tag)"},
{"snoop", CmdLFSnoop, 0, "['l'|'h'|<divisor>] [trigger threshold]-- Snoop LF (l:125khz, h:134khz)"},
{"ti", CmdLFTI, 1, "{ TI RFIDs... }"},
{"hitag", CmdLFHitag, 1, "{ Hitag tags and transponders... }"},
{"vchdemod", CmdVchDemod, 1, "['clone'] -- Demodulate samples for VeriChip"},
{"t55xx", CmdLFT55XX, 1, "{ T55xx RFIDs... }"},
{"pcf7931", CmdLFPCF7931, 1, "{PCF7931 RFIDs...}"},
{NULL, NULL, 0, NULL}
};

View file

@ -73,22 +73,23 @@ int CmdEM410xSim(const char *Cmd)
uint8_t uid[5] = {0x00};
if (cmdp == 'h' || cmdp == 'H') {
PrintAndLog("Usage: lf em4x 410xsim <UID>");
PrintAndLog("Usage: lf em4x em410xsim <UID> <clock>");
PrintAndLog("");
PrintAndLog(" sample: lf em4x 410xsim 0F0368568B");
PrintAndLog(" sample: lf em4x em410xsim 0F0368568B");
return 0;
}
/* clock is 64 in EM410x tags */
uint8_t clock = 64;
if (param_gethex(Cmd, 0, uid, 10)) {
PrintAndLog("UID must include 10 HEX symbols");
return 0;
}
PrintAndLog("Starting simulating UID %02X%02X%02X%02X%02X", uid[0],uid[1],uid[2],uid[3],uid[4]);
param_getdec(Cmd,1, &clock);
PrintAndLog("Starting simulating UID %02X%02X%02X%02X%02X clock: %d", uid[0],uid[1],uid[2],uid[3],uid[4],clock);
PrintAndLog("Press pm3-button to about simulation");
/* clock is 64 in EM410x tags */
int clock = 64;
/* clear our graph */
ClearGraph(0);
@ -197,21 +198,13 @@ int CmdEM410xWrite(const char *Cmd)
}
// Check Clock
if (card == 1)
{
// Default: 64
if (clock == 0)
clock = 64;
// Default: 64
if (clock == 0)
clock = 64;
// Allowed clock rates: 16, 32 and 64
if ((clock != 16) && (clock != 32) && (clock != 64)) {
PrintAndLog("Error! Clock rate %d not valid. Supported clock rates are 16, 32 and 64.\n", clock);
return 0;
}
}
else if (clock != 0)
{
PrintAndLog("Error! Clock rate is only supported on T55x7 tags.\n");
// Allowed clock rates: 16, 32, 40 and 64
if ((clock != 16) && (clock != 32) && (clock != 64) && (clock != 40)) {
PrintAndLog("Error! Clock rate %d not valid. Supported clock rates are 16, 32, 40 and 64.\n", clock);
return 0;
}
@ -221,11 +214,11 @@ int CmdEM410xWrite(const char *Cmd)
// provide for backwards-compatibility for older firmware, and to avoid
// having to add another argument to CMD_EM410X_WRITE_TAG, we just store
// the clock rate in bits 8-15 of the card value
card = (card & 0xFF) | (((uint64_t)clock << 8) & 0xFF00);
}
else if (card == 0)
card = (card & 0xFF) | ((clock << 8) & 0xFF00);
} else if (card == 0) {
PrintAndLog("Writing %s tag with UID 0x%010" PRIx64, "T5555", id, clock);
else {
card = (card & 0xFF) | ((clock << 8) & 0xFF00);
} else {
PrintAndLog("Error! Bad card type selected.\n");
return 0;
}
@ -608,7 +601,7 @@ static command_t CommandTable[] =
{"help", CmdHelp, 1, "This help"},
{"em410xdemod", CmdEMdemodASK, 0, "[findone] -- Extract ID from EM410x tag (option 0 for continuous loop, 1 for only 1 tag)"},
{"em410xread", CmdEM410xRead, 1, "[clock rate] -- Extract ID from EM410x tag in GraphBuffer"},
{"em410xsim", CmdEM410xSim, 0, "<UID> -- Simulate EM410x tag"},
{"em410xsim", CmdEM410xSim, 0, "<UID> [clock rate] -- Simulate EM410x tag"},
{"em410xwatch", CmdEM410xWatch, 0, "['h'] -- Watches for EM410x 125/134 kHz tags (option 'h' for 134)"},
{"em410xspoof", CmdEM410xWatchnSpoof, 0, "['h'] --- Watches for EM410x 125/134 kHz tags, and replays them. (option 'h' for 134)" },
{"em410xwrite", CmdEM410xWrite, 0, "<UID> <'0' T5555> <'1' T55x7> [clock rate] -- Write EM410x UID to T5555(Q5) or T55x7 tag, optionally setting clock rate"},

View file

@ -8,11 +8,11 @@
//-----------------------------------------------------------------------------
// Low frequency PCF7931 commands
//-----------------------------------------------------------------------------
#include <stdio.h>
#include <string.h>
#include "proxmark3.h"
#include "ui.h"
#include "util.h"
#include "graph.h"
#include "cmdparser.h"
#include "cmddata.h"
@ -22,115 +22,158 @@
static int CmdHelp(const char *Cmd);
struct pcf7931_config configPcf = {{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},17500,{0,0}};
#define PCF7931_DEFAULT_INITDELAY 17500
#define PCF7931_DEFAULT_OFFSET_WIDTH 0
#define PCF7931_DEFAULT_OFFSET_POSITION 0
int CmdLFPCF7931Read(const char *Cmd)
{
UsbCommand c = {CMD_PCF7931_READ};
SendCommand(&c);
UsbCommand resp;
WaitForResponse(CMD_ACK,&resp);
return 0;
// Default values - Configuration
struct pcf7931_config configPcf = {
{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
PCF7931_DEFAULT_INITDELAY,
PCF7931_DEFAULT_OFFSET_WIDTH,
PCF7931_DEFAULT_OFFSET_POSITION
};
// Resets the configuration settings to default values.
int pcf7931_resetConfig(){
memset(configPcf.Pwd, 0xFF, sizeof(configPcf.Pwd) );
configPcf.InitDelay = PCF7931_DEFAULT_INITDELAY;
configPcf.OffsetWidth = PCF7931_DEFAULT_OFFSET_WIDTH;
configPcf.OffsetPosition = PCF7931_DEFAULT_OFFSET_POSITION;
return 0;
}
int CmdLFPCF7931Config(const char *Cmd)
{
int res = 0;
res = sscanf(Cmd, "%02x %02x %02x %02x %02x %02x %02x %d %d %d", &configPcf.password[0], &configPcf.password[1], &configPcf.password[2], &configPcf.password[3], &configPcf.password[4], &configPcf.password[5], &configPcf.password[6], &configPcf.init_delay, &configPcf.offset[0], &configPcf.offset[1]);
if (res >= 7 || res < 1){
if(res == 7) configPcf.init_delay = 17500; //default value
if(res<=8){
configPcf.offset[0] = 0; //default value
configPcf.offset[1] = 0; //default value
}
if(res < 1){
PrintAndLog("Usage: <password byte 1 (in hex, lsb first)> <password byte 2 (in hex, lsb first)> [...] <password byte 7 (in hex, lsb first)> <tag initialization delay (in us)> <optional : offset on the low pulses width (in us)> <optional : offset on the low pulses position (in us)>");
PrintAndLog("The time offsets could be usefull to correct slew rate generated by the antenna.");
}
PrintAndLog("Current configuration :");
PrintAndLog("Password (LSB first on each byte) : %02x %02x %02x %02x %02x %02x %02x", configPcf.password[0], configPcf.password[1], configPcf.password[2], configPcf.password[3], configPcf.password[4], configPcf.password[5], configPcf.password[6]);
PrintAndLog("Tag initialization delay : %d us", configPcf.init_delay);
PrintAndLog("Offsets : %d us on the low pulses width, %d us on the low pulses positions", configPcf.offset[0], configPcf.offset[1]);
return 0;
}
//default values
configPcf.password[0] = 0xFF;
configPcf.password[1] = 0xFF;
configPcf.password[2] = 0xFF;
configPcf.password[3] = 0xFF;
configPcf.password[4] = 0xFF;
configPcf.password[5] = 0xFF;
configPcf.password[6] = 0xFF;
configPcf.init_delay = 17500;
configPcf.offset[0] = 0;
configPcf.offset[1] = 0;
PrintAndLog("Incorrect format");
PrintAndLog("Examples of right usage : lf pcf7931 config 11 22 33 44 55 66 77 20000");
PrintAndLog(" lf pcf7931 config FF FF FF FF FF FF FF 17500 -10 30");
return 0;
int pcf7931_printConfig(){
PrintAndLog("Password (LSB first on bytes) : %s", sprint_hex( configPcf.Pwd, sizeof(configPcf.Pwd)));
PrintAndLog("Tag initialization delay : %d us", configPcf.InitDelay);
PrintAndLog("Offset low pulses width : %d us", configPcf.OffsetWidth);
PrintAndLog("Offset low pulses position : %d us", configPcf.OffsetPosition);
return 0;
}
int CmdLFPCF7931Write(const char *Cmd)
{
UsbCommand c = {CMD_PCF7931_WRITE};
int res = 0;
res = sscanf(Cmd, "%x %x %x", &c.arg[0], &c.arg[1], &c.arg[2]);
if(res < 1) {
PrintAndLog("Please specify the block address in hex");
return 0;
}
if (res == 1){
PrintAndLog("Please specify the byte address in hex");
return 0;
}
if(res == 2) {
PrintAndLog("Please specify the data in hex (1 byte)");
return 0;
}
if(res == 3) {
uint8_t n=0;
for(n=0;n<7;n++) c.d.asDwords[n] = configPcf.password[n];
c.d.asDwords[7] = (configPcf.offset[0]+128);
c.d.asDwords[8] = (configPcf.offset[1]+128);
c.d.asDwords[9] = configPcf.init_delay;
SendCommand(&c);
return 0;
}
PrintAndLog("INCORRECT FORMAT");
return 0;
int usage_pcf7931_read(){
PrintAndLog("Usage: lf pcf7931 read [h] ");
PrintAndLog("This command tries to read a PCF7931 tag.");
PrintAndLog("Options:");
PrintAndLog(" h This help");
PrintAndLog("Examples:");
PrintAndLog(" lf pcf7931 read");
return 0;
}
int usage_pcf7931_write(){
PrintAndLog("Usage: lf pcf7931 write [h] <block address> <byte address> <data>");
PrintAndLog("This command tries to write a PCF7931 tag.");
PrintAndLog("Options:");
PrintAndLog(" h This help");
PrintAndLog(" blockaddress Block to save [0-7]");
PrintAndLog(" byteaddress Index of byte inside block to write [0-15]");
PrintAndLog(" data one byte of data (hex)");
PrintAndLog("Examples:");
PrintAndLog(" lf pcf7931 write 2 1 FF");
return 0;
}
int usage_pcf7931_config(){
PrintAndLog("Usage: lf pcf7931 config [h] [r] <pwd> <delay> <offset width> <offset position>");
PrintAndLog("This command tries to set the configuration used with PCF7931 commands");
PrintAndLog("The time offsets could be useful to correct slew rate generated by the antenna");
PrintAndLog("Caling without some parameter will print the current configuration.");
PrintAndLog("Options:");
PrintAndLog(" h This help");
PrintAndLog(" r Reset configuration to default values");
PrintAndLog(" pwd Password, hex, 7bytes, LSB-order");
PrintAndLog(" delay Tag initialization delay (in us) decimal");
PrintAndLog(" offset Low pulses width (in us) decimal");
PrintAndLog(" offset Low pulses position (in us) decimal");
PrintAndLog("Examples:");
PrintAndLog(" lf pcf7931 config");
PrintAndLog(" lf pcf7931 config r");
PrintAndLog(" lf pcf7931 config 11223344556677 20000");
PrintAndLog(" lf pcf7931 config 11223344556677 17500 -10 30");
return 0;
}
int CmdLFPCF7931Read(const char *Cmd){
uint8_t ctmp = param_getchar(Cmd, 0);
if ( ctmp == 'H' || ctmp == 'h' ) return usage_pcf7931_read();
UsbCommand resp;
UsbCommand c = {CMD_PCF7931_READ, {0, 0, 0}};
clearCommandBuffer();
SendCommand(&c);
if ( !WaitForResponseTimeout(CMD_ACK, &resp, 2500) ) {
PrintAndLog("command execution time out");
return 1;
}
return 0;
}
int CmdLFPCF7931Config(const char *Cmd){
uint8_t ctmp = param_getchar(Cmd, 0);
if ( ctmp == 0) return pcf7931_printConfig();
if ( ctmp == 'H' || ctmp == 'h' ) return usage_pcf7931_config();
if ( ctmp == 'R' || ctmp == 'r' ) return pcf7931_resetConfig();
if ( param_gethex(Cmd, 0, configPcf.Pwd, 14) ) return usage_pcf7931_config();
configPcf.InitDelay = (param_get32ex(Cmd,1,0,10) & 0xFFFF);
configPcf.OffsetWidth = (int)(param_get32ex(Cmd,2,0,10) & 0xFFFF);
configPcf.OffsetPosition = (int)(param_get32ex(Cmd,3,0,10) & 0xFFFF);
pcf7931_printConfig();
return 0;
}
int CmdLFPCF7931Write(const char *Cmd){
uint8_t ctmp = param_getchar(Cmd, 0);
if (strlen(Cmd) < 1 || ctmp == 'h' || ctmp == 'H') return usage_pcf7931_write();
uint8_t block = 0, bytepos = 0, data = 0;
if ( param_getdec(Cmd, 0, &block) ) return usage_pcf7931_write();
if ( param_getdec(Cmd, 1, &bytepos) ) return usage_pcf7931_write();
if ( (block > 7) || (bytepos > 15) ) return usage_pcf7931_write();
data = param_get8ex(Cmd, 2, 0, 16);
PrintAndLog("Writing block: %d", block);
PrintAndLog(" pos: %d", bytepos);
PrintAndLog(" data: 0x%02X", data);
UsbCommand c = {CMD_PCF7931_WRITE, { block, bytepos, data} };
memcpy(c.d.asDwords, configPcf.Pwd, sizeof(configPcf.Pwd) );
c.d.asDwords[7] = (configPcf.OffsetWidth + 128);
c.d.asDwords[8] = (configPcf.OffsetPosition + 128);
c.d.asDwords[9] = configPcf.InitDelay;
clearCommandBuffer();
SendCommand(&c);
//no ack?
return 0;
}
static command_t CommandTable[] =
{
{"help", CmdHelp, 1, "This help"},
{"read", CmdLFPCF7931Read, 1, "Read content of a PCF7931 transponder"},
{"write", CmdLFPCF7931Write, 1, "Write data on a PCF7931 transponder. Usage : lf pcf7931 write <bloc address> <byte address> <data>"},
{"config", CmdLFPCF7931Config, 1, "Configure the password, the tags initialization delay and time offsets (optional)"},
{NULL, NULL, 0, NULL}
{"help", CmdHelp, 1, "This help"},
{"read", CmdLFPCF7931Read, 0, "Read content of a PCF7931 transponder"},
{"write", CmdLFPCF7931Write, 0, "Write data on a PCF7931 transponder."},
{"config", CmdLFPCF7931Config, 1, "Configure the password, the tags initialization delay and time offsets (optional)"},
{NULL, NULL, 0, NULL}
};
int CmdLFPCF7931(const char *Cmd)
{
CmdsParse(CommandTable, Cmd);
return 0;
CmdsParse(CommandTable, Cmd);
return 0;
}
int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable);
return 0;
CmdsHelp(CommandTable);
return 0;
}

View file

@ -13,17 +13,23 @@
#define CMDLFPCF7931_H__
struct pcf7931_config{
uint8_t password[7];
uint16_t init_delay;
int16_t offset[2];
uint8_t Pwd[7];
uint16_t InitDelay;
int16_t OffsetWidth;
int16_t OffsetPosition;
};
int pcf7931_resetConfig();
int pcf7931_printConfig();
int usage_pcf7931_read();
int usage_pcf7931_write();
int usage_pcf7931_config();
int CmdLFPCF7931(const char *Cmd);
int CmdLFPCF7931Read(const char *Cmd);
int CmdLFPCF7931Write(const char *Cmd);
int CmdLFPCF7931Config(const char *Cmd);
#endif

View file

@ -28,13 +28,21 @@
#define CONFIGURATION_BLOCK 0x00
#define TRACE_BLOCK 0x01
#define REGULAR_READ_MODE_BLOCK 0xFF
// Default configuration
t55xx_conf_block_t config = { .modulation = DEMOD_ASK, .inverted = FALSE, .offset = 0x00, .block0 = 0x00};
t55xx_conf_block_t Get_t55xx_Config(){
return config;
}
void Set_t55xx_Config(t55xx_conf_block_t conf){
config = conf;
}
int usage_t55xx_config(){
PrintAndLog("Usage: lf t55xx config [d <demodulation>] [i 1] [o <offset>]");
PrintAndLog("Options: ");
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");
@ -49,31 +57,41 @@ int usage_t55xx_config(){
return 0;
}
int usage_t55xx_read(){
PrintAndLog("Usage: lf t55xx read <block> <password>");
PrintAndLog(" <block>, block number to read. Between 0-7");
PrintAndLog(" <password>, OPTIONAL password (8 hex characters)");
PrintAndLog("Usage: lf t55xx read [b <block>] [p <password>] <override_safety> <page1>");
PrintAndLog("Options:");
PrintAndLog(" b <block> - block number to read. Between 0-7");
PrintAndLog(" p <password> - OPTIONAL password (8 hex characters)");
PrintAndLog(" o - OPTIONAL override safety check");
PrintAndLog(" 1 - OPTIONAL read Page 1 instead of Page 0");
PrintAndLog(" ****WARNING****");
PrintAndLog(" Use of read with password on a tag not configured for a pwd");
PrintAndLog(" can damage the tag");
PrintAndLog("");
PrintAndLog("Examples:");
PrintAndLog(" lf t55xx read 0 - read data from block 0");
PrintAndLog(" lf t55xx read 0 feedbeef - read data from block 0 password feedbeef");
PrintAndLog(" lf t55xx read b 0 - read data from block 0");
PrintAndLog(" lf t55xx read b 0 p feedbeef - read data from block 0 password feedbeef");
PrintAndLog(" lf t55xx read b 0 p feedbeef o - read data from block 0 password feedbeef safety check");
PrintAndLog("");
return 0;
}
int usage_t55xx_write(){
PrintAndLog("Usage: lf t55xx wr <block> <data> [password]");
PrintAndLog(" <block>, block number to write. Between 0-7");
PrintAndLog(" <data>, 4 bytes of data to write (8 hex characters)");
PrintAndLog(" [password], OPTIONAL password 4bytes (8 hex characters)");
PrintAndLog("Usage: lf t55xx wr [b <block>] [d <data>] [p <password>] [1]");
PrintAndLog("Options:");
PrintAndLog(" b <block> - block number to write. Between 0-7");
PrintAndLog(" d <data> - 4 bytes of data to write (8 hex characters)");
PrintAndLog(" p <password> - OPTIONAL password 4bytes (8 hex characters)");
PrintAndLog(" 1 - OPTIONAL write Page 1 instead of Page 0");
PrintAndLog("");
PrintAndLog("Examples:");
PrintAndLog(" lf t55xx wr 3 11223344 - write 11223344 to block 3");
PrintAndLog(" lf t55xx wr 3 11223344 feedbeef - write 11223344 to block 3 password feedbeef");
PrintAndLog(" lf t55xx wr b 3 d 11223344 - write 11223344 to block 3");
PrintAndLog(" lf t55xx wr b 3 d 11223344 p feedbeef - write 11223344 to block 3 password feedbeef");
PrintAndLog("");
return 0;
}
int usage_t55xx_trace() {
PrintAndLog("Usage: lf t55xx trace [1]");
PrintAndLog(" [graph buffer data], if set, use Graphbuffer otherwise read data from tag.");
PrintAndLog("Options:");
PrintAndLog(" [graph buffer data] - if set, use Graphbuffer otherwise read data from tag.");
PrintAndLog("");
PrintAndLog("Examples:");
PrintAndLog(" lf t55xx trace");
@ -83,7 +101,8 @@ int usage_t55xx_trace() {
}
int usage_t55xx_info() {
PrintAndLog("Usage: lf t55xx info [1]");
PrintAndLog(" [graph buffer data], if set, use Graphbuffer otherwise read data from tag.");
PrintAndLog("Options:");
PrintAndLog(" [graph buffer data] - if set, use Graphbuffer otherwise read data from tag.");
PrintAndLog("");
PrintAndLog("Examples:");
PrintAndLog(" lf t55xx info");
@ -92,17 +111,21 @@ int usage_t55xx_info() {
return 0;
}
int usage_t55xx_dump(){
PrintAndLog("Usage: lf t55xx dump <password>");
PrintAndLog(" <password>, OPTIONAL password 4bytes (8 hex symbols)");
PrintAndLog("Usage: lf t55xx dump <password> [o]");
PrintAndLog("Options:");
PrintAndLog(" <password> - OPTIONAL password 4bytes (8 hex symbols)");
PrintAndLog(" o - OPTIONAL override, force pwd read despite danger to card");
PrintAndLog("");
PrintAndLog("Examples:");
PrintAndLog(" lf t55xx dump");
PrintAndLog(" lf t55xx dump feedbeef");
PrintAndLog(" lf t55xx dump feedbeef o");
PrintAndLog("");
return 0;
}
int usage_t55xx_detect(){
PrintAndLog("Usage: lf t55xx detect");
PrintAndLog("Usage: lf t55xx detect [1]");
PrintAndLog("Options:");
PrintAndLog(" [graph buffer data] - if set, use Graphbuffer otherwise read data from tag.");
PrintAndLog("");
PrintAndLog("Examples:");
PrintAndLog(" lf t55xx detect");
@ -110,18 +133,29 @@ int usage_t55xx_detect(){
PrintAndLog("");
return 0;
}
int usage_t55xx_wakup(){
PrintAndLog("Usage: lf t55xx wakeup [h] p <password>");
PrintAndLog("This commands send the Answer-On-Request command and leaves the readerfield ON afterwards.");
PrintAndLog("Options:");
PrintAndLog(" h - this help");
PrintAndLog(" p <password> - password 4bytes (8 hex symbols)");
PrintAndLog("");
PrintAndLog("Examples:");
PrintAndLog(" lf t55xx wakeup p 11223344 - send wakeup password");
return 0;
}
static int CmdHelp(const char *Cmd);
int CmdT55xxSetConfig(const char *Cmd) {
uint8_t offset = 0;
bool errors = FALSE;
uint8_t cmdp = 0;
char modulation[5] = {0x00};
char tmp = 0x00;
uint8_t bitRate = 0;
uint8_t rates[9] = {8,16,32,40,50,64,100,128,0};
uint8_t cmdp = 0;
bool errors = FALSE;
while(param_getchar(Cmd, cmdp) != 0x00 && !errors)
{
tmp = param_getchar(Cmd, cmdp);
@ -201,64 +235,91 @@ int CmdT55xxSetConfig(const char *Cmd) {
}
// No args
if (cmdp == 0) {
printConfiguration( config );
return 0;
}
//Validations
if (errors)
return usage_t55xx_config();
if (cmdp == 0) return printConfiguration( config );
config.block0 = 0;
printConfiguration ( config );
return 0;
//Validations
if (errors) return usage_t55xx_config();
config.block0 = 0;
return printConfiguration ( config );
}
int T55xxReadBlock(uint8_t block, bool page1, bool usepwd, bool override, uint32_t password){
//Password mode
if ( usepwd ) {
// try reading the config block and verify that PWD bit is set before doing this!
if ( !override ) {
if ( !AquireData(0, CONFIGURATION_BLOCK, false, 0 ) ) return 0;
if ( !tryDetectModulation() ) {
PrintAndLog("Safety Check: Could not detect if PWD bit is set in config block. Exits.");
return 0;
} else {
PrintAndLog("Safety Check: PWD bit is NOT set in config block. Reading without password...");
usepwd = false;
page1 = false;
}
} else {
PrintAndLog("Safety Check Overriden - proceeding despite risk");
}
}
if (!AquireData(page1, block, usepwd, password) ) return 0;
if (!DecodeT55xxBlock()) return 0;
char blk[10]={0};
sprintf(blk,"%d", block);
printT55xxBlock(blk);
return 1;
}
int CmdT55xxReadBlock(const char *Cmd) {
int block = -1;
int password = 0xFFFFFFFF; //default to blank Block 7
uint8_t block = REGULAR_READ_MODE_BLOCK;
uint32_t password = 0; //default to blank Block 7
bool usepwd = false;
bool override = false;
bool page1 = false;
bool errors = false;
uint8_t cmdp = 0;
while(param_getchar(Cmd, cmdp) != 0x00 && !errors) {
switch(param_getchar(Cmd, cmdp)) {
case 'h':
case 'H':
return usage_t55xx_read();
case 'b':
case 'B':
errors |= param_getdec(Cmd, cmdp+1, &block);
cmdp += 2;
break;
case 'o':
case 'O':
override = true;
cmdp++;
break;
case 'p':
case 'P':
password = param_get32ex(Cmd, cmdp+1, 0, 16);
usepwd = true;
cmdp += 2;
break;
case '1':
page1 = true;
cmdp++;
break;
default:
PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));
errors = true;
break;
}
}
if (errors) return usage_t55xx_read();
char cmdp = param_getchar(Cmd, 0);
if (cmdp == 'h' || cmdp == 'H')
return usage_t55xx_read();
int res = sscanf(Cmd, "%d %x", &block, &password);
if ( res < 1 || res > 2 )
return usage_t55xx_read();
if ((block < 0) | (block > 7)) {
if (block > 7 && block != REGULAR_READ_MODE_BLOCK ) {
PrintAndLog("Block must be between 0 and 7");
return 1;
}
UsbCommand c = {CMD_T55XX_READ_BLOCK, {0, block, 0}};
c.d.asBytes[0] = 0x0;
//Password mode
if ( res == 2 ) {
c.arg[2] = password;
c.d.asBytes[0] = 0x1;
return 0;
}
clearCommandBuffer();
SendCommand(&c);
if ( !WaitForResponseTimeout(CMD_ACK,NULL,2500) ) {
PrintAndLog("command execution time out");
return 2;
}
uint8_t got[12000];
GetFromBigBuf(got,sizeof(got),0);
WaitForResponse(CMD_ACK,NULL);
setGraphBuf(got, 12000);
DemodBufferLen=0;
if (!DecodeT55xxBlock()) return 3;
char blk[10]={0};
sprintf(blk,"%d", block);
printT55xxBlock(blk);
return 0;
PrintAndLog("Reading Page %d:", page1);
PrintAndLog("blk | hex data | binary");
return T55xxReadBlock(block, page1, usepwd, override, password);
}
bool DecodeT55xxBlock(){
@ -269,9 +330,6 @@ bool DecodeT55xxBlock(){
uint8_t bitRate[8] = {8,16,32,40,50,64,100,128};
DemodBufferLen = 0x00;
//trim 1/2 a clock from beginning
snprintf(cmdStr, sizeof(buf),"%d", bitRate[config.bitrate]/2 );
CmdLtrim(cmdStr);
switch( config.modulation ){
case DEMOD_FSK:
snprintf(cmdStr, sizeof(buf),"%d %d", bitRate[config.bitrate], config.inverted );
@ -323,17 +381,17 @@ int CmdT55xxDetect(const char *Cmd){
return usage_t55xx_detect();
if (strlen(Cmd)==0)
AquireData( CONFIGURATION_BLOCK );
if ( !AquireData(0, CONFIGURATION_BLOCK, false, 0) )
return 0;
if ( !tryDetectModulation() )
PrintAndLog("Could not detect modulation automatically. Try setting it manually with \'lf t55xx config\'");
return 0;
return 1;
}
// detect configuration?
bool tryDetectModulation(){
char cmdStr[8] = {0};
uint8_t hits = 0;
t55xx_conf_block_t tests[15];
int bitRate=0;
@ -341,8 +399,6 @@ bool tryDetectModulation(){
save_restoreGB(1);
if (GetFskClock("", FALSE, FALSE)){
fskClocks(&fc1, &fc2, &clk, FALSE);
sprintf(cmdStr,"%d", clk/2);
CmdLtrim(cmdStr);
if ( FSKrawDemod("0 0", FALSE) && test(DEMOD_FSK, &tests[hits].offset, &bitRate)){
tests[hits].modulation = DEMOD_FSK;
if (fc1==8 && fc2 == 5)
@ -369,8 +425,6 @@ bool tryDetectModulation(){
} else {
clk = GetAskClock("", FALSE, FALSE);
if (clk>0) {
sprintf(cmdStr,"%d", clk/2);
CmdLtrim(cmdStr);
if ( ASKDemod("0 0 0", FALSE, FALSE, 1) && test(DEMOD_ASK, &tests[hits].offset, &bitRate)) {
tests[hits].modulation = DEMOD_ASK;
tests[hits].bitrate = bitRate;
@ -404,8 +458,6 @@ bool tryDetectModulation(){
save_restoreGB(0);
clk = GetNrzClock("", FALSE, FALSE);
if (clk>0) {
sprintf(cmdStr,"%d", clk/2);
CmdLtrim(cmdStr);
if ( NRZrawDemod("0 0 1", FALSE) && test(DEMOD_NRZ, &tests[hits].offset, &bitRate)) {
tests[hits].modulation = DEMOD_NRZ;
tests[hits].bitrate = bitRate;
@ -427,9 +479,6 @@ bool tryDetectModulation(){
save_restoreGB(0);
clk = GetPskClock("", FALSE, FALSE);
if (clk>0) {
PrintAndLog("clk %d",clk);
sprintf(cmdStr,"%d", clk/2);
CmdLtrim(cmdStr);
if ( PSKDemod("0 0 1", FALSE) && test(DEMOD_PSK1, &tests[hits].offset, &bitRate)) {
tests[hits].modulation = DEMOD_PSK1;
tests[hits].bitrate = bitRate;
@ -491,7 +540,7 @@ bool tryDetectModulation(){
bool testModulation(uint8_t mode, uint8_t modread){
switch( mode ){
case DEMOD_FSK:
if (modread > 3 && modread < 8) return TRUE;
if (modread >= DEMOD_FSK1 && modread <= DEMOD_FSK2a) return TRUE;
break;
case DEMOD_ASK:
if (modread == DEMOD_ASK) return TRUE;
@ -615,14 +664,14 @@ void printT55xxBlock(const char *blockNum){
bits[i - config.offset]=DemodBuffer[i];
blockData = PackBits(0, 32, bits);
PrintAndLog("[%s] 0x%08X %s", blockNum, blockData, sprint_bin(bits,32));
PrintAndLog(" %s | %08X | %s", blockNum, blockData, sprint_bin(bits,32));
}
int special(const char *Cmd) {
uint32_t blockData = 0;
uint8_t bits[32] = {0x00};
PrintAndLog("[OFFSET] [DATA] [BINARY]");
PrintAndLog("OFFSET | DATA | BINARY");
PrintAndLog("----------------------------------------------------");
int i,j = 0;
for (; j < 64; ++j){
@ -632,86 +681,142 @@ int special(const char *Cmd) {
blockData = PackBits(0, 32, bits);
PrintAndLog("[%02d] 0x%08X %s",j , blockData, sprint_bin(bits,32));
PrintAndLog(" %02d | 0x%08X | %s",j , blockData, sprint_bin(bits,32));
}
return 0;
}
void printConfiguration( t55xx_conf_block_t b){
int printConfiguration( t55xx_conf_block_t b){
PrintAndLog("Modulation : %s", GetSelectedModulationStr(b.modulation) );
PrintAndLog("Bit Rate : %s", GetBitRateStr(b.bitrate) );
PrintAndLog("Inverted : %s", (b.inverted) ? "Yes" : "No" );
PrintAndLog("Offset : %d", b.offset);
PrintAndLog("Block0 : 0x%08X", b.block0);
PrintAndLog("");
return 0;
}
int CmdT55xxWriteBlock(const char *Cmd)
{
int block = 8; //default to invalid block
int data = 0xFFFFFFFF; //default to blank Block
int password = 0xFFFFFFFF; //default to blank Block 7
char cmdp = param_getchar(Cmd, 0);
if (cmdp == 'h' || cmdp == 'H') {
usage_t55xx_write();
return 0;
int CmdT55xxWakeUp(const char *Cmd) {
uint32_t password = 0;
uint8_t cmdp = 0;
bool errors = true;
while(param_getchar(Cmd, cmdp) != 0x00) {
switch(param_getchar(Cmd, cmdp)) {
case 'h':
case 'H':
return usage_t55xx_wakup();
case 'p':
case 'P':
password = param_get32ex(Cmd, cmdp+1, 0xFFFFFFFF, 16);
cmdp += 2;
errors = false;
break;
default:
PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));
errors = true;
break;
}
}
int res = sscanf(Cmd, "%d %x %x",&block, &data, &password);
if ( res < 2 || res > 3) {
usage_t55xx_write();
return 1;
if (errors) return usage_t55xx_wakup();
UsbCommand c = {CMD_T55XX_WAKEUP, {password, 0, 0}};
clearCommandBuffer();
SendCommand(&c);
PrintAndLog("Wake up command sent. Try read now");
return 0;
}
int CmdT55xxWriteBlock(const char *Cmd) {
uint8_t block = 0xFF; //default to invalid block
uint32_t data = 0xFFFFFFFF; //default to blank Block
uint32_t password = 0xFFFFFFFF; //default to blank Block 7
bool usepwd = false;
bool page1 = false;
bool gotdata = false;
bool errors = false;
uint8_t cmdp = 0;
while(param_getchar(Cmd, cmdp) != 0x00 && !errors) {
switch(param_getchar(Cmd, cmdp)) {
case 'h':
case 'H':
return usage_t55xx_write();
case 'b':
case 'B':
errors |= param_getdec(Cmd, cmdp+1, &block);
cmdp += 2;
break;
case 'd':
case 'D':
data = param_get32ex(Cmd, cmdp+1, 0, 16);
gotdata = true;
cmdp += 2;
break;
case 'p':
case 'P':
password = param_get32ex(Cmd, cmdp+1, 0, 16);
usepwd = true;
cmdp += 2;
break;
case '1':
page1 = true;
cmdp++;
break;
default:
PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));
errors = true;
break;
}
}
if (errors || !gotdata) return usage_t55xx_write();
if (block > 7) {
PrintAndLog("Block number must be between 0 and 7");
return 1;
return 0;
}
UsbCommand c = {CMD_T55XX_WRITE_BLOCK, {data, block, 0}};
UsbCommand resp;
c.d.asBytes[0] = 0x0;
c.d.asBytes[0] = (page1) ? 0x2 : 0;
PrintAndLog("Writing to block: %d data : 0x%08X", block, data);
PrintAndLog("Writing to page: %d block: %d data : 0x%08X", page1, block, data);
//Password mode
if (res == 3) {
if (usepwd) {
c.arg[2] = password;
c.d.asBytes[0] = 0x1;
c.d.asBytes[0] |= 0x1;
PrintAndLog("pwd : 0x%08X", password);
}
clearCommandBuffer();
SendCommand(&c);
if (!WaitForResponseTimeout(CMD_ACK, &resp, 1000)){
PrintAndLog("Error occurred, device did not ACK write operation. (May be due to old firmware)");
return -1;
return 0;
}
return 0;
return 1;
}
int CmdT55xxReadTrace(const char *Cmd)
{
int CmdT55xxReadTrace(const char *Cmd) {
char cmdp = param_getchar(Cmd, 0);
bool pwdmode = false;
uint32_t password = 0;
if (strlen(Cmd) > 1 || cmdp == 'h' || cmdp == 'H')
return usage_t55xx_trace();
if (strlen(Cmd)==0)
AquireData( TRACE_BLOCK );
if ( !AquireData( TRACE_BLOCK, REGULAR_READ_MODE_BLOCK, pwdmode, password ) )
return 0;
if (!DecodeT55xxBlock()) return 1;
if (!DecodeT55xxBlock()) return 0;
if ( !DemodBufferLen) return 0;
if ( !DemodBufferLen) return 1;
RepaintGraphWindow();
uint8_t repeat = 0;
if (config.offset > 5)
repeat = 32;
uint8_t si = config.offset+repeat;
uint32_t bl0 = PackBits(si, 32, DemodBuffer);
uint32_t bl1 = PackBits(si+32, 32, DemodBuffer);
uint32_t bl1 = PackBits(si, 32, DemodBuffer);
uint32_t bl2 = PackBits(si+32, 32, DemodBuffer);
uint32_t acl = PackBits(si, 8, DemodBuffer); si += 8;
uint32_t mfc = PackBits(si, 8, DemodBuffer); si += 8;
@ -732,7 +837,7 @@ int CmdT55xxReadTrace(const char *Cmd)
if ( acl != 0xE0 ) {
PrintAndLog("The modulation is most likely wrong since the ACL is not 0xE0. ");
return 1;
return 0;
}
PrintAndLog("");
@ -749,8 +854,8 @@ int CmdT55xxReadTrace(const char *Cmd)
PrintAndLog(" Die Number : %d", dw);
PrintAndLog("-------------------------------------------------------------");
PrintAndLog(" Raw Data - Page 1");
PrintAndLog(" Block 0 : 0x%08X %s", bl0, sprint_bin(DemodBuffer+config.offset+repeat,32) );
PrintAndLog(" Block 1 : 0x%08X %s", bl1, sprint_bin(DemodBuffer+config.offset+repeat+32,32) );
PrintAndLog(" Block 1 : 0x%08X %s", bl1, sprint_bin(DemodBuffer+config.offset+repeat,32) );
PrintAndLog(" Block 2 : 0x%08X %s", bl2, sprint_bin(DemodBuffer+config.offset+repeat+32,32) );
PrintAndLog("-------------------------------------------------------------");
/*
@ -779,13 +884,16 @@ int CmdT55xxInfo(const char *Cmd){
Normal mode
Extended mode
*/
bool pwdmode = false;
uint32_t password = 0;
char cmdp = param_getchar(Cmd, 0);
if (strlen(Cmd) > 1 || cmdp == 'h' || cmdp == 'H')
return usage_t55xx_info();
if (strlen(Cmd)==0)
AquireData( CONFIGURATION_BLOCK );
if ( !AquireData( 0, CONFIGURATION_BLOCK, pwdmode, password ) )
return 1;
if (!DecodeT55xxBlock()) return 1;
@ -836,67 +944,59 @@ int CmdT55xxInfo(const char *Cmd){
int CmdT55xxDump(const char *Cmd){
char s[20] = {0x00};
uint8_t pwd[4] = {0x00};
uint32_t password = 0;
char cmdp = param_getchar(Cmd, 0);
if ( cmdp == 'h' || cmdp == 'H') {
usage_t55xx_dump();
return 0;
}
bool override = false;
if ( cmdp == 'h' || cmdp == 'H') return usage_t55xx_dump();
bool hasPwd = ( strlen(Cmd) > 0);
if ( hasPwd ){
if (param_gethex(Cmd, 0, pwd, 8)) {
PrintAndLog("password must include 8 HEX symbols");
return 1;
}
bool usepwd = ( strlen(Cmd) > 0);
if ( usepwd ){
password = param_get32ex(Cmd, 0, 0, 16);
if (param_getchar(Cmd, 1) =='o' )
override = true;
}
for ( int i = 0; i <8; ++i){
memset(s,0,sizeof(s));
PrintAndLog("Reading Page 0:");
PrintAndLog("blk | hex data | binary");
for ( uint8_t i = 0; i <8; ++i){
T55xxReadBlock(i, 0, usepwd, override, password);
/*memset(s,0,sizeof(s));
if ( hasPwd ) {
sprintf(s,"%d %02x%02x%02x%02x", i, pwd[0],pwd[1],pwd[2],pwd[3]);
if ( override ) {
sprintf(s,"b %d p %02x%02x%02x%02x o", i, pwd[0],pwd[1],pwd[2],pwd[3]);
} else {
sprintf(s,"b %d p %02x%02x%02x%02x", i, pwd[0],pwd[1],pwd[2],pwd[3]);
}
} else {
sprintf(s,"%d", i);
sprintf(s,"b %d", i);
}
CmdT55xxReadBlock(s);
CmdT55xxReadBlock(s);*/
}
return 0;
PrintAndLog("Reading Page 1:");
PrintAndLog("blk | hex data | binary");
for ( uint8_t i = 0; i<4; i++){
T55xxReadBlock(i, 1, usepwd, override, password);
}
return 1;
}
int AquireData( uint8_t block ){
int AquireData( uint8_t page, uint8_t block, bool pwdmode, uint32_t password ){
UsbCommand c;
if ( block == CONFIGURATION_BLOCK )
c.cmd = CMD_T55XX_READ_BLOCK;
else if (block == TRACE_BLOCK )
c.cmd = CMD_T55XX_READ_TRACE;
c.arg[0] = 0x00;
c.arg[1] = 0x00;
c.arg[2] = 0x00;
c.d.asBytes[0] = 0x0;
//Password mode
// if ( res == 2 ) {
// c.arg[2] = password;
// c.d.asBytes[0] = 0x1;
// }
uint8_t arg0 = (page<<1) | pwdmode;
UsbCommand c = {CMD_T55XX_READ_BLOCK, {arg0, block, password}};
clearCommandBuffer();
SendCommand(&c);
if ( !WaitForResponseTimeout(CMD_ACK,NULL,2500) ) {
PrintAndLog("command execution time out");
return 1;
return 0;
}
uint8_t got[12000];
GetFromBigBuf(got,sizeof(got),0);
WaitForResponse(CMD_ACK,NULL);
setGraphBuf(got, 12000);
return 0;
setGraphBuf(got, sizeof(got));
return 1;
}
char * GetBitRateStr(uint32_t id){
@ -1072,17 +1172,36 @@ uint32_t PackBits(uint8_t start, uint8_t len, uint8_t* bits){
return tmp;
}
int CmdResetRead(const char *Cmd) {
UsbCommand c = {CMD_T55XX_RESET_READ, {0,0,0}};
clearCommandBuffer();
SendCommand(&c);
if ( !WaitForResponseTimeout(CMD_ACK,NULL,2500) ) {
PrintAndLog("command execution time out");
return 0;
}
uint8_t got[BIGBUF_SIZE-1];
GetFromBigBuf(got,sizeof(got),0);
WaitForResponse(CMD_ACK,NULL);
setGraphBuf(got, sizeof(got));
return 1;
}
static command_t CommandTable[] =
{
{"help", CmdHelp, 1, "This help"},
{"config", CmdT55xxSetConfig, 1, "Set/Get T55XX configuration (modulation, inverted, offset, rate)"},
{"detect", CmdT55xxDetect, 0, "[1] Try detecting the tag modulation from reading the configuration block."},
{"read", CmdT55xxReadBlock, 0, "<block> [password] -- Read T55xx block data (page 0) [optional password]"},
{"write", CmdT55xxWriteBlock,0, "<block> <data> [password] -- Write T55xx block data (page 0) [optional password]"},
{"trace", CmdT55xxReadTrace, 0, "[1] Show T55xx traceability data (page 1/ blk 0-1)"},
{"info", CmdT55xxInfo, 0, "[1] Show T55xx configuration data (page 0/ blk 0)"},
{"dump", CmdT55xxDump, 0, "[password] Dump T55xx card block 0-7. [optional password]"},
{"special", special, 0, "Show block changes with 64 different offsets"},
{"help", CmdHelp, 1, "This help"},
{"config", CmdT55xxSetConfig, 1, "Set/Get T55XX configuration (modulation, inverted, offset, rate)"},
{"detect", CmdT55xxDetect, 0, "[1] Try detecting the tag modulation from reading the configuration block."},
{"read", CmdT55xxReadBlock, 0, "b <block> p [password] [o] [1] -- Read T55xx block data. Optional [p password], [override], [page1]"},
{"resetread",CmdResetRead, 0, "Send Reset Cmd then lf read the stream to attempt to identify the start of it (needs a demod and/or plot after)"},
{"write", CmdT55xxWriteBlock,0, "b <block> d <data> p [password] [1] -- Write T55xx block data. Optional [p password], [page1]"},
{"trace", CmdT55xxReadTrace, 0, "[1] Show T55xx traceability data (page 1/ blk 0-1)"},
{"info", CmdT55xxInfo, 0, "[1] Show T55xx configuration data (page 0/ blk 0)"},
{"dump", CmdT55xxDump, 0, "[password] [o] Dump T55xx card block 0-7. Optional [password], [override]"},
{"special", special, 0, "Show block changes with 64 different offsets"},
{"wakeup", CmdT55xxWakeUp, 0, "Send AOR wakeup command"},
{NULL, NULL, 0, NULL}
};

View file

@ -39,6 +39,9 @@ typedef struct {
RF_128 = 0x07,
} bitrate;
} t55xx_conf_block_t;
t55xx_conf_block_t Get_t55xx_Config();
void Set_t55xx_Config(t55xx_conf_block_t conf);
int CmdLFT55XX(const char *Cmd);
int CmdT55xxSetConfig(const char *Cmd);
@ -47,6 +50,7 @@ int CmdT55xxWriteBlock(const char *Cmd);
int CmdT55xxReadTrace(const char *Cmd);
int CmdT55xxInfo(const char *Cmd);
int CmdT55xxDetect(const char *Cmd);
int CmdResetRead(const char *Cmd);
char * GetBitRateStr(uint32_t id);
char * GetSaferStr(uint32_t id);
@ -55,12 +59,12 @@ char * GetModelStrFromCID(uint32_t cid);
char * GetSelectedModulationStr( uint8_t id);
uint32_t PackBits(uint8_t start, uint8_t len, uint8_t *bitstream);
void printT55xxBlock(const char *demodStr);
void printConfiguration( t55xx_conf_block_t b);
int printConfiguration( t55xx_conf_block_t b);
bool DecodeT55xxBlock();
bool tryDetectModulation();
bool test(uint8_t mode, uint8_t *offset, int *fndBitRate);
int special(const char *Cmd);
int AquireData( uint8_t block );
int AquireData( uint8_t page, uint8_t block, bool pwdmode, uint32_t password );
#endif

View file

@ -73,7 +73,7 @@ typedef struct {
#define CMD_INDALA_CLONE_TAG_L 0x0213
#define CMD_T55XX_READ_BLOCK 0x0214
#define CMD_T55XX_WRITE_BLOCK 0x0215
#define CMD_T55XX_READ_TRACE 0x0216
#define CMD_T55XX_RESET_READ 0x0216
#define CMD_PCF7931_READ 0x0217
#define CMD_EM4X_READ_WORD 0x0218
#define CMD_EM4X_WRITE_WORD 0x0219
@ -85,6 +85,7 @@ typedef struct {
#define CMD_ASK_SIM_TAG 0x021F
#define CMD_PSK_SIM_TAG 0x0220
#define CMD_AWID_DEMOD_FSK 0x0221
#define CMD_T55XX_WAKEUP 0x0224
/* CMD_SET_ADC_MUX: ext1 is 0 for lopkd, 1 for loraw, 2 for hipkd, 3 for hiraw */

View file

@ -44,7 +44,7 @@ local _commands = {
CMD_INDALA_CLONE_TAG_L = 0x0213,
CMD_T55XX_READ_BLOCK = 0x0214,
CMD_T55XX_WRITE_BLOCK = 0x0215,
CMD_T55XX_READ_TRACE = 0x0216,
CMD_T55XX_RESET_READ = 0x0216,
CMD_PCF7931_READ = 0x0217,
CMD_EM4X_READ_WORD = 0x0218,
CMD_EM4X_WRITE_WORD = 0x0219,
@ -56,7 +56,7 @@ local _commands = {
CMD_ASK_SIM_TAG = 0x021F,
CMD_PSK_SIM_TAG = 0x0220,
CMD_AWID_DEMOD_FSK = 0x0221,
CMD_T55XX_WAKEUP = 0x0224,
--/* CMD_SET_ADC_MUX: ext1 is 0 for lopkd, 1 for loraw, 2 for hipkd, 3 for hiraw */
--// For the 13.56 MHz tags

View file

@ -18,6 +18,7 @@
#include "util.h"
#include "nonce2key/nonce2key.h"
#include "../common/iso15693tools.h"
#include "iso14443crc.h"
#include "../common/crc16.h"
#include "../common/crc64.h"
#include "../common/sha1.h"
@ -228,6 +229,27 @@ static int l_iso15693_crc(lua_State *L)
return 1;
}
static int l_iso14443b_crc(lua_State *L)
{
/* void ComputeCrc14443(int CrcType,
const unsigned char *Data, int Length,
unsigned char *TransmitFirst,
unsigned char *TransmitSecond)
*/
unsigned char buf[USB_CMD_DATA_SIZE];
size_t len = 0;
const char *data = luaL_checklstring(L, 1, &len);
if (USB_CMD_DATA_SIZE < len)
len = USB_CMD_DATA_SIZE-2;
for (int i = 0; i < len; i += 2) {
sscanf(&data[i], "%02x", (unsigned int *)&buf[i / 2]);
}
ComputeCrc14443(CRC_14443_B, buf, len, &buf[len], &buf[len+1]);
lua_pushlstring(L, (const char *)&buf, len+2);
return 1;
}
/*
Simple AES 128 cbc hook up to OpenSSL.
params: key, input
@ -426,6 +448,7 @@ int set_pm3_libraries(lua_State *L)
{"clearCommandBuffer", l_clearCommandBuffer},
{"console", l_CmdConsole},
{"iso15693_crc", l_iso15693_crc},
{"iso14443b_crc", l_iso14443b_crc},
{"aes128_decrypt", l_aes128decrypt_cbc},
{"aes128_decrypt_ecb", l_aes128decrypt_ecb},
{"aes128_encrypt", l_aes128encrypt_cbc},