2010-02-21 08:47:22 +08:00
//-----------------------------------------------------------------------------
// Copyright (C) 2010 iZsh <izsh at fail0verflow.com>
//
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
// at your option, any later version. See the LICENSE.txt file for the text of
// the license.
//-----------------------------------------------------------------------------
// Low frequency EM4x commands
//-----------------------------------------------------------------------------
Client cleanup and restructuring. Stage 1...
Next Step is refactoring some of the giant functions which are
just copy/paste of some other ones with just a few line changes,
removing unnecessary 'goto' etc.
The MS Windows version is broken with this commit but will be fixed
soon. Everything can't be done all at once :P
The commands are now hierarchical, for example:
"hf 14a read" vs. "hf 14b read".
You can also request help:
"hf help", "data help", "hf 15 help" etc.
Indents are now space-based, not tab-based anymore. Hopefully
no one will be trolling about it, considering the suicide-prone work
being done here ;)
client/cmdhw.c, client/proxusb.c, client/cmdhw.h, client/proxusb.h,
client/cmdmain.c, client/cmdlfhid.c, client/cmdmain.h, client/cmdlfhid.h,
client/data.c, client/data.h, client/cmdhf.c, client/cmdlf.c,
client/cmdhf.h, client/cmdhf15.c, client/cmdhf14b.c, client/cmdlf.h,
client/cmdhf15.h, client/cmdhf14b.h, client/cmddata.c, client/cmddata.h,
client/ui.c, client/cmdparser.c, client/cmdlfti.c, client/ui.h,
client/cmdlfem4x.c, client/cmdparser.h, client/cmdlfti.h, client/cmdlfem4x.h,
client/graph.c, client/graph.h, client/cmdhf14a.c, client/cmdhf14a.h,
client/cmdhflegic.c, client/cmdhflegic.c: New files.
client/cli.c, client/flasher.c, client/snooper.c, client/proxmark3.c,
client/proxmark3.h, client/Makefile: Update accordingly.
client/flash.h, client/flash.c, client/proxgui.cpp: Cosmetic changes.
client/translate.h, client/command.c, client/gui.c,
client/usb.c, client/prox.h: Remove.
include/usb_cmd.h (CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443_SIM): Remove dead cmd.
common/crc16.h: New file.
common/crc16.c: Modify accordingly.
common/iso14443crc.h: New file.
common/iso14443_crc.c: Rename to
common/iso14443crc.c: and modify accordingly.
armsrc/lfops.c, armsrc/iso14443.c,
armsrc/iso14443a.c: include .h files from
the common directory instead of including the c files.
common/Makefile.common, armsrc/Makefile: Modify accordingly.
2010-02-04 09:27:07 +08:00
# include "cmdlfem4x.h"
2015-06-15 05:02:52 +08:00
2016-10-20 07:50:30 +08:00
uint64_t g_em410xid = 0 ;
Client cleanup and restructuring. Stage 1...
Next Step is refactoring some of the giant functions which are
just copy/paste of some other ones with just a few line changes,
removing unnecessary 'goto' etc.
The MS Windows version is broken with this commit but will be fixed
soon. Everything can't be done all at once :P
The commands are now hierarchical, for example:
"hf 14a read" vs. "hf 14b read".
You can also request help:
"hf help", "data help", "hf 15 help" etc.
Indents are now space-based, not tab-based anymore. Hopefully
no one will be trolling about it, considering the suicide-prone work
being done here ;)
client/cmdhw.c, client/proxusb.c, client/cmdhw.h, client/proxusb.h,
client/cmdmain.c, client/cmdlfhid.c, client/cmdmain.h, client/cmdlfhid.h,
client/data.c, client/data.h, client/cmdhf.c, client/cmdlf.c,
client/cmdhf.h, client/cmdhf15.c, client/cmdhf14b.c, client/cmdlf.h,
client/cmdhf15.h, client/cmdhf14b.h, client/cmddata.c, client/cmddata.h,
client/ui.c, client/cmdparser.c, client/cmdlfti.c, client/ui.h,
client/cmdlfem4x.c, client/cmdparser.h, client/cmdlfti.h, client/cmdlfem4x.h,
client/graph.c, client/graph.h, client/cmdhf14a.c, client/cmdhf14a.h,
client/cmdhflegic.c, client/cmdhflegic.c: New files.
client/cli.c, client/flasher.c, client/snooper.c, client/proxmark3.c,
client/proxmark3.h, client/Makefile: Update accordingly.
client/flash.h, client/flash.c, client/proxgui.cpp: Cosmetic changes.
client/translate.h, client/command.c, client/gui.c,
client/usb.c, client/prox.h: Remove.
include/usb_cmd.h (CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443_SIM): Remove dead cmd.
common/crc16.h: New file.
common/crc16.c: Modify accordingly.
common/iso14443crc.h: New file.
common/iso14443_crc.c: Rename to
common/iso14443crc.c: and modify accordingly.
armsrc/lfops.c, armsrc/iso14443.c,
armsrc/iso14443a.c: include .h files from
the common directory instead of including the c files.
common/Makefile.common, armsrc/Makefile: Modify accordingly.
2010-02-04 09:27:07 +08:00
static int CmdHelp ( const char * Cmd ) ;
2017-07-30 15:17:48 +08:00
//////////////// 410x commands
int usage_lf_em410x_demod ( void ) {
2017-08-10 00:33:30 +08:00
PrintAndLog ( " Usage: lf em 410x_demod [h] [clock] <0|1> [maxError] " ) ;
PrintAndLog ( " Options: " ) ;
PrintAndLog ( " h - this help " ) ;
PrintAndLog ( " clock - set clock as integer, optional, if not set, autodetect. " ) ;
PrintAndLog ( " <0|1> - 0 normal output, 1 for invert output " ) ;
PrintAndLog ( " maxerror - set maximum allowed errors, default = 100. " ) ;
2017-07-30 15:17:48 +08:00
PrintAndLog ( " " ) ;
2017-07-31 03:21:02 +08:00
PrintAndLog ( " sample: lf em 410x_demod = demod an EM410x Tag ID from GraphBuffer " ) ;
PrintAndLog ( " : lf em 410x_demod 32 = demod an EM410x Tag ID from GraphBuffer using a clock of RF/32 " ) ;
PrintAndLog ( " : lf em 410x_demod 32 1 = demod an EM410x Tag ID from GraphBuffer using a clock of RF/32 and inverting data " ) ;
PrintAndLog ( " : lf em 410x_demod 1 = demod an EM410x Tag ID from GraphBuffer while inverting data " ) ;
PrintAndLog ( " : lf em 410x_demod 64 1 0 = demod an EM410x Tag ID from GraphBuffer using a clock of RF/64 and inverting data and allowing 0 demod errors " ) ;
2017-07-30 15:17:48 +08:00
return 0 ;
}
int usage_lf_em410x_write ( void ) {
PrintAndLog ( " Writes EM410x ID to a T55x7 / T5555 (Q5) tag " ) ;
PrintAndLog ( " " ) ;
2017-08-10 00:33:30 +08:00
PrintAndLog ( " Usage: lf em 410x_write [h] <id> <card> [clock] " ) ;
2017-07-30 15:17:48 +08:00
PrintAndLog ( " Options: " ) ;
PrintAndLog ( " h - this help " ) ;
PrintAndLog ( " <id> - ID number " ) ;
PrintAndLog ( " <card> - 0|1 T5555 (Q5) / T55x7 " ) ;
PrintAndLog ( " <clock> - 16|32|40|64, optional, set R/F clock rate, defaults to 64 " ) ;
PrintAndLog ( " samples: " ) ;
2017-08-10 00:33:30 +08:00
PrintAndLog ( " lf em 410x_write 0F0368568B " ) ;
2017-07-30 15:17:48 +08:00
return 0 ;
}
int usage_lf_em410x_ws ( void ) {
PrintAndLog ( " Watch 'nd Spoof, activates reader, waits until a EM410x tag gets presented then it starts simulating the found UID " ) ;
PrintAndLog ( " " ) ;
2017-08-10 00:33:30 +08:00
PrintAndLog ( " Usage: lf em 410x_spoof [h] " ) ;
2017-07-30 15:17:48 +08:00
PrintAndLog ( " Options: " ) ;
PrintAndLog ( " h - this help " ) ;
PrintAndLog ( " samples: " ) ;
2017-08-10 00:33:30 +08:00
PrintAndLog ( " lf em 410x_spoof " ) ;
2017-07-30 15:17:48 +08:00
return 0 ;
}
int usage_lf_em410x_clone ( void ) {
PrintAndLog ( " Simulating EM410x tag " ) ;
PrintAndLog ( " " ) ;
2017-08-10 00:33:30 +08:00
PrintAndLog ( " Usage: lf em 410x_clone [h] <uid> <clock> " ) ;
2017-07-30 15:17:48 +08:00
PrintAndLog ( " Options: " ) ;
PrintAndLog ( " h - this help " ) ;
PrintAndLog ( " uid - uid (10 HEX symbols) " ) ;
PrintAndLog ( " clock - clock (32|64) (optional) " ) ;
PrintAndLog ( " samples: " ) ;
2017-08-10 00:33:30 +08:00
PrintAndLog ( " lf em 410x_clone 0F0368568B " ) ;
PrintAndLog ( " lf em 410x_clone 0F0368568B 32 " ) ;
2017-07-30 15:17:48 +08:00
return 0 ;
}
2017-02-27 21:04:50 +08:00
int usage_lf_em410x_sim ( void ) {
PrintAndLog ( " Simulating EM410x tag " ) ;
PrintAndLog ( " " ) ;
2017-08-10 00:33:30 +08:00
PrintAndLog ( " Usage: lf em 410x_sim [h] <uid> <clock> " ) ;
2017-02-27 21:04:50 +08:00
PrintAndLog ( " Options: " ) ;
PrintAndLog ( " h - this help " ) ;
PrintAndLog ( " uid - uid (10 HEX symbols) " ) ;
PrintAndLog ( " clock - clock (32|64) (optional) " ) ;
PrintAndLog ( " samples: " ) ;
2017-08-10 00:33:30 +08:00
PrintAndLog ( " lf em 410x_sim 0F0368568B " ) ;
PrintAndLog ( " lf em 410x_sim 0F0368568B 32 " ) ;
2017-02-27 21:04:50 +08:00
return 0 ;
}
2017-07-30 15:17:48 +08:00
int usage_lf_em410x_brute ( void ) {
PrintAndLog ( " Bruteforcing by emulating EM410x tag " ) ;
PrintAndLog ( " " ) ;
2017-08-10 00:33:30 +08:00
PrintAndLog ( " Usage: lf em 410x_brute [h] ids.txt [d 2000] [c clock] " ) ;
2017-07-30 15:17:48 +08:00
PrintAndLog ( " Options: " ) ;
PrintAndLog ( " h - this help " ) ;
PrintAndLog ( " ids.txt - file with UIDs in HEX format, one per line " ) ;
PrintAndLog ( " d (2000) - pause delay in milliseconds between UIDs simulation, default 1000 ms (optional) " ) ;
PrintAndLog ( " c (32) - clock (32|64), default 64 (optional) " ) ;
PrintAndLog ( " samples: " ) ;
2017-08-10 00:33:30 +08:00
PrintAndLog ( " lf em 410x_brute ids.txt " ) ;
PrintAndLog ( " lf em 410x_brute ids.txt c 32 " ) ;
PrintAndLog ( " lf em 410x_brute ids.txt d 3000 " ) ;
PrintAndLog ( " lf em 410x_brute ids.txt d 3000 c 32 " ) ;
2017-07-30 15:17:48 +08:00
return 0 ;
}
2017-02-27 21:04:50 +08:00
2017-07-30 15:17:48 +08:00
//////////////// 4050 / 4450 commands
int usage_lf_em4x50_dump ( void ) {
PrintAndLog ( " Dump EM4x50/EM4x69. Tag must be on antenna. " ) ;
PrintAndLog ( " " ) ;
2017-08-10 00:33:30 +08:00
PrintAndLog ( " Usage: lf em 4x50_dump [h] <pwd> " ) ;
2017-07-30 15:17:48 +08:00
PrintAndLog ( " Options: " ) ;
PrintAndLog ( " h - this help " ) ;
PrintAndLog ( " pwd - password (hex) (optional) " ) ;
PrintAndLog ( " samples: " ) ;
2017-08-10 00:33:30 +08:00
PrintAndLog ( " lf em 4x50_dump " ) ;
PrintAndLog ( " lf em 4x50_dump 11223344 " ) ;
2017-07-30 15:17:48 +08:00
return 0 ;
}
int usage_lf_em4x50_read ( void ) {
PrintAndLog ( " Read EM 4x50/EM4x69. Tag must be on antenna. " ) ;
PrintAndLog ( " " ) ;
2017-08-10 00:33:30 +08:00
PrintAndLog ( " Usage: lf em 4x50_read [h] <address> <pwd> " ) ;
2017-07-30 15:17:48 +08:00
PrintAndLog ( " Options: " ) ;
PrintAndLog ( " h - this help " ) ;
PrintAndLog ( " address - memory address to read. (0-15) " ) ;
PrintAndLog ( " pwd - password (hex) (optional) " ) ;
PrintAndLog ( " samples: " ) ;
2017-08-10 00:33:30 +08:00
PrintAndLog ( " lf em 4x50_read 1 " ) ;
PrintAndLog ( " lf em 4x50_read 1 11223344 " ) ;
2017-07-30 15:17:48 +08:00
return 0 ;
}
int usage_lf_em4x50_write ( void ) {
PrintAndLog ( " Write EM 4x50/4x69. Tag must be on antenna. " ) ;
PrintAndLog ( " " ) ;
2017-08-10 00:33:30 +08:00
PrintAndLog ( " Usage: lf em 4x50_write [h] <address> <data> <pwd> " ) ;
2017-07-30 15:17:48 +08:00
PrintAndLog ( " Options: " ) ;
PrintAndLog ( " h - this help " ) ;
PrintAndLog ( " address - memory address to write to. (0-15) " ) ;
PrintAndLog ( " data - data to write (hex) " ) ;
PrintAndLog ( " pwd - password (hex) (optional) " ) ;
PrintAndLog ( " samples: " ) ;
2017-08-10 00:33:30 +08:00
PrintAndLog ( " lf em 4x50_write 1 deadc0de " ) ;
PrintAndLog ( " lf em 4x50_write 1 deadc0de 11223344 " ) ;
2017-07-30 15:17:48 +08:00
return 0 ;
}
//////////////// 4205 / 4305 commands
int usage_lf_em4x05_dump ( void ) {
PrintAndLog ( " Dump EM4x05/EM4x69. Tag must be on antenna. " ) ;
PrintAndLog ( " " ) ;
2017-08-10 00:33:30 +08:00
PrintAndLog ( " Usage: lf em 4x05_dump [h] <pwd> " ) ;
2017-07-30 15:17:48 +08:00
PrintAndLog ( " Options: " ) ;
PrintAndLog ( " h - this help " ) ;
PrintAndLog ( " pwd - password (hex) (optional) " ) ;
PrintAndLog ( " samples: " ) ;
2017-08-10 00:33:30 +08:00
PrintAndLog ( " lf em 4x05_dump " ) ;
PrintAndLog ( " lf em 4x05_dump 11223344 " ) ;
2017-07-30 15:17:48 +08:00
return 0 ;
}
int usage_lf_em4x05_read ( void ) {
PrintAndLog ( " Read EM4x05/EM4x69. Tag must be on antenna. " ) ;
PrintAndLog ( " " ) ;
2017-08-10 00:33:30 +08:00
PrintAndLog ( " Usage: lf em 4x05_read [h] <address> <pwd> " ) ;
2017-07-30 15:17:48 +08:00
PrintAndLog ( " Options: " ) ;
PrintAndLog ( " h - this help " ) ;
PrintAndLog ( " address - memory address to read. (0-15) " ) ;
PrintAndLog ( " pwd - password (hex) (optional) " ) ;
PrintAndLog ( " samples: " ) ;
2017-08-10 00:33:30 +08:00
PrintAndLog ( " lf em 4x05_read 1 " ) ;
PrintAndLog ( " lf em 4x05_read 1 11223344 " ) ;
2017-07-30 15:17:48 +08:00
return 0 ;
}
int usage_lf_em4x05_write ( void ) {
PrintAndLog ( " Write EM4x05/4x69. Tag must be on antenna. " ) ;
PrintAndLog ( " " ) ;
2017-08-10 00:33:30 +08:00
PrintAndLog ( " Usage: lf em 4x05_write [h] <address> <data> <pwd> " ) ;
2017-07-30 15:17:48 +08:00
PrintAndLog ( " Options: " ) ;
PrintAndLog ( " h - this help " ) ;
PrintAndLog ( " address - memory address to write to. (0-15) " ) ;
PrintAndLog ( " data - data to write (hex) " ) ;
PrintAndLog ( " pwd - password (hex) (optional) " ) ;
PrintAndLog ( " samples: " ) ;
2017-08-10 00:33:30 +08:00
PrintAndLog ( " lf em 4x05_write 1 deadc0de " ) ;
PrintAndLog ( " lf em 4x05_write 1 deadc0de 11223344 " ) ;
2017-07-30 15:17:48 +08:00
return 0 ;
}
int usage_lf_em4x05_info ( void ) {
PrintAndLog ( " Tag information EM4205/4305/4469//4569 tags. Tag must be on antenna. " ) ;
PrintAndLog ( " " ) ;
2017-08-10 00:33:30 +08:00
PrintAndLog ( " Usage: lf em 4x05_info [h] <pwd> " ) ;
2017-07-30 15:17:48 +08:00
PrintAndLog ( " Options: " ) ;
PrintAndLog ( " h - this help " ) ;
PrintAndLog ( " pwd - password (hex) (optional) " ) ;
PrintAndLog ( " samples: " ) ;
2017-08-10 00:33:30 +08:00
PrintAndLog ( " lf em 4x05_info " ) ;
PrintAndLog ( " lf em 4x05_info deadc0de " ) ;
2017-07-30 15:17:48 +08:00
return 0 ;
}
2017-07-31 03:21:02 +08:00
/* Read the ID of an EM410x tag.
* Format :
* 1111 1111 1 < - - standard non - repeatable header
* XXXX [ row parity bit ] < - - 10 rows of 5 bits for our 40 bit tag ID
* . . . .
* CCCC < - - each bit here is parity for the 10 bits above in corresponding column
* 0 < - - stop bit , end of tag
*/
2017-07-30 15:17:48 +08:00
// Construct the graph for emulating an EM410X tag
void ConstructEM410xEmulGraph ( const char * uid , const uint8_t clock ) {
int i , n , j , binary [ 4 ] , parity [ 4 ] ;
/* clear our graph */
ClearGraph ( 0 ) ;
/* write 9 start bits */
for ( i = 0 ; i < 9 ; i + + )
AppendGraph ( 0 , clock , 1 ) ;
/* for each hex char */
parity [ 0 ] = parity [ 1 ] = parity [ 2 ] = parity [ 3 ] = 0 ;
for ( i = 0 ; i < 10 ; i + + ) {
/* read each hex char */
sscanf ( & uid [ i ] , " %1x " , & n ) ;
for ( j = 3 ; j > = 0 ; j - - , n / = 2 )
binary [ j ] = n % 2 ;
/* append each bit */
AppendGraph ( 0 , clock , binary [ 0 ] ) ;
AppendGraph ( 0 , clock , binary [ 1 ] ) ;
AppendGraph ( 0 , clock , binary [ 2 ] ) ;
AppendGraph ( 0 , clock , binary [ 3 ] ) ;
/* append parity bit */
AppendGraph ( 0 , clock , binary [ 0 ] ^ binary [ 1 ] ^ binary [ 2 ] ^ binary [ 3 ] ) ;
/* keep track of column parity */
parity [ 0 ] ^ = binary [ 0 ] ;
parity [ 1 ] ^ = binary [ 1 ] ;
parity [ 2 ] ^ = binary [ 2 ] ;
parity [ 3 ] ^ = binary [ 3 ] ;
}
/* parity columns */
AppendGraph ( 0 , clock , parity [ 0 ] ) ;
AppendGraph ( 0 , clock , parity [ 1 ] ) ;
AppendGraph ( 0 , clock , parity [ 2 ] ) ;
AppendGraph ( 0 , clock , parity [ 3 ] ) ;
/* stop bit */
AppendGraph ( 1 , clock , 0 ) ;
}
//by marshmellow
//print 64 bit EM410x ID in multiple formats
void printEM410x ( uint32_t hi , uint64_t id ) {
if ( ! id & & ! hi ) return ;
PrintAndLog ( " EM410x %s pattern found " , ( hi ) ? " XL " : " " ) ;
uint64_t iii = 1 ;
uint64_t id2lo = 0 ;
uint32_t ii = 0 ;
uint32_t i = 0 ;
for ( ii = 5 ; ii > 0 ; ii - - ) {
for ( i = 0 ; i < 8 ; i + + ) {
id2lo = ( id2lo < < 1LL ) | ( ( id & ( iii < < ( i + ( ( ii - 1 ) * 8 ) ) ) ) > > ( i + ( ( ii - 1 ) * 8 ) ) ) ;
}
}
if ( hi ) {
//output 88 bit em id
PrintAndLog ( " \n EM TAG ID : %06X%016 " PRIX64 , hi , id ) ;
} else {
//output 40 bit em id
PrintAndLog ( " \n EM TAG ID : %010 " PRIX64 , id ) ;
PrintAndLog ( " \n Possible de-scramble patterns " ) ;
PrintAndLog ( " Unique TAG ID : %010 " PRIX64 , id2lo ) ;
PrintAndLog ( " HoneyWell IdentKey { " ) ;
PrintAndLog ( " DEZ 8 : %08 " PRIu64 , id & 0xFFFFFF ) ;
PrintAndLog ( " DEZ 10 : %010 " PRIu64 , id & 0xFFFFFFFF ) ;
PrintAndLog ( " DEZ 5.5 : %05 " PRIu64 " .%05 " PRIu64 , ( id > > 16LL ) & 0xFFFF , ( id & 0xFFFF ) ) ;
PrintAndLog ( " DEZ 3.5A : %03 " PRIu64 " .%05 " PRIu64 , ( id > > 32ll ) , ( id & 0xFFFF ) ) ;
PrintAndLog ( " DEZ 3.5B : %03 " PRIu64 " .%05 " PRIu64 , ( id & 0xFF000000 ) > > 24 , ( id & 0xFFFF ) ) ;
PrintAndLog ( " DEZ 3.5C : %03 " PRIu64 " .%05 " PRIu64 , ( id & 0xFF0000 ) > > 16 , ( id & 0xFFFF ) ) ;
PrintAndLog ( " DEZ 14/IK2 : %014 " PRIu64 , id ) ;
PrintAndLog ( " DEZ 15/IK3 : %015 " PRIu64 , id2lo ) ;
PrintAndLog ( " DEZ 20/ZK : %02 " PRIu64 " %02 " PRIu64 " %02 " PRIu64 " %02 " PRIu64 " %02 " PRIu64 " %02 " PRIu64 " %02 " PRIu64 " %02 " PRIu64 " %02 " PRIu64 " %02 " PRIu64 ,
( id2lo & 0xf000000000 ) > > 36 ,
( id2lo & 0x0f00000000 ) > > 32 ,
( id2lo & 0x00f0000000 ) > > 28 ,
( id2lo & 0x000f000000 ) > > 24 ,
( id2lo & 0x0000f00000 ) > > 20 ,
( id2lo & 0x00000f0000 ) > > 16 ,
( id2lo & 0x000000f000 ) > > 12 ,
( id2lo & 0x0000000f00 ) > > 8 ,
( id2lo & 0x00000000f0 ) > > 4 ,
( id2lo & 0x000000000f )
) ;
uint64_t paxton = ( ( ( id > > 32 ) < < 24 ) | ( id & 0xffffff ) ) + 0x143e00 ;
PrintAndLog ( " } \n Other : %05 " PRIu64 " _%03 " PRIu64 " _%08 " PRIu64 , ( id & 0xFFFF ) , ( ( id > > 16LL ) & 0xFF ) , ( id & 0xFFFFFF ) ) ;
PrintAndLog ( " Pattern Paxton : % " PRIu64 " [0x% " PRIX64 " ] " , paxton , paxton ) ;
uint32_t p1id = ( id & 0xFFFFFF ) ;
uint8_t arr [ 32 ] = { 0x00 } ;
int i = 0 ;
int j = 23 ;
for ( ; i < 24 ; + + i , - - j ) {
arr [ i ] = ( p1id > > i ) & 1 ;
}
uint32_t p1 = 0 ;
p1 | = arr [ 23 ] < < 21 ;
p1 | = arr [ 22 ] < < 23 ;
p1 | = arr [ 21 ] < < 20 ;
p1 | = arr [ 20 ] < < 22 ;
p1 | = arr [ 19 ] < < 18 ;
p1 | = arr [ 18 ] < < 16 ;
p1 | = arr [ 17 ] < < 19 ;
p1 | = arr [ 16 ] < < 17 ;
p1 | = arr [ 15 ] < < 13 ;
p1 | = arr [ 14 ] < < 15 ;
p1 | = arr [ 13 ] < < 12 ;
p1 | = arr [ 12 ] < < 14 ;
p1 | = arr [ 11 ] < < 6 ;
p1 | = arr [ 10 ] < < 2 ;
p1 | = arr [ 9 ] < < 7 ;
p1 | = arr [ 8 ] < < 1 ;
p1 | = arr [ 7 ] < < 0 ;
p1 | = arr [ 6 ] < < 8 ;
p1 | = arr [ 5 ] < < 11 ;
p1 | = arr [ 4 ] < < 3 ;
p1 | = arr [ 3 ] < < 10 ;
p1 | = arr [ 2 ] < < 4 ;
p1 | = arr [ 1 ] < < 5 ;
p1 | = arr [ 0 ] < < 9 ;
PrintAndLog ( " Pattern 1 : %d [0x%X] " , p1 , p1 ) ;
uint16_t sebury1 = id & 0xFFFF ;
uint8_t sebury2 = ( id > > 16 ) & 0x7F ;
uint32_t sebury3 = id & 0x7FFFFF ;
PrintAndLog ( " Pattern Sebury : %d %d %d [0x%X 0x%X 0x%X] " , sebury1 , sebury2 , sebury3 , sebury1 , sebury2 , sebury3 ) ;
}
}
/* Read the ID of an EM410x tag.
* Format :
* 1111 1111 1 < - - standard non - repeatable header
* XXXX [ row parity bit ] < - - 10 rows of 5 bits for our 40 bit tag ID
* . . . .
* CCCC < - - each bit here is parity for the 10 bits above in corresponding column
* 0 < - - stop bit , end of tag
*/
int AskEm410xDecode ( bool verbose , uint32_t * hi , uint64_t * lo ) {
size_t idx = 0 ;
2017-07-31 03:21:02 +08:00
uint8_t bits [ 512 ] = { 0 } ;
size_t size = sizeof ( bits ) ;
if ( ! getDemodBuf ( bits , & size ) ) {
PrintAndLog ( " DEBUG: Error - Em410x problem during copy from ASK demod " ) ;
return 0 ;
}
int ans = Em410xDecode ( bits , & size , & idx , hi , lo ) ;
2017-07-30 15:17:48 +08:00
if ( ans < 0 ) {
if ( g_debugMode ) {
if ( ans = = - 1 )
PrintAndLog ( " DEBUG: Error - Em410x not only 0|1 in decoded bitstream " ) ;
else if ( ans = = - 2 )
2017-07-31 03:21:02 +08:00
PrintAndLog ( " DEBUG: Error - Em410x not enough samples after demod " ) ;
else if ( ans = = - 4 )
2017-07-30 15:17:48 +08:00
PrintAndLog ( " DEBUG: Error - Em410x preamble not found " ) ;
2017-07-31 03:21:02 +08:00
else if ( ans = = - 5 )
2017-07-30 15:17:48 +08:00
PrintAndLog ( " DEBUG: Error - Em410x Size not correct: %d " , size ) ;
2017-07-31 03:21:02 +08:00
else if ( ans = = - 6 )
2017-07-30 15:17:48 +08:00
PrintAndLog ( " DEBUG: Error - Em410x parity failed " ) ;
}
return 0 ;
}
if ( ! lo & & ! hi ) {
PrintAndLog ( " DEBUG: Error - Em410x decoded to all zeros " ) ;
return 0 ;
}
//set GraphBuffer for clone or sim command
2017-07-31 03:21:02 +08:00
setDemodBuf ( DemodBuffer , ( size = = 40 ) ? 64 : 128 , idx + 1 ) ;
setClockGrid ( g_DemodClock , g_DemodStartIdx + ( ( idx + 1 ) * g_DemodClock ) ) ;
2017-07-30 15:17:48 +08:00
if ( g_debugMode ) {
PrintAndLog ( " DEBUG: Em410x idx: %d, Len: %d, Printing Demod Buffer: " , idx , size ) ;
printDemodBuff ( ) ;
}
2017-07-31 17:46:35 +08:00
2017-07-30 15:17:48 +08:00
if ( verbose )
printEM410x ( * hi , * lo ) ;
return 1 ;
}
int AskEm410xDemod ( const char * Cmd , uint32_t * hi , uint64_t * lo , bool verbose ) {
bool st = true ;
if ( ! ASKDemod_ext ( Cmd , false , false , 1 , & st ) ) return 0 ;
return AskEm410xDecode ( verbose , hi , lo ) ;
}
2017-07-31 03:21:02 +08:00
// this read is the "normal" read, which download lf signal and tries to demod here.
int CmdEM410xRead ( const char * Cmd ) {
lf_read ( true , 8192 ) ;
CmdEM410xDemod ( Cmd ) ;
return 0 ;
2017-07-30 15:17:48 +08:00
}
2017-07-31 03:21:02 +08:00
// this read loops on device side.
// uses the demod in lfops.c
int CmdEM410xRead_device ( const char * Cmd ) {
2015-01-05 22:51:27 +08:00
char cmdp = param_getchar ( Cmd , 0 ) ;
2017-02-08 05:26:06 +08:00
uint8_t findone = ( cmdp = = ' 1 ' ) ? 1 : 0 ;
UsbCommand c = { CMD_EM410X_DEMOD , { findone , 0 , 0 } } ;
2015-04-03 00:48:52 +08:00
SendCommand ( & c ) ;
return 0 ;
2014-12-30 04:32:53 +08:00
}
2017-07-31 03:21:02 +08:00
//by marshmellow
//takes 3 arguments - clock, invert and maxErr as integers
//attempts to demodulate ask while decoding manchester
//prints binary found and saves in graphbuffer for further commands
int CmdEM410xDemod ( const char * Cmd ) {
char cmdp = param_getchar ( Cmd , 0 ) ;
if ( strlen ( Cmd ) > 10 | | cmdp = = ' h ' | | cmdp = = ' H ' ) return usage_lf_em410x_demod ( ) ;
2017-02-27 04:32:51 +08:00
uint32_t hi = 0 ;
uint64_t lo = 0 ;
2015-04-03 00:48:52 +08:00
2017-07-31 03:21:02 +08:00
if ( AskEm410xDemod ( Cmd , & hi , & lo , true ) ! = 1 ) return 0 ;
2016-10-20 07:50:30 +08:00
g_em410xid = lo ;
2015-04-03 00:48:52 +08:00
return 1 ;
Client cleanup and restructuring. Stage 1...
Next Step is refactoring some of the giant functions which are
just copy/paste of some other ones with just a few line changes,
removing unnecessary 'goto' etc.
The MS Windows version is broken with this commit but will be fixed
soon. Everything can't be done all at once :P
The commands are now hierarchical, for example:
"hf 14a read" vs. "hf 14b read".
You can also request help:
"hf help", "data help", "hf 15 help" etc.
Indents are now space-based, not tab-based anymore. Hopefully
no one will be trolling about it, considering the suicide-prone work
being done here ;)
client/cmdhw.c, client/proxusb.c, client/cmdhw.h, client/proxusb.h,
client/cmdmain.c, client/cmdlfhid.c, client/cmdmain.h, client/cmdlfhid.h,
client/data.c, client/data.h, client/cmdhf.c, client/cmdlf.c,
client/cmdhf.h, client/cmdhf15.c, client/cmdhf14b.c, client/cmdlf.h,
client/cmdhf15.h, client/cmdhf14b.h, client/cmddata.c, client/cmddata.h,
client/ui.c, client/cmdparser.c, client/cmdlfti.c, client/ui.h,
client/cmdlfem4x.c, client/cmdparser.h, client/cmdlfti.h, client/cmdlfem4x.h,
client/graph.c, client/graph.h, client/cmdhf14a.c, client/cmdhf14a.h,
client/cmdhflegic.c, client/cmdhflegic.c: New files.
client/cli.c, client/flasher.c, client/snooper.c, client/proxmark3.c,
client/proxmark3.h, client/Makefile: Update accordingly.
client/flash.h, client/flash.c, client/proxgui.cpp: Cosmetic changes.
client/translate.h, client/command.c, client/gui.c,
client/usb.c, client/prox.h: Remove.
include/usb_cmd.h (CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443_SIM): Remove dead cmd.
common/crc16.h: New file.
common/crc16.c: Modify accordingly.
common/iso14443crc.h: New file.
common/iso14443_crc.c: Rename to
common/iso14443crc.c: and modify accordingly.
armsrc/lfops.c, armsrc/iso14443.c,
armsrc/iso14443a.c: include .h files from
the common directory instead of including the c files.
common/Makefile.common, armsrc/Makefile: Modify accordingly.
2010-02-04 09:27:07 +08:00
}
2015-03-23 03:28:48 +08:00
// emulate an EM410X tag
2017-07-14 22:20:34 +08:00
int CmdEM410xSim ( const char * Cmd ) {
2016-10-20 06:41:34 +08:00
char cmdp = param_getchar ( Cmd , 0 ) ;
2017-02-08 05:26:06 +08:00
if ( cmdp = = ' h ' | | cmdp = = ' H ' ) return usage_lf_em410x_sim ( ) ;
2017-07-14 22:20:34 +08:00
uint8_t uid [ 5 ] = { 0x00 } ;
2015-11-10 04:49:02 +08:00
/* clock is 64 in EM410x tags */
uint8_t clock = 64 ;
2015-01-05 22:51:27 +08:00
if ( param_gethex ( Cmd , 0 , uid , 10 ) ) {
PrintAndLog ( " UID must include 10 HEX symbols " ) ;
return 0 ;
}
2017-02-08 05:26:06 +08:00
2015-11-10 04:49:02 +08:00
param_getdec ( Cmd , 1 , & clock ) ;
2015-01-05 22:51:27 +08:00
2015-11-10 04:49:02 +08:00
PrintAndLog ( " Starting simulating UID %02X%02X%02X%02X%02X clock: %d " , uid [ 0 ] , uid [ 1 ] , uid [ 2 ] , uid [ 3 ] , uid [ 4 ] , clock ) ;
2017-07-30 15:17:48 +08:00
PrintAndLog ( " Press pm3-button to abort simulation " ) ;
2015-04-03 00:48:52 +08:00
2017-07-30 15:17:48 +08:00
ConstructEM410xEmulGraph ( Cmd , clock ) ;
CmdLFSim ( " 0 " ) ; //240 start_gap.
return 0 ;
}
2016-10-20 06:41:34 +08:00
2017-07-30 15:17:48 +08:00
int CmdEM410xBrute ( const char * Cmd ) {
char filename [ FILE_PATH_SIZE ] = { 0 } ;
FILE * f = NULL ;
char buf [ 11 ] ;
uint32_t uidcnt = 0 ;
uint8_t stUidBlock = 20 ;
uint8_t * uidBlock = NULL , * p = NULL ;
uint8_t uid [ 5 ] = { 0x00 } ;
/* clock is 64 in EM410x tags */
uint8_t clock = 64 ;
/* default pause time: 1 second */
uint32_t delay = 1000 ;
char cmdp = param_getchar ( Cmd , 0 ) ;
if ( cmdp = = ' h ' | | cmdp = = ' H ' ) return usage_lf_em410x_brute ( ) ;
cmdp = param_getchar ( Cmd , 1 ) ;
if ( cmdp = = ' d ' | | cmdp = = ' D ' ) {
delay = param_get32ex ( Cmd , 2 , 1000 , 10 ) ;
param_getdec ( Cmd , 4 , & clock ) ;
} else if ( cmdp = = ' c ' | | cmdp = = ' C ' ) {
param_getdec ( Cmd , 2 , & clock ) ;
delay = param_get32ex ( Cmd , 4 , 1000 , 10 ) ;
}
2016-10-20 06:41:34 +08:00
2017-07-30 15:17:48 +08:00
param_getstr ( Cmd , 0 , filename ) ;
if ( strlen ( filename ) = = 0 ) {
PrintAndLog ( " Error: Please specify a filename " ) ;
return 1 ;
}
if ( ( f = fopen ( filename , " r " ) ) = = NULL ) {
PrintAndLog ( " Error: Could not open UIDs file [%s] " , filename ) ;
return 1 ;
}
2016-10-20 06:41:34 +08:00
2017-07-30 15:17:48 +08:00
uidBlock = calloc ( stUidBlock , 5 ) ;
if ( uidBlock = = NULL ) return 1 ;
while ( fgets ( buf , sizeof ( buf ) , f ) ) {
if ( strlen ( buf ) < 10 | | buf [ 9 ] = = ' \n ' ) continue ;
while ( fgetc ( f ) ! = ' \n ' & & ! feof ( f ) ) ; //goto next line
2016-10-20 06:41:34 +08:00
2017-07-30 15:17:48 +08:00
//The line start with # is comment, skip
if ( buf [ 0 ] = = ' # ' ) continue ;
if ( param_gethex ( buf , 0 , uid , 10 ) ) {
PrintAndLog ( " UIDs must include 10 HEX symbols " ) ;
free ( uidBlock ) ;
fclose ( f ) ;
return 1 ;
}
buf [ 10 ] = 0 ;
if ( stUidBlock - uidcnt < 2 ) {
p = realloc ( uidBlock , 5 * ( stUidBlock + = 10 ) ) ;
if ( ! p ) {
PrintAndLog ( " Cannot allocate memory for UIDs " ) ;
free ( uidBlock ) ;
fclose ( f ) ;
return 1 ;
}
uidBlock = p ;
}
memset ( uidBlock + 5 * uidcnt , 0 , 5 ) ;
num_to_bytes ( strtoll ( buf , NULL , 16 ) , 5 , uidBlock + 5 * uidcnt ) ;
uidcnt + + ;
memset ( buf , 0 , sizeof ( buf ) ) ;
2016-10-20 06:41:34 +08:00
}
2017-07-30 15:17:48 +08:00
fclose ( f ) ;
if ( uidcnt = = 0 ) {
PrintAndLog ( " No UIDs found in file " ) ;
free ( uidBlock ) ;
return 1 ;
}
PrintAndLog ( " Loaded %d UIDs from %s, pause delay: %d ms " , uidcnt , filename , delay ) ;
// loop
for ( uint32_t c = 0 ; c < uidcnt ; + + c ) {
char testuid [ 11 ] ;
testuid [ 10 ] = 0 ;
if ( ukbhit ( ) ) {
int gc = getchar ( ) ; ( void ) gc ;
printf ( " \n Aborted via keyboard! \n " ) ;
free ( uidBlock ) ;
return 0 ;
}
sprintf ( testuid , " %010 " PRIX64 , bytes_to_num ( uidBlock + 5 * c , 5 ) ) ;
PrintAndLog ( " Bruteforce %d / %d: simulating UID %s, clock %d " , c + 1 , uidcnt , testuid , clock ) ;
ConstructEM410xEmulGraph ( testuid , clock ) ;
CmdLFSim ( " 0 " ) ; //240 start_gap.
2015-04-03 00:48:52 +08:00
2017-07-30 15:17:48 +08:00
msleep ( delay ) ;
}
free ( uidBlock ) ;
2015-04-03 00:48:52 +08:00
return 0 ;
Client cleanup and restructuring. Stage 1...
Next Step is refactoring some of the giant functions which are
just copy/paste of some other ones with just a few line changes,
removing unnecessary 'goto' etc.
The MS Windows version is broken with this commit but will be fixed
soon. Everything can't be done all at once :P
The commands are now hierarchical, for example:
"hf 14a read" vs. "hf 14b read".
You can also request help:
"hf help", "data help", "hf 15 help" etc.
Indents are now space-based, not tab-based anymore. Hopefully
no one will be trolling about it, considering the suicide-prone work
being done here ;)
client/cmdhw.c, client/proxusb.c, client/cmdhw.h, client/proxusb.h,
client/cmdmain.c, client/cmdlfhid.c, client/cmdmain.h, client/cmdlfhid.h,
client/data.c, client/data.h, client/cmdhf.c, client/cmdlf.c,
client/cmdhf.h, client/cmdhf15.c, client/cmdhf14b.c, client/cmdlf.h,
client/cmdhf15.h, client/cmdhf14b.h, client/cmddata.c, client/cmddata.h,
client/ui.c, client/cmdparser.c, client/cmdlfti.c, client/ui.h,
client/cmdlfem4x.c, client/cmdparser.h, client/cmdlfti.h, client/cmdlfem4x.h,
client/graph.c, client/graph.h, client/cmdhf14a.c, client/cmdhf14a.h,
client/cmdhflegic.c, client/cmdhflegic.c: New files.
client/cli.c, client/flasher.c, client/snooper.c, client/proxmark3.c,
client/proxmark3.h, client/Makefile: Update accordingly.
client/flash.h, client/flash.c, client/proxgui.cpp: Cosmetic changes.
client/translate.h, client/command.c, client/gui.c,
client/usb.c, client/prox.h: Remove.
include/usb_cmd.h (CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443_SIM): Remove dead cmd.
common/crc16.h: New file.
common/crc16.c: Modify accordingly.
common/iso14443crc.h: New file.
common/iso14443_crc.c: Rename to
common/iso14443crc.c: and modify accordingly.
armsrc/lfops.c, armsrc/iso14443.c,
armsrc/iso14443a.c: include .h files from
the common directory instead of including the c files.
common/Makefile.common, armsrc/Makefile: Modify accordingly.
2010-02-04 09:27:07 +08:00
}
2015-01-05 22:51:27 +08:00
/* Function is equivalent of lf read + data samples + em410xread
* looped until an EM410x tag is detected
*
* Why is CmdSamples ( " 16000 " ) ?
* TBD : Auto - grow sample size based on detected sample rate . IE : If the
* rate gets lower , then grow the number of samples
* Changed by martin , 4000 x 4 = 16000 ,
* see http : //www.proxmark.org/forum/viewtopic.php?pid=7235#p7235
2017-07-14 22:20:34 +08:00
*
* EDIT - - capture enough to get 2 complete preambles at the slowest data rate known to be used ( rf / 64 ) ( 64 * 64 * 2 + 9 = 8201 ) marshmellow
2015-01-05 22:51:27 +08:00
*/
2017-02-27 04:32:51 +08:00
int CmdEM410xWatch ( const char * Cmd ) {
2015-01-05 22:51:27 +08:00
do {
if ( ukbhit ( ) ) {
2017-07-30 15:17:48 +08:00
int gc = getchar ( ) ; ( void ) gc ;
2015-01-05 22:51:27 +08:00
printf ( " \n aborted via keyboard! \n " ) ;
break ;
2017-02-27 04:32:51 +08:00
}
2017-07-30 15:17:48 +08:00
lf_read ( true , 8201 ) ;
2015-03-23 03:28:48 +08:00
} while ( ! CmdEM410xRead ( " " ) ) ;
2015-01-05 22:51:27 +08:00
return 0 ;
Client cleanup and restructuring. Stage 1...
Next Step is refactoring some of the giant functions which are
just copy/paste of some other ones with just a few line changes,
removing unnecessary 'goto' etc.
The MS Windows version is broken with this commit but will be fixed
soon. Everything can't be done all at once :P
The commands are now hierarchical, for example:
"hf 14a read" vs. "hf 14b read".
You can also request help:
"hf help", "data help", "hf 15 help" etc.
Indents are now space-based, not tab-based anymore. Hopefully
no one will be trolling about it, considering the suicide-prone work
being done here ;)
client/cmdhw.c, client/proxusb.c, client/cmdhw.h, client/proxusb.h,
client/cmdmain.c, client/cmdlfhid.c, client/cmdmain.h, client/cmdlfhid.h,
client/data.c, client/data.h, client/cmdhf.c, client/cmdlf.c,
client/cmdhf.h, client/cmdhf15.c, client/cmdhf14b.c, client/cmdlf.h,
client/cmdhf15.h, client/cmdhf14b.h, client/cmddata.c, client/cmddata.h,
client/ui.c, client/cmdparser.c, client/cmdlfti.c, client/ui.h,
client/cmdlfem4x.c, client/cmdparser.h, client/cmdlfti.h, client/cmdlfem4x.h,
client/graph.c, client/graph.h, client/cmdhf14a.c, client/cmdhf14a.h,
client/cmdhflegic.c, client/cmdhflegic.c: New files.
client/cli.c, client/flasher.c, client/snooper.c, client/proxmark3.c,
client/proxmark3.h, client/Makefile: Update accordingly.
client/flash.h, client/flash.c, client/proxgui.cpp: Cosmetic changes.
client/translate.h, client/command.c, client/gui.c,
client/usb.c, client/prox.h: Remove.
include/usb_cmd.h (CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443_SIM): Remove dead cmd.
common/crc16.h: New file.
common/crc16.c: Modify accordingly.
common/iso14443crc.h: New file.
common/iso14443_crc.c: Rename to
common/iso14443crc.c: and modify accordingly.
armsrc/lfops.c, armsrc/iso14443.c,
armsrc/iso14443a.c: include .h files from
the common directory instead of including the c files.
common/Makefile.common, armsrc/Makefile: Modify accordingly.
2010-02-04 09:27:07 +08:00
}
2015-04-03 00:48:52 +08:00
//currently only supports manchester modulations
2017-07-30 15:17:48 +08:00
int CmdEM410xWatchnSpoof ( const char * Cmd ) {
char cmdp = param_getchar ( Cmd , 0 ) ;
if ( cmdp = = ' h ' | | cmdp = = ' H ' ) return usage_lf_em410x_ws ( ) ;
2016-10-20 07:50:30 +08:00
// loops if the captured ID was in XL-format.
2016-10-20 23:31:23 +08:00
CmdEM410xWatch ( Cmd ) ;
2017-07-30 15:17:48 +08:00
PrintAndLog ( " # Replaying captured ID: %010 " PRIx64 , g_em410xid ) ;
2016-10-20 23:31:23 +08:00
CmdLFaskSim ( " " ) ;
2015-03-24 04:29:50 +08:00
return 0 ;
2015-01-08 07:17:40 +08:00
}
2017-07-30 15:17:48 +08:00
int CmdEM410xWrite ( const char * Cmd ) {
char cmdp = param_getchar ( Cmd , 0 ) ;
if ( cmdp = = ' h ' | | cmdp = = ' H ' ) return usage_lf_em410x_write ( ) ;
2015-04-03 11:55:12 +08:00
uint64_t id = 0xFFFFFFFFFFFFFFFF ; // invalid id value
int card = 0xFF ; // invalid card value
2015-12-02 23:48:25 +08:00
uint32_t clock = 0 ; // invalid clock value
2013-05-12 16:11:00 +08:00
2017-07-30 15:17:48 +08:00
sscanf ( Cmd , " % " SCNx64 " %d %d " , & id , & card , & clock ) ;
2013-05-12 16:11:00 +08:00
// Check ID
if ( id = = 0xFFFFFFFFFFFFFFFF ) {
PrintAndLog ( " Error! ID is required. \n " ) ;
return 0 ;
}
if ( id > = 0x10000000000 ) {
PrintAndLog ( " Error! Given EM410x ID is longer than 40 bits. \n " ) ;
return 0 ;
}
// Check Card
if ( card = = 0xFF ) {
PrintAndLog ( " Error! Card type required. \n " ) ;
return 0 ;
}
if ( card < 0 ) {
PrintAndLog ( " Error! Bad card type selected. \n " ) ;
return 0 ;
}
// Check Clock
2015-12-02 23:48:25 +08:00
if ( clock = = 0 )
clock = 64 ;
2013-05-12 16:11:00 +08:00
2015-11-10 04:49:02 +08:00
// 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 ) ;
2013-05-12 16:11:00 +08:00
return 0 ;
}
if ( card = = 1 ) {
PrintAndLog ( " Writing %s tag with UID 0x%010 " PRIx64 " (clock rate: %d) " , " T55x7 " , id , clock ) ;
// NOTE: We really should pass the clock in as a separate argument, but to
// 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
2015-11-10 04:49:02 +08:00
card = ( card & 0xFF ) | ( ( clock < < 8 ) & 0xFF00 ) ;
} else if ( card = = 0 ) {
2013-05-12 16:11:00 +08:00
PrintAndLog ( " Writing %s tag with UID 0x%010 " PRIx64 , " T5555 " , id , clock ) ;
2015-11-10 04:49:02 +08:00
card = ( card & 0xFF ) | ( ( clock < < 8 ) & 0xFF00 ) ;
} else {
2013-05-12 16:11:00 +08:00
PrintAndLog ( " Error! Bad card type selected. \n " ) ;
return 0 ;
}
2012-03-07 21:44:53 +08:00
2015-04-03 11:55:12 +08:00
UsbCommand c = { CMD_EM410X_WRITE_TAG , { card , ( uint32_t ) ( id > > 32 ) , ( uint32_t ) id } } ;
SendCommand ( & c ) ;
return 0 ;
}
2012-03-07 21:44:53 +08:00
2017-07-30 15:17:48 +08:00
//**************** Start of EM4x50 Code ************************
bool EM_EndParityTest ( uint8_t * BitStream , size_t size , uint8_t rows , uint8_t cols , uint8_t pType ) {
2017-07-27 15:28:43 +08:00
if ( rows * cols > size ) return false ;
2015-04-03 00:48:52 +08:00
uint8_t colP = 0 ;
2015-04-07 11:17:30 +08:00
//assume last col is a parity and do not test
2015-04-03 00:48:52 +08:00
for ( uint8_t colNum = 0 ; colNum < cols - 1 ; colNum + + ) {
for ( uint8_t rowNum = 0 ; rowNum < rows ; rowNum + + ) {
colP ^ = BitStream [ ( rowNum * cols ) + colNum ] ;
}
2017-07-14 22:20:34 +08:00
if ( colP ! = pType ) return false ;
2015-04-03 00:48:52 +08:00
}
2017-07-14 22:20:34 +08:00
return true ;
2015-04-03 00:48:52 +08:00
}
2017-07-30 15:17:48 +08:00
bool EM_ByteParityTest ( uint8_t * BitStream , size_t size , uint8_t rows , uint8_t cols , uint8_t pType ) {
2017-07-27 15:28:43 +08:00
if ( rows * cols > size ) return false ;
2015-04-03 00:48:52 +08:00
uint8_t rowP = 0 ;
//assume last row is a parity row and do not test
for ( uint8_t rowNum = 0 ; rowNum < rows - 1 ; rowNum + + ) {
for ( uint8_t colNum = 0 ; colNum < cols ; colNum + + ) {
rowP ^ = BitStream [ ( rowNum * cols ) + colNum ] ;
}
2017-07-14 22:20:34 +08:00
if ( rowP ! = pType ) return false ;
2017-02-20 06:24:19 +08:00
}
2017-07-14 22:20:34 +08:00
return true ;
2017-02-20 06:24:19 +08:00
}
// EM word parity test.
// 9*5 = 45 bits in total
// 012345678|r1
// 012345678|r2
// 012345678|r3
// 012345678|r4
// ------------
//c012345678| 0
// |- must be zero
bool EMwordparitytest ( uint8_t * bits ) {
// last row/col parity must be 0
2017-07-14 22:20:34 +08:00
if ( bits [ 44 ] ! = 0 ) return false ;
2017-02-20 06:24:19 +08:00
// col parity check
uint8_t c1 = bytebits_to_byte ( bits , 8 ) ^ bytebits_to_byte ( bits + 9 , 8 ) ^ bytebits_to_byte ( bits + 18 , 8 ) ^ bytebits_to_byte ( bits + 27 , 8 ) ;
uint8_t c2 = bytebits_to_byte ( bits + 36 , 8 ) ;
2017-07-14 22:20:34 +08:00
if ( c1 ! = c2 ) return false ;
2017-02-20 06:24:19 +08:00
// row parity check
uint8_t rowP = 0 ;
for ( uint8_t i = 0 ; i < 36 ; + + i ) {
rowP ^ = bits [ i ] ;
if ( i > 0 & & ( i % 9 ) = = 0 ) {
if ( rowP ! = EVEN )
2017-07-14 22:20:34 +08:00
return false ;
2017-02-20 06:24:19 +08:00
rowP = 0 ;
}
2015-04-03 00:48:52 +08:00
}
2017-02-20 06:24:19 +08:00
// all checks ok.
2017-07-14 22:20:34 +08:00
return true ;
2015-04-03 00:48:52 +08:00
}
2017-02-19 07:12:35 +08:00
//////////////// 4050 / 4450 commands
2017-07-30 15:17:48 +08:00
uint32_t OutputEM4x50_Block ( uint8_t * BitStream , size_t size , bool verbose , bool pTest ) {
2015-04-03 00:48:52 +08:00
if ( size < 45 ) return 0 ;
2017-02-08 05:26:06 +08:00
2015-04-03 00:48:52 +08:00
uint32_t code = bytebits_to_byte ( BitStream , 8 ) ;
code = code < < 8 | bytebits_to_byte ( BitStream + 9 , 8 ) ;
code = code < < 8 | bytebits_to_byte ( BitStream + 18 , 8 ) ;
code = code < < 8 | bytebits_to_byte ( BitStream + 27 , 8 ) ;
2017-02-08 05:26:06 +08:00
2015-04-03 00:48:52 +08:00
if ( verbose | | g_debugMode ) {
for ( uint8_t i = 0 ; i < 5 ; i + + ) {
2015-04-07 11:17:30 +08:00
if ( i = = 4 ) PrintAndLog ( " " ) ; //parity byte spacer
2015-04-03 00:48:52 +08:00
PrintAndLog ( " %d%d%d%d%d%d%d%d %d -> 0x%02x " ,
BitStream [ i * 9 ] ,
BitStream [ i * 9 + 1 ] ,
BitStream [ i * 9 + 2 ] ,
BitStream [ i * 9 + 3 ] ,
BitStream [ i * 9 + 4 ] ,
BitStream [ i * 9 + 5 ] ,
BitStream [ i * 9 + 6 ] ,
BitStream [ i * 9 + 7 ] ,
BitStream [ i * 9 + 8 ] ,
bytebits_to_byte ( BitStream + i * 9 , 8 )
) ;
}
if ( pTest )
PrintAndLog ( " Parity Passed " ) ;
else
PrintAndLog ( " Parity Failed " ) ;
}
return code ;
}
2017-02-19 07:12:35 +08:00
2017-02-13 17:58:28 +08:00
/* Read the transmitted data of an EM4x50 tag from the graphbuffer
Client cleanup and restructuring. Stage 1...
Next Step is refactoring some of the giant functions which are
just copy/paste of some other ones with just a few line changes,
removing unnecessary 'goto' etc.
The MS Windows version is broken with this commit but will be fixed
soon. Everything can't be done all at once :P
The commands are now hierarchical, for example:
"hf 14a read" vs. "hf 14b read".
You can also request help:
"hf help", "data help", "hf 15 help" etc.
Indents are now space-based, not tab-based anymore. Hopefully
no one will be trolling about it, considering the suicide-prone work
being done here ;)
client/cmdhw.c, client/proxusb.c, client/cmdhw.h, client/proxusb.h,
client/cmdmain.c, client/cmdlfhid.c, client/cmdmain.h, client/cmdlfhid.h,
client/data.c, client/data.h, client/cmdhf.c, client/cmdlf.c,
client/cmdhf.h, client/cmdhf15.c, client/cmdhf14b.c, client/cmdlf.h,
client/cmdhf15.h, client/cmdhf14b.h, client/cmddata.c, client/cmddata.h,
client/ui.c, client/cmdparser.c, client/cmdlfti.c, client/ui.h,
client/cmdlfem4x.c, client/cmdparser.h, client/cmdlfti.h, client/cmdlfem4x.h,
client/graph.c, client/graph.h, client/cmdhf14a.c, client/cmdhf14a.h,
client/cmdhflegic.c, client/cmdhflegic.c: New files.
client/cli.c, client/flasher.c, client/snooper.c, client/proxmark3.c,
client/proxmark3.h, client/Makefile: Update accordingly.
client/flash.h, client/flash.c, client/proxgui.cpp: Cosmetic changes.
client/translate.h, client/command.c, client/gui.c,
client/usb.c, client/prox.h: Remove.
include/usb_cmd.h (CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443_SIM): Remove dead cmd.
common/crc16.h: New file.
common/crc16.c: Modify accordingly.
common/iso14443crc.h: New file.
common/iso14443_crc.c: Rename to
common/iso14443crc.c: and modify accordingly.
armsrc/lfops.c, armsrc/iso14443.c,
armsrc/iso14443a.c: include .h files from
the common directory instead of including the c files.
common/Makefile.common, armsrc/Makefile: Modify accordingly.
2010-02-04 09:27:07 +08:00
* Format :
*
* XXXXXXXX [ row parity bit ( even ) ] < - 8 bits plus parity
* XXXXXXXX [ row parity bit ( even ) ] < - 8 bits plus parity
* XXXXXXXX [ row parity bit ( even ) ] < - 8 bits plus parity
* XXXXXXXX [ row parity bit ( even ) ] < - 8 bits plus parity
* CCCCCCCC < - column parity bits
* 0 < - stop bit
* LW < - Listen Window
*
* This pattern repeats for every block of data being transmitted .
* Transmission starts with two Listen Windows ( LW - a modulated
* pattern of 320 cycles each ( 32 / 32 / 128 / 64 / 64 ) ) .
*
* Note that this data may or may not be the UID . It is whatever data
* is stored in the blocks defined in the control word First and Last
* Word Read values . UID is stored in block 32.
*/
2015-04-07 11:17:30 +08:00
//completed by Marshmellow
2017-02-19 07:12:35 +08:00
int EM4x50Read ( const char * Cmd , bool verbose ) {
2015-04-07 11:17:30 +08:00
uint8_t fndClk [ ] = { 8 , 16 , 32 , 40 , 50 , 64 , 128 } ;
2015-04-03 00:48:52 +08:00
int clk = 0 ;
int invert = 0 ;
int tol = 0 ;
int i , j , startblock , skip , block , start , end , low , high , minClk ;
2015-04-07 11:17:30 +08:00
bool complete = false ;
2015-04-03 00:48:52 +08:00
int tmpbuff [ MAX_GRAPH_TRACE_LEN / 64 ] ;
uint32_t Code [ 6 ] ;
char tmp [ 6 ] ;
char tmp2 [ 20 ] ;
2015-04-07 12:53:06 +08:00
int phaseoff ;
2015-04-07 11:17:30 +08:00
high = low = 0 ;
2017-09-26 23:02:18 +08:00
memset ( tmpbuff , 0 , sizeof ( tmpbuff ) ) ;
2015-04-07 11:17:30 +08:00
// get user entry if any
sscanf ( Cmd , " %i %i " , & clk , & invert ) ;
2015-04-03 00:48:52 +08:00
// first get high and low values
2015-04-07 11:17:30 +08:00
for ( i = 0 ; i < GraphTraceLen ; i + + ) {
2015-04-03 00:48:52 +08:00
if ( GraphBuffer [ i ] > high )
high = GraphBuffer [ i ] ;
else if ( GraphBuffer [ i ] < low )
low = GraphBuffer [ i ] ;
}
2015-04-07 11:17:30 +08:00
i = 0 ;
j = 0 ;
minClk = 255 ;
// get to first full low to prime loop and skip incomplete first pulse
while ( ( GraphBuffer [ i ] < high ) & & ( i < GraphTraceLen ) )
+ + i ;
while ( ( GraphBuffer [ i ] > low ) & & ( i < GraphTraceLen ) )
+ + i ;
skip = i ;
// populate tmpbuff buffer with pulse lengths
while ( i < GraphTraceLen ) {
2015-04-03 00:48:52 +08:00
// measure from low to low
2015-04-07 11:17:30 +08:00
while ( ( GraphBuffer [ i ] > low ) & & ( i < GraphTraceLen ) )
2015-04-03 00:48:52 +08:00
+ + i ;
start = i ;
2015-04-07 11:17:30 +08:00
while ( ( GraphBuffer [ i ] < high ) & & ( i < GraphTraceLen ) )
2015-04-03 00:48:52 +08:00
+ + i ;
2015-04-07 11:17:30 +08:00
while ( ( GraphBuffer [ i ] > low ) & & ( i < GraphTraceLen ) )
2015-04-03 00:48:52 +08:00
+ + i ;
if ( j > = ( MAX_GRAPH_TRACE_LEN / 64 ) ) {
break ;
}
tmpbuff [ j + + ] = i - start ;
2015-04-07 11:17:30 +08:00
if ( i - start < minClk & & i < GraphTraceLen ) {
minClk = i - start ;
}
2015-04-03 00:48:52 +08:00
}
// set clock
2015-04-07 11:17:30 +08:00
if ( ! clk ) {
2015-04-03 00:48:52 +08:00
for ( uint8_t clkCnt = 0 ; clkCnt < 7 ; clkCnt + + ) {
tol = fndClk [ clkCnt ] / 8 ;
2015-04-07 11:17:30 +08:00
if ( minClk > = fndClk [ clkCnt ] - tol & & minClk < = fndClk [ clkCnt ] + 1 ) {
2015-04-03 00:48:52 +08:00
clk = fndClk [ clkCnt ] ;
break ;
}
}
2017-02-08 05:26:06 +08:00
if ( ! clk ) {
2017-02-28 23:55:16 +08:00
if ( verbose | | g_debugMode ) PrintAndLog ( " ERROR: EM4x50 - didn't find a clock " ) ;
2017-02-08 05:26:06 +08:00
return 0 ;
}
2015-04-03 11:55:12 +08:00
} else tol = clk / 8 ;
2015-04-03 00:48:52 +08:00
// look for data start - should be 2 pairs of LW (pulses of clk*3,clk*2)
2015-04-07 11:17:30 +08:00
start = - 1 ;
for ( i = 0 ; i < j - 4 ; + + i ) {
2015-04-03 00:48:52 +08:00
skip + = tmpbuff [ i ] ;
2015-04-07 11:17:30 +08:00
if ( tmpbuff [ i ] > = clk * 3 - tol & & tmpbuff [ i ] < = clk * 3 + tol ) //3 clocks
if ( tmpbuff [ i + 1 ] > = clk * 2 - tol & & tmpbuff [ i + 1 ] < = clk * 2 + tol ) //2 clocks
if ( tmpbuff [ i + 2 ] > = clk * 3 - tol & & tmpbuff [ i + 2 ] < = clk * 3 + tol ) //3 clocks
if ( tmpbuff [ i + 3 ] > = clk - tol ) //1.5 to 2 clocks - depends on bit following
2015-04-03 00:48:52 +08:00
{
start = i + 4 ;
break ;
}
}
2015-04-07 11:17:30 +08:00
startblock = i + 4 ;
2015-04-03 00:48:52 +08:00
// skip over the remainder of LW
2015-04-07 12:53:06 +08:00
skip + = tmpbuff [ i + 1 ] + tmpbuff [ i + 2 ] + clk ;
if ( tmpbuff [ i + 3 ] > clk )
phaseoff = tmpbuff [ i + 3 ] - clk ;
else
phaseoff = 0 ;
2015-04-03 00:48:52 +08:00
// now do it again to find the end
end = skip ;
2015-04-07 11:17:30 +08:00
for ( i + = 3 ; i < j - 4 ; + + i ) {
2015-04-03 00:48:52 +08:00
end + = tmpbuff [ i ] ;
2015-04-07 11:17:30 +08:00
if ( tmpbuff [ i ] > = clk * 3 - tol & & tmpbuff [ i ] < = clk * 3 + tol ) //3 clocks
if ( tmpbuff [ i + 1 ] > = clk * 2 - tol & & tmpbuff [ i + 1 ] < = clk * 2 + tol ) //2 clocks
if ( tmpbuff [ i + 2 ] > = clk * 3 - tol & & tmpbuff [ i + 2 ] < = clk * 3 + tol ) //3 clocks
if ( tmpbuff [ i + 3 ] > = clk - tol ) //1.5 to 2 clocks - depends on bit following
2015-04-03 00:48:52 +08:00
{
complete = true ;
break ;
}
}
end = i ;
// report back
if ( verbose | | g_debugMode ) {
if ( start > = 0 ) {
2015-04-07 11:17:30 +08:00
PrintAndLog ( " \n Note: one block = 50 bits (32 data, 12 parity, 6 marker) " ) ;
2015-04-03 00:48:52 +08:00
} else {
2015-04-07 11:17:30 +08:00
PrintAndLog ( " No data found!, clock tried:%d " , clk ) ;
2015-04-03 00:48:52 +08:00
PrintAndLog ( " Try again with more samples. " ) ;
2015-04-07 11:17:30 +08:00
PrintAndLog ( " or after a 'data askedge' command to clean up the read " ) ;
2015-04-03 00:48:52 +08:00
return 0 ;
}
} else if ( start < 0 ) return 0 ;
2015-04-07 11:17:30 +08:00
start = skip ;
2015-04-03 00:48:52 +08:00
snprintf ( tmp2 , sizeof ( tmp2 ) , " %d %d 1000 %d " , clk , invert , clk * 47 ) ;
2017-07-30 15:17:48 +08:00
// save GraphBuffer - to restore it later
save_restoreGB ( GRAPH_SAVE ) ;
2015-04-03 00:48:52 +08:00
// get rid of leading crap
2015-04-07 11:17:30 +08:00
snprintf ( tmp , sizeof ( tmp ) , " %i " , skip ) ;
2015-04-03 00:48:52 +08:00
CmdLtrim ( tmp ) ;
bool pTest ;
2015-04-07 11:17:30 +08:00
bool AllPTest = true ;
2015-04-03 00:48:52 +08:00
// now work through remaining buffer printing out data blocks
block = 0 ;
i = startblock ;
2015-04-07 11:17:30 +08:00
while ( block < 6 ) {
2015-04-03 00:48:52 +08:00
if ( verbose | | g_debugMode ) PrintAndLog ( " \n Block %i: " , block ) ;
skip = phaseoff ;
// look for LW before start of next block
2015-04-07 11:17:30 +08:00
for ( ; i < j - 4 ; + + i ) {
2015-04-03 00:48:52 +08:00
skip + = tmpbuff [ i ] ;
if ( tmpbuff [ i ] > = clk * 3 - tol & & tmpbuff [ i ] < = clk * 3 + tol )
if ( tmpbuff [ i + 1 ] > = clk - tol )
break ;
}
2015-04-07 12:53:06 +08:00
if ( i > = j - 4 ) break ; //next LW not found
2015-04-03 00:48:52 +08:00
skip + = clk ;
2015-04-07 12:53:06 +08:00
if ( tmpbuff [ i + 1 ] > clk )
phaseoff = tmpbuff [ i + 1 ] - clk ;
else
phaseoff = 0 ;
2015-04-03 00:48:52 +08:00
i + = 2 ;
2015-04-08 13:07:39 +08:00
if ( ASKDemod ( tmp2 , false , false , 1 ) < 1 ) {
2017-07-30 15:17:48 +08:00
save_restoreGB ( GRAPH_RESTORE ) ;
2015-04-07 11:17:30 +08:00
return 0 ;
}
2015-04-03 00:48:52 +08:00
//set DemodBufferLen to just one block
DemodBufferLen = skip / clk ;
//test parities
pTest = EM_ByteParityTest ( DemodBuffer , DemodBufferLen , 5 , 9 , 0 ) ;
pTest & = EM_EndParityTest ( DemodBuffer , DemodBufferLen , 5 , 9 , 0 ) ;
AllPTest & = pTest ;
//get output
2015-04-07 11:17:30 +08:00
Code [ block ] = OutputEM4x50_Block ( DemodBuffer , DemodBufferLen , verbose , pTest ) ;
if ( g_debugMode ) PrintAndLog ( " \n skipping %d samples, bits:%d " , skip , skip / clk ) ;
2015-04-03 00:48:52 +08:00
//skip to start of next block
snprintf ( tmp , sizeof ( tmp ) , " %i " , skip ) ;
CmdLtrim ( tmp ) ;
block + + ;
2015-04-07 11:17:30 +08:00
if ( i > = end ) break ; //in case chip doesn't output 6 blocks
2015-04-03 00:48:52 +08:00
}
//print full code:
if ( verbose | | g_debugMode | | AllPTest ) {
2015-04-07 12:53:06 +08:00
if ( ! complete ) {
PrintAndLog ( " *** Warning! " ) ;
PrintAndLog ( " Partial data - no end found! " ) ;
PrintAndLog ( " Try again with more samples. " ) ;
}
2015-04-07 11:17:30 +08:00
PrintAndLog ( " Found data at sample: %i - using clock: %i " , start , clk ) ;
end = block ;
for ( block = 0 ; block < end ; block + + ) {
2015-04-03 00:48:52 +08:00
PrintAndLog ( " Block %d: %08x " , block , Code [ block ] ) ;
}
2015-04-07 12:53:06 +08:00
if ( AllPTest ) {
2015-04-03 00:48:52 +08:00
PrintAndLog ( " Parities Passed " ) ;
2015-04-07 12:53:06 +08:00
} else {
2015-04-03 00:48:52 +08:00
PrintAndLog ( " Parities Failed " ) ;
2015-04-07 11:17:30 +08:00
PrintAndLog ( " Try cleaning the read samples with 'data askedge' " ) ;
2015-04-07 12:53:06 +08:00
}
2015-04-03 00:48:52 +08:00
}
//restore GraphBuffer
2017-07-30 15:17:48 +08:00
save_restoreGB ( GRAPH_RESTORE ) ;
2015-04-03 00:48:52 +08:00
return ( int ) AllPTest ;
}
2017-02-08 05:26:06 +08:00
int CmdEM4x50Read ( const char * Cmd ) {
2017-02-19 07:12:35 +08:00
uint8_t ctmp = param_getchar ( Cmd , 0 ) ;
if ( ctmp = = ' H ' | | ctmp = = ' h ' ) return usage_lf_em4x50_read ( ) ;
2015-04-03 00:48:52 +08:00
return EM4x50Read ( Cmd , true ) ;
2012-03-07 21:44:53 +08:00
}
2017-02-19 07:12:35 +08:00
int CmdEM4x50Write ( const char * Cmd ) {
uint8_t ctmp = param_getchar ( Cmd , 0 ) ;
if ( ctmp = = ' H ' | | ctmp = = ' h ' ) return usage_lf_em4x50_write ( ) ;
PrintAndLog ( " no implemented yet " ) ;
2015-04-03 00:48:52 +08:00
return 0 ;
2013-03-01 01:04:23 +08:00
}
2017-02-19 07:12:35 +08:00
int CmdEM4x50Dump ( const char * Cmd ) {
uint8_t ctmp = param_getchar ( Cmd , 0 ) ;
if ( ctmp = = ' H ' | | ctmp = = ' h ' ) return usage_lf_em4x50_dump ( ) ;
PrintAndLog ( " no implemented yet " ) ;
2017-02-17 02:48:50 +08:00
return 0 ;
}
# define EM_PREAMBLE_LEN 6
2017-02-23 07:03:10 +08:00
// download samples from device and copy to Graphbuffer
2017-02-17 02:48:50 +08:00
bool downloadSamplesEM ( ) {
// 8 bit preamble + 32 bit word response (max clock (128) * 40bits = 5120 samples)
uint8_t got [ 6000 ] ;
GetFromBigBuf ( got , sizeof ( got ) , 0 ) ;
if ( ! WaitForResponseTimeout ( CMD_ACK , NULL , 2500 ) ) {
PrintAndLog ( " command execution time out " ) ;
2017-07-14 22:20:34 +08:00
return false ;
2017-02-17 02:48:50 +08:00
}
setGraphBuf ( got , sizeof ( got ) ) ;
2017-07-14 22:20:34 +08:00
return true ;
2017-02-17 02:48:50 +08:00
}
2017-02-23 07:03:10 +08:00
// em_demod
2017-02-17 02:48:50 +08:00
bool doPreambleSearch ( size_t * startIdx ) {
// sanity check
2017-02-17 04:52:14 +08:00
if ( DemodBufferLen < EM_PREAMBLE_LEN ) {
if ( g_debugMode ) PrintAndLog ( " DEBUG: Error - EM4305 demodbuffer too small " ) ;
2017-07-14 22:20:34 +08:00
return false ;
2017-02-17 04:52:14 +08:00
}
2017-02-23 07:03:10 +08:00
// set size to 20 to only test first 14 positions for the preamble
size_t size = ( 20 > DemodBufferLen ) ? DemodBufferLen : 20 ;
2017-02-17 02:48:50 +08:00
* startIdx = 0 ;
2017-02-23 07:03:10 +08:00
// skip first two 0 bits as they might have been missed in the demod
uint8_t preamble [ EM_PREAMBLE_LEN ] = { 0 , 0 , 1 , 0 , 1 , 0 } ;
2017-02-17 02:48:50 +08:00
2017-07-14 22:20:34 +08:00
if ( ! preambleSearchEx ( DemodBuffer , preamble , EM_PREAMBLE_LEN , & size , startIdx , true ) ) {
2017-02-17 02:48:50 +08:00
if ( g_debugMode ) PrintAndLog ( " DEBUG: Error - EM4305 preamble not found :: %d " , * startIdx ) ;
2017-07-14 22:20:34 +08:00
return false ;
2017-02-17 02:48:50 +08:00
}
2017-07-14 22:20:34 +08:00
return true ;
2017-02-15 23:58:29 +08:00
}
2017-02-16 23:38:09 +08:00
bool detectFSK ( ) {
// detect fsk clock
2017-07-14 22:20:34 +08:00
if ( ! GetFskClock ( " " , false , false ) ) {
2017-02-19 07:12:35 +08:00
if ( g_debugMode ) PrintAndLog ( " DEBUG: Error - EM: FSK clock failed " ) ;
2017-07-14 22:20:34 +08:00
return false ;
2017-02-15 23:58:29 +08:00
}
2017-02-16 23:38:09 +08:00
// demod
2017-07-14 22:20:34 +08:00
int ans = FSKrawDemod ( " 0 0 " , false ) ;
2017-02-16 23:38:09 +08:00
if ( ! ans ) {
2017-02-19 07:12:35 +08:00
if ( g_debugMode ) PrintAndLog ( " DEBUG: Error - EM: FSK Demod failed " ) ;
2017-07-14 22:20:34 +08:00
return false ;
2017-02-16 16:53:47 +08:00
}
2017-07-14 22:20:34 +08:00
return true ;
2017-02-16 23:38:09 +08:00
}
// PSK clocks should be easy to detect ( but difficult to demod a non-repeating pattern... )
bool detectPSK ( ) {
2017-07-14 22:20:34 +08:00
int ans = GetPskClock ( " " , false , false ) ;
2017-02-17 04:52:14 +08:00
if ( ans < = 0 ) {
2017-02-19 07:12:35 +08:00
if ( g_debugMode ) PrintAndLog ( " DEBUG: Error - EM: PSK clock failed " ) ;
2017-07-14 22:20:34 +08:00
return false ;
2017-02-16 23:38:09 +08:00
}
2017-02-19 07:12:35 +08:00
//demod
//try psk1 -- 0 0 6 (six errors?!?)
2017-07-14 22:20:34 +08:00
ans = PSKDemod ( " 0 0 6 " , false ) ;
2017-02-19 07:12:35 +08:00
if ( ! ans ) {
if ( g_debugMode ) PrintAndLog ( " DEBUG: Error - EM: PSK1 Demod failed " ) ;
//try psk1 inverted
2017-07-14 22:20:34 +08:00
ans = PSKDemod ( " 0 1 6 " , false ) ;
2017-02-19 07:12:35 +08:00
if ( ! ans ) {
if ( g_debugMode ) PrintAndLog ( " DEBUG: Error - EM: PSK1 inverted Demod failed " ) ;
2017-07-14 22:20:34 +08:00
return false ;
2017-02-19 07:12:35 +08:00
}
}
// either PSK1 or PSK1 inverted is ok from here.
// lets check PSK2 later.
2017-07-14 22:20:34 +08:00
return true ;
2017-02-16 23:38:09 +08:00
}
// try manchester - NOTE: ST only applies to T55x7 tags.
bool detectASK_MAN ( ) {
2017-07-14 22:20:34 +08:00
bool stcheck = false ;
2017-08-06 22:31:01 +08:00
if ( ! ASKDemod_ext ( " 0 0 0 " , false , false , 1 , & stcheck ) ) {
2017-02-19 07:12:35 +08:00
if ( g_debugMode ) PrintAndLog ( " DEBUG: Error - EM: ASK/Manchester Demod failed " ) ;
2017-07-14 22:20:34 +08:00
return false ;
2017-02-16 23:38:09 +08:00
}
2017-07-14 22:20:34 +08:00
return true ;
2017-02-16 23:38:09 +08:00
}
bool detectASK_BI ( ) {
2017-07-14 22:20:34 +08:00
int ans = ASKbiphaseDemod ( " 0 0 1 " , false ) ;
2017-02-16 23:38:09 +08:00
if ( ! ans ) {
2017-02-19 07:12:35 +08:00
if ( g_debugMode ) PrintAndLog ( " DEBUG: Error - EM: ASK/biphase normal demod failed " ) ;
2017-02-16 23:38:09 +08:00
2017-07-14 22:20:34 +08:00
ans = ASKbiphaseDemod ( " 0 1 1 " , false ) ;
2017-02-16 16:53:47 +08:00
if ( ! ans ) {
2017-02-19 07:12:35 +08:00
if ( g_debugMode ) PrintAndLog ( " DEBUG: Error - EM: ASK/biphase inverted demod failed " ) ;
2017-07-14 22:20:34 +08:00
return false ;
2017-02-16 16:53:47 +08:00
}
}
2017-07-14 22:20:34 +08:00
return true ;
2017-02-16 23:38:09 +08:00
}
2017-02-15 23:58:29 +08:00
2017-02-17 02:48:50 +08:00
// param: idx - start index in demoded data.
2017-02-19 07:12:35 +08:00
bool setDemodBufferEM ( uint32_t * word , size_t idx ) {
//test for even parity bits.
2017-02-20 06:24:19 +08:00
uint8_t parity [ 45 ] = { 0 } ;
2017-02-20 06:52:09 +08:00
memcpy ( parity , DemodBuffer , 45 ) ;
2017-02-20 06:24:19 +08:00
if ( ! EMwordparitytest ( parity ) ) {
2017-08-01 02:45:16 +08:00
if ( g_debugMode ) PrintAndLog ( " DEBUG: Error - EM Parity tests failed " ) ;
2017-07-14 22:20:34 +08:00
return false ;
2017-02-20 06:24:19 +08:00
}
2017-02-24 08:14:47 +08:00
// test for even parity bits and remove them. (leave out the end row of parities so 36 bits)
if ( ! removeParity ( DemodBuffer , idx + EM_PREAMBLE_LEN , 9 , 0 , 36 ) ) {
2017-02-23 07:03:10 +08:00
if ( g_debugMode ) PrintAndLog ( " DEBUG: Error - EM, failed removing parity " ) ;
2017-07-14 22:20:34 +08:00
return false ;
2017-02-17 02:48:50 +08:00
}
2017-02-24 08:14:47 +08:00
setDemodBuf ( DemodBuffer , 32 , 0 ) ;
2017-02-19 07:12:35 +08:00
* word = bytebits_to_byteLSBF ( DemodBuffer , 32 ) ;
2017-07-14 22:20:34 +08:00
return true ;
2017-02-16 23:38:09 +08:00
}
2017-02-15 23:58:29 +08:00
2017-02-16 23:38:09 +08:00
// FSK, PSK, ASK/MANCHESTER, ASK/BIPHASE, ASK/DIPHASE
// should cover 90% of known used configs
// the rest will need to be manually demoded for now...
2017-02-19 07:12:35 +08:00
bool demodEM4x05resp ( uint32_t * word ) {
size_t idx = 0 ;
2017-02-27 04:32:51 +08:00
* word = 0 ;
2017-02-19 07:12:35 +08:00
if ( detectASK_MAN ( ) & & doPreambleSearch ( & idx ) )
return setDemodBufferEM ( word , idx ) ;
2017-02-16 23:38:09 +08:00
2017-02-19 07:12:35 +08:00
if ( detectASK_BI ( ) & & doPreambleSearch ( & idx ) )
return setDemodBufferEM ( word , idx ) ;
2017-02-16 23:38:09 +08:00
2017-02-19 07:12:35 +08:00
if ( detectFSK ( ) & & doPreambleSearch ( & idx ) )
return setDemodBufferEM ( word , idx ) ;
2017-02-16 23:38:09 +08:00
2017-02-19 07:12:35 +08:00
if ( detectPSK ( ) ) {
if ( doPreambleSearch ( & idx ) )
return setDemodBufferEM ( word , idx ) ;
psk1TOpsk2 ( DemodBuffer , DemodBufferLen ) ;
if ( doPreambleSearch ( & idx ) )
return setDemodBufferEM ( word , idx ) ;
}
2017-07-14 22:20:34 +08:00
return false ;
2017-02-19 07:12:35 +08:00
}
//////////////// 4205 / 4305 commands
2017-02-27 04:32:51 +08:00
int EM4x05ReadWord_ext ( uint8_t addr , uint32_t pwd , bool usePwd , uint32_t * word ) {
UsbCommand c = { CMD_EM4X_READ_WORD , { addr , pwd , usePwd } } ;
clearCommandBuffer ( ) ;
SendCommand ( & c ) ;
UsbCommand resp ;
if ( ! WaitForResponseTimeout ( CMD_ACK , & resp , 2500 ) ) {
PrintAndLog ( " Command timed out " ) ;
return - 1 ;
}
if ( ! downloadSamplesEM ( ) ) {
return - 1 ;
}
int testLen = ( GraphTraceLen < 1000 ) ? GraphTraceLen : 1000 ;
2017-07-31 03:21:02 +08:00
if ( is_justnoise ( GraphBuffer , testLen ) ) {
2017-02-28 15:16:02 +08:00
PrintAndLog ( " no tag found " ) ;
2017-02-27 04:32:51 +08:00
return - 1 ;
}
return demodEM4x05resp ( word ) ;
}
2017-02-19 07:12:35 +08:00
int CmdEM4x05Dump ( const char * Cmd ) {
uint8_t addr = 0 ;
2017-02-20 06:24:19 +08:00
uint32_t pwd = 0 ;
2017-02-19 07:12:35 +08:00
bool usePwd = false ;
uint8_t ctmp = param_getchar ( Cmd , 0 ) ;
if ( ctmp = = ' H ' | | ctmp = = ' h ' ) return usage_lf_em4x05_dump ( ) ;
// for now use default input of 1 as invalid (unlikely 1 will be a valid password...)
pwd = param_get32ex ( Cmd , 0 , 1 , 16 ) ;
2017-02-16 23:38:09 +08:00
2017-02-19 08:34:45 +08:00
if ( pwd ! = 1 )
2017-02-19 07:12:35 +08:00
usePwd = true ;
2017-02-19 08:34:45 +08:00
2017-02-19 07:12:35 +08:00
int success = 1 ;
2017-02-27 04:32:51 +08:00
uint32_t word = 0 ;
2017-02-20 06:24:19 +08:00
PrintAndLog ( " Addr | data | ascii " ) ;
PrintAndLog ( " -----+--------+------ " ) ;
2017-02-19 07:12:35 +08:00
for ( ; addr < 16 ; addr + + ) {
2017-02-27 04:32:51 +08:00
2017-02-19 07:12:35 +08:00
if ( addr = = 2 ) {
if ( usePwd ) {
2017-02-27 04:32:51 +08:00
PrintAndLog ( " %02u | %08X " , addr , pwd , word ) ;
2017-02-19 07:12:35 +08:00
} else {
2017-02-20 06:24:19 +08:00
PrintAndLog ( " 02 | cannot read " ) ;
2017-02-19 07:12:35 +08:00
}
} else {
2017-02-27 04:32:51 +08:00
success & = EM4x05ReadWord_ext ( addr , pwd , usePwd , & word ) ;
2017-02-19 07:12:35 +08:00
}
}
2017-02-17 04:59:57 +08:00
2017-02-19 07:12:35 +08:00
return success ;
2017-02-15 23:58:29 +08:00
}
2017-02-27 04:32:51 +08:00
2017-02-19 07:12:35 +08:00
int CmdEM4x05Read ( const char * Cmd ) {
2017-02-27 04:32:51 +08:00
uint8_t addr ;
uint32_t pwd ;
2017-02-08 05:26:06 +08:00
bool usePwd = false ;
uint8_t ctmp = param_getchar ( Cmd , 0 ) ;
2017-02-19 07:12:35 +08:00
if ( strlen ( Cmd ) = = 0 | | ctmp = = ' H ' | | ctmp = = ' h ' ) return usage_lf_em4x05_read ( ) ;
2017-02-08 05:26:06 +08:00
2017-02-27 04:32:51 +08:00
addr = param_get8ex ( Cmd , 0 , 50 , 10 ) ;
pwd = param_get32ex ( Cmd , 1 , 1 , 16 ) ;
2015-04-03 00:48:52 +08:00
2017-02-27 04:32:51 +08:00
if ( addr > 15 ) {
2017-02-08 05:26:06 +08:00
PrintAndLog ( " Address must be between 0 and 15 " ) ;
2015-04-03 00:48:52 +08:00
return 1 ;
}
2017-02-27 04:32:51 +08:00
if ( pwd = = 1 ) {
PrintAndLog ( " Reading address %02u " , addr ) ;
2017-07-30 15:17:48 +08:00
} else {
2017-02-08 05:26:06 +08:00
usePwd = true ;
2017-02-27 04:32:51 +08:00
PrintAndLog ( " Reading address %02u | password %08X " , addr , pwd ) ;
2015-04-03 00:48:52 +08:00
}
2017-02-17 02:48:50 +08:00
2017-02-19 07:12:35 +08:00
uint32_t word = 0 ;
2017-02-27 04:32:51 +08:00
int isOk = EM4x05ReadWord_ext ( addr , pwd , usePwd , & word ) ;
2017-02-19 07:12:35 +08:00
if ( isOk )
2017-02-27 04:32:51 +08:00
PrintAndLog ( " Address %02d | %08X - %s " , addr , word , ( addr > 13 ) ? " Lock " : " " ) ;
2017-02-19 07:12:35 +08:00
else
2017-02-27 04:32:51 +08:00
PrintAndLog ( " Read Address %02d | failed " , addr ) ;
2017-02-19 07:12:35 +08:00
return isOk ;
2013-03-01 01:04:23 +08:00
}
2017-02-19 07:12:35 +08:00
int CmdEM4x05Write ( const char * Cmd ) {
2017-02-08 05:26:06 +08:00
uint8_t ctmp = param_getchar ( Cmd , 0 ) ;
2017-02-19 07:12:35 +08:00
if ( strlen ( Cmd ) = = 0 | | ctmp = = ' H ' | | ctmp = = ' h ' ) return usage_lf_em4x05_write ( ) ;
2017-02-08 05:26:06 +08:00
2017-02-17 02:48:50 +08:00
bool usePwd = false ;
2017-02-27 04:32:51 +08:00
uint8_t addr = 50 ; // default to invalid address
uint32_t data = 0 ; // default to blank data
uint32_t pwd = 1 ; // default to blank password
2017-02-08 05:26:06 +08:00
2017-02-27 04:32:51 +08:00
addr = param_get8ex ( Cmd , 0 , 50 , 10 ) ;
data = param_get32ex ( Cmd , 1 , 0 , 16 ) ;
pwd = param_get32ex ( Cmd , 2 , 1 , 16 ) ;
2015-04-03 00:48:52 +08:00
2017-02-27 04:32:51 +08:00
if ( addr > 15 ) {
2017-02-08 05:26:06 +08:00
PrintAndLog ( " Address must be between 0 and 15 " ) ;
2015-04-03 00:48:52 +08:00
return 1 ;
}
2017-02-27 21:04:50 +08:00
if ( pwd = = 1 )
2017-02-08 05:26:06 +08:00
PrintAndLog ( " Writing address %d data %08X " , addr , data ) ;
else {
usePwd = true ;
PrintAndLog ( " Writing address %d data %08X using password %08X " , addr , data , pwd ) ;
}
2015-04-03 00:48:52 +08:00
2017-02-08 05:26:06 +08:00
uint16_t flag = ( addr < < 8 ) | usePwd ;
2015-04-03 00:48:52 +08:00
2017-02-08 05:26:06 +08:00
UsbCommand c = { CMD_EM4X_WRITE_WORD , { flag , data , pwd } } ;
clearCommandBuffer ( ) ;
2015-04-03 00:48:52 +08:00
SendCommand ( & c ) ;
2017-02-08 05:26:06 +08:00
UsbCommand resp ;
2017-02-19 07:12:35 +08:00
if ( ! WaitForResponseTimeout ( CMD_ACK , & resp , 2000 ) ) {
2017-02-08 05:26:06 +08:00
PrintAndLog ( " Error occurred, device did not respond during write operation. " ) ;
return - 1 ;
}
2017-02-13 17:58:28 +08:00
2017-02-17 02:48:50 +08:00
if ( ! downloadSamplesEM ( ) )
return - 1 ;
2017-02-16 16:53:47 +08:00
//need 0 bits demoded (after preamble) to verify write cmd
2017-02-19 07:12:35 +08:00
uint32_t dummy = 0 ;
int isOk = demodEM4x05resp ( & dummy ) ;
if ( isOk )
2017-02-16 16:53:47 +08:00
PrintAndLog ( " Write Verified " ) ;
2017-02-24 08:14:47 +08:00
else
PrintAndLog ( " Write could not be verified " ) ;
2017-02-19 07:12:35 +08:00
return isOk ;
2013-03-01 01:04:23 +08:00
}
2017-02-24 08:14:47 +08:00
void printEM4x05config ( uint32_t wordData ) {
uint16_t datarate = ( ( ( wordData & 0x3F ) + 1 ) * 2 ) ;
uint8_t encoder = ( ( wordData > > 6 ) & 0xF ) ;
char enc [ 14 ] ;
memset ( enc , 0 , sizeof ( enc ) ) ;
uint8_t PSKcf = ( wordData > > 10 ) & 0x3 ;
char cf [ 10 ] ;
memset ( cf , 0 , sizeof ( cf ) ) ;
uint8_t delay = ( wordData > > 12 ) & 0x3 ;
char cdelay [ 33 ] ;
memset ( cdelay , 0 , sizeof ( cdelay ) ) ;
2017-07-30 15:17:48 +08:00
uint8_t numblks = EM4x05_GET_NUM_BLOCKS ( wordData ) ;
uint8_t LWR = numblks + 5 - 1 ; //last word read
2017-02-24 08:14:47 +08:00
switch ( encoder ) {
case 0 : snprintf ( enc , sizeof ( enc ) , " NRZ " ) ; break ;
case 1 : snprintf ( enc , sizeof ( enc ) , " Manchester " ) ; break ;
case 2 : snprintf ( enc , sizeof ( enc ) , " Biphase " ) ; break ;
case 3 : snprintf ( enc , sizeof ( enc ) , " Miller " ) ; break ;
case 4 : snprintf ( enc , sizeof ( enc ) , " PSK1 " ) ; break ;
case 5 : snprintf ( enc , sizeof ( enc ) , " PSK2 " ) ; break ;
case 6 : snprintf ( enc , sizeof ( enc ) , " PSK3 " ) ; break ;
case 7 : snprintf ( enc , sizeof ( enc ) , " Unknown " ) ; break ;
case 8 : snprintf ( enc , sizeof ( enc ) , " FSK1 " ) ; break ;
case 9 : snprintf ( enc , sizeof ( enc ) , " FSK2 " ) ; break ;
default : snprintf ( enc , sizeof ( enc ) , " Unknown " ) ; break ;
}
switch ( PSKcf ) {
case 0 : snprintf ( cf , sizeof ( cf ) , " RF/2 " ) ; break ;
case 1 : snprintf ( cf , sizeof ( cf ) , " RF/8 " ) ; break ;
case 2 : snprintf ( cf , sizeof ( cf ) , " RF/4 " ) ; break ;
case 3 : snprintf ( cf , sizeof ( cf ) , " unknown " ) ; break ;
}
switch ( delay ) {
case 0 : snprintf ( cdelay , sizeof ( cdelay ) , " no delay " ) ; break ;
case 1 : snprintf ( cdelay , sizeof ( cdelay ) , " BP/8 or 1/8th bit period delay " ) ; break ;
case 2 : snprintf ( cdelay , sizeof ( cdelay ) , " BP/4 or 1/4th bit period delay " ) ; break ;
case 3 : snprintf ( cdelay , sizeof ( cdelay ) , " no delay " ) ; break ;
}
2017-07-30 15:17:48 +08:00
uint8_t readLogin = ( wordData & EM4x05_READ_LOGIN_REQ ) > > 18 ;
uint8_t readHKL = ( wordData & EM4x05_READ_HK_LOGIN_REQ ) > > 19 ;
uint8_t writeLogin = ( wordData & EM4x05_WRITE_LOGIN_REQ ) > > 20 ;
uint8_t writeHKL = ( wordData & EM4x05_WRITE_HK_LOGIN_REQ ) > > 21 ;
uint8_t raw = ( wordData & EM4x05_READ_AFTER_WRITE ) > > 22 ;
uint8_t disable = ( wordData & EM4x05_DISABLE_ALLOWED ) > > 23 ;
uint8_t rtf = ( wordData & EM4x05_READER_TALK_FIRST ) > > 24 ;
uint8_t pigeon = ( wordData & ( 1 < < 26 ) ) > > 26 ;
2017-02-24 08:14:47 +08:00
PrintAndLog ( " ConfigWord: %08X (Word 4) \n " , wordData ) ;
2017-07-30 15:17:48 +08:00
PrintAndLog ( " Config Breakdown: " ) ;
2017-02-24 08:14:47 +08:00
PrintAndLog ( " Data Rate: %02u | RF/%u " , wordData & 0x3F , datarate ) ;
PrintAndLog ( " Encoder: %u | %s " , encoder , enc ) ;
PrintAndLog ( " PSK CF: %u | %s " , PSKcf , cf ) ;
PrintAndLog ( " Delay: %u | %s " , delay , cdelay ) ;
2017-07-30 15:17:48 +08:00
PrintAndLog ( " LastWordR: %02u | Address of last word for default read - meaning %u blocks are output " , LWR , numblks ) ;
PrintAndLog ( " ReadLogin: %u | Read Login is %s " , readLogin , readLogin ? " Required " : " Not Required " ) ;
PrintAndLog ( " ReadHKL: %u | Read Housekeeping Words Login is %s " , readHKL , readHKL ? " Required " : " Not Required " ) ;
PrintAndLog ( " WriteLogin: %u | Write Login is %s " , writeLogin , writeLogin ? " Required " : " Not Required " ) ;
PrintAndLog ( " WriteHKL: %u | Write Housekeeping Words Login is %s " , writeHKL , writeHKL ? " Required " : " Not Required " ) ;
PrintAndLog ( " R.A.W.: %u | Read After Write is %s " , raw , raw ? " On " : " Off " ) ;
PrintAndLog ( " Disable: %u | Disable Command is %s " , disable , disable ? " Accepted " : " Not Accepted " ) ;
PrintAndLog ( " R.T.F.: %u | Reader Talk First is %s " , rtf , rtf ? " Enabled " : " Disabled " ) ;
PrintAndLog ( " Pigeon: %u | Pigeon Mode is %s \n " , pigeon , pigeon ? " Enabled " : " Disabled " ) ;
2017-02-24 08:14:47 +08:00
}
2017-02-27 04:32:51 +08:00
void printEM4x05info ( uint32_t block0 , uint32_t serial ) {
uint8_t chipType = ( block0 > > 1 ) & 0xF ;
uint8_t cap = ( block0 > > 5 ) & 3 ;
uint16_t custCode = ( block0 > > 9 ) & 0x3FF ;
2017-02-24 08:14:47 +08:00
switch ( chipType ) {
2017-02-27 04:32:51 +08:00
case 9 : PrintAndLog ( " \n Chip Type: %u | EM4305 " , chipType ) ; break ;
2017-02-28 15:16:02 +08:00
case 8 : PrintAndLog ( " \n Chip Type: %u | EM4205 " , chipType ) ; break ;
2017-02-27 04:32:51 +08:00
case 4 : PrintAndLog ( " Chip Type: %u | Unknown " , chipType ) ; break ;
case 2 : PrintAndLog ( " Chip Type: %u | EM4469 " , chipType ) ; break ;
2017-02-24 08:14:47 +08:00
//add more here when known
default : PrintAndLog ( " Chip Type: %u Unknown " , chipType ) ; break ;
}
switch ( cap ) {
2017-02-27 04:32:51 +08:00
case 3 : PrintAndLog ( " Cap Type: %u | 330pF " , cap ) ; break ;
case 2 : PrintAndLog ( " Cap Type: %u | %spF " , cap , ( chipType = = 2 ) ? " 75 " : " 210 " ) ; break ;
case 1 : PrintAndLog ( " Cap Type: %u | 250pF " , cap ) ; break ;
case 0 : PrintAndLog ( " Cap Type: %u | no resonant capacitor " , cap ) ; break ;
2017-02-24 08:14:47 +08:00
default : PrintAndLog ( " Cap Type: %u | unknown " , cap ) ; break ;
}
PrintAndLog ( " Cust Code: %03u | %s " , custCode , ( custCode = = 0x200 ) ? " Default " : " Unknown " ) ;
2017-02-27 04:32:51 +08:00
if ( serial ! = 0 )
2017-02-24 08:14:47 +08:00
PrintAndLog ( " \n Serial #: %08X \n " , serial ) ;
}
2017-02-27 04:32:51 +08:00
void printEM4x05ProtectionBits ( uint32_t word ) {
2017-02-24 08:14:47 +08:00
for ( uint8_t i = 0 ; i < 15 ; i + + ) {
2017-02-27 04:32:51 +08:00
PrintAndLog ( " Word: %02u | %s " , i , ( ( ( 1 < < i ) & word ) | | i < 2 ) ? " Is Write Locked " : " Is Not Write Locked " ) ;
if ( i = = 14 )
PrintAndLog ( " Word: %02u | %s " , i + 1 , ( ( ( 1 < < i ) & word ) | | i < 2 ) ? " Is Write Locked " : " Is Not Write Locked " ) ;
2017-02-24 08:14:47 +08:00
}
}
//quick test for EM4x05/EM4x69 tag
2017-02-27 04:32:51 +08:00
bool EM4x05IsBlock0 ( uint32_t * word ) {
2017-07-14 22:20:34 +08:00
return EM4x05ReadWord_ext ( 0 , 0 , false , word ) ;
2017-02-24 08:14:47 +08:00
}
int CmdEM4x05Info ( const char * Cmd ) {
2017-02-27 04:32:51 +08:00
# define EM_SERIAL_BLOCK 1
# define EM_CONFIG_BLOCK 4
# define EM_PROT1_BLOCK 14
# define EM_PROT2_BLOCK 15
2017-02-24 08:14:47 +08:00
uint32_t pwd ;
2017-02-27 04:32:51 +08:00
uint32_t word = 0 , block0 = 0 , serial = 0 ;
2017-02-24 08:14:47 +08:00
bool usePwd = false ;
uint8_t ctmp = param_getchar ( Cmd , 0 ) ;
if ( ctmp = = ' H ' | | ctmp = = ' h ' ) return usage_lf_em4x05_info ( ) ;
// for now use default input of 1 as invalid (unlikely 1 will be a valid password...)
pwd = param_get32ex ( Cmd , 0 , 1 , 16 ) ;
if ( pwd ! = 1 )
usePwd = true ;
// read word 0 (chip info)
// block 0 can be read even without a password.
2017-02-27 04:32:51 +08:00
if ( ! EM4x05IsBlock0 ( & block0 ) )
2017-02-24 08:14:47 +08:00
return - 1 ;
// read word 1 (serial #) doesn't need pwd
2017-02-27 04:32:51 +08:00
// continue if failed, .. non blocking fail.
EM4x05ReadWord_ext ( EM_SERIAL_BLOCK , 0 , false , & serial ) ;
printEM4x05info ( block0 , serial ) ;
2017-02-24 08:14:47 +08:00
// read word 4 (config block)
// needs password if one is set
2017-02-27 04:32:51 +08:00
if ( EM4x05ReadWord_ext ( EM_CONFIG_BLOCK , pwd , usePwd , & word ) ! = 1 )
2017-02-24 08:14:47 +08:00
return 0 ;
2017-02-27 04:32:51 +08:00
printEM4x05config ( word ) ;
2017-02-24 08:14:47 +08:00
// read word 14 and 15 to see which is being used for the protection bits
2017-02-27 04:32:51 +08:00
if ( EM4x05ReadWord_ext ( EM_PROT1_BLOCK , pwd , usePwd , & word ) ! = 1 ) {
2017-02-24 08:14:47 +08:00
return 0 ;
}
// if status bit says this is not the used protection word
2017-02-27 04:32:51 +08:00
if ( ! ( word & 0x8000 ) ) {
if ( EM4x05ReadWord_ext ( EM_PROT2_BLOCK , pwd , usePwd , & word ) ! = 1 )
2017-02-24 08:14:47 +08:00
return 0 ;
}
2017-02-27 04:32:51 +08:00
//something went wrong
if ( ! ( word & 0x8000 ) ) return 0 ;
printEM4x05ProtectionBits ( word ) ;
2017-02-24 08:14:47 +08:00
return 1 ;
}
2017-02-08 05:26:06 +08:00
static command_t CommandTable [ ] = {
{ " help " , CmdHelp , 1 , " This help " } ,
2017-07-31 03:21:02 +08:00
//{"410x_demod", CmdEMdemodASK, 0, "Extract ID from EM410x tag on antenna)"},
2017-08-10 00:33:30 +08:00
{ " 410x_demod " , CmdEM410xDemod , 0 , " demodulate a EM410x tag from the GraphBuffer " } ,
{ " 410x_read " , CmdEM410xRead , 1 , " attempt to read and extract tag data " } ,
2017-07-30 15:17:48 +08:00
{ " 410x_sim " , CmdEM410xSim , 0 , " simulate EM410x tag " } ,
2017-08-10 00:33:30 +08:00
{ " 410x_brute " , CmdEM410xBrute , 0 , " reader bruteforce attack by simulating EM410x tags " } ,
{ " 410x_watch " , CmdEM410xWatch , 0 , " watches for EM410x 125/134 kHz tags (option 'h' for 134) " } ,
{ " 410x_spoof " , CmdEM410xWatchnSpoof , 0 , " watches for EM410x 125/134 kHz tags, and replays them. (option 'h' for 134) " } ,
{ " 410x_write " , CmdEM410xWrite , 0 , " write EM410x UID to T5555(Q5) or T55x7 tag " } ,
2017-07-30 15:17:48 +08:00
{ " 4x05_dump " , CmdEM4x05Dump , 0 , " dump EM4x05/EM4x69 tag " } ,
{ " 4x05_info " , CmdEM4x05Info , 0 , " tag information EM4x05/EM4x69 " } ,
{ " 4x05_read " , CmdEM4x05Read , 0 , " read word data from EM4x05/EM4x69 " } ,
{ " 4x05_write " , CmdEM4x05Write , 0 , " write word data to EM4x05/EM4x69 " } ,
2017-08-10 00:33:30 +08:00
{ " 4x50_dump " , CmdEM4x50Dump , 0 , " dump EM4x50 tag " } ,
2017-07-30 15:17:48 +08:00
{ " 4x50_read " , CmdEM4x50Read , 0 , " read word data from EM4x50 " } ,
{ " 4x50_write " , CmdEM4x50Write , 0 , " write word data to EM4x50 " } ,
2015-04-03 00:48:52 +08:00
{ NULL , NULL , 0 , NULL }
Client cleanup and restructuring. Stage 1...
Next Step is refactoring some of the giant functions which are
just copy/paste of some other ones with just a few line changes,
removing unnecessary 'goto' etc.
The MS Windows version is broken with this commit but will be fixed
soon. Everything can't be done all at once :P
The commands are now hierarchical, for example:
"hf 14a read" vs. "hf 14b read".
You can also request help:
"hf help", "data help", "hf 15 help" etc.
Indents are now space-based, not tab-based anymore. Hopefully
no one will be trolling about it, considering the suicide-prone work
being done here ;)
client/cmdhw.c, client/proxusb.c, client/cmdhw.h, client/proxusb.h,
client/cmdmain.c, client/cmdlfhid.c, client/cmdmain.h, client/cmdlfhid.h,
client/data.c, client/data.h, client/cmdhf.c, client/cmdlf.c,
client/cmdhf.h, client/cmdhf15.c, client/cmdhf14b.c, client/cmdlf.h,
client/cmdhf15.h, client/cmdhf14b.h, client/cmddata.c, client/cmddata.h,
client/ui.c, client/cmdparser.c, client/cmdlfti.c, client/ui.h,
client/cmdlfem4x.c, client/cmdparser.h, client/cmdlfti.h, client/cmdlfem4x.h,
client/graph.c, client/graph.h, client/cmdhf14a.c, client/cmdhf14a.h,
client/cmdhflegic.c, client/cmdhflegic.c: New files.
client/cli.c, client/flasher.c, client/snooper.c, client/proxmark3.c,
client/proxmark3.h, client/Makefile: Update accordingly.
client/flash.h, client/flash.c, client/proxgui.cpp: Cosmetic changes.
client/translate.h, client/command.c, client/gui.c,
client/usb.c, client/prox.h: Remove.
include/usb_cmd.h (CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443_SIM): Remove dead cmd.
common/crc16.h: New file.
common/crc16.c: Modify accordingly.
common/iso14443crc.h: New file.
common/iso14443_crc.c: Rename to
common/iso14443crc.c: and modify accordingly.
armsrc/lfops.c, armsrc/iso14443.c,
armsrc/iso14443a.c: include .h files from
the common directory instead of including the c files.
common/Makefile.common, armsrc/Makefile: Modify accordingly.
2010-02-04 09:27:07 +08:00
} ;
2016-02-14 22:24:11 +08:00
int CmdLFEM4X ( const char * Cmd ) {
clearCommandBuffer ( ) ;
2015-04-03 00:48:52 +08:00
CmdsParse ( CommandTable , Cmd ) ;
return 0 ;
Client cleanup and restructuring. Stage 1...
Next Step is refactoring some of the giant functions which are
just copy/paste of some other ones with just a few line changes,
removing unnecessary 'goto' etc.
The MS Windows version is broken with this commit but will be fixed
soon. Everything can't be done all at once :P
The commands are now hierarchical, for example:
"hf 14a read" vs. "hf 14b read".
You can also request help:
"hf help", "data help", "hf 15 help" etc.
Indents are now space-based, not tab-based anymore. Hopefully
no one will be trolling about it, considering the suicide-prone work
being done here ;)
client/cmdhw.c, client/proxusb.c, client/cmdhw.h, client/proxusb.h,
client/cmdmain.c, client/cmdlfhid.c, client/cmdmain.h, client/cmdlfhid.h,
client/data.c, client/data.h, client/cmdhf.c, client/cmdlf.c,
client/cmdhf.h, client/cmdhf15.c, client/cmdhf14b.c, client/cmdlf.h,
client/cmdhf15.h, client/cmdhf14b.h, client/cmddata.c, client/cmddata.h,
client/ui.c, client/cmdparser.c, client/cmdlfti.c, client/ui.h,
client/cmdlfem4x.c, client/cmdparser.h, client/cmdlfti.h, client/cmdlfem4x.h,
client/graph.c, client/graph.h, client/cmdhf14a.c, client/cmdhf14a.h,
client/cmdhflegic.c, client/cmdhflegic.c: New files.
client/cli.c, client/flasher.c, client/snooper.c, client/proxmark3.c,
client/proxmark3.h, client/Makefile: Update accordingly.
client/flash.h, client/flash.c, client/proxgui.cpp: Cosmetic changes.
client/translate.h, client/command.c, client/gui.c,
client/usb.c, client/prox.h: Remove.
include/usb_cmd.h (CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443_SIM): Remove dead cmd.
common/crc16.h: New file.
common/crc16.c: Modify accordingly.
common/iso14443crc.h: New file.
common/iso14443_crc.c: Rename to
common/iso14443crc.c: and modify accordingly.
armsrc/lfops.c, armsrc/iso14443.c,
armsrc/iso14443a.c: include .h files from
the common directory instead of including the c files.
common/Makefile.common, armsrc/Makefile: Modify accordingly.
2010-02-04 09:27:07 +08:00
}
2016-02-14 22:24:11 +08:00
int CmdHelp ( const char * Cmd ) {
2015-04-03 00:48:52 +08:00
CmdsHelp ( CommandTable ) ;
return 0 ;
Client cleanup and restructuring. Stage 1...
Next Step is refactoring some of the giant functions which are
just copy/paste of some other ones with just a few line changes,
removing unnecessary 'goto' etc.
The MS Windows version is broken with this commit but will be fixed
soon. Everything can't be done all at once :P
The commands are now hierarchical, for example:
"hf 14a read" vs. "hf 14b read".
You can also request help:
"hf help", "data help", "hf 15 help" etc.
Indents are now space-based, not tab-based anymore. Hopefully
no one will be trolling about it, considering the suicide-prone work
being done here ;)
client/cmdhw.c, client/proxusb.c, client/cmdhw.h, client/proxusb.h,
client/cmdmain.c, client/cmdlfhid.c, client/cmdmain.h, client/cmdlfhid.h,
client/data.c, client/data.h, client/cmdhf.c, client/cmdlf.c,
client/cmdhf.h, client/cmdhf15.c, client/cmdhf14b.c, client/cmdlf.h,
client/cmdhf15.h, client/cmdhf14b.h, client/cmddata.c, client/cmddata.h,
client/ui.c, client/cmdparser.c, client/cmdlfti.c, client/ui.h,
client/cmdlfem4x.c, client/cmdparser.h, client/cmdlfti.h, client/cmdlfem4x.h,
client/graph.c, client/graph.h, client/cmdhf14a.c, client/cmdhf14a.h,
client/cmdhflegic.c, client/cmdhflegic.c: New files.
client/cli.c, client/flasher.c, client/snooper.c, client/proxmark3.c,
client/proxmark3.h, client/Makefile: Update accordingly.
client/flash.h, client/flash.c, client/proxgui.cpp: Cosmetic changes.
client/translate.h, client/command.c, client/gui.c,
client/usb.c, client/prox.h: Remove.
include/usb_cmd.h (CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443_SIM): Remove dead cmd.
common/crc16.h: New file.
common/crc16.c: Modify accordingly.
common/iso14443crc.h: New file.
common/iso14443_crc.c: Rename to
common/iso14443crc.c: and modify accordingly.
armsrc/lfops.c, armsrc/iso14443.c,
armsrc/iso14443a.c: include .h files from
the common directory instead of including the c files.
common/Makefile.common, armsrc/Makefile: Modify accordingly.
2010-02-04 09:27:07 +08:00
}